On Wed, Jan 25, 2017 at 12:41:26AM -0700, Theo de Raadt wrote:
> > On Wed, Jan 25, 2017 at 12:33:36AM -0700, Theo de Raadt wrote:
> > > > 2. vmd calls openpty() in the pledged parent whenever a new VM is
> > > > started - effectively doing ioctls on post-pledge fds.  I will
> > > > probably solve this by opening the pty in the non-pledged "priv"
> > > > process, and do some additional passing, but then I'll also have to
> > > > give up its chroot to access /dev/.
> > > > 
> > > > vmd: ioctl 40287401 post-pledge fd 12
> > > > vmd(51681): syscall 54 "tty"
> > > 
> > > How about opening PATH_PTMDEV early and keeping it open in a
> > > properly protected process; then create pty pairs as required.
> > 
> > Oh, yes, I should have looked at openpty() in libutil first :)
> > That makes sense, I will try it.
> 
> But please don't become too attached to the proposed semantics.
> It's a proposal, we need to learn if it actually helps or hinders
> privsep programs become better.

ok, no problem, it is a very simple thing in vmd.

so, just as a proposal, the attached diff makes it work with vmd and
the chroot-friendly version of openpty might be useful for libutil.

Reyk

Index: lib/libutil/openpty.3
===================================================================
RCS file: /cvs/src/lib/libutil/openpty.3,v
retrieving revision 1.17
diff -u -p -u -p -r1.17 openpty.3
--- lib/libutil/openpty.3       28 Aug 2015 19:54:06 -0000      1.17
+++ lib/libutil/openpty.3       25 Jan 2017 08:40:46 -0000
@@ -44,6 +44,8 @@
 .Ft int
 .Fn openpty "int *amaster" "int *aslave" "char *name" "struct termios *termp" 
"struct winsize *winp"
 .Ft int
+.Fn fdopenpty "int ptmfd" "int *amaster" "int *aslave" "char *name" "struct 
termios *termp" "struct winsize *winp"
+.Ft int
 .Fn login_tty "int fd"
 .Ft pid_t
 .Fn forkpty "int *amaster" "char *name" "struct termios *termp" "struct 
winsize *winp"
@@ -88,6 +90,15 @@ the caller, permissions are set to corre
 uses of that device are revoked (see
 .Xr revoke 2
 for details).
+.Pp
+The
+.Fn fdopenpty
+function works like
+.Fn openpty
+but expects a pre-opened
+.Pa /dev/ptm
+file descriptor
+.Fa ptmfd .
 .Pp
 The
 .Fn login_tty
Index: lib/libutil/pty.c
===================================================================
RCS file: /cvs/src/lib/libutil/pty.c,v
retrieving revision 1.20
diff -u -p -u -p -r1.20 pty.c
--- lib/libutil/pty.c   30 Aug 2016 14:44:45 -0000      1.20
+++ lib/libutil/pty.c   25 Jan 2017 08:40:46 -0000
@@ -57,11 +57,30 @@ openpty(int *amaster, int *aslave, char 
        fd = open(PATH_PTMDEV, O_RDWR|O_CLOEXEC);
        if (fd == -1)
                return (-1);
-       if ((ioctl(fd, PTMGET, &ptm) == -1)) {
+
+       if (fdopenpty(fd, amaster, aslave, name, termp, winp) == -1) {
                close(fd);
                return (-1);
        }
        close(fd);
+
+       return (0);
+}
+
+int
+fdopenpty(int ptmfd, int *amaster, int *aslave, char *name,
+    struct termios *termp, struct winsize *winp)
+{
+       int master, slave;
+       struct ptmget ptm;
+
+       /*
+        * Use /dev/ptm and the PTMGET ioctl to get a properly set up and
+        * owned pty/tty pair.
+        */
+       if ((ioctl(ptmfd, PTMGET, &ptm) == -1))
+               return (-1);
+
        master = ptm.cfd;
        slave = ptm.sfd;
        if (name) {
Index: lib/libutil/util.h
===================================================================
RCS file: /cvs/src/lib/libutil/util.h,v
retrieving revision 1.34
diff -u -p -u -p -r1.34 util.h
--- lib/libutil/util.h  3 Jun 2013 21:07:02 -0000       1.34
+++ lib/libutil/util.h  25 Jan 2017 08:40:46 -0000
@@ -99,6 +99,7 @@ void  pw_copy(int, int, const struct pass
 int    pw_scan(char *, struct passwd *, int *);
 void   pw_error(const char *, int, int);
 int    openpty(int *, int *, char *, struct termios *, struct winsize *);
+int    fdopenpty(int, int *, int *, char *, struct termios *, struct winsize 
*);
 int    opendisk(const char *, int, char *, size_t, int);
 pid_t  forkpty(int *, char *, struct termios *, struct winsize *);
 int    getmaxpartitions(void);
Index: usr.sbin/vmd/config.c
===================================================================
RCS file: /cvs/src/usr.sbin/vmd/config.c,v
retrieving revision 1.23
diff -u -p -u -p -r1.23 config.c
--- usr.sbin/vmd/config.c       17 Jan 2017 21:51:01 -0000      1.23
+++ usr.sbin/vmd/config.c       25 Jan 2017 08:40:46 -0000
@@ -34,6 +34,7 @@
 #include <util.h>
 #include <errno.h>
 #include <imsg.h>
+#include <util.h>
 
 #include "proc.h"
 #include "vmd.h"
@@ -122,6 +123,7 @@ config_getreset(struct vmd *env, struct 
 int
 config_setvm(struct privsep *ps, struct vmd_vm *vm, uint32_t peerid)
 {
+       struct vmd              *env = ps->ps_env;
        struct vmd_if           *vif;
        struct vmop_create_params *vmc = &vm->vm_params;
        struct vm_create_params *vcp = &vmc->vmc_params;
@@ -241,7 +243,8 @@ config_setvm(struct privsep *ps, struct 
 
        /* Open TTY */
        if (vm->vm_ttyname == NULL) {
-               if (openpty(&vm->vm_tty, &ttys_fd, ptyname, NULL, NULL) == -1 ||
+               if (fdopenpty(env->vmd_ptmfd,
+                   &vm->vm_tty, &ttys_fd, ptyname, NULL, NULL) == -1 ||
                    (vm->vm_ttyname = strdup(ptyname)) == NULL) {
                        log_warn("%s: can't open tty %s", __func__, ptyname);
                        goto fail;
Index: usr.sbin/vmd/vmd.c
===================================================================
RCS file: /cvs/src/usr.sbin/vmd/vmd.c,v
retrieving revision 1.50
diff -u -p -u -p -r1.50 vmd.c
--- usr.sbin/vmd/vmd.c  13 Jan 2017 19:21:16 -0000      1.50
+++ usr.sbin/vmd/vmd.c  25 Jan 2017 08:40:46 -0000
@@ -20,6 +20,7 @@
 #include <sys/queue.h>
 #include <sys/wait.h>
 #include <sys/cdefs.h>
+#include <sys/tty.h>
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -483,6 +484,9 @@ vmd_configure(void)
 {
        struct vmd_vm           *vm;
        struct vmd_switch       *vsw;
+
+       if ((env->vmd_ptmfd = open(PATH_PTMDEV, O_RDWR|O_CLOEXEC)) == -1)
+               fatal("open %s", PATH_PTMDEV);
 
        /*
         * pledge in the parent process:
Index: usr.sbin/vmd/vmd.h
===================================================================
RCS file: /cvs/src/usr.sbin/vmd/vmd.h,v
retrieving revision 1.43
diff -u -p -u -p -r1.43 vmd.h
--- usr.sbin/vmd/vmd.h  13 Jan 2017 19:21:16 -0000      1.43
+++ usr.sbin/vmd/vmd.h  25 Jan 2017 08:40:46 -0000
@@ -185,6 +185,7 @@ struct vmd {
        struct switchlist       *vmd_switches;
 
        int                      vmd_fd;
+       int                      vmd_ptmfd;
 };
 
 /* vmd.c */

Reply via email to