standards/189353: POSIX sem_unlink does not actually unlink the semaphore in the process context

Konstantin Belousov kostikbel at gmail.com
Sun May 4 12:40:01 UTC 2014


The following reply was made to PR standards/189353; it has been noted by GNATS.

From: Konstantin Belousov <kostikbel at gmail.com>
To: Joris <joris at giovannangeli.fr>
Cc: freebsd-gnats-submit at FreeBSD.org
Subject: Re: standards/189353: POSIX sem_unlink does not actually unlink the
 semaphore in the process context
Date: Sun, 4 May 2014 15:37:43 +0300

 --X+8siUETKMkW99st
 Content-Type: text/plain; charset=us-ascii
 Content-Disposition: inline
 Content-Transfer-Encoding: quoted-printable
 
 On Sun, May 04, 2014 at 11:15:23AM +0000, Joris wrote:
 >=20
 > >Number:         189353
 > >Category:       standards
 > >Synopsis:       POSIX sem_unlink does not actually unlink the semaphore =
 in the process context
 > >Confidential:   no
 > >Severity:       non-critical
 > >Priority:       low
 > >Responsible:    freebsd-standards
 > >State:          open
 > >Quarter:       =20
 > >Keywords:      =20
 > >Date-Required:
 > >Class:          sw-bug
 > >Submitter-Id:   current-users
 > >Arrival-Date:   Sun May 04 11:20:00 UTC 2014
 > >Closed-Date:
 > >Last-Modified:
 > >Originator:     Joris
 > >Release:        freebsd 10
 > >Organization:
 > >Environment:
 > >Description:
 > When a posix sempahore is open, it is cached in the process address space=
 =2E A call to sem_unlink does not invalidate the caching, and trying to reo=
 pen the semaphore with O_EXCL after calling sem_unlink fails with EEXIST.
 > >How-To-Repeat:
 > Here is a test case :
 >=20
 > #include <fcntl.h>
 > #include <sys/stat.h>
 > #include <sys/wait.h>
 > #include <sys/types.h>
 > #include <semaphore.h>
 >=20
 > #include <err.h>
 >=20
 >=20
 > int
 > main(int argc, char *argv[])
 > {
 > 	sem_t *sem1, *sem2;
 > 	int error;
 >=20
 > 	sem1 =3D sem_open("/test-sem1", O_CREAT | O_EXCL, S_IRWXU, 1);
 > 	if (sem1 =3D=3D SEM_FAILED)
 > 		err(1,"Cannot create test /test-sem1 semaphore");
 >=20
 > 	error =3D sem_unlink("/test-sem1");
 >=20
 > 	if (error)
 > 		err(1, "Cannot unlink semaphore /test-sem1");
 >=20
 >=20
 > 	sem2 =3D sem_open("/test-sem1", O_CREAT | O_EXCL, S_IRWXU, 2);
 >=20
 > 	if (sem2 =3D=3D SEM_FAILED)
 > 		err(1, "Cannot re-create semaphore /test-sem1");
 >=20
 > 	error =3D sem_unlink("/test-sem1");
 >=20
 > 	if (error)
 > 		err(1, "Cannot unlink semaphore /test-sem1");
 >=20
 > 	return(0);
 > }
 
 Yes, I think you are right.  Please try the following patch, which worked
 for me, but I only lightly tested it.
 
 diff --git a/lib/libc/gen/sem_new.c b/lib/libc/gen/sem_new.c
 index 9a2ab27..8e4a91d 100644
 --- a/lib/libc/gen/sem_new.c
 +++ b/lib/libc/gen/sem_new.c
 @@ -161,7 +161,7 @@ _sem_open(const char *name, int flags, ...)
 =20
  	_pthread_mutex_lock(&sem_llock);
  	LIST_FOREACH(ni, &sem_list, next) {
 -		if (strcmp(name, ni->name) =3D=3D 0) {
 +		if (ni->name !=3D NULL && strcmp(name, ni->name) =3D=3D 0) {
  			if ((flags & (O_CREAT|O_EXCL)) =3D=3D (O_CREAT|O_EXCL)) {
  				_pthread_mutex_unlock(&sem_llock);
  				errno =3D EEXIST;
 @@ -287,20 +287,32 @@ _sem_close(sem_t *sem)
  int
  _sem_unlink(const char *name)
  {
 +	struct sem_nameinfo *ni;
  	char path[PATH_MAX];
 +	int error;
 =20
  	if (name[0] !=3D '/') {
  		errno =3D ENOENT;
  		return -1;
  	}
  	name++;
 -
  	strcpy(path, SEM_PREFIX);
  	if (strlcat(path, name, sizeof(path)) >=3D sizeof(path)) {
  		errno =3D ENAMETOOLONG;
  		return (-1);
  	}
 -	return unlink(path);
 +
 +	_pthread_once(&once, sem_module_init);
 +	_pthread_mutex_lock(&sem_llock);
 +	LIST_FOREACH(ni, &sem_list, next) {
 +		if (ni->name !=3D NULL && strcmp(name, ni->name) =3D=3D 0) {
 +			ni->name =3D NULL;
 +			break;
 +		}
 +	}
 +	error =3D unlink(path);
 +	_pthread_mutex_unlock(&sem_llock);
 +	return (error);
  }
 =20
  int
 
 --X+8siUETKMkW99st
 Content-Type: application/pgp-signature
 
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v2.0.22 (FreeBSD)
 
 iQIcBAEBAgAGBQJTZjSWAAoJEJDCuSvBvK1B8i0P/2MxJ9aHmhC1hsx1ktljC9mw
 lvb4xHSsy1JpYIRU2tafKTQyRglO9Md1jpKTTjkUbL1sakifvqZzFZv5vbJ7uEDe
 ST5rqLoydfrayBrMlj/2vV9pX5QV1vc40N3kjGDpwuT+Wkxbsg5bFU87b34HrxvQ
 jg4RDkRt7IVbv9dLGT1AUxePBoPtc+ZUF3A+UgqH7G5LZ3JA3umM35Sp9oWjv4Ot
 mR16WyonZ798Qk9Xcj8OGqD8DXJqamgZAlqoMbXYD8hcamqD35Ge4SRHVAb+cySV
 25wgXvkB3LpGzfLLRC0EGwAjE3ZwuCAplAXPjCVfLh8wU8XZxZSNla8deUAo+xKS
 7Wz4Fdhj/j6JURMvnbLc9pFyIIUTrIPWh/ZydloUjJh5k+oSHtXaVyvxxtoxxMIR
 Cuh6JzYwMupcMT0Pf/PKRMXGdo72KlJ5WuPkvNSotIl3jaOwJN0CsJslvD0qZr71
 AxD5H6h8YDCdXdeYy3zzMI9yau+R7M84nH8cTG8xodLax26DZddRRxCZST4biLTA
 8rj6tic4/xlpoEH2g54QBEW6qwm1CmtSEDlnQplJ4obLvinON69IZ8/QYLhwHhdA
 yQ0qiiNTtNjRWGBPGglT94fsyy4Wh0gOxLod0JegcqkasCnD0qdKnPcVySH79YyD
 DYFeUb3f+LZgezOI3h5N
 =wOWb
 -----END PGP SIGNATURE-----
 
 --X+8siUETKMkW99st--


More information about the freebsd-standards mailing list