svn commit: r297747 - in stable/10: sys/kern tools/regression/sysvsem
Jilles Tjoelker
jilles at FreeBSD.org
Sat Apr 9 13:32:43 UTC 2016
Author: jilles
Date: Sat Apr 9 13:32:42 2016
New Revision: 297747
URL: https://svnweb.freebsd.org/changeset/base/297747
Log:
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
Modified:
stable/10/sys/kern/sysv_sem.c
stable/10/tools/regression/sysvsem/semtest.c
Directory Properties:
stable/10/ (props changed)
Modified: stable/10/sys/kern/sysv_sem.c
==============================================================================
--- stable/10/sys/kern/sysv_sem.c Sat Apr 9 13:15:34 2016 (r297746)
+++ stable/10/sys/kern/sysv_sem.c Sat Apr 9 13:32:42 2016 (r297747)
@@ -877,6 +877,11 @@ sys_semget(struct thread *td, struct sem
}
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 sem
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)
Modified: stable/10/tools/regression/sysvsem/semtest.c
==============================================================================
--- stable/10/tools/regression/sysvsem/semtest.c Sat Apr 9 13:15:34 2016 (r297746)
+++ stable/10/tools/regression/sysvsem/semtest.c Sat Apr 9 13:32:42 2016 (r297747)
@@ -152,6 +152,15 @@ main(int argc, char *argv[])
print_semid_ds(&s_ds, 0600);
+ errno = 0;
+ if (semget(semkey, 1, IPC_CREAT | IPC_EXCL | 0600) != -1 ||
+ errno != EEXIST)
+ err(1, "semget IPC_EXCL 1 did not fail with [EEXIST]");
+ errno = 0;
+ if (semget(semkey, 2, IPC_CREAT | IPC_EXCL | 0600) != -1 ||
+ errno != EEXIST)
+ err(1, "semget IPC_EXCL 2 did not fail with [EEXIST]");
+
for (child_count = 0; child_count < 5; child_count++) {
switch ((child_pid = fork())) {
case -1:
More information about the svn-src-all
mailing list