Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 20 Jan 2001 01:19:48 -0800
From:      Kris Kennaway <kris@FreeBSD.org>
To:        audit@FreeBSD.org
Subject:   openpty(8) helper app
Message-ID:  <20010120011948.A37806@citusc17.usc.edu>

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

--J/dobhs11T7y2rNN
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

For a long time now I've been wanting to fix openpty(3) to work
correctly for non-root users, i.e. to change the ownership and file
permissions so that it is secure for non-root callers (presently it's
a big security hole than ptys obtained will still be world
readable/writable, so applications cannot use them securely).

Then I discovered bin/9770, which is a solution to this problem which
has existed for almost 2 years :-)

Here's the patch - please review carefully:

Kris

Index: libexec/Makefile
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /mnt/ncvs/src/libexec/Makefile,v
retrieving revision 1.44
diff -u -r1.44 Makefile
--- libexec/Makefile	2001/01/11 13:01:15	1.44
+++ libexec/Makefile	2001/01/20 08:13:09
@@ -25,6 +25,7 @@
 	save-entropy \
 	talkd \
 	tftpd \
+	ttymode \
 	xtend \
 	ypxfr
=20
Index: lib/libutil/pty.3
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /mnt/ncvs/src/lib/libutil/pty.3,v
retrieving revision 1.9
diff -u -r1.9 pty.3
--- lib/libutil/pty.3	2000/04/22 16:16:58	1.9
+++ lib/libutil/pty.3	2001/01/20 08:50:24
@@ -56,6 +56,10 @@
 reading and writing by the owner, and for writing by the group, and to
 invalidate any current use of the line by calling
 .Xr revoke 2 .
+If the calling process does not have an effective UID of super-user,
+the auxiliary program
+.Xr ttymode 8
+is used to perform the intended actions.
 .Pp
 If the argument
 .Fa name
@@ -127,10 +131,10 @@
 .Xr login_tty 3 ,
 .Xr pty 4 ,
 .Xr termios 4 ,
-.Xr group 5
+.Xr group 5 ,
+.Xr ttymode 8
 .Sh BUGS
-The calling process must have an effective UID of super-user in order
-to perform all the intended actions.  No notification will occur if
+No notification will occur if
 .Fn openpty
 or
 .Fn forkpty
Index: lib/libutil/pty.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /mnt/ncvs/src/lib/libutil/pty.c,v
retrieving revision 1.10
diff -u -r1.10 pty.c
--- lib/libutil/pty.c	1999/08/28 00:05:51	1.10
+++ lib/libutil/pty.c	2001/01/20 08:49:27
@@ -43,16 +43,61 @@
 #include <sys/types.h>
 #include <sys/ioctl.h>
 #include <sys/stat.h>
+#include <sys/wait.h>
=20
 #include <errno.h>
 #include <fcntl.h>
 #include <grp.h>
+#include <signal.h>
 #include <stdlib.h>
 #include <string.h>
 #include <termios.h>
+#include <time.h>
 #include <unistd.h>
 #include <libutil.h>
=20
+#ifndef _PATH_TTYMODE
+#define _PATH_TTYMODE "/usr/libexec/ttymode"
+#define NAME_TTYMODE "ttymode"
+#endif
+
+
+static int
+set_ttymode(ptyname, ptyfd)
+	char *ptyname;
+	int ptyfd;
+{
+	pid_t pid;
+	int ret, status;
+	sigset_t oset, nset;
+=09
+	if (sigemptyset(&nset) =3D=3D -1 || sigaddset(&nset, SIGCHLD) =3D=3D -1
+	    || sigprocmask(SIG_BLOCK, &nset, &oset) =3D=3D -1)
+		return -1;
+	switch(pid =3D fork()) {
+	case -1:
+		sigprocmask(SIG_SETMASK, &oset, (sigset_t *)NULL);
+		return -1;
+	case 0:
+		if (dup2(ptyfd, 0) =3D=3D -1)
+			_exit(1);
+		execl(_PATH_TTYMODE, NAME_TTYMODE, ptyname, (char *)NULL);
+		_exit(1);
+	default:
+		while ((ret =3D waitpid(pid, &status, 0)) =3D=3D -1
+		    && errno =3D=3D EINTR)
+			continue;
+		sigprocmask(SIG_SETMASK, &oset, (sigset_t *)NULL);
+		if (ret =3D=3D -1)
+			return -1;
+		if (WIFEXITED(status))
+			return WEXITSTATUS(status) =3D=3D 0 ? 0 : -1;
+		else
+			return -1;
+	}
+}
+
+
 int
 openpty(amaster, aslave, name, termp, winp)
 	int *amaster, *aslave;
@@ -79,9 +124,15 @@
 				if (errno =3D=3D ENOENT)
 					return (-1);	/* out of ptys */
 			} else {
-				line[5] =3D 't';
-				(void) chown(line, getuid(), ttygid);
-				(void) chmod(line, S_IRUSR|S_IWUSR|S_IWGRP);
+				if (getuid() =3D=3D 0) {
+					line[5] =3D 't';
+					(void) chown(line, getuid(), ttygid);
+					(void) chmod(line,
+					    S_IRUSR|S_IWUSR|S_IWGRP);
+				} else {
+					(void) set_ttymode(line, master);
+					line[5] =3D 't';
+				}
 				(void) revoke(line);
 				if ((slave =3D open(line, O_RDWR, 0)) !=3D -1) {
 					*amaster =3D master;
diff -ruN /dev/null libexec/ttymode/Makefile
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ libexec/ttymode/Makefile	Sat Jan 20 00:28:44 2001
@@ -0,0 +1,10 @@
+#  $Id$
+
+PROG=3D	ttymode
+SRCS=3D	ttymode.c
+MAN8=3D	ttymode.8
+COPTS+=3D	-Wall
+
+BINMODE=3D4555
+
+.include <bsd.prog.mk>
diff -ruN /dev/null libexec/ttymode/ttymode.8
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ libexec/ttymode/ttymode.8	Thu Jan 28 18:09:05 1999
@@ -0,0 +1,54 @@
+.\"=20
+.\" Copyright (c) 1999 Ronald Kuehn <rk@ronald.org>
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PUR=
POSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUEN=
TIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ST=
RICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY =
WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\"	$Id$
+.\"=20
+.Dd January 28, 1999
+.Dt TTYMODE 8
+.Os "FreeBSD 3.0"
+.Sh NAME
+.Nm ttymode
+.Nd set owner, group and mode on pseudo terminals
+.Sh SYNOPSIS
+.Nm ttymode
+.Ar ptyname
+.Sh DESCRIPTION
+.Nm Ttyname
+sets owner, group and mode on pseudo terminals. It is usually called by
+.Xr openpty 3
+and is not intended to be used directly.
+.Pp
+.Sh FILES
+.Bl -tag -width /dev/pty[p-sP-S][0-9a-v] -compact
+.It Pa /dev/pty[p-sP-S][0-9a-v]
+master pseudo terminals
+.It Pa /dev/tty[p-sP-S][0-9a-v]
+slave pseudo terminals
+.El
+.Sh SEE ALSO
+.Xr openpty 3 ,
+.Xr forkpty 3
+.Sh AUTHOR
+.An Ronald Kuehn Aq rk@ronald.org .
diff -ruN /dev/null libexec/ttymode/ttymode.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ libexec/ttymode/ttymode.c	Thu Jan 28 18:12:47 1999
@@ -0,0 +1,82 @@
+/*-
+ * Copyright (c) 1999 Ronald Kuehn <rk@ronald.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURP=
OSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENT=
IAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STR=
ICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY W=
AY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	$Id$
+ */
+
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include <grp.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sysexits.h>
+#include <unistd.h>
+
+
+#ifndef lint
+static const char cvsid[] =3D
+    "$Id$";
+#endif
+
+/*=20
+ * This program is expected to be called from openpty(3) from within=20
+ * libutil. It is installed setuid root. Beware of the bugs! ;-)
+ * Descriptor 0 (stdin) is expected to be a valid descriptor on
+ * "/dev/pty??" (ptyname). If all checks succeed, the corresponding
+ * "/dev/tty??" is chown()ed to the real user of the calling process.
+ * The group is set to "tty" and mode 0620 is set.
+ */
+int
+main(int argc, char *argv[])
+{
+	gid_t	ttygid;
+	char	*name;
+	struct	group *ttygroup;
+	struct	stat fsb, nsb;
+
+	if (argc !=3D 2) {
+		setuid(getuid());
+		fprintf(stderr, "usage: ttymode ptyname\n");
+		return EX_USAGE;
+	}
+	name =3D argv[1];
+	if (strlen(name) !=3D 10 || strncmp(name, "/dev/pty", 8) !=3D 0)
+		return EX_DATAERR;
+	if (lstat(name, &nsb) =3D=3D -1 || fstat(0, &fsb) =3D=3D -1)
+		return EX_DATAERR;
+	if (nsb.st_dev !=3D fsb.st_dev || nsb.st_ino !=3D fsb.st_ino ||
+	    nsb.st_rdev !=3D fsb.st_rdev || !S_ISCHR(fsb.st_mode))
+		return EX_DATAERR;
+	if ((ttygroup =3D getgrnam("tty")) =3D=3D NULL)
+		ttygid =3D -1;
+	else
+		ttygid =3D ttygroup->gr_gid;
+	name[5] =3D 't';
+	(void)chown(name, getuid(), ttygid);
+	(void)chmod(name, S_IRUSR|S_IWUSR|S_IWGRP);
+	return EX_OK;
+}

--J/dobhs11T7y2rNN
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.4 (FreeBSD)
Comment: For info see http://www.gnupg.org

iD8DBQE6aVgzWry0BWjoQKURAszgAKCnxfWVAQ9VeKM4BS4KOppv8tD3oQCfUiTB
rnXaIyeLFG77msYzjq6LLUU=
=DDgZ
-----END PGP SIGNATURE-----

--J/dobhs11T7y2rNN--


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




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