fd.c 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351
  1. #include <linux/sched.h>
  2. #include <linux/errno.h>
  3. #include <linux/dcache.h>
  4. #include <linux/path.h>
  5. #include <linux/fdtable.h>
  6. #include <linux/namei.h>
  7. #include <linux/pid.h>
  8. #include <linux/security.h>
  9. #include <linux/proc_fs.h>
  10. #include "internal.h"
  11. #include "fd.h"
  12. #define PROC_FDINFO_MAX 64
  13. static int proc_fd_info(struct inode *inode, struct path *path, char *info)
  14. {
  15. struct task_struct *task = get_proc_task(inode);
  16. struct files_struct *files = NULL;
  17. int fd = proc_fd(inode);
  18. struct file *file;
  19. if (task) {
  20. files = get_files_struct(task);
  21. put_task_struct(task);
  22. }
  23. if (files) {
  24. /*
  25. * We are not taking a ref to the file structure, so we must
  26. * hold ->file_lock.
  27. */
  28. spin_lock(&files->file_lock);
  29. file = fcheck_files(files, fd);
  30. if (file) {
  31. unsigned int f_flags;
  32. struct fdtable *fdt;
  33. fdt = files_fdtable(files);
  34. f_flags = file->f_flags & ~O_CLOEXEC;
  35. if (close_on_exec(fd, fdt))
  36. f_flags |= O_CLOEXEC;
  37. if (path) {
  38. *path = file->f_path;
  39. path_get(&file->f_path);
  40. }
  41. if (info)
  42. snprintf(info, PROC_FDINFO_MAX,
  43. "pos:\t%lli\n"
  44. "flags:\t0%o\n",
  45. (long long) file->f_pos,
  46. f_flags);
  47. spin_unlock(&files->file_lock);
  48. put_files_struct(files);
  49. return 0;
  50. }
  51. spin_unlock(&files->file_lock);
  52. put_files_struct(files);
  53. }
  54. return -ENOENT;
  55. }
  56. static int tid_fd_revalidate(struct dentry *dentry, unsigned int flags)
  57. {
  58. struct files_struct *files;
  59. struct task_struct *task;
  60. const struct cred *cred;
  61. struct inode *inode;
  62. int fd;
  63. if (flags & LOOKUP_RCU)
  64. return -ECHILD;
  65. inode = dentry->d_inode;
  66. task = get_proc_task(inode);
  67. fd = proc_fd(inode);
  68. if (task) {
  69. files = get_files_struct(task);
  70. if (files) {
  71. struct file *file;
  72. rcu_read_lock();
  73. file = fcheck_files(files, fd);
  74. if (file) {
  75. unsigned f_mode = file->f_mode;
  76. rcu_read_unlock();
  77. put_files_struct(files);
  78. if (task_dumpable(task)) {
  79. rcu_read_lock();
  80. cred = __task_cred(task);
  81. inode->i_uid = cred->euid;
  82. inode->i_gid = cred->egid;
  83. rcu_read_unlock();
  84. } else {
  85. inode->i_uid = GLOBAL_ROOT_UID;
  86. inode->i_gid = GLOBAL_ROOT_GID;
  87. }
  88. if (S_ISLNK(inode->i_mode)) {
  89. unsigned i_mode = S_IFLNK;
  90. if (f_mode & FMODE_READ)
  91. i_mode |= S_IRUSR | S_IXUSR;
  92. if (f_mode & FMODE_WRITE)
  93. i_mode |= S_IWUSR | S_IXUSR;
  94. inode->i_mode = i_mode;
  95. }
  96. security_task_to_inode(task, inode);
  97. put_task_struct(task);
  98. return 1;
  99. }
  100. rcu_read_unlock();
  101. put_files_struct(files);
  102. }
  103. put_task_struct(task);
  104. }
  105. d_drop(dentry);
  106. return 0;
  107. }
  108. static const struct dentry_operations tid_fd_dentry_operations = {
  109. .d_revalidate = tid_fd_revalidate,
  110. .d_delete = pid_delete_dentry,
  111. };
  112. static int proc_fd_link(struct dentry *dentry, struct path *path)
  113. {
  114. return proc_fd_info(dentry->d_inode, path, NULL);
  115. }
  116. static struct dentry *
  117. proc_fd_instantiate(struct inode *dir, struct dentry *dentry,
  118. struct task_struct *task, const void *ptr)
  119. {
  120. struct dentry *error = ERR_PTR(-ENOENT);
  121. unsigned fd = (unsigned long)ptr;
  122. struct proc_inode *ei;
  123. struct inode *inode;
  124. inode = proc_pid_make_inode(dir->i_sb, task);
  125. if (!inode)
  126. goto out;
  127. ei = PROC_I(inode);
  128. ei->fd = fd;
  129. inode->i_mode = S_IFLNK;
  130. inode->i_op = &proc_pid_link_inode_operations;
  131. inode->i_size = 64;
  132. ei->op.proc_get_link = proc_fd_link;
  133. d_set_d_op(dentry, &tid_fd_dentry_operations);
  134. d_add(dentry, inode);
  135. /* Close the race of the process dying before we return the dentry */
  136. if (tid_fd_revalidate(dentry, 0))
  137. error = NULL;
  138. out:
  139. return error;
  140. }
  141. static struct dentry *proc_lookupfd_common(struct inode *dir,
  142. struct dentry *dentry,
  143. instantiate_t instantiate)
  144. {
  145. struct task_struct *task = get_proc_task(dir);
  146. struct dentry *result = ERR_PTR(-ENOENT);
  147. unsigned fd = name_to_int(dentry);
  148. if (!task)
  149. goto out_no_task;
  150. if (fd == ~0U)
  151. goto out;
  152. result = instantiate(dir, dentry, task, (void *)(unsigned long)fd);
  153. out:
  154. put_task_struct(task);
  155. out_no_task:
  156. return result;
  157. }
  158. static int proc_readfd_common(struct file * filp, void * dirent,
  159. filldir_t filldir, instantiate_t instantiate)
  160. {
  161. struct dentry *dentry = filp->f_path.dentry;
  162. struct inode *inode = dentry->d_inode;
  163. struct task_struct *p = get_proc_task(inode);
  164. struct files_struct *files;
  165. unsigned int fd, ino;
  166. int retval;
  167. retval = -ENOENT;
  168. if (!p)
  169. goto out_no_task;
  170. retval = 0;
  171. fd = filp->f_pos;
  172. switch (fd) {
  173. case 0:
  174. if (filldir(dirent, ".", 1, 0, inode->i_ino, DT_DIR) < 0)
  175. goto out;
  176. filp->f_pos++;
  177. case 1:
  178. ino = parent_ino(dentry);
  179. if (filldir(dirent, "..", 2, 1, ino, DT_DIR) < 0)
  180. goto out;
  181. filp->f_pos++;
  182. default:
  183. files = get_files_struct(p);
  184. if (!files)
  185. goto out;
  186. rcu_read_lock();
  187. for (fd = filp->f_pos - 2;
  188. fd < files_fdtable(files)->max_fds;
  189. fd++, filp->f_pos++) {
  190. char name[PROC_NUMBUF];
  191. int len;
  192. int rv;
  193. if (!fcheck_files(files, fd))
  194. continue;
  195. rcu_read_unlock();
  196. len = snprintf(name, sizeof(name), "%d", fd);
  197. rv = proc_fill_cache(filp, dirent, filldir,
  198. name, len, instantiate, p,
  199. (void *)(unsigned long)fd);
  200. if (rv < 0)
  201. goto out_fd_loop;
  202. rcu_read_lock();
  203. }
  204. rcu_read_unlock();
  205. out_fd_loop:
  206. put_files_struct(files);
  207. }
  208. out:
  209. put_task_struct(p);
  210. out_no_task:
  211. return retval;
  212. }
  213. static ssize_t proc_fdinfo_read(struct file *file, char __user *buf,
  214. size_t len, loff_t *ppos)
  215. {
  216. char tmp[PROC_FDINFO_MAX];
  217. int err = proc_fd_info(file->f_path.dentry->d_inode, NULL, tmp);
  218. if (!err)
  219. err = simple_read_from_buffer(buf, len, ppos, tmp, strlen(tmp));
  220. return err;
  221. }
  222. static const struct file_operations proc_fdinfo_file_operations = {
  223. .open = nonseekable_open,
  224. .read = proc_fdinfo_read,
  225. .llseek = no_llseek,
  226. };
  227. static int proc_readfd(struct file *filp, void *dirent, filldir_t filldir)
  228. {
  229. return proc_readfd_common(filp, dirent, filldir, proc_fd_instantiate);
  230. }
  231. const struct file_operations proc_fd_operations = {
  232. .read = generic_read_dir,
  233. .readdir = proc_readfd,
  234. .llseek = default_llseek,
  235. };
  236. static struct dentry *proc_lookupfd(struct inode *dir, struct dentry *dentry,
  237. unsigned int flags)
  238. {
  239. return proc_lookupfd_common(dir, dentry, proc_fd_instantiate);
  240. }
  241. /*
  242. * /proc/pid/fd needs a special permission handler so that a process can still
  243. * access /proc/self/fd after it has executed a setuid().
  244. */
  245. int proc_fd_permission(struct inode *inode, int mask)
  246. {
  247. int rv = generic_permission(inode, mask);
  248. if (rv == 0)
  249. return 0;
  250. if (task_pid(current) == proc_pid(inode))
  251. rv = 0;
  252. return rv;
  253. }
  254. const struct inode_operations proc_fd_inode_operations = {
  255. .lookup = proc_lookupfd,
  256. .permission = proc_fd_permission,
  257. .setattr = proc_setattr,
  258. };
  259. static struct dentry *
  260. proc_fdinfo_instantiate(struct inode *dir, struct dentry *dentry,
  261. struct task_struct *task, const void *ptr)
  262. {
  263. struct dentry *error = ERR_PTR(-ENOENT);
  264. unsigned fd = (unsigned long)ptr;
  265. struct proc_inode *ei;
  266. struct inode *inode;
  267. inode = proc_pid_make_inode(dir->i_sb, task);
  268. if (!inode)
  269. goto out;
  270. ei = PROC_I(inode);
  271. ei->fd = fd;
  272. inode->i_mode = S_IFREG | S_IRUSR;
  273. inode->i_fop = &proc_fdinfo_file_operations;
  274. d_set_d_op(dentry, &tid_fd_dentry_operations);
  275. d_add(dentry, inode);
  276. /* Close the race of the process dying before we return the dentry */
  277. if (tid_fd_revalidate(dentry, 0))
  278. error = NULL;
  279. out:
  280. return error;
  281. }
  282. static struct dentry *
  283. proc_lookupfdinfo(struct inode *dir, struct dentry *dentry, unsigned int flags)
  284. {
  285. return proc_lookupfd_common(dir, dentry, proc_fdinfo_instantiate);
  286. }
  287. static int proc_readfdinfo(struct file *filp, void *dirent, filldir_t filldir)
  288. {
  289. return proc_readfd_common(filp, dirent, filldir,
  290. proc_fdinfo_instantiate);
  291. }
  292. const struct inode_operations proc_fdinfo_inode_operations = {
  293. .lookup = proc_lookupfdinfo,
  294. .setattr = proc_setattr,
  295. };
  296. const struct file_operations proc_fdinfo_operations = {
  297. .read = generic_read_dir,
  298. .readdir = proc_readfdinfo,
  299. .llseek = default_llseek,
  300. };