On 8/02/2016 9:12 AM, Jilles Tjoelker wrote:
> Author: jilles
> Date: Sun Feb  7 22:12:39 2016
> New Revision: 295385
> URL: https://svnweb.freebsd.org/changeset/base/295385
> 
> Log:
>   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:
>   head/sys/kern/sysv_sem.c
>   head/tools/regression/sysvsem/semtest.c


+infinity for bugfix & issue reference & regression test.

Thank you Jilles!

> Modified: head/sys/kern/sysv_sem.c
> ==============================================================================
> --- head/sys/kern/sysv_sem.c  Sun Feb  7 21:25:08 2016        (r295384)
> +++ head/sys/kern/sysv_sem.c  Sun Feb  7 22:12:39 2016        (r295385)
> @@ -867,6 +867,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;
> @@ -876,11 +881,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: head/tools/regression/sysvsem/semtest.c
> ==============================================================================
> --- head/tools/regression/sysvsem/semtest.c   Sun Feb  7 21:25:08 2016        
> (r295384)
> +++ head/tools/regression/sysvsem/semtest.c   Sun Feb  7 22:12:39 2016        
> (r295385)
> @@ -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:


_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to