PageRenderTime 52ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 0ms

/sys/kern/sys_procdesc.c

https://bitbucket.org/freebsd/freebsd-head/
C | 532 lines | 318 code | 68 blank | 146 comment | 39 complexity | 44fffda414a7f9cc6f65b3d0fd2b0d25 MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, BSD-3-Clause, LGPL-2.0, LGPL-2.1, BSD-2-Clause, 0BSD, JSON, AGPL-1.0, GPL-2.0
  1. /*-
  2. * Copyright (c) 2009 Robert N. M. Watson
  3. * All rights reserved.
  4. *
  5. * This software was developed at the University of Cambridge Computer
  6. * Laboratory with support from a grant from Google, Inc.
  7. *
  8. * Redistribution and use in source and binary forms, with or without
  9. * modification, are permitted provided that the following conditions
  10. * are met:
  11. * 1. Redistributions of source code must retain the above copyright
  12. * notice, this list of conditions and the following disclaimer.
  13. * 2. Redistributions in binary form must reproduce the above copyright
  14. * notice, this list of conditions and the following disclaimer in the
  15. * documentation and/or other materials provided with the distribution.
  16. *
  17. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  18. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  19. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  20. * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  21. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  22. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  23. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  24. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  25. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  26. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  27. * SUCH DAMAGE.
  28. */
  29. /*-
  30. * FreeBSD process descriptor facility.
  31. *
  32. * Some processes are represented by a file descriptor, which will be used in
  33. * preference to signaling and pids for the purposes of process management,
  34. * and is, in effect, a form of capability. When a process descriptor is
  35. * used with a process, it ceases to be visible to certain traditional UNIX
  36. * process facilities, such as waitpid(2).
  37. *
  38. * Some semantics:
  39. *
  40. * - At most one process descriptor will exist for any process, although
  41. * references to that descriptor may be held from many processes (or even
  42. * be in flight between processes over a local domain socket).
  43. * - Last close on the process descriptor will terminate the process using
  44. * SIGKILL and reparent it to init so that there's a process to reap it
  45. * when it's done exiting.
  46. * - If the process exits before the descriptor is closed, it will not
  47. * generate SIGCHLD on termination, or be picked up by waitpid().
  48. * - The pdkill(2) system call may be used to deliver a signal to the process
  49. * using its process descriptor.
  50. * - The pdwait4(2) system call may be used to block (or not) on a process
  51. * descriptor to collect termination information.
  52. *
  53. * Open questions:
  54. *
  55. * - How to handle ptrace(2)?
  56. * - Will we want to add a pidtoprocdesc(2) system call to allow process
  57. * descriptors to be created for processes without pfork(2)?
  58. */
  59. #include <sys/cdefs.h>
  60. __FBSDID("$FreeBSD$");
  61. #include "opt_procdesc.h"
  62. #include <sys/param.h>
  63. #include <sys/capability.h>
  64. #include <sys/fcntl.h>
  65. #include <sys/file.h>
  66. #include <sys/filedesc.h>
  67. #include <sys/kernel.h>
  68. #include <sys/lock.h>
  69. #include <sys/mutex.h>
  70. #include <sys/poll.h>
  71. #include <sys/proc.h>
  72. #include <sys/procdesc.h>
  73. #include <sys/resourcevar.h>
  74. #include <sys/stat.h>
  75. #include <sys/sysproto.h>
  76. #include <sys/sysctl.h>
  77. #include <sys/systm.h>
  78. #include <sys/ucred.h>
  79. #include <security/audit/audit.h>
  80. #include <vm/uma.h>
  81. #ifdef PROCDESC
  82. FEATURE(process_descriptors, "Process Descriptors");
  83. static uma_zone_t procdesc_zone;
  84. static fo_rdwr_t procdesc_read;
  85. static fo_rdwr_t procdesc_write;
  86. static fo_truncate_t procdesc_truncate;
  87. static fo_ioctl_t procdesc_ioctl;
  88. static fo_poll_t procdesc_poll;
  89. static fo_kqfilter_t procdesc_kqfilter;
  90. static fo_stat_t procdesc_stat;
  91. static fo_close_t procdesc_close;
  92. static fo_chmod_t procdesc_chmod;
  93. static fo_chown_t procdesc_chown;
  94. static struct fileops procdesc_ops = {
  95. .fo_read = procdesc_read,
  96. .fo_write = procdesc_write,
  97. .fo_truncate = procdesc_truncate,
  98. .fo_ioctl = procdesc_ioctl,
  99. .fo_poll = procdesc_poll,
  100. .fo_kqfilter = procdesc_kqfilter,
  101. .fo_stat = procdesc_stat,
  102. .fo_close = procdesc_close,
  103. .fo_chmod = procdesc_chmod,
  104. .fo_chown = procdesc_chown,
  105. .fo_flags = DFLAG_PASSABLE,
  106. };
  107. /*
  108. * Initialize with VFS so that process descriptors are available along with
  109. * other file descriptor types. As long as it runs before init(8) starts,
  110. * there shouldn't be a problem.
  111. */
  112. static void
  113. procdesc_init(void *dummy __unused)
  114. {
  115. procdesc_zone = uma_zcreate("procdesc", sizeof(struct procdesc),
  116. NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0);
  117. if (procdesc_zone == NULL)
  118. panic("procdesc_init: procdesc_zone not initialized");
  119. }
  120. SYSINIT(vfs, SI_SUB_VFS, SI_ORDER_ANY, procdesc_init, NULL);
  121. /*
  122. * Return a locked process given a process descriptor, or ESRCH if it has
  123. * died.
  124. */
  125. int
  126. procdesc_find(struct thread *td, int fd, cap_rights_t rights,
  127. struct proc **p)
  128. {
  129. struct procdesc *pd;
  130. struct file *fp;
  131. int error;
  132. error = fget(td, fd, rights, &fp);
  133. if (error)
  134. return (error);
  135. if (fp->f_type != DTYPE_PROCDESC) {
  136. error = EBADF;
  137. goto out;
  138. }
  139. pd = fp->f_data;
  140. sx_slock(&proctree_lock);
  141. if (pd->pd_proc != NULL) {
  142. *p = pd->pd_proc;
  143. PROC_LOCK(*p);
  144. } else
  145. error = ESRCH;
  146. sx_sunlock(&proctree_lock);
  147. out:
  148. fdrop(fp, td);
  149. return (error);
  150. }
  151. /*
  152. * Function to be used by procstat(1) sysctls when returning procdesc
  153. * information.
  154. */
  155. pid_t
  156. procdesc_pid(struct file *fp_procdesc)
  157. {
  158. struct procdesc *pd;
  159. KASSERT(fp_procdesc->f_type == DTYPE_PROCDESC,
  160. ("procdesc_pid: !procdesc"));
  161. pd = fp_procdesc->f_data;
  162. return (pd->pd_pid);
  163. }
  164. /*
  165. * Retrieve the PID associated with a process descriptor.
  166. */
  167. int
  168. kern_pdgetpid(struct thread *td, int fd, cap_rights_t rights, pid_t *pidp)
  169. {
  170. struct file *fp;
  171. int error;
  172. error = fget(td, fd, rights, &fp);
  173. if (error)
  174. return (error);
  175. if (fp->f_type != DTYPE_PROCDESC) {
  176. error = EBADF;
  177. goto out;
  178. }
  179. *pidp = procdesc_pid(fp);
  180. out:
  181. fdrop(fp, td);
  182. return (error);
  183. }
  184. /*
  185. * System call to return the pid of a process given its process descriptor.
  186. */
  187. int
  188. sys_pdgetpid(struct thread *td, struct pdgetpid_args *uap)
  189. {
  190. pid_t pid;
  191. int error;
  192. AUDIT_ARG_FD(uap->fd);
  193. error = kern_pdgetpid(td, uap->fd, CAP_PDGETPID, &pid);
  194. if (error == 0)
  195. error = copyout(&pid, uap->pidp, sizeof(pid));
  196. return (error);
  197. }
  198. /*
  199. * When a new process is forked by pdfork(), a file descriptor is allocated
  200. * by the fork code first, then the process is forked, and then we get a
  201. * chance to set up the process descriptor. Failure is not permitted at this
  202. * point, so procdesc_new() must succeed.
  203. */
  204. void
  205. procdesc_new(struct proc *p, int flags)
  206. {
  207. struct procdesc *pd;
  208. pd = uma_zalloc(procdesc_zone, M_WAITOK | M_ZERO);
  209. pd->pd_proc = p;
  210. pd->pd_pid = p->p_pid;
  211. p->p_procdesc = pd;
  212. pd->pd_flags = 0;
  213. if (flags & PD_DAEMON)
  214. pd->pd_flags |= PDF_DAEMON;
  215. PROCDESC_LOCK_INIT(pd);
  216. /*
  217. * Process descriptors start out with two references: one from their
  218. * struct file, and the other from their struct proc.
  219. */
  220. refcount_init(&pd->pd_refcount, 2);
  221. }
  222. /*
  223. * Initialize a file with a process descriptor.
  224. */
  225. void
  226. procdesc_finit(struct procdesc *pdp, struct file *fp)
  227. {
  228. finit(fp, FREAD | FWRITE, DTYPE_PROCDESC, pdp, &procdesc_ops);
  229. }
  230. static void
  231. procdesc_free(struct procdesc *pd)
  232. {
  233. /*
  234. * When the last reference is released, we assert that the descriptor
  235. * has been closed, but not that the process has exited, as we will
  236. * detach the descriptor before the process dies if the descript is
  237. * closed, as we can't wait synchronously.
  238. */
  239. if (refcount_release(&pd->pd_refcount)) {
  240. KASSERT(pd->pd_proc == NULL,
  241. ("procdesc_free: pd_proc != NULL"));
  242. KASSERT((pd->pd_flags & PDF_CLOSED),
  243. ("procdesc_free: !PDF_CLOSED"));
  244. PROCDESC_LOCK_DESTROY(pd);
  245. uma_zfree(procdesc_zone, pd);
  246. }
  247. }
  248. /*
  249. * procdesc_exit() - notify a process descriptor that its process is exiting.
  250. * We use the proctree_lock to ensure that process exit either happens
  251. * strictly before or strictly after a concurrent call to procdesc_close().
  252. */
  253. int
  254. procdesc_exit(struct proc *p)
  255. {
  256. struct procdesc *pd;
  257. sx_assert(&proctree_lock, SA_XLOCKED);
  258. PROC_LOCK_ASSERT(p, MA_OWNED);
  259. KASSERT(p->p_procdesc != NULL, ("procdesc_exit: p_procdesc NULL"));
  260. pd = p->p_procdesc;
  261. PROCDESC_LOCK(pd);
  262. KASSERT((pd->pd_flags & PDF_CLOSED) == 0 || p->p_pptr == initproc,
  263. ("procdesc_exit: closed && parent not init"));
  264. pd->pd_flags |= PDF_EXITED;
  265. /*
  266. * If the process descriptor has been closed, then we have nothing
  267. * to do; return 1 so that init will get SIGCHLD and do the reaping.
  268. * Clean up the procdesc now rather than letting it happen during
  269. * that reap.
  270. */
  271. if (pd->pd_flags & PDF_CLOSED) {
  272. PROCDESC_UNLOCK(pd);
  273. pd->pd_proc = NULL;
  274. p->p_procdesc = NULL;
  275. procdesc_free(pd);
  276. return (1);
  277. }
  278. if (pd->pd_flags & PDF_SELECTED) {
  279. pd->pd_flags &= ~PDF_SELECTED;
  280. selwakeup(&pd->pd_selinfo);
  281. }
  282. PROCDESC_UNLOCK(pd);
  283. return (0);
  284. }
  285. /*
  286. * When a process descriptor is reaped, perhaps as a result of close() or
  287. * pdwait4(), release the process's reference on the process descriptor.
  288. */
  289. void
  290. procdesc_reap(struct proc *p)
  291. {
  292. struct procdesc *pd;
  293. sx_assert(&proctree_lock, SA_XLOCKED);
  294. KASSERT(p->p_procdesc != NULL, ("procdesc_reap: p_procdesc == NULL"));
  295. pd = p->p_procdesc;
  296. pd->pd_proc = NULL;
  297. p->p_procdesc = NULL;
  298. procdesc_free(pd);
  299. }
  300. /*
  301. * procdesc_close() - last close on a process descriptor. If the process is
  302. * still running, terminate with SIGKILL (unless PDF_DAEMON is set) and let
  303. * init(8) clean up the mess; if not, we have to clean up the zombie ourselves.
  304. */
  305. static int
  306. procdesc_close(struct file *fp, struct thread *td)
  307. {
  308. struct procdesc *pd;
  309. struct proc *p;
  310. KASSERT(fp->f_type == DTYPE_PROCDESC, ("procdesc_close: !procdesc"));
  311. pd = fp->f_data;
  312. fp->f_ops = &badfileops;
  313. fp->f_data = NULL;
  314. sx_xlock(&proctree_lock);
  315. PROCDESC_LOCK(pd);
  316. pd->pd_flags |= PDF_CLOSED;
  317. PROCDESC_UNLOCK(pd);
  318. p = pd->pd_proc;
  319. if (p == NULL) {
  320. /*
  321. * This is the case where process' exit status was already
  322. * collected and procdesc_reap() was already called.
  323. */
  324. sx_xunlock(&proctree_lock);
  325. } else if (p->p_state == PRS_ZOMBIE) {
  326. /*
  327. * If the process is already dead and just awaiting reaping,
  328. * do that now. This will release the process's reference to
  329. * the process descriptor when it calls back into
  330. * procdesc_reap().
  331. */
  332. PROC_LOCK(p);
  333. PROC_SLOCK(p);
  334. proc_reap(curthread, p, NULL, 0, NULL);
  335. } else {
  336. /*
  337. * If the process is not yet dead, we need to kill it, but we
  338. * can't wait around synchronously for it to go away, as that
  339. * path leads to madness (and deadlocks). First, detach the
  340. * process from its descriptor so that its exit status will
  341. * be reported normally.
  342. */
  343. PROC_LOCK(p);
  344. pd->pd_proc = NULL;
  345. p->p_procdesc = NULL;
  346. procdesc_free(pd);
  347. /*
  348. * Next, reparent it to init(8) so that there's someone to
  349. * pick up the pieces; finally, terminate with prejudice.
  350. */
  351. p->p_sigparent = SIGCHLD;
  352. proc_reparent(p, initproc);
  353. if ((pd->pd_flags & PDF_DAEMON) == 0)
  354. kern_psignal(p, SIGKILL);
  355. PROC_UNLOCK(p);
  356. sx_xunlock(&proctree_lock);
  357. }
  358. /*
  359. * Release the file descriptor's reference on the process descriptor.
  360. */
  361. procdesc_free(pd);
  362. return (0);
  363. }
  364. static int
  365. procdesc_read(struct file *fp, struct uio *uio, struct ucred *active_cred,
  366. int flags, struct thread *td)
  367. {
  368. return (EOPNOTSUPP);
  369. }
  370. static int
  371. procdesc_write(struct file *fp, struct uio *uio, struct ucred *active_cred,
  372. int flags, struct thread *td)
  373. {
  374. return (EOPNOTSUPP);
  375. }
  376. static int
  377. procdesc_truncate(struct file *fp, off_t length, struct ucred *active_cred,
  378. struct thread *td)
  379. {
  380. return (EOPNOTSUPP);
  381. }
  382. static int
  383. procdesc_ioctl(struct file *fp, u_long com, void *data,
  384. struct ucred *active_cred, struct thread *td)
  385. {
  386. return (EOPNOTSUPP);
  387. }
  388. static int
  389. procdesc_poll(struct file *fp, int events, struct ucred *active_cred,
  390. struct thread *td)
  391. {
  392. struct procdesc *pd;
  393. int revents;
  394. revents = 0;
  395. pd = fp->f_data;
  396. PROCDESC_LOCK(pd);
  397. if (pd->pd_flags & PDF_EXITED)
  398. revents |= POLLHUP;
  399. if (revents == 0) {
  400. selrecord(td, &pd->pd_selinfo);
  401. pd->pd_flags |= PDF_SELECTED;
  402. }
  403. PROCDESC_UNLOCK(pd);
  404. return (revents);
  405. }
  406. static int
  407. procdesc_kqfilter(struct file *fp, struct knote *kn)
  408. {
  409. return (EOPNOTSUPP);
  410. }
  411. static int
  412. procdesc_stat(struct file *fp, struct stat *sb, struct ucred *active_cred,
  413. struct thread *td)
  414. {
  415. struct procdesc *pd;
  416. struct timeval pstart;
  417. /*
  418. * XXXRW: Perhaps we should cache some more information from the
  419. * process so that we can return it reliably here even after it has
  420. * died. For example, caching its credential data.
  421. */
  422. bzero(sb, sizeof(*sb));
  423. pd = fp->f_data;
  424. sx_slock(&proctree_lock);
  425. if (pd->pd_proc != NULL) {
  426. PROC_LOCK(pd->pd_proc);
  427. /* Set birth and [acm] times to process start time. */
  428. pstart = pd->pd_proc->p_stats->p_start;
  429. timevaladd(&pstart, &boottime);
  430. TIMEVAL_TO_TIMESPEC(&pstart, &sb->st_birthtim);
  431. sb->st_atim = sb->st_birthtim;
  432. sb->st_ctim = sb->st_birthtim;
  433. sb->st_mtim = sb->st_birthtim;
  434. if (pd->pd_proc->p_state != PRS_ZOMBIE)
  435. sb->st_mode = S_IFREG | S_IRWXU;
  436. else
  437. sb->st_mode = S_IFREG;
  438. sb->st_uid = pd->pd_proc->p_ucred->cr_ruid;
  439. sb->st_gid = pd->pd_proc->p_ucred->cr_rgid;
  440. PROC_UNLOCK(pd->pd_proc);
  441. } else
  442. sb->st_mode = S_IFREG;
  443. sx_sunlock(&proctree_lock);
  444. return (0);
  445. }
  446. static int
  447. procdesc_chmod(struct file *fp, mode_t mode, struct ucred *active_cred,
  448. struct thread *td)
  449. {
  450. return (EOPNOTSUPP);
  451. }
  452. static int
  453. procdesc_chown(struct file *fp, uid_t uid, gid_t gid, struct ucred *active_cred,
  454. struct thread *td)
  455. {
  456. return (EOPNOTSUPP);
  457. }
  458. #else /* !PROCDESC */
  459. int
  460. sys_pdgetpid(struct thread *td, struct pdgetpid_args *uap)
  461. {
  462. return (ENOSYS);
  463. }
  464. #endif /* PROCDESC */