Changeset View
Changeset View
Standalone View
Standalone View
head/sys/kern/sysv_sem.c
Show First 20 Lines • Show All 274 Lines • ▼ Show 20 Lines | osd_method_t methods[PR_MAXMETHOD] = { | ||||
[PR_METHOD_CHECK] = sem_prison_check, | [PR_METHOD_CHECK] = sem_prison_check, | ||||
[PR_METHOD_SET] = sem_prison_set, | [PR_METHOD_SET] = sem_prison_set, | ||||
[PR_METHOD_GET] = sem_prison_get, | [PR_METHOD_GET] = sem_prison_get, | ||||
[PR_METHOD_REMOVE] = sem_prison_remove, | [PR_METHOD_REMOVE] = sem_prison_remove, | ||||
}; | }; | ||||
sem = malloc(sizeof(struct sem) * seminfo.semmns, M_SEM, M_WAITOK); | sem = malloc(sizeof(struct sem) * seminfo.semmns, M_SEM, M_WAITOK); | ||||
sema = malloc(sizeof(struct semid_kernel) * seminfo.semmni, M_SEM, | sema = malloc(sizeof(struct semid_kernel) * seminfo.semmni, M_SEM, | ||||
M_WAITOK); | M_WAITOK | M_ZERO); | ||||
sema_mtx = malloc(sizeof(struct mtx) * seminfo.semmni, M_SEM, | sema_mtx = malloc(sizeof(struct mtx) * seminfo.semmni, M_SEM, | ||||
M_WAITOK | M_ZERO); | M_WAITOK | M_ZERO); | ||||
semu = malloc(seminfo.semmnu * seminfo.semusz, M_SEM, M_WAITOK); | semu = malloc(seminfo.semmnu * seminfo.semusz, M_SEM, M_WAITOK); | ||||
for (i = 0; i < seminfo.semmni; i++) { | for (i = 0; i < seminfo.semmni; i++) { | ||||
sema[i].u.sem_base = 0; | sema[i].u.sem_base = 0; | ||||
sema[i].u.sem_perm.mode = 0; | sema[i].u.sem_perm.mode = 0; | ||||
sema[i].u.sem_perm.seq = 0; | sema[i].u.sem_perm.seq = 0; | ||||
▲ Show 20 Lines • Show All 1,190 Lines • ▼ Show 20 Lines | semexit_myhook(void *arg, struct proc *p) | ||||
SEMUNDO_UNLOCK(); | SEMUNDO_UNLOCK(); | ||||
} | } | ||||
static int | static int | ||||
sysctl_sema(SYSCTL_HANDLER_ARGS) | sysctl_sema(SYSCTL_HANDLER_ARGS) | ||||
{ | { | ||||
struct prison *pr, *rpr; | struct prison *pr, *rpr; | ||||
struct semid_kernel tsemak; | struct semid_kernel tsemak; | ||||
#ifdef COMPAT_FREEBSD32 | |||||
struct semid_kernel32 tsemak32; | |||||
#endif | |||||
void *outaddr; | |||||
size_t outsize; | |||||
int error, i; | int error, i; | ||||
pr = req->td->td_ucred->cr_prison; | pr = req->td->td_ucred->cr_prison; | ||||
rpr = sem_find_prison(req->td->td_ucred); | rpr = sem_find_prison(req->td->td_ucred); | ||||
error = 0; | error = 0; | ||||
for (i = 0; i < seminfo.semmni; i++) { | for (i = 0; i < seminfo.semmni; i++) { | ||||
mtx_lock(&sema_mtx[i]); | mtx_lock(&sema_mtx[i]); | ||||
if ((sema[i].u.sem_perm.mode & SEM_ALLOC) == 0 || | if ((sema[i].u.sem_perm.mode & SEM_ALLOC) == 0 || | ||||
rpr == NULL || sem_prison_cansee(rpr, &sema[i]) != 0) | rpr == NULL || sem_prison_cansee(rpr, &sema[i]) != 0) | ||||
bzero(&tsemak, sizeof(tsemak)); | bzero(&tsemak, sizeof(tsemak)); | ||||
else { | else { | ||||
tsemak = sema[i]; | tsemak = sema[i]; | ||||
if (tsemak.cred->cr_prison != pr) | if (tsemak.cred->cr_prison != pr) | ||||
tsemak.u.sem_perm.key = IPC_PRIVATE; | tsemak.u.sem_perm.key = IPC_PRIVATE; | ||||
} | } | ||||
mtx_unlock(&sema_mtx[i]); | mtx_unlock(&sema_mtx[i]); | ||||
error = SYSCTL_OUT(req, &tsemak, sizeof(tsemak)); | #ifdef COMPAT_FREEBSD32 | ||||
if (SV_CURPROC_FLAG(SV_ILP32)) { | |||||
bzero(&tsemak32, sizeof(tsemak32)); | |||||
freebsd32_ipcperm_out(&tsemak.u.sem_perm, | |||||
&tsemak32.u.sem_perm); | |||||
/* Don't copy u.sem_base */ | |||||
CP(tsemak, tsemak32, u.sem_nsems); | |||||
CP(tsemak, tsemak32, u.sem_otime); | |||||
CP(tsemak, tsemak32, u.sem_ctime); | |||||
/* Don't copy label or cred */ | |||||
outaddr = &tsemak32; | |||||
outsize = sizeof(tsemak32); | |||||
} else | |||||
#endif | |||||
{ | |||||
tsemak.u.sem_base = NULL; | |||||
tsemak.label = NULL; | |||||
tsemak.cred = NULL; | |||||
outaddr = &tsemak; | |||||
outsize = sizeof(tsemak); | |||||
} | |||||
error = SYSCTL_OUT(req, outaddr, outsize); | |||||
if (error != 0) | if (error != 0) | ||||
break; | break; | ||||
} | } | ||||
return (error); | return (error); | ||||
} | } | ||||
static int | static int | ||||
sem_prison_check(void *obj, void *data) | sem_prison_check(void *obj, void *data) | ||||
▲ Show 20 Lines • Show All 460 Lines • Show Last 20 Lines |