kthread.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /**
  3. * eCryptfs: Linux filesystem encryption layer
  4. *
  5. * Copyright (C) 2008 International Business Machines Corp.
  6. * Author(s): Michael A. Halcrow <mahalcro@us.ibm.com>
  7. */
  8. #include <linux/kthread.h>
  9. #include <linux/freezer.h>
  10. #include <linux/slab.h>
  11. #include <linux/wait.h>
  12. #include <linux/mount.h>
  13. #include "ecryptfs_kernel.h"
  14. struct ecryptfs_open_req {
  15. struct file **lower_file;
  16. struct path path;
  17. struct completion done;
  18. struct list_head kthread_ctl_list;
  19. };
  20. static struct ecryptfs_kthread_ctl {
  21. #define ECRYPTFS_KTHREAD_ZOMBIE 0x00000001
  22. u32 flags;
  23. struct mutex mux;
  24. struct list_head req_list;
  25. wait_queue_head_t wait;
  26. } ecryptfs_kthread_ctl;
  27. static struct task_struct *ecryptfs_kthread;
  28. /**
  29. * ecryptfs_threadfn
  30. * @ignored: ignored
  31. *
  32. * The eCryptfs kernel thread that has the responsibility of getting
  33. * the lower file with RW permissions.
  34. *
  35. * Returns zero on success; non-zero otherwise
  36. */
  37. static int ecryptfs_threadfn(void *ignored)
  38. {
  39. set_freezable();
  40. while (1) {
  41. struct ecryptfs_open_req *req;
  42. wait_event_freezable(
  43. ecryptfs_kthread_ctl.wait,
  44. (!list_empty(&ecryptfs_kthread_ctl.req_list)
  45. || kthread_should_stop()));
  46. mutex_lock(&ecryptfs_kthread_ctl.mux);
  47. if (ecryptfs_kthread_ctl.flags & ECRYPTFS_KTHREAD_ZOMBIE) {
  48. mutex_unlock(&ecryptfs_kthread_ctl.mux);
  49. goto out;
  50. }
  51. while (!list_empty(&ecryptfs_kthread_ctl.req_list)) {
  52. req = list_first_entry(&ecryptfs_kthread_ctl.req_list,
  53. struct ecryptfs_open_req,
  54. kthread_ctl_list);
  55. list_del(&req->kthread_ctl_list);
  56. *req->lower_file = dentry_open(&req->path,
  57. (O_RDWR | O_LARGEFILE), current_cred());
  58. complete(&req->done);
  59. }
  60. mutex_unlock(&ecryptfs_kthread_ctl.mux);
  61. }
  62. out:
  63. return 0;
  64. }
  65. int __init ecryptfs_init_kthread(void)
  66. {
  67. int rc = 0;
  68. mutex_init(&ecryptfs_kthread_ctl.mux);
  69. init_waitqueue_head(&ecryptfs_kthread_ctl.wait);
  70. INIT_LIST_HEAD(&ecryptfs_kthread_ctl.req_list);
  71. ecryptfs_kthread = kthread_run(&ecryptfs_threadfn, NULL,
  72. "ecryptfs-kthread");
  73. if (IS_ERR(ecryptfs_kthread)) {
  74. rc = PTR_ERR(ecryptfs_kthread);
  75. printk(KERN_ERR "%s: Failed to create kernel thread; rc = [%d]"
  76. "\n", __func__, rc);
  77. }
  78. return rc;
  79. }
  80. void ecryptfs_destroy_kthread(void)
  81. {
  82. struct ecryptfs_open_req *req, *tmp;
  83. mutex_lock(&ecryptfs_kthread_ctl.mux);
  84. ecryptfs_kthread_ctl.flags |= ECRYPTFS_KTHREAD_ZOMBIE;
  85. list_for_each_entry_safe(req, tmp, &ecryptfs_kthread_ctl.req_list,
  86. kthread_ctl_list) {
  87. list_del(&req->kthread_ctl_list);
  88. *req->lower_file = ERR_PTR(-EIO);
  89. complete(&req->done);
  90. }
  91. mutex_unlock(&ecryptfs_kthread_ctl.mux);
  92. kthread_stop(ecryptfs_kthread);
  93. wake_up(&ecryptfs_kthread_ctl.wait);
  94. }
  95. /**
  96. * ecryptfs_privileged_open
  97. * @lower_file: Result of dentry_open by root on lower dentry
  98. * @lower_dentry: Lower dentry for file to open
  99. * @lower_mnt: Lower vfsmount for file to open
  100. *
  101. * This function gets a r/w file opened against the lower dentry.
  102. *
  103. * Returns zero on success; non-zero otherwise
  104. */
  105. int ecryptfs_privileged_open(struct file **lower_file,
  106. struct dentry *lower_dentry,
  107. struct vfsmount *lower_mnt,
  108. const struct cred *cred)
  109. {
  110. struct ecryptfs_open_req req;
  111. int flags = O_LARGEFILE;
  112. int rc = 0;
  113. init_completion(&req.done);
  114. req.lower_file = lower_file;
  115. req.path.dentry = lower_dentry;
  116. req.path.mnt = lower_mnt;
  117. /* Corresponding dput() and mntput() are done when the
  118. * lower file is fput() when all eCryptfs files for the inode are
  119. * released. */
  120. flags |= IS_RDONLY(d_inode(lower_dentry)) ? O_RDONLY : O_RDWR;
  121. (*lower_file) = dentry_open(&req.path, flags, cred);
  122. if (!IS_ERR(*lower_file))
  123. goto out;
  124. if ((flags & O_ACCMODE) == O_RDONLY) {
  125. rc = PTR_ERR((*lower_file));
  126. goto out;
  127. }
  128. mutex_lock(&ecryptfs_kthread_ctl.mux);
  129. if (ecryptfs_kthread_ctl.flags & ECRYPTFS_KTHREAD_ZOMBIE) {
  130. rc = -EIO;
  131. mutex_unlock(&ecryptfs_kthread_ctl.mux);
  132. printk(KERN_ERR "%s: We are in the middle of shutting down; "
  133. "aborting privileged request to open lower file\n",
  134. __func__);
  135. goto out;
  136. }
  137. list_add_tail(&req.kthread_ctl_list, &ecryptfs_kthread_ctl.req_list);
  138. mutex_unlock(&ecryptfs_kthread_ctl.mux);
  139. wake_up(&ecryptfs_kthread_ctl.wait);
  140. wait_for_completion(&req.done);
  141. if (IS_ERR(*lower_file))
  142. rc = PTR_ERR(*lower_file);
  143. out:
  144. return rc;
  145. }