0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/kthread.h>
0010 #include <linux/freezer.h>
0011 #include <linux/slab.h>
0012 #include <linux/wait.h>
0013 #include <linux/mount.h>
0014 #include "ecryptfs_kernel.h"
0015
0016 struct ecryptfs_open_req {
0017 struct file **lower_file;
0018 struct path path;
0019 struct completion done;
0020 struct list_head kthread_ctl_list;
0021 };
0022
0023 static struct ecryptfs_kthread_ctl {
0024 #define ECRYPTFS_KTHREAD_ZOMBIE 0x00000001
0025 u32 flags;
0026 struct mutex mux;
0027 struct list_head req_list;
0028 wait_queue_head_t wait;
0029 } ecryptfs_kthread_ctl;
0030
0031 static struct task_struct *ecryptfs_kthread;
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042 static int ecryptfs_threadfn(void *ignored)
0043 {
0044 set_freezable();
0045 while (1) {
0046 struct ecryptfs_open_req *req;
0047
0048 wait_event_freezable(
0049 ecryptfs_kthread_ctl.wait,
0050 (!list_empty(&ecryptfs_kthread_ctl.req_list)
0051 || kthread_should_stop()));
0052 mutex_lock(&ecryptfs_kthread_ctl.mux);
0053 if (ecryptfs_kthread_ctl.flags & ECRYPTFS_KTHREAD_ZOMBIE) {
0054 mutex_unlock(&ecryptfs_kthread_ctl.mux);
0055 goto out;
0056 }
0057 while (!list_empty(&ecryptfs_kthread_ctl.req_list)) {
0058 req = list_first_entry(&ecryptfs_kthread_ctl.req_list,
0059 struct ecryptfs_open_req,
0060 kthread_ctl_list);
0061 list_del(&req->kthread_ctl_list);
0062 *req->lower_file = dentry_open(&req->path,
0063 (O_RDWR | O_LARGEFILE), current_cred());
0064 complete(&req->done);
0065 }
0066 mutex_unlock(&ecryptfs_kthread_ctl.mux);
0067 }
0068 out:
0069 return 0;
0070 }
0071
0072 int __init ecryptfs_init_kthread(void)
0073 {
0074 int rc = 0;
0075
0076 mutex_init(&ecryptfs_kthread_ctl.mux);
0077 init_waitqueue_head(&ecryptfs_kthread_ctl.wait);
0078 INIT_LIST_HEAD(&ecryptfs_kthread_ctl.req_list);
0079 ecryptfs_kthread = kthread_run(&ecryptfs_threadfn, NULL,
0080 "ecryptfs-kthread");
0081 if (IS_ERR(ecryptfs_kthread)) {
0082 rc = PTR_ERR(ecryptfs_kthread);
0083 printk(KERN_ERR "%s: Failed to create kernel thread; rc = [%d]"
0084 "\n", __func__, rc);
0085 }
0086 return rc;
0087 }
0088
0089 void ecryptfs_destroy_kthread(void)
0090 {
0091 struct ecryptfs_open_req *req, *tmp;
0092
0093 mutex_lock(&ecryptfs_kthread_ctl.mux);
0094 ecryptfs_kthread_ctl.flags |= ECRYPTFS_KTHREAD_ZOMBIE;
0095 list_for_each_entry_safe(req, tmp, &ecryptfs_kthread_ctl.req_list,
0096 kthread_ctl_list) {
0097 list_del(&req->kthread_ctl_list);
0098 *req->lower_file = ERR_PTR(-EIO);
0099 complete(&req->done);
0100 }
0101 mutex_unlock(&ecryptfs_kthread_ctl.mux);
0102 kthread_stop(ecryptfs_kthread);
0103 wake_up(&ecryptfs_kthread_ctl.wait);
0104 }
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117 int ecryptfs_privileged_open(struct file **lower_file,
0118 struct dentry *lower_dentry,
0119 struct vfsmount *lower_mnt,
0120 const struct cred *cred)
0121 {
0122 struct ecryptfs_open_req req;
0123 int flags = O_LARGEFILE;
0124 int rc = 0;
0125
0126 init_completion(&req.done);
0127 req.lower_file = lower_file;
0128 req.path.dentry = lower_dentry;
0129 req.path.mnt = lower_mnt;
0130
0131
0132
0133
0134 flags |= IS_RDONLY(d_inode(lower_dentry)) ? O_RDONLY : O_RDWR;
0135 (*lower_file) = dentry_open(&req.path, flags, cred);
0136 if (!IS_ERR(*lower_file))
0137 goto out;
0138 if ((flags & O_ACCMODE) == O_RDONLY) {
0139 rc = PTR_ERR((*lower_file));
0140 goto out;
0141 }
0142 mutex_lock(&ecryptfs_kthread_ctl.mux);
0143 if (ecryptfs_kthread_ctl.flags & ECRYPTFS_KTHREAD_ZOMBIE) {
0144 rc = -EIO;
0145 mutex_unlock(&ecryptfs_kthread_ctl.mux);
0146 printk(KERN_ERR "%s: We are in the middle of shutting down; "
0147 "aborting privileged request to open lower file\n",
0148 __func__);
0149 goto out;
0150 }
0151 list_add_tail(&req.kthread_ctl_list, &ecryptfs_kthread_ctl.req_list);
0152 mutex_unlock(&ecryptfs_kthread_ctl.mux);
0153 wake_up(&ecryptfs_kthread_ctl.wait);
0154 wait_for_completion(&req.done);
0155 if (IS_ERR(*lower_file))
0156 rc = PTR_ERR(*lower_file);
0157 out:
0158 return rc;
0159 }