* This is common code for FIOSETOWN ioctl called by fcntl(fd, F_SETOWN, arg). * * After permission checking, add a sigio structure to the sigio list for * the process or process group. */
| 1141 | * the process or process group. |
| 1142 | */ |
| 1143 | int |
| 1144 | fsetown(pid_t pgid, struct sigio **sigiop) |
| 1145 | { |
| 1146 | struct proc *proc; |
| 1147 | struct pgrp *pgrp; |
| 1148 | struct sigio *osigio, *sigio; |
| 1149 | int ret; |
| 1150 | |
| 1151 | if (pgid == 0) { |
| 1152 | funsetown(sigiop); |
| 1153 | return (0); |
| 1154 | } |
| 1155 | |
| 1156 | ret = 0; |
| 1157 | |
| 1158 | sigio = malloc(sizeof(struct sigio), M_SIGIO, M_WAITOK); |
| 1159 | sigio->sio_pgid = pgid; |
| 1160 | sigio->sio_ucred = crhold(curthread->td_ucred); |
| 1161 | sigio->sio_myref = sigiop; |
| 1162 | |
| 1163 | sx_slock(&proctree_lock); |
| 1164 | SIGIO_LOCK(); |
| 1165 | osigio = funsetown_locked(*sigiop); |
| 1166 | if (pgid > 0) { |
| 1167 | proc = pfind(pgid); |
| 1168 | if (proc == NULL) { |
| 1169 | ret = ESRCH; |
| 1170 | goto fail; |
| 1171 | } |
| 1172 | |
| 1173 | /* |
| 1174 | * Policy - Don't allow a process to FSETOWN a process |
| 1175 | * in another session. |
| 1176 | * |
| 1177 | * Remove this test to allow maximum flexibility or |
| 1178 | * restrict FSETOWN to the current process or process |
| 1179 | * group for maximum safety. |
| 1180 | */ |
| 1181 | if (proc->p_session != curthread->td_proc->p_session) { |
| 1182 | PROC_UNLOCK(proc); |
| 1183 | ret = EPERM; |
| 1184 | goto fail; |
| 1185 | } |
| 1186 | |
| 1187 | sigio->sio_proc = proc; |
| 1188 | SLIST_INSERT_HEAD(&proc->p_sigiolst, sigio, sio_pgsigio); |
| 1189 | PROC_UNLOCK(proc); |
| 1190 | } else /* if (pgid < 0) */ { |
| 1191 | pgrp = pgfind(-pgid); |
| 1192 | if (pgrp == NULL) { |
| 1193 | ret = ESRCH; |
| 1194 | goto fail; |
| 1195 | } |
| 1196 | |
| 1197 | /* |
| 1198 | * Policy - Don't allow a process to FSETOWN a process |
| 1199 | * in another session. |
| 1200 | * |
no test coverage detected