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>
