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
[-- Attachment #1 --]
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
===================================================================
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
Index: lib/libutil/pty.3
===================================================================
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
===================================================================
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>
#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>
+#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;
+
+ if (sigemptyset(&nset) == -1 || sigaddset(&nset, SIGCHLD) == -1
+ || sigprocmask(SIG_BLOCK, &nset, &oset) == -1)
+ return -1;
+ switch(pid = fork()) {
+ case -1:
+ sigprocmask(SIG_SETMASK, &oset, (sigset_t *)NULL);
+ return -1;
+ case 0:
+ if (dup2(ptyfd, 0) == -1)
+ _exit(1);
+ execl(_PATH_TTYMODE, NAME_TTYMODE, ptyname, (char *)NULL);
+ _exit(1);
+ default:
+ while ((ret = waitpid(pid, &status, 0)) == -1
+ && errno == EINTR)
+ continue;
+ sigprocmask(SIG_SETMASK, &oset, (sigset_t *)NULL);
+ if (ret == -1)
+ return -1;
+ if (WIFEXITED(status))
+ return WEXITSTATUS(status) == 0 ? 0 : -1;
+ else
+ return -1;
+ }
+}
+
+
int
openpty(amaster, aslave, name, termp, winp)
int *amaster, *aslave;
@@ -79,9 +124,15 @@
if (errno == ENOENT)
return (-1); /* out of ptys */
} else {
- line[5] = 't';
- (void) chown(line, getuid(), ttygid);
- (void) chmod(line, S_IRUSR|S_IWUSR|S_IWGRP);
+ if (getuid() == 0) {
+ line[5] = 't';
+ (void) chown(line, getuid(), ttygid);
+ (void) chmod(line,
+ S_IRUSR|S_IWUSR|S_IWGRP);
+ } else {
+ (void) set_ttymode(line, master);
+ line[5] = 't';
+ }
(void) revoke(line);
if ((slave = open(line, O_RDWR, 0)) != -1) {
*amaster = 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= ttymode
+SRCS= ttymode.c
+MAN8= ttymode.8
+COPTS+= -Wall
+
+BINMODE=4555
+
+.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 @@
+.\"
+.\" 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 PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" 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, STRICT
+.\" 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$
+.\"
+.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 PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * 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, STRICT
+ * 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$
+ */
+
+#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[] =
+ "$Id$";
+#endif
+
+/*
+ * This program is expected to be called from openpty(3) from within
+ * 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 != 2) {
+ setuid(getuid());
+ fprintf(stderr, "usage: ttymode ptyname\n");
+ return EX_USAGE;
+ }
+ name = argv[1];
+ if (strlen(name) != 10 || strncmp(name, "/dev/pty", 8) != 0)
+ return EX_DATAERR;
+ if (lstat(name, &nsb) == -1 || fstat(0, &fsb) == -1)
+ return EX_DATAERR;
+ if (nsb.st_dev != fsb.st_dev || nsb.st_ino != fsb.st_ino ||
+ nsb.st_rdev != fsb.st_rdev || !S_ISCHR(fsb.st_mode))
+ return EX_DATAERR;
+ if ((ttygroup = getgrnam("tty")) == NULL)
+ ttygid = -1;
+ else
+ ttygid = ttygroup->gr_gid;
+ name[5] = 't';
+ (void)chown(name, getuid(), ttygid);
+ (void)chmod(name, S_IRUSR|S_IWUSR|S_IWGRP);
+ return EX_OK;
+}
[-- Attachment #2 --]
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.4 (FreeBSD)
Comment: For info see http://www.gnupg.org
iD8DBQE6aVgzWry0BWjoQKURAszgAKCnxfWVAQ9VeKM4BS4KOppv8tD3oQCfUiTB
rnXaIyeLFG77msYzjq6LLUU=
=DDgZ
-----END PGP SIGNATURE-----
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20010120011948.A37806>
