diff options
author | jilles <jilles@FreeBSD.org> | 2016-04-09 13:32:42 +0000 |
---|---|---|
committer | jilles <jilles@FreeBSD.org> | 2016-04-09 13:32:42 +0000 |
commit | 15cca94824de0fbecb8dc3951d0a7e27f5a0ec67 (patch) | |
tree | bf032f976c283c35de30d920650828c88cf09e0e /sys/kern/sysv_sem.c | |
parent | 336b1f7bb670aa4ebb365bab9cfc602548954333 (diff) | |
download | FreeBSD-src-15cca94824de0fbecb8dc3951d0a7e27f5a0ec67.zip FreeBSD-src-15cca94824de0fbecb8dc3951d0a7e27f5a0ec67.tar.gz |
MFC r295385: semget(): Check for [EEXIST] error first.
Although POSIX literally permits failing with [EINVAL] if IPC_CREAT and
IPC_EXCL were both passed, the semaphore set already exists and has fewer
semaphores than nsems, this does not allow an application to retry safely:
if the [EINVAL] is actually because of the semmsl limit, an infinite loop
would result.
PR: 206927
Diffstat (limited to 'sys/kern/sysv_sem.c')
-rw-r--r-- | sys/kern/sysv_sem.c | 10 |
1 files changed, 5 insertions, 5 deletions
diff --git a/sys/kern/sysv_sem.c b/sys/kern/sysv_sem.c index 441cbfc..4337d4d 100644 --- a/sys/kern/sysv_sem.c +++ b/sys/kern/sysv_sem.c @@ -877,6 +877,11 @@ sys_semget(struct thread *td, struct semget_args *uap) } if (semid < seminfo.semmni) { DPRINTF(("found public key\n")); + if ((semflg & IPC_CREAT) && (semflg & IPC_EXCL)) { + DPRINTF(("not exclusive\n")); + error = EEXIST; + goto done2; + } if ((error = ipcperm(td, &sema[semid].u.sem_perm, semflg & 0700))) { goto done2; @@ -886,11 +891,6 @@ sys_semget(struct thread *td, struct semget_args *uap) error = EINVAL; goto done2; } - if ((semflg & IPC_CREAT) && (semflg & IPC_EXCL)) { - DPRINTF(("not exclusive\n")); - error = EEXIST; - goto done2; - } #ifdef MAC error = mac_sysvsem_check_semget(cred, &sema[semid]); if (error != 0) |