Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
messaging.c
Go to the documentation of this file.
1 
22 #include <linux/sched.h>
23 #include <linux/slab.h>
24 #include <linux/user_namespace.h>
25 #include <linux/nsproxy.h>
26 #include "ecryptfs_kernel.h"
27 
28 static LIST_HEAD(ecryptfs_msg_ctx_free_list);
29 static LIST_HEAD(ecryptfs_msg_ctx_alloc_list);
30 static struct mutex ecryptfs_msg_ctx_lists_mux;
31 
32 static struct hlist_head *ecryptfs_daemon_hash;
34 static int ecryptfs_hash_bits;
35 #define ecryptfs_current_euid_hash(uid) \
36  hash_long((unsigned long)from_kuid(&init_user_ns, current_euid()), ecryptfs_hash_bits)
37 
38 static u32 ecryptfs_msg_counter;
39 static struct ecryptfs_msg_ctx *ecryptfs_msg_ctx_arr;
40 
51 static int ecryptfs_acquire_free_msg_ctx(struct ecryptfs_msg_ctx **msg_ctx)
52 {
53  struct list_head *p;
54  int rc;
55 
56  if (list_empty(&ecryptfs_msg_ctx_free_list)) {
57  printk(KERN_WARNING "%s: The eCryptfs free "
58  "context list is empty. It may be helpful to "
59  "specify the ecryptfs_message_buf_len "
60  "parameter to be greater than the current "
61  "value of [%d]\n", __func__, ecryptfs_message_buf_len);
62  rc = -ENOMEM;
63  goto out;
64  }
65  list_for_each(p, &ecryptfs_msg_ctx_free_list) {
66  *msg_ctx = list_entry(p, struct ecryptfs_msg_ctx, node);
67  if (mutex_trylock(&(*msg_ctx)->mux)) {
68  (*msg_ctx)->task = current;
69  rc = 0;
70  goto out;
71  }
72  }
73  rc = -ENOMEM;
74 out:
75  return rc;
76 }
77 
84 static void ecryptfs_msg_ctx_free_to_alloc(struct ecryptfs_msg_ctx *msg_ctx)
85 {
86  list_move(&msg_ctx->node, &ecryptfs_msg_ctx_alloc_list);
88  msg_ctx->counter = ++ecryptfs_msg_counter;
89 }
90 
98 {
99  list_move(&(msg_ctx->node), &ecryptfs_msg_ctx_free_list);
100  if (msg_ctx->msg)
101  kfree(msg_ctx->msg);
102  msg_ctx->msg = NULL;
104 }
105 
117 {
118  struct hlist_node *elem;
119  int rc;
120 
121  hlist_for_each_entry(*daemon, elem,
122  &ecryptfs_daemon_hash[ecryptfs_current_euid_hash()],
123  euid_chain) {
124  if (uid_eq((*daemon)->file->f_cred->euid, current_euid())) {
125  rc = 0;
126  goto out;
127  }
128  }
129  rc = -EINVAL;
130 out:
131  return rc;
132 }
133 
144 int
146 {
147  int rc = 0;
148 
149  (*daemon) = kzalloc(sizeof(**daemon), GFP_KERNEL);
150  if (!(*daemon)) {
151  rc = -ENOMEM;
152  printk(KERN_ERR "%s: Failed to allocate [%zd] bytes of "
153  "GFP_KERNEL memory\n", __func__, sizeof(**daemon));
154  goto out;
155  }
156  (*daemon)->file = file;
157  mutex_init(&(*daemon)->mux);
158  INIT_LIST_HEAD(&(*daemon)->msg_ctx_out_queue);
159  init_waitqueue_head(&(*daemon)->wait);
160  (*daemon)->num_queued_msg_ctx = 0;
161  hlist_add_head(&(*daemon)->euid_chain,
162  &ecryptfs_daemon_hash[ecryptfs_current_euid_hash()]);
163 out:
164  return rc;
165 }
166 
174 {
175  struct ecryptfs_msg_ctx *msg_ctx, *msg_ctx_tmp;
176  int rc = 0;
177 
178  mutex_lock(&daemon->mux);
179  if ((daemon->flags & ECRYPTFS_DAEMON_IN_READ)
180  || (daemon->flags & ECRYPTFS_DAEMON_IN_POLL)) {
181  rc = -EBUSY;
182  mutex_unlock(&daemon->mux);
183  goto out;
184  }
185  list_for_each_entry_safe(msg_ctx, msg_ctx_tmp,
187  list_del(&msg_ctx->daemon_out_list);
188  daemon->num_queued_msg_ctx--;
189  printk(KERN_WARNING "%s: Warning: dropping message that is in "
190  "the out queue of a dying daemon\n", __func__);
192  }
193  hlist_del(&daemon->euid_chain);
194  mutex_unlock(&daemon->mux);
195  kzfree(daemon);
196 out:
197  return rc;
198 }
199 
223  struct ecryptfs_message *msg, u32 seq)
224 {
225  struct ecryptfs_msg_ctx *msg_ctx;
226  size_t msg_size;
227  int rc;
228 
229  if (msg->index >= ecryptfs_message_buf_len) {
230  rc = -EINVAL;
231  printk(KERN_ERR "%s: Attempt to reference "
232  "context buffer at index [%d]; maximum "
233  "allowable is [%d]\n", __func__, msg->index,
235  goto out;
236  }
237  msg_ctx = &ecryptfs_msg_ctx_arr[msg->index];
238  mutex_lock(&msg_ctx->mux);
239  if (msg_ctx->state != ECRYPTFS_MSG_CTX_STATE_PENDING) {
240  rc = -EINVAL;
241  printk(KERN_WARNING "%s: Desired context element is not "
242  "pending a response\n", __func__);
243  goto unlock;
244  } else if (msg_ctx->counter != seq) {
245  rc = -EINVAL;
246  printk(KERN_WARNING "%s: Invalid message sequence; "
247  "expected [%d]; received [%d]\n", __func__,
248  msg_ctx->counter, seq);
249  goto unlock;
250  }
251  msg_size = (sizeof(*msg) + msg->data_len);
252  msg_ctx->msg = kmalloc(msg_size, GFP_KERNEL);
253  if (!msg_ctx->msg) {
254  rc = -ENOMEM;
255  printk(KERN_ERR "%s: Failed to allocate [%zd] bytes of "
256  "GFP_KERNEL memory\n", __func__, msg_size);
257  goto unlock;
258  }
259  memcpy(msg_ctx->msg, msg, msg_size);
261  wake_up_process(msg_ctx->task);
262  rc = 0;
263 unlock:
264  mutex_unlock(&msg_ctx->mux);
265 out:
266  return rc;
267 }
268 
279 static int
280 ecryptfs_send_message_locked(char *data, int data_len, u8 msg_type,
281  struct ecryptfs_msg_ctx **msg_ctx)
282 {
283  struct ecryptfs_daemon *daemon;
284  int rc;
285 
286  rc = ecryptfs_find_daemon_by_euid(&daemon);
287  if (rc || !daemon) {
288  rc = -ENOTCONN;
289  goto out;
290  }
291  mutex_lock(&ecryptfs_msg_ctx_lists_mux);
292  rc = ecryptfs_acquire_free_msg_ctx(msg_ctx);
293  if (rc) {
294  mutex_unlock(&ecryptfs_msg_ctx_lists_mux);
295  printk(KERN_WARNING "%s: Could not claim a free "
296  "context element\n", __func__);
297  goto out;
298  }
299  ecryptfs_msg_ctx_free_to_alloc(*msg_ctx);
300  mutex_unlock(&(*msg_ctx)->mux);
301  mutex_unlock(&ecryptfs_msg_ctx_lists_mux);
302  rc = ecryptfs_send_miscdev(data, data_len, *msg_ctx, msg_type, 0,
303  daemon);
304  if (rc)
305  printk(KERN_ERR "%s: Error attempting to send message to "
306  "userspace daemon; rc = [%d]\n", __func__, rc);
307 out:
308  return rc;
309 }
310 
321 int ecryptfs_send_message(char *data, int data_len,
322  struct ecryptfs_msg_ctx **msg_ctx)
323 {
324  int rc;
325 
327  rc = ecryptfs_send_message_locked(data, data_len, ECRYPTFS_MSG_REQUEST,
328  msg_ctx);
330  return rc;
331 }
332 
345  struct ecryptfs_message **msg)
346 {
347  signed long timeout = ecryptfs_message_wait_timeout * HZ;
348  int rc = 0;
349 
350 sleep:
351  timeout = schedule_timeout_interruptible(timeout);
352  mutex_lock(&ecryptfs_msg_ctx_lists_mux);
353  mutex_lock(&msg_ctx->mux);
354  if (msg_ctx->state != ECRYPTFS_MSG_CTX_STATE_DONE) {
355  if (timeout) {
356  mutex_unlock(&msg_ctx->mux);
357  mutex_unlock(&ecryptfs_msg_ctx_lists_mux);
358  goto sleep;
359  }
360  rc = -ENOMSG;
361  } else {
362  *msg = msg_ctx->msg;
363  msg_ctx->msg = NULL;
364  }
366  mutex_unlock(&msg_ctx->mux);
367  mutex_unlock(&ecryptfs_msg_ctx_lists_mux);
368  return rc;
369 }
370 
372 {
373  int i;
374  int rc = 0;
375 
378  printk(KERN_WARNING "%s: Specified number of users is "
379  "too large, defaulting to [%d] users\n", __func__,
381  }
384  ecryptfs_hash_bits = 1;
385  while (ecryptfs_number_of_users >> ecryptfs_hash_bits)
386  ecryptfs_hash_bits++;
387  ecryptfs_daemon_hash = kmalloc((sizeof(struct hlist_head)
388  * (1 << ecryptfs_hash_bits)),
389  GFP_KERNEL);
390  if (!ecryptfs_daemon_hash) {
391  rc = -ENOMEM;
392  printk(KERN_ERR "%s: Failed to allocate memory\n", __func__);
394  goto out;
395  }
396  for (i = 0; i < (1 << ecryptfs_hash_bits); i++)
397  INIT_HLIST_HEAD(&ecryptfs_daemon_hash[i]);
399  ecryptfs_msg_ctx_arr = kmalloc((sizeof(struct ecryptfs_msg_ctx)
401  GFP_KERNEL);
402  if (!ecryptfs_msg_ctx_arr) {
403  rc = -ENOMEM;
404  printk(KERN_ERR "%s: Failed to allocate memory\n", __func__);
405  goto out;
406  }
407  mutex_init(&ecryptfs_msg_ctx_lists_mux);
408  mutex_lock(&ecryptfs_msg_ctx_lists_mux);
409  ecryptfs_msg_counter = 0;
410  for (i = 0; i < ecryptfs_message_buf_len; i++) {
411  INIT_LIST_HEAD(&ecryptfs_msg_ctx_arr[i].node);
412  INIT_LIST_HEAD(&ecryptfs_msg_ctx_arr[i].daemon_out_list);
413  mutex_init(&ecryptfs_msg_ctx_arr[i].mux);
414  mutex_lock(&ecryptfs_msg_ctx_arr[i].mux);
415  ecryptfs_msg_ctx_arr[i].index = i;
416  ecryptfs_msg_ctx_arr[i].state = ECRYPTFS_MSG_CTX_STATE_FREE;
417  ecryptfs_msg_ctx_arr[i].counter = 0;
418  ecryptfs_msg_ctx_arr[i].task = NULL;
419  ecryptfs_msg_ctx_arr[i].msg = NULL;
420  list_add_tail(&ecryptfs_msg_ctx_arr[i].node,
421  &ecryptfs_msg_ctx_free_list);
422  mutex_unlock(&ecryptfs_msg_ctx_arr[i].mux);
423  }
424  mutex_unlock(&ecryptfs_msg_ctx_lists_mux);
426  if (rc)
428 out:
429  return rc;
430 }
431 
433 {
434  if (ecryptfs_msg_ctx_arr) {
435  int i;
436 
437  mutex_lock(&ecryptfs_msg_ctx_lists_mux);
438  for (i = 0; i < ecryptfs_message_buf_len; i++) {
439  mutex_lock(&ecryptfs_msg_ctx_arr[i].mux);
440  if (ecryptfs_msg_ctx_arr[i].msg)
441  kfree(ecryptfs_msg_ctx_arr[i].msg);
442  mutex_unlock(&ecryptfs_msg_ctx_arr[i].mux);
443  }
444  kfree(ecryptfs_msg_ctx_arr);
445  mutex_unlock(&ecryptfs_msg_ctx_lists_mux);
446  }
447  if (ecryptfs_daemon_hash) {
448  struct hlist_node *elem;
449  struct ecryptfs_daemon *daemon;
450  int i;
451 
453  for (i = 0; i < (1 << ecryptfs_hash_bits); i++) {
454  int rc;
455 
456  hlist_for_each_entry(daemon, elem,
457  &ecryptfs_daemon_hash[i],
458  euid_chain) {
459  rc = ecryptfs_exorcise_daemon(daemon);
460  if (rc)
461  printk(KERN_ERR "%s: Error whilst "
462  "attempting to destroy daemon; "
463  "rc = [%d]. Dazed and confused, "
464  "but trying to continue.\n",
465  __func__, rc);
466  }
467  }
468  kfree(ecryptfs_daemon_hash);
470  }
472  return;
473 }