Date: Sat, 9 Apr 2016 13:32:42 +0000 (UTC) From: Jilles Tjoelker <jilles@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r297747 - in stable/10: sys/kern tools/regression/sysvsem Message-ID: <201604091332.u39DWglh072540@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
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:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201604091332.u39DWglh072540>