Skip site navigation (1)Skip section navigation (2)
Date:      13 Dec 2002 18:26:12 -0000
From:      Joe Kelsey <joek@zircon.staff.flyingcroc.net>
To:        FreeBSD-gnats-submit@FreeBSD.org
Subject:   kern/46239: posix semaphore implementation errors
Message-ID:  <20021213182612.73922.qmail@zircon.staff.flyingcroc.net>

next in thread | raw e-mail | index | archive | help

>Number:         46239
>Category:       kern
>Synopsis:       posix semaphore implementation errors
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Fri Dec 13 10:30:01 PST 2002
>Closed-Date:
>Last-Modified:
>Originator:     Joe Kelsey
>Release:        FreeBSD 5.0
>Organization:
>Environment:
System: FreeBSD zircon.staff.flyingcroc.net 4.7-STABLE FreeBSD 4.7-STABLE #4: Mon Dec 2 10:11:39 PST 2002 joek@zircon.staff.flyingcroc.net:/usr/obj/usr/src/sys/ZIRCON i386

>Description:
	The new posix semaphore implementation in 5.0 has potential
	standards problems.
>How-To-Repeat:
	By inspection of code.

	Looking at src/lib/libc/sys/sem.c:
sem_t *
sem_open(const char *name, int oflag, ...)
{
	sem_t *sem;
	sem_t s;
	semid_t semid;
	mode_t mode;
	unsigned int value;

	mode = 0;
	value = 0;

	if ((oflag & O_CREAT) != 0) {
		va_list ap;

		va_start(ap, oflag);
		mode = va_arg(ap, int);
		value = va_arg(ap, unsigned int);
		va_end(ap);
	}
	/*
	 * we can be lazy and let the kernel handle the "oflag",
	 * we'll just merge duplicate IDs into our list.
	 */
	if (ksem_open(&semid, name, oflag, mode, value) == -1)
		return (SEM_FAILED);
...

	This clearly simply passes the name parameter to ksem_open.  We
	then examine src/sys/kern/uipc_sem.c:
static int
sem_create(td, name, ksret, mode, value)
	struct thread *td;
	const char *name;
	struct ksem **ksret;
	mode_t mode;
	unsigned int value;
{
	struct ksem *ret;
	struct proc *p;
	struct ucred *uc;
	size_t len;
	int error;

	DP(("sem_create\n"));
	p = td->td_proc;
	uc = p->p_ucred;
	if (value > SEM_VALUE_MAX)
		return (EINVAL);
	ret = malloc(sizeof(*ret), M_SEM, M_WAITOK | M_ZERO);
	if (name != NULL) {
		len = strlen(name);
		if (len > SEM_MAX_NAMELEN) {
			free(ret, M_SEM);
			return (ENAMETOOLONG);
		}
		/* name must start with a '/' but not contain one. */
		if (*name != '/' || len < 2 || index(name + 1, '/') != NULL) {
			free(ret, M_SEM);
			return (EINVAL);
		}
		ret->ks_name = malloc(len + 1, M_SEM, M_WAITOK);
		strcpy(ret->ks_name, name);
...

	It appears that names are restricted to a fixed length
	(SEM_MAX_NAMELEN, manifestly 14) and *must* start with '/' and
	not contain '/'.  This is in direct violation of the POSIX
	standard which says that the implementation must distinguish
	between names beginning or not beginning with '/', but otherwise
	the names must conform to pathname standards.

	The semaphore implementation should allow arbitrary pathnames as
	semaphore names.  In the future, the implementation should
	create empty files to stand-in for semaphores and coordinate
	with the file system code somehow.  For now, simply allowing
	longer semaphore names and not bothering with the whole '/'
	checking should suffice for POSIX.

>Fix:

	Remove the SEM_MAX_NAMELEN check.

	Remove the whole '/' checking stuff.



>Release-Note:
>Audit-Trail:
>Unformatted:

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20021213182612.73922.qmail>