diff options
Diffstat (limited to 'fs/ecryptfs/messaging.c')
-rw-r--r-- | fs/ecryptfs/messaging.c | 105 |
1 files changed, 16 insertions, 89 deletions
diff --git a/fs/ecryptfs/messaging.c b/fs/ecryptfs/messaging.c index c11911decdc1..b29bb8bfa8d9 100644 --- a/fs/ecryptfs/messaging.c +++ b/fs/ecryptfs/messaging.c | |||
@@ -32,8 +32,8 @@ static struct mutex ecryptfs_msg_ctx_lists_mux; | |||
32 | static struct hlist_head *ecryptfs_daemon_hash; | 32 | static struct hlist_head *ecryptfs_daemon_hash; |
33 | struct mutex ecryptfs_daemon_hash_mux; | 33 | struct mutex ecryptfs_daemon_hash_mux; |
34 | static int ecryptfs_hash_bits; | 34 | static int ecryptfs_hash_bits; |
35 | #define ecryptfs_uid_hash(uid) \ | 35 | #define ecryptfs_current_euid_hash(uid) \ |
36 | hash_long((unsigned long)uid, ecryptfs_hash_bits) | 36 | hash_long((unsigned long)current_euid(), ecryptfs_hash_bits) |
37 | 37 | ||
38 | static u32 ecryptfs_msg_counter; | 38 | static u32 ecryptfs_msg_counter; |
39 | static struct ecryptfs_msg_ctx *ecryptfs_msg_ctx_arr; | 39 | static struct ecryptfs_msg_ctx *ecryptfs_msg_ctx_arr; |
@@ -105,26 +105,24 @@ void ecryptfs_msg_ctx_alloc_to_free(struct ecryptfs_msg_ctx *msg_ctx) | |||
105 | 105 | ||
106 | /** | 106 | /** |
107 | * ecryptfs_find_daemon_by_euid | 107 | * ecryptfs_find_daemon_by_euid |
108 | * @euid: The effective user id which maps to the desired daemon id | ||
109 | * @user_ns: The namespace in which @euid applies | ||
110 | * @daemon: If return value is zero, points to the desired daemon pointer | 108 | * @daemon: If return value is zero, points to the desired daemon pointer |
111 | * | 109 | * |
112 | * Must be called with ecryptfs_daemon_hash_mux held. | 110 | * Must be called with ecryptfs_daemon_hash_mux held. |
113 | * | 111 | * |
114 | * Search the hash list for the given user id. | 112 | * Search the hash list for the current effective user id. |
115 | * | 113 | * |
116 | * Returns zero if the user id exists in the list; non-zero otherwise. | 114 | * Returns zero if the user id exists in the list; non-zero otherwise. |
117 | */ | 115 | */ |
118 | int ecryptfs_find_daemon_by_euid(struct ecryptfs_daemon **daemon, uid_t euid, | 116 | int ecryptfs_find_daemon_by_euid(struct ecryptfs_daemon **daemon) |
119 | struct user_namespace *user_ns) | ||
120 | { | 117 | { |
121 | struct hlist_node *elem; | 118 | struct hlist_node *elem; |
122 | int rc; | 119 | int rc; |
123 | 120 | ||
124 | hlist_for_each_entry(*daemon, elem, | 121 | hlist_for_each_entry(*daemon, elem, |
125 | &ecryptfs_daemon_hash[ecryptfs_uid_hash(euid)], | 122 | &ecryptfs_daemon_hash[ecryptfs_current_euid_hash()], |
126 | euid_chain) { | 123 | euid_chain) { |
127 | if ((*daemon)->euid == euid && (*daemon)->user_ns == user_ns) { | 124 | if ((*daemon)->file->f_cred->euid == current_euid() && |
125 | (*daemon)->file->f_cred->user_ns == current_user_ns()) { | ||
128 | rc = 0; | 126 | rc = 0; |
129 | goto out; | 127 | goto out; |
130 | } | 128 | } |
@@ -137,9 +135,7 @@ out: | |||
137 | /** | 135 | /** |
138 | * ecryptfs_spawn_daemon - Create and initialize a new daemon struct | 136 | * ecryptfs_spawn_daemon - Create and initialize a new daemon struct |
139 | * @daemon: Pointer to set to newly allocated daemon struct | 137 | * @daemon: Pointer to set to newly allocated daemon struct |
140 | * @euid: Effective user id for the daemon | 138 | * @file: File used when opening /dev/ecryptfs |
141 | * @user_ns: The namespace in which @euid applies | ||
142 | * @pid: Process id for the daemon | ||
143 | * | 139 | * |
144 | * Must be called ceremoniously while in possession of | 140 | * Must be called ceremoniously while in possession of |
145 | * ecryptfs_sacred_daemon_hash_mux | 141 | * ecryptfs_sacred_daemon_hash_mux |
@@ -147,8 +143,7 @@ out: | |||
147 | * Returns zero on success; non-zero otherwise | 143 | * Returns zero on success; non-zero otherwise |
148 | */ | 144 | */ |
149 | int | 145 | int |
150 | ecryptfs_spawn_daemon(struct ecryptfs_daemon **daemon, uid_t euid, | 146 | ecryptfs_spawn_daemon(struct ecryptfs_daemon **daemon, struct file *file) |
151 | struct user_namespace *user_ns, struct pid *pid) | ||
152 | { | 147 | { |
153 | int rc = 0; | 148 | int rc = 0; |
154 | 149 | ||
@@ -159,16 +154,13 @@ ecryptfs_spawn_daemon(struct ecryptfs_daemon **daemon, uid_t euid, | |||
159 | "GFP_KERNEL memory\n", __func__, sizeof(**daemon)); | 154 | "GFP_KERNEL memory\n", __func__, sizeof(**daemon)); |
160 | goto out; | 155 | goto out; |
161 | } | 156 | } |
162 | (*daemon)->euid = euid; | 157 | (*daemon)->file = file; |
163 | (*daemon)->user_ns = get_user_ns(user_ns); | ||
164 | (*daemon)->pid = get_pid(pid); | ||
165 | (*daemon)->task = current; | ||
166 | mutex_init(&(*daemon)->mux); | 158 | mutex_init(&(*daemon)->mux); |
167 | INIT_LIST_HEAD(&(*daemon)->msg_ctx_out_queue); | 159 | INIT_LIST_HEAD(&(*daemon)->msg_ctx_out_queue); |
168 | init_waitqueue_head(&(*daemon)->wait); | 160 | init_waitqueue_head(&(*daemon)->wait); |
169 | (*daemon)->num_queued_msg_ctx = 0; | 161 | (*daemon)->num_queued_msg_ctx = 0; |
170 | hlist_add_head(&(*daemon)->euid_chain, | 162 | hlist_add_head(&(*daemon)->euid_chain, |
171 | &ecryptfs_daemon_hash[ecryptfs_uid_hash(euid)]); | 163 | &ecryptfs_daemon_hash[ecryptfs_current_euid_hash()]); |
172 | out: | 164 | out: |
173 | return rc; | 165 | return rc; |
174 | } | 166 | } |
@@ -188,9 +180,6 @@ int ecryptfs_exorcise_daemon(struct ecryptfs_daemon *daemon) | |||
188 | if ((daemon->flags & ECRYPTFS_DAEMON_IN_READ) | 180 | if ((daemon->flags & ECRYPTFS_DAEMON_IN_READ) |
189 | || (daemon->flags & ECRYPTFS_DAEMON_IN_POLL)) { | 181 | || (daemon->flags & ECRYPTFS_DAEMON_IN_POLL)) { |
190 | rc = -EBUSY; | 182 | rc = -EBUSY; |
191 | printk(KERN_WARNING "%s: Attempt to destroy daemon with pid " | ||
192 | "[0x%p], but it is in the midst of a read or a poll\n", | ||
193 | __func__, daemon->pid); | ||
194 | mutex_unlock(&daemon->mux); | 183 | mutex_unlock(&daemon->mux); |
195 | goto out; | 184 | goto out; |
196 | } | 185 | } |
@@ -203,12 +192,6 @@ int ecryptfs_exorcise_daemon(struct ecryptfs_daemon *daemon) | |||
203 | ecryptfs_msg_ctx_alloc_to_free(msg_ctx); | 192 | ecryptfs_msg_ctx_alloc_to_free(msg_ctx); |
204 | } | 193 | } |
205 | hlist_del(&daemon->euid_chain); | 194 | hlist_del(&daemon->euid_chain); |
206 | if (daemon->task) | ||
207 | wake_up_process(daemon->task); | ||
208 | if (daemon->pid) | ||
209 | put_pid(daemon->pid); | ||
210 | if (daemon->user_ns) | ||
211 | put_user_ns(daemon->user_ns); | ||
212 | mutex_unlock(&daemon->mux); | 195 | mutex_unlock(&daemon->mux); |
213 | kzfree(daemon); | 196 | kzfree(daemon); |
214 | out: | 197 | out: |
@@ -219,8 +202,6 @@ out: | |||
219 | * ecryptfs_process_reponse | 202 | * ecryptfs_process_reponse |
220 | * @msg: The ecryptfs message received; the caller should sanity check | 203 | * @msg: The ecryptfs message received; the caller should sanity check |
221 | * msg->data_len and free the memory | 204 | * msg->data_len and free the memory |
222 | * @pid: The process ID of the userspace application that sent the | ||
223 | * message | ||
224 | * @seq: The sequence number of the message; must match the sequence | 205 | * @seq: The sequence number of the message; must match the sequence |
225 | * number for the existing message context waiting for this | 206 | * number for the existing message context waiting for this |
226 | * response | 207 | * response |
@@ -239,16 +220,11 @@ out: | |||
239 | * | 220 | * |
240 | * Returns zero on success; non-zero otherwise | 221 | * Returns zero on success; non-zero otherwise |
241 | */ | 222 | */ |
242 | int ecryptfs_process_response(struct ecryptfs_message *msg, uid_t euid, | 223 | int ecryptfs_process_response(struct ecryptfs_daemon *daemon, |
243 | struct user_namespace *user_ns, struct pid *pid, | 224 | struct ecryptfs_message *msg, u32 seq) |
244 | u32 seq) | ||
245 | { | 225 | { |
246 | struct ecryptfs_daemon *uninitialized_var(daemon); | ||
247 | struct ecryptfs_msg_ctx *msg_ctx; | 226 | struct ecryptfs_msg_ctx *msg_ctx; |
248 | size_t msg_size; | 227 | size_t msg_size; |
249 | struct nsproxy *nsproxy; | ||
250 | struct user_namespace *tsk_user_ns; | ||
251 | uid_t ctx_euid; | ||
252 | int rc; | 228 | int rc; |
253 | 229 | ||
254 | if (msg->index >= ecryptfs_message_buf_len) { | 230 | if (msg->index >= ecryptfs_message_buf_len) { |
@@ -261,51 +237,6 @@ int ecryptfs_process_response(struct ecryptfs_message *msg, uid_t euid, | |||
261 | } | 237 | } |
262 | msg_ctx = &ecryptfs_msg_ctx_arr[msg->index]; | 238 | msg_ctx = &ecryptfs_msg_ctx_arr[msg->index]; |
263 | mutex_lock(&msg_ctx->mux); | 239 | mutex_lock(&msg_ctx->mux); |
264 | mutex_lock(&ecryptfs_daemon_hash_mux); | ||
265 | rcu_read_lock(); | ||
266 | nsproxy = task_nsproxy(msg_ctx->task); | ||
267 | if (nsproxy == NULL) { | ||
268 | rc = -EBADMSG; | ||
269 | printk(KERN_ERR "%s: Receiving process is a zombie. Dropping " | ||
270 | "message.\n", __func__); | ||
271 | rcu_read_unlock(); | ||
272 | mutex_unlock(&ecryptfs_daemon_hash_mux); | ||
273 | goto wake_up; | ||
274 | } | ||
275 | tsk_user_ns = __task_cred(msg_ctx->task)->user_ns; | ||
276 | ctx_euid = task_euid(msg_ctx->task); | ||
277 | rc = ecryptfs_find_daemon_by_euid(&daemon, ctx_euid, tsk_user_ns); | ||
278 | rcu_read_unlock(); | ||
279 | mutex_unlock(&ecryptfs_daemon_hash_mux); | ||
280 | if (rc) { | ||
281 | rc = -EBADMSG; | ||
282 | printk(KERN_WARNING "%s: User [%d] received a " | ||
283 | "message response from process [0x%p] but does " | ||
284 | "not have a registered daemon\n", __func__, | ||
285 | ctx_euid, pid); | ||
286 | goto wake_up; | ||
287 | } | ||
288 | if (ctx_euid != euid) { | ||
289 | rc = -EBADMSG; | ||
290 | printk(KERN_WARNING "%s: Received message from user " | ||
291 | "[%d]; expected message from user [%d]\n", __func__, | ||
292 | euid, ctx_euid); | ||
293 | goto unlock; | ||
294 | } | ||
295 | if (tsk_user_ns != user_ns) { | ||
296 | rc = -EBADMSG; | ||
297 | printk(KERN_WARNING "%s: Received message from user_ns " | ||
298 | "[0x%p]; expected message from user_ns [0x%p]\n", | ||
299 | __func__, user_ns, tsk_user_ns); | ||
300 | goto unlock; | ||
301 | } | ||
302 | if (daemon->pid != pid) { | ||
303 | rc = -EBADMSG; | ||
304 | printk(KERN_ERR "%s: User [%d] sent a message response " | ||
305 | "from an unrecognized process [0x%p]\n", | ||
306 | __func__, ctx_euid, pid); | ||
307 | goto unlock; | ||
308 | } | ||
309 | if (msg_ctx->state != ECRYPTFS_MSG_CTX_STATE_PENDING) { | 240 | if (msg_ctx->state != ECRYPTFS_MSG_CTX_STATE_PENDING) { |
310 | rc = -EINVAL; | 241 | rc = -EINVAL; |
311 | printk(KERN_WARNING "%s: Desired context element is not " | 242 | printk(KERN_WARNING "%s: Desired context element is not " |
@@ -328,9 +259,8 @@ int ecryptfs_process_response(struct ecryptfs_message *msg, uid_t euid, | |||
328 | } | 259 | } |
329 | memcpy(msg_ctx->msg, msg, msg_size); | 260 | memcpy(msg_ctx->msg, msg, msg_size); |
330 | msg_ctx->state = ECRYPTFS_MSG_CTX_STATE_DONE; | 261 | msg_ctx->state = ECRYPTFS_MSG_CTX_STATE_DONE; |
331 | rc = 0; | ||
332 | wake_up: | ||
333 | wake_up_process(msg_ctx->task); | 262 | wake_up_process(msg_ctx->task); |
263 | rc = 0; | ||
334 | unlock: | 264 | unlock: |
335 | mutex_unlock(&msg_ctx->mux); | 265 | mutex_unlock(&msg_ctx->mux); |
336 | out: | 266 | out: |
@@ -352,14 +282,11 @@ ecryptfs_send_message_locked(char *data, int data_len, u8 msg_type, | |||
352 | struct ecryptfs_msg_ctx **msg_ctx) | 282 | struct ecryptfs_msg_ctx **msg_ctx) |
353 | { | 283 | { |
354 | struct ecryptfs_daemon *daemon; | 284 | struct ecryptfs_daemon *daemon; |
355 | uid_t euid = current_euid(); | ||
356 | int rc; | 285 | int rc; |
357 | 286 | ||
358 | rc = ecryptfs_find_daemon_by_euid(&daemon, euid, current_user_ns()); | 287 | rc = ecryptfs_find_daemon_by_euid(&daemon); |
359 | if (rc || !daemon) { | 288 | if (rc || !daemon) { |
360 | rc = -ENOTCONN; | 289 | rc = -ENOTCONN; |
361 | printk(KERN_ERR "%s: User [%d] does not have a daemon " | ||
362 | "registered\n", __func__, euid); | ||
363 | goto out; | 290 | goto out; |
364 | } | 291 | } |
365 | mutex_lock(&ecryptfs_msg_ctx_lists_mux); | 292 | mutex_lock(&ecryptfs_msg_ctx_lists_mux); |