From owner-svn-src-all@FreeBSD.ORG Sat May 17 11:43:15 2014 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id F389D193; Sat, 17 May 2014 11:43:14 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id D5CC62922; Sat, 17 May 2014 11:43:14 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.8/8.14.8) with ESMTP id s4HBhEoU047033; Sat, 17 May 2014 11:43:14 GMT (envelope-from kib@svn.freebsd.org) Received: (from kib@localhost) by svn.freebsd.org (8.14.8/8.14.8/Submit) id s4HBhEAN047032; Sat, 17 May 2014 11:43:14 GMT (envelope-from kib@svn.freebsd.org) Message-Id: <201405171143.s4HBhEAN047032@svn.freebsd.org> From: Konstantin Belousov Date: Sat, 17 May 2014 11:43:14 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r266306 - stable/10/lib/libc/gen X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 17 May 2014 11:43:15 -0000 Author: kib Date: Sat May 17 11:43:14 2014 New Revision: 266306 URL: http://svnweb.freebsd.org/changeset/base/266306 Log: MFC r265847: Fix sem_unlink(3) to properly invalidate the semaphores name cache. PR: standards/189353 Modified: stable/10/lib/libc/gen/sem_new.c Directory Properties: stable/10/ (props changed) Modified: stable/10/lib/libc/gen/sem_new.c ============================================================================== --- stable/10/lib/libc/gen/sem_new.c Sat May 17 11:38:26 2014 (r266305) +++ stable/10/lib/libc/gen/sem_new.c Sat May 17 11:43:14 2014 (r266306) @@ -66,6 +66,8 @@ __weak_reference(_sem_wait, sem_wait); struct sem_nameinfo { int open_count; char *name; + dev_t dev; + ino_t ino; sem_t *sem; LIST_ENTRY(sem_nameinfo) next; }; @@ -151,37 +153,46 @@ _sem_open(const char *name, int flags, . return (SEM_FAILED); } name++; - + strcpy(path, SEM_PREFIX); + if (strlcat(path, name, sizeof(path)) >= sizeof(path)) { + errno = ENAMETOOLONG; + return (SEM_FAILED); + } if (flags & ~(O_CREAT|O_EXCL)) { errno = EINVAL; return (SEM_FAILED); } - + if ((flags & O_CREAT) != 0) { + va_start(ap, flags); + mode = va_arg(ap, int); + value = va_arg(ap, int); + va_end(ap); + } + fd = -1; _pthread_once(&once, sem_module_init); _pthread_mutex_lock(&sem_llock); LIST_FOREACH(ni, &sem_list, next) { - if (strcmp(name, ni->name) == 0) { - if ((flags & (O_CREAT|O_EXCL)) == (O_CREAT|O_EXCL)) { - _pthread_mutex_unlock(&sem_llock); - errno = EEXIST; - return (SEM_FAILED); - } else { - ni->open_count++; - sem = ni->sem; - _pthread_mutex_unlock(&sem_llock); - return (sem); + if (ni->name != NULL && strcmp(name, ni->name) == 0) { + fd = _open(path, flags | O_RDWR | O_CLOEXEC | + O_EXLOCK, mode); + if (fd == -1 || _fstat(fd, &sb) == -1) + goto error; + if ((flags & (O_CREAT | O_EXCL)) == (O_CREAT | + O_EXCL) || ni->dev != sb.st_dev || + ni->ino != sb.st_ino) { + ni->name = NULL; + ni = NULL; + break; } + ni->open_count++; + sem = ni->sem; + _pthread_mutex_unlock(&sem_llock); + _close(fd); + return (sem); } } - if (flags & O_CREAT) { - va_start(ap, flags); - mode = va_arg(ap, int); - value = va_arg(ap, int); - va_end(ap); - } - len = sizeof(*ni) + strlen(name) + 1; ni = (struct sem_nameinfo *)malloc(len); if (ni == NULL) { @@ -192,17 +203,11 @@ _sem_open(const char *name, int flags, . ni->name = (char *)(ni+1); strcpy(ni->name, name); - strcpy(path, SEM_PREFIX); - if (strlcat(path, name, sizeof(path)) >= sizeof(path)) { - errno = ENAMETOOLONG; - goto error; + if (fd == -1) { + fd = _open(path, flags | O_RDWR | O_CLOEXEC | O_EXLOCK, mode); + if (fd == -1 || _fstat(fd, &sb) == -1) + goto error; } - - fd = _open(path, flags|O_RDWR|O_CLOEXEC|O_EXLOCK, mode); - if (fd == -1) - goto error; - if (_fstat(fd, &sb)) - goto error; if (sb.st_size < sizeof(sem_t)) { sem_t tmp; @@ -228,6 +233,8 @@ _sem_open(const char *name, int flags, . } ni->open_count = 1; ni->sem = sem; + ni->dev = sb.st_dev; + ni->ino = sb.st_ino; LIST_INSERT_HEAD(&sem_list, ni, next); _close(fd); _pthread_mutex_unlock(&sem_llock);