* It is unsafe for set[ug]id processes to be started with file * descriptors 0..2 closed, as these descriptors are given implicit * significance in the Standard C library. fdcheckstd() will create a * descriptor referencing /dev/null for each of stdin, stdout, and * stderr that is not already open. */
| 2804 | * stderr that is not already open. |
| 2805 | */ |
| 2806 | int |
| 2807 | fdcheckstd(struct thread *td) |
| 2808 | { |
| 2809 | struct filedesc *fdp; |
| 2810 | register_t save; |
| 2811 | int i, error, devnull; |
| 2812 | |
| 2813 | fdp = td->td_proc->p_fd; |
| 2814 | KASSERT(refcount_load(&fdp->fd_refcnt) == 1, |
| 2815 | ("the fdtable should not be shared")); |
| 2816 | MPASS(fdp->fd_nfiles >= 3); |
| 2817 | devnull = -1; |
| 2818 | for (i = 0; i <= 2; i++) { |
| 2819 | if (fdp->fd_ofiles[i].fde_file != NULL) |
| 2820 | continue; |
| 2821 | |
| 2822 | save = td->td_retval[0]; |
| 2823 | if (devnull != -1) { |
| 2824 | error = kern_dup(td, FDDUP_FIXED, 0, devnull, i); |
| 2825 | } else { |
| 2826 | error = kern_openat(td, AT_FDCWD, "/dev/null", |
| 2827 | UIO_SYSSPACE, O_RDWR, 0); |
| 2828 | if (error == 0) { |
| 2829 | devnull = td->td_retval[0]; |
| 2830 | KASSERT(devnull == i, ("we didn't get our fd")); |
| 2831 | } |
| 2832 | } |
| 2833 | td->td_retval[0] = save; |
| 2834 | if (error != 0) |
| 2835 | return (error); |
| 2836 | } |
| 2837 | return (0); |
| 2838 | } |
| 2839 | |
| 2840 | /* |
| 2841 | * Internal form of close. Decrement reference count on file structure. |
no test coverage detected