aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ecryptfs/messaging.c
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
commit8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch)
treea8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /fs/ecryptfs/messaging.c
parent406089d01562f1e2bf9f089fd7637009ebaad589 (diff)
Patched in Tegra support.
Diffstat (limited to 'fs/ecryptfs/messaging.c')
-rw-r--r--fs/ecryptfs/messaging.c135
1 files changed, 120 insertions, 15 deletions
diff --git a/fs/ecryptfs/messaging.c b/fs/ecryptfs/messaging.c
index 5fa2471796c..ab224809051 100644
--- a/fs/ecryptfs/messaging.c
+++ b/fs/ecryptfs/messaging.c
@@ -32,8 +32,8 @@ static struct mutex ecryptfs_msg_ctx_lists_mux;
32static struct hlist_head *ecryptfs_daemon_hash; 32static struct hlist_head *ecryptfs_daemon_hash;
33struct mutex ecryptfs_daemon_hash_mux; 33struct mutex ecryptfs_daemon_hash_mux;
34static int ecryptfs_hash_bits; 34static int ecryptfs_hash_bits;
35#define ecryptfs_current_euid_hash(uid) \ 35#define ecryptfs_uid_hash(uid) \
36 hash_long((unsigned long)from_kuid(&init_user_ns, current_euid()), ecryptfs_hash_bits) 36 hash_long((unsigned long)uid, ecryptfs_hash_bits)
37 37
38static u32 ecryptfs_msg_counter; 38static u32 ecryptfs_msg_counter;
39static struct ecryptfs_msg_ctx *ecryptfs_msg_ctx_arr; 39static struct ecryptfs_msg_ctx *ecryptfs_msg_ctx_arr;
@@ -105,23 +105,26 @@ 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
108 * @daemon: If return value is zero, points to the desired daemon pointer 110 * @daemon: If return value is zero, points to the desired daemon pointer
109 * 111 *
110 * Must be called with ecryptfs_daemon_hash_mux held. 112 * Must be called with ecryptfs_daemon_hash_mux held.
111 * 113 *
112 * Search the hash list for the current effective user id. 114 * Search the hash list for the given user id.
113 * 115 *
114 * Returns zero if the user id exists in the list; non-zero otherwise. 116 * Returns zero if the user id exists in the list; non-zero otherwise.
115 */ 117 */
116int ecryptfs_find_daemon_by_euid(struct ecryptfs_daemon **daemon) 118int ecryptfs_find_daemon_by_euid(struct ecryptfs_daemon **daemon, uid_t euid,
119 struct user_namespace *user_ns)
117{ 120{
118 struct hlist_node *elem; 121 struct hlist_node *elem;
119 int rc; 122 int rc;
120 123
121 hlist_for_each_entry(*daemon, elem, 124 hlist_for_each_entry(*daemon, elem,
122 &ecryptfs_daemon_hash[ecryptfs_current_euid_hash()], 125 &ecryptfs_daemon_hash[ecryptfs_uid_hash(euid)],
123 euid_chain) { 126 euid_chain) {
124 if (uid_eq((*daemon)->file->f_cred->euid, current_euid())) { 127 if ((*daemon)->euid == euid && (*daemon)->user_ns == user_ns) {
125 rc = 0; 128 rc = 0;
126 goto out; 129 goto out;
127 } 130 }
@@ -134,7 +137,9 @@ out:
134/** 137/**
135 * ecryptfs_spawn_daemon - Create and initialize a new daemon struct 138 * ecryptfs_spawn_daemon - Create and initialize a new daemon struct
136 * @daemon: Pointer to set to newly allocated daemon struct 139 * @daemon: Pointer to set to newly allocated daemon struct
137 * @file: File used when opening /dev/ecryptfs 140 * @euid: Effective user id for the daemon
141 * @user_ns: The namespace in which @euid applies
142 * @pid: Process id for the daemon
138 * 143 *
139 * Must be called ceremoniously while in possession of 144 * Must be called ceremoniously while in possession of
140 * ecryptfs_sacred_daemon_hash_mux 145 * ecryptfs_sacred_daemon_hash_mux
@@ -142,7 +147,8 @@ out:
142 * Returns zero on success; non-zero otherwise 147 * Returns zero on success; non-zero otherwise
143 */ 148 */
144int 149int
145ecryptfs_spawn_daemon(struct ecryptfs_daemon **daemon, struct file *file) 150ecryptfs_spawn_daemon(struct ecryptfs_daemon **daemon, uid_t euid,
151 struct user_namespace *user_ns, struct pid *pid)
146{ 152{
147 int rc = 0; 153 int rc = 0;
148 154
@@ -153,13 +159,16 @@ ecryptfs_spawn_daemon(struct ecryptfs_daemon **daemon, struct file *file)
153 "GFP_KERNEL memory\n", __func__, sizeof(**daemon)); 159 "GFP_KERNEL memory\n", __func__, sizeof(**daemon));
154 goto out; 160 goto out;
155 } 161 }
156 (*daemon)->file = file; 162 (*daemon)->euid = euid;
163 (*daemon)->user_ns = get_user_ns(user_ns);
164 (*daemon)->pid = get_pid(pid);
165 (*daemon)->task = current;
157 mutex_init(&(*daemon)->mux); 166 mutex_init(&(*daemon)->mux);
158 INIT_LIST_HEAD(&(*daemon)->msg_ctx_out_queue); 167 INIT_LIST_HEAD(&(*daemon)->msg_ctx_out_queue);
159 init_waitqueue_head(&(*daemon)->wait); 168 init_waitqueue_head(&(*daemon)->wait);
160 (*daemon)->num_queued_msg_ctx = 0; 169 (*daemon)->num_queued_msg_ctx = 0;
161 hlist_add_head(&(*daemon)->euid_chain, 170 hlist_add_head(&(*daemon)->euid_chain,
162 &ecryptfs_daemon_hash[ecryptfs_current_euid_hash()]); 171 &ecryptfs_daemon_hash[ecryptfs_uid_hash(euid)]);
163out: 172out:
164 return rc; 173 return rc;
165} 174}
@@ -179,6 +188,9 @@ int ecryptfs_exorcise_daemon(struct ecryptfs_daemon *daemon)
179 if ((daemon->flags & ECRYPTFS_DAEMON_IN_READ) 188 if ((daemon->flags & ECRYPTFS_DAEMON_IN_READ)
180 || (daemon->flags & ECRYPTFS_DAEMON_IN_POLL)) { 189 || (daemon->flags & ECRYPTFS_DAEMON_IN_POLL)) {
181 rc = -EBUSY; 190 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);
182 mutex_unlock(&daemon->mux); 194 mutex_unlock(&daemon->mux);
183 goto out; 195 goto out;
184 } 196 }
@@ -191,6 +203,12 @@ int ecryptfs_exorcise_daemon(struct ecryptfs_daemon *daemon)
191 ecryptfs_msg_ctx_alloc_to_free(msg_ctx); 203 ecryptfs_msg_ctx_alloc_to_free(msg_ctx);
192 } 204 }
193 hlist_del(&daemon->euid_chain); 205 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);
194 mutex_unlock(&daemon->mux); 212 mutex_unlock(&daemon->mux);
195 kzfree(daemon); 213 kzfree(daemon);
196out: 214out:
@@ -198,9 +216,42 @@ out:
198} 216}
199 217
200/** 218/**
219 * ecryptfs_process_quit
220 * @euid: The user ID owner of the message
221 * @user_ns: The namespace in which @euid applies
222 * @pid: The process ID for the userspace program that sent the
223 * message
224 *
225 * Deletes the corresponding daemon for the given euid and pid, if
226 * it is the registered that is requesting the deletion. Returns zero
227 * after deleting the desired daemon; non-zero otherwise.
228 */
229int ecryptfs_process_quit(uid_t euid, struct user_namespace *user_ns,
230 struct pid *pid)
231{
232 struct ecryptfs_daemon *daemon;
233 int rc;
234
235 mutex_lock(&ecryptfs_daemon_hash_mux);
236 rc = ecryptfs_find_daemon_by_euid(&daemon, euid, user_ns);
237 if (rc || !daemon) {
238 rc = -EINVAL;
239 printk(KERN_ERR "Received request from user [%d] to "
240 "unregister unrecognized daemon [0x%p]\n", euid, pid);
241 goto out_unlock;
242 }
243 rc = ecryptfs_exorcise_daemon(daemon);
244out_unlock:
245 mutex_unlock(&ecryptfs_daemon_hash_mux);
246 return rc;
247}
248
249/**
201 * ecryptfs_process_reponse 250 * ecryptfs_process_reponse
202 * @msg: The ecryptfs message received; the caller should sanity check 251 * @msg: The ecryptfs message received; the caller should sanity check
203 * msg->data_len and free the memory 252 * msg->data_len and free the memory
253 * @pid: The process ID of the userspace application that sent the
254 * message
204 * @seq: The sequence number of the message; must match the sequence 255 * @seq: The sequence number of the message; must match the sequence
205 * number for the existing message context waiting for this 256 * number for the existing message context waiting for this
206 * response 257 * response
@@ -219,11 +270,16 @@ out:
219 * 270 *
220 * Returns zero on success; non-zero otherwise 271 * Returns zero on success; non-zero otherwise
221 */ 272 */
222int ecryptfs_process_response(struct ecryptfs_daemon *daemon, 273int ecryptfs_process_response(struct ecryptfs_message *msg, uid_t euid,
223 struct ecryptfs_message *msg, u32 seq) 274 struct user_namespace *user_ns, struct pid *pid,
275 u32 seq)
224{ 276{
277 struct ecryptfs_daemon *uninitialized_var(daemon);
225 struct ecryptfs_msg_ctx *msg_ctx; 278 struct ecryptfs_msg_ctx *msg_ctx;
226 size_t msg_size; 279 size_t msg_size;
280 struct nsproxy *nsproxy;
281 struct user_namespace *tsk_user_ns;
282 uid_t ctx_euid;
227 int rc; 283 int rc;
228 284
229 if (msg->index >= ecryptfs_message_buf_len) { 285 if (msg->index >= ecryptfs_message_buf_len) {
@@ -236,6 +292,51 @@ int ecryptfs_process_response(struct ecryptfs_daemon *daemon,
236 } 292 }
237 msg_ctx = &ecryptfs_msg_ctx_arr[msg->index]; 293 msg_ctx = &ecryptfs_msg_ctx_arr[msg->index];
238 mutex_lock(&msg_ctx->mux); 294 mutex_lock(&msg_ctx->mux);
295 mutex_lock(&ecryptfs_daemon_hash_mux);
296 rcu_read_lock();
297 nsproxy = task_nsproxy(msg_ctx->task);
298 if (nsproxy == NULL) {
299 rc = -EBADMSG;
300 printk(KERN_ERR "%s: Receiving process is a zombie. Dropping "
301 "message.\n", __func__);
302 rcu_read_unlock();
303 mutex_unlock(&ecryptfs_daemon_hash_mux);
304 goto wake_up;
305 }
306 tsk_user_ns = __task_cred(msg_ctx->task)->user->user_ns;
307 ctx_euid = task_euid(msg_ctx->task);
308 rc = ecryptfs_find_daemon_by_euid(&daemon, ctx_euid, tsk_user_ns);
309 rcu_read_unlock();
310 mutex_unlock(&ecryptfs_daemon_hash_mux);
311 if (rc) {
312 rc = -EBADMSG;
313 printk(KERN_WARNING "%s: User [%d] received a "
314 "message response from process [0x%p] but does "
315 "not have a registered daemon\n", __func__,
316 ctx_euid, pid);
317 goto wake_up;
318 }
319 if (ctx_euid != euid) {
320 rc = -EBADMSG;
321 printk(KERN_WARNING "%s: Received message from user "
322 "[%d]; expected message from user [%d]\n", __func__,
323 euid, ctx_euid);
324 goto unlock;
325 }
326 if (tsk_user_ns != user_ns) {
327 rc = -EBADMSG;
328 printk(KERN_WARNING "%s: Received message from user_ns "
329 "[0x%p]; expected message from user_ns [0x%p]\n",
330 __func__, user_ns, tsk_user_ns);
331 goto unlock;
332 }
333 if (daemon->pid != pid) {
334 rc = -EBADMSG;
335 printk(KERN_ERR "%s: User [%d] sent a message response "
336 "from an unrecognized process [0x%p]\n",
337 __func__, ctx_euid, pid);
338 goto unlock;
339 }
239 if (msg_ctx->state != ECRYPTFS_MSG_CTX_STATE_PENDING) { 340 if (msg_ctx->state != ECRYPTFS_MSG_CTX_STATE_PENDING) {
240 rc = -EINVAL; 341 rc = -EINVAL;
241 printk(KERN_WARNING "%s: Desired context element is not " 342 printk(KERN_WARNING "%s: Desired context element is not "
@@ -258,8 +359,9 @@ int ecryptfs_process_response(struct ecryptfs_daemon *daemon,
258 } 359 }
259 memcpy(msg_ctx->msg, msg, msg_size); 360 memcpy(msg_ctx->msg, msg, msg_size);
260 msg_ctx->state = ECRYPTFS_MSG_CTX_STATE_DONE; 361 msg_ctx->state = ECRYPTFS_MSG_CTX_STATE_DONE;
261 wake_up_process(msg_ctx->task);
262 rc = 0; 362 rc = 0;
363wake_up:
364 wake_up_process(msg_ctx->task);
263unlock: 365unlock:
264 mutex_unlock(&msg_ctx->mux); 366 mutex_unlock(&msg_ctx->mux);
265out: 367out:
@@ -281,11 +383,14 @@ ecryptfs_send_message_locked(char *data, int data_len, u8 msg_type,
281 struct ecryptfs_msg_ctx **msg_ctx) 383 struct ecryptfs_msg_ctx **msg_ctx)
282{ 384{
283 struct ecryptfs_daemon *daemon; 385 struct ecryptfs_daemon *daemon;
386 uid_t euid = current_euid();
284 int rc; 387 int rc;
285 388
286 rc = ecryptfs_find_daemon_by_euid(&daemon); 389 rc = ecryptfs_find_daemon_by_euid(&daemon, euid, current_user_ns());
287 if (rc || !daemon) { 390 if (rc || !daemon) {
288 rc = -ENOTCONN; 391 rc = -ENOTCONN;
392 printk(KERN_ERR "%s: User [%d] does not have a daemon "
393 "registered\n", __func__, euid);
289 goto out; 394 goto out;
290 } 395 }
291 mutex_lock(&ecryptfs_msg_ctx_lists_mux); 396 mutex_lock(&ecryptfs_msg_ctx_lists_mux);