kthread.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  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 <[email protected]>
  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. * @cred: credential to use for this call
  101. *
  102. * This function gets a r/w file opened against the lower dentry.
  103. *
  104. * Returns zero on success; non-zero otherwise
  105. */
  106. int ecryptfs_privileged_open(struct file **lower_file,
  107. struct dentry *lower_dentry,
  108. struct vfsmount *lower_mnt,
  109. const struct cred *cred)
  110. {
  111. struct ecryptfs_open_req req;
  112. int flags = O_LARGEFILE;
  113. int rc = 0;
  114. init_completion(&req.done);
  115. req.lower_file = lower_file;
  116. req.path.dentry = lower_dentry;
  117. req.path.mnt = lower_mnt;
  118. /* Corresponding dput() and mntput() are done when the
  119. * lower file is fput() when all eCryptfs files for the inode are
  120. * released. */
  121. flags |= IS_RDONLY(d_inode(lower_dentry)) ? O_RDONLY : O_RDWR;
  122. (*lower_file) = dentry_open(&req.path, flags, cred);
  123. if (!IS_ERR(*lower_file))
  124. goto out;
  125. if ((flags & O_ACCMODE) == O_RDONLY) {
  126. rc = PTR_ERR((*lower_file));
  127. goto out;
  128. }
  129. mutex_lock(&ecryptfs_kthread_ctl.mux);
  130. if (ecryptfs_kthread_ctl.flags & ECRYPTFS_KTHREAD_ZOMBIE) {
  131. rc = -EIO;
  132. mutex_unlock(&ecryptfs_kthread_ctl.mux);
  133. printk(KERN_ERR "%s: We are in the middle of shutting down; "
  134. "aborting privileged request to open lower file\n",
  135. __func__);
  136. goto out;
  137. }
  138. list_add_tail(&req.kthread_ctl_list, &ecryptfs_kthread_ctl.req_list);
  139. mutex_unlock(&ecryptfs_kthread_ctl.mux);
  140. wake_up(&ecryptfs_kthread_ctl.wait);
  141. wait_for_completion(&req.done);
  142. if (IS_ERR(*lower_file))
  143. rc = PTR_ERR(*lower_file);
  144. out:
  145. return rc;
  146. }