From owner-freebsd-standards@FreeBSD.ORG Wed Oct 29 01:10:20 2003 Return-Path: Delivered-To: freebsd-standards@hub.freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 74C1416A4CE for ; Wed, 29 Oct 2003 01:10:20 -0800 (PST) Received: from freefall.freebsd.org (freefall.freebsd.org [216.136.204.21]) by mx1.FreeBSD.org (Postfix) with ESMTP id 040C843FB1 for ; Wed, 29 Oct 2003 01:10:19 -0800 (PST) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.12.9/8.12.9) with ESMTP id h9T9AIFY015426 for ; Wed, 29 Oct 2003 01:10:18 -0800 (PST) (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.12.9/8.12.9/Submit) id h9T9AIvj015425; Wed, 29 Oct 2003 01:10:18 -0800 (PST) (envelope-from gnats) Resent-Date: Wed, 29 Oct 2003 01:10:18 -0800 (PST) Resent-Message-Id: <200310290910.h9T9AIvj015425@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-standards@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, Ryan Younce Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 11CF716A4CE for ; Wed, 29 Oct 2003 01:07:16 -0800 (PST) Received: from turing.vangyzen.net (turing.vangyzen.net [152.3.22.133]) by mx1.FreeBSD.org (Postfix) with ESMTP id 70E7F43F3F for ; Wed, 29 Oct 2003 01:07:15 -0800 (PST) (envelope-from ryan@turing.vangyzen.net) Received: by turing.vangyzen.net (Postfix, from userid 1010) id CD2A71145D; Wed, 29 Oct 2003 04:07:14 -0500 (EST) Message-Id: <20031029090714.CD2A71145D@turing.vangyzen.net> Date: Wed, 29 Oct 2003 04:07:14 -0500 (EST) From: Ryan Younce To: FreeBSD-gnats-submit@FreeBSD.org X-Send-Pr-Version: 3.113 Subject: standards/58676: grantpt(3) alters storage used by ptsname(3) X-BeenThere: freebsd-standards@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list Reply-To: Ryan Younce List-Id: Standards compliance List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 29 Oct 2003 09:10:20 -0000 >Number: 58676 >Category: standards >Synopsis: grantpt(3) alters storage used by ptsname(3) >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-standards >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Wed Oct 29 01:10:18 PST 2003 >Closed-Date: >Last-Modified: >Originator: Ryan Younce >Release: FreeBSD 5.1-RELEASE >Organization: >Environment: FreeBSD kara 5.1-RELEASE FreeBSD 5.1-RELEASE #3: Mon Oct 6 22:31:51 GMT 2003 root@kara:/usr/src/sys/i386/compile/KARA i386 >Description: The ptsname(3) function is allowed by POSIX to hold the returned slave PTY name in static storage that may be overwritten by subsequent calls to ptsname() (which it does). In the current implementation, however, grantpt(3) calls ptsname() to obtain the name of the slave device. Hence, a call to grantpt() will alter the object returned by a previous ptsname() if grantpt() is called with a different descriptor than the one used in the last call to ptsname(). This is incorrect; POSIX makes no mention that the returned object of ptsname() may be modified by subsequent calls to grantpt(). >How-To-Repeat: #include #include #include int main(void) { char *slave; int fd1, fd2; fd1 = posix_openpt(0); fd2 = posix_openpt(0); slave = ptsname(fd1); printf("fd1 slave name (before grantpt(fd2)): '%s'\n", slave); /* call grantpt(3) on fd2 */ grantpt(fd2); /* print out slave again, which should not have changed */ printf("fd1 slave name (after grantpt(fd2)): '%s'\n", slave); return 0; } >Fix: Moved the code that obtains the name of the PTY slave from the master's descriptor into a separate (internal) function, derive_slave(), that is called by both grantpt() and ptsname(). (As a side, the manual page should be updated to reflect that ptsname() holds its return in static storage that may be overwritten by subsequent calls to ptsname().) The following are patches to both files. Index: grantpt.c =================================================================== RCS file: /home/ncvs/src/lib/libc/stdlib/grantpt.c,v retrieving revision 1.2 diff -u -r1.2 grantpt.c --- grantpt.c 4 Jan 2003 08:10:55 -0000 1.2 +++ grantpt.c 27 Oct 2003 06:21:45 -0000 @@ -81,6 +81,27 @@ minor((x).st_rdev) >= 0 && \ minor((x).st_rdev) < PT_MAX) +static char * +derive_slave(int fildes, char *slave) +{ + struct stat sbuf; + char *retname = NULL; + + if (_fstat(fildes, &sbuf) == 0) { + /* Ensure fildes is a master PTY device */ + if (!ISPTM(sbuf)) + errno = EINVAL; + else { + /* Translate fildes into path to counterpart slave. */ + (void)sprintf(slave, _PATH_DEV PTS_PREFIX "%c%c", + PT_DEV1[minor(sbuf.st_rdev) / 32], + PT_DEV2[minor(sbuf.st_rdev) % 32]); + retname = slave; + } + } + return retname; +} + /* * grantpt(): grant ownership of a slave pseudo-terminal device to the * current user. @@ -92,14 +113,14 @@ int retval, serrno, status; pid_t pid, spid; gid_t gid; - char *slave; + char slave[] = _PATH_DEV PTS_PREFIX "XY"; sigset_t oblock, nblock; struct group *grp; retval = -1; serrno = errno; - if ((slave = ptsname(fildes)) != NULL) { + if (derive_slave(fildes, slave) != NULL) { /* * Block SIGCHLD. */ @@ -217,23 +238,7 @@ ptsname(int fildes) { static char slave[] = _PATH_DEV PTS_PREFIX "XY"; - char *retval; - struct stat sbuf; - - retval = NULL; - - if (_fstat(fildes, &sbuf) == 0) { - if (!ISPTM(sbuf)) - errno = EINVAL; - else { - (void)sprintf(slave, _PATH_DEV PTS_PREFIX "%c%c", - PT_DEV1[minor(sbuf.st_rdev) / 32], - PT_DEV2[minor(sbuf.st_rdev) % 32]); - retval = slave; - } - } - - return (retval); + return derive_slave(fildes, slave); } /* Index: grantpt.3 =================================================================== RCS file: /home/ncvs/src/lib/libc/stdlib/grantpt.3,v retrieving revision 1.3 diff -u -r1.3 grantpt.3 --- grantpt.3 14 Sep 2003 13:41:57 -0000 1.3 +++ grantpt.3 27 Oct 2003 06:21:45 -0000 @@ -211,6 +211,14 @@ .Fn posix_openpt functions appeared in .Fx 5.0 . +.Sh BUGS +The function +.Fn ptsname +leaves its result in an internal static object and returns +a pointer to that object. +Subsequent calls to +.Fn ptsname +will modify the same object. .Sh NOTES The purpose of the .Fn unlockpt >Release-Note: >Audit-Trail: >Unformatted: