From owner-svn-src-all@freebsd.org Tue Sep 3 14:08:14 2019 Return-Path: Delivered-To: svn-src-all@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id DDD62DD966; Tue, 3 Sep 2019 14:07:21 +0000 (UTC) (envelope-from yuripv@freebsd.org) Received: from freefall.freebsd.org (freefall.freebsd.org [96.47.72.132]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "freefall.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 46N80T2J3Mz4QWf; Tue, 3 Sep 2019 14:07:21 +0000 (UTC) (envelope-from yuripv@freebsd.org) Received: by freefall.freebsd.org (Postfix, from userid 1452) id AF5AB1B4DB; Tue, 3 Sep 2019 14:06:36 +0000 (UTC) X-Original-To: yuripv@localmail.freebsd.org Delivered-To: yuripv@localmail.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (Client CN "mx1.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by freefall.freebsd.org (Postfix) with ESMTPS id 046D3EB0B; Mon, 22 Apr 2019 13:57:56 +0000 (UTC) (envelope-from owner-src-committers@freebsd.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2610:1c1:1:6074::16:84]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "freefall.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4410C8BFB9; Mon, 22 Apr 2019 13:57:56 +0000 (UTC) (envelope-from owner-src-committers@freebsd.org) Received: by freefall.freebsd.org (Postfix, from userid 538) id 19873EA9F; Mon, 22 Apr 2019 13:57:56 +0000 (UTC) Delivered-To: src-committers@localmail.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [96.47.72.80]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (Client CN "mx1.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by freefall.freebsd.org (Postfix) with ESMTPS id 974F1EA94 for ; Mon, 22 Apr 2019 13:57:53 +0000 (UTC) (envelope-from markj@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 536D88BFA4; Mon, 22 Apr 2019 13:57:53 +0000 (UTC) (envelope-from markj@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 2F4AADDEA; Mon, 22 Apr 2019 13:57:53 +0000 (UTC) (envelope-from markj@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id x3MDvrCu024912; Mon, 22 Apr 2019 13:57:53 GMT (envelope-from markj@FreeBSD.org) Received: (from markj@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id x3MDvreI024911; Mon, 22 Apr 2019 13:57:53 GMT (envelope-from markj@FreeBSD.org) Message-Id: <201904221357.x3MDvreI024911@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: markj set sender to markj@FreeBSD.org using -f From: Mark Johnston To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r346550 - head/usr.sbin/bhyve X-SVN-Group: head X-SVN-Commit-Author: markj X-SVN-Commit-Paths: head/usr.sbin/bhyve X-SVN-Commit-Revision: 346550 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk X-Loop: FreeBSD.org Sender: owner-src-committers@freebsd.org X-Rspamd-Queue-Id: 4410C8BFB9 X-Spamd-Bar: -- Authentication-Results: mx1.freebsd.org X-Spamd-Result: default: False [-2.92 / 15.00]; local_wl_from(0.00)[freebsd.org]; NEURAL_HAM_MEDIUM(-1.00)[-1.000,0]; NEURAL_HAM_SHORT(-0.92)[-0.925,0]; ASN(0.00)[asn:11403, ipnet:2610:1c1:1::/48, country:US]; NEURAL_HAM_LONG(-1.00)[-1.000,0] Status: O X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.29 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: , Date: Tue, 03 Sep 2019 14:08:14 -0000 X-Original-Date: Mon, 22 Apr 2019 13:57:53 +0000 (UTC) X-List-Received-Date: Tue, 03 Sep 2019 14:08:14 -0000 Author: markj Date: Mon Apr 22 13:57:52 2019 New Revision: 346550 URL: https://svnweb.freebsd.org/changeset/base/346550 Log: Use separate descriptors in bhyve's stdio uart backend. bhyve was previously using stdin for both reading and writing to the console, which made it difficult to redirect console output. Use stdin for reading and stdout for writing. This makes it easier to use bhyve as a backend for syzkaller. As a side effect, the change fixes a minor bug which would cause bhyve to fail with ENOTCAPABLE if configured to use nmdm for com1 and stdio for com2. bhyveload already uses separate descriptors, as does the bvmcons driver. Reviewed by: jhb MFC after: 1 month Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D19788 Modified: head/usr.sbin/bhyve/uart_emul.c Modified: head/usr.sbin/bhyve/uart_emul.c ============================================================================== --- head/usr.sbin/bhyve/uart_emul.c Mon Apr 22 13:55:06 2019 (r346549) +++ head/usr.sbin/bhyve/uart_emul.c Mon Apr 22 13:57:52 2019 (r346550) @@ -100,8 +100,8 @@ struct fifo { struct ttyfd { bool opened; - int fd; /* tty device file descriptor */ - struct termios tio_orig, tio_new; /* I/O Terminals */ + int rfd; /* fd for reading */ + int wfd; /* fd for writing, may be == rfd */ }; struct uart_softc { @@ -141,16 +141,15 @@ ttyclose(void) static void ttyopen(struct ttyfd *tf) { + struct termios orig, new; - tcgetattr(tf->fd, &tf->tio_orig); - - tf->tio_new = tf->tio_orig; - cfmakeraw(&tf->tio_new); - tf->tio_new.c_cflag |= CLOCAL; - tcsetattr(tf->fd, TCSANOW, &tf->tio_new); - - if (tf->fd == STDIN_FILENO) { - tio_stdio_orig = tf->tio_orig; + tcgetattr(tf->rfd, &orig); + new = orig; + cfmakeraw(&new); + new.c_cflag |= CLOCAL; + tcsetattr(tf->rfd, TCSANOW, &new); + if (uart_stdio) { + tio_stdio_orig = orig; atexit(ttyclose); } } @@ -160,7 +159,7 @@ ttyread(struct ttyfd *tf) { unsigned char rb; - if (read(tf->fd, &rb, 1) == 1) + if (read(tf->rfd, &rb, 1) == 1) return (rb); else return (-1); @@ -170,7 +169,7 @@ static void ttywrite(struct ttyfd *tf, unsigned char wb) { - (void)write(tf->fd, &wb, 1); + (void)write(tf->wfd, &wb, 1); } static void @@ -190,7 +189,7 @@ rxfifo_reset(struct uart_softc *sc, int size) * Flush any unread input from the tty buffer. */ while (1) { - nread = read(sc->tty.fd, flushbuf, sizeof(flushbuf)); + nread = read(sc->tty.rfd, flushbuf, sizeof(flushbuf)); if (nread != sizeof(flushbuf)) break; } @@ -277,7 +276,7 @@ uart_opentty(struct uart_softc *sc) { ttyopen(&sc->tty); - sc->mev = mevent_add(sc->tty.fd, EVF_READ, uart_drain, sc); + sc->mev = mevent_add(sc->tty.rfd, EVF_READ, uart_drain, sc); assert(sc->mev != NULL); } @@ -374,7 +373,7 @@ uart_drain(int fd, enum ev_type ev, void *arg) sc = arg; - assert(fd == sc->tty.fd); + assert(fd == sc->tty.rfd); assert(ev == EVF_READ); /* @@ -637,68 +636,79 @@ uart_init(uart_intr_func_t intr_assert, uart_intr_func } static int -uart_tty_backend(struct uart_softc *sc, const char *opts) +uart_stdio_backend(struct uart_softc *sc) { - int fd; - int retval; +#ifndef WITHOUT_CAPSICUM + cap_rights_t rights; + cap_ioctl_t cmds[] = { TIOCGETA, TIOCSETA, TIOCGWINSZ }; +#endif - retval = -1; + if (uart_stdio) + return (-1); - fd = open(opts, O_RDWR | O_NONBLOCK); - if (fd > 0 && isatty(fd)) { - sc->tty.fd = fd; - sc->tty.opened = true; - retval = 0; - } + sc->tty.rfd = STDIN_FILENO; + sc->tty.wfd = STDOUT_FILENO; + sc->tty.opened = true; - return (retval); + if (fcntl(sc->tty.rfd, F_SETFL, O_NONBLOCK) != 0) + return (-1); + if (fcntl(sc->tty.wfd, F_SETFL, O_NONBLOCK) != 0) + return (-1); + +#ifndef WITHOUT_CAPSICUM + cap_rights_init(&rights, CAP_EVENT, CAP_IOCTL, CAP_READ); + if (caph_rights_limit(sc->tty.rfd, &rights) == -1) + errx(EX_OSERR, "Unable to apply rights for sandbox"); + if (caph_ioctls_limit(sc->tty.rfd, cmds, nitems(cmds)) == -1) + errx(EX_OSERR, "Unable to apply rights for sandbox"); +#endif + + uart_stdio = true; + + return (0); } -int -uart_set_backend(struct uart_softc *sc, const char *opts) +static int +uart_tty_backend(struct uart_softc *sc, const char *opts) { - int retval; #ifndef WITHOUT_CAPSICUM cap_rights_t rights; cap_ioctl_t cmds[] = { TIOCGETA, TIOCSETA, TIOCGWINSZ }; #endif + int fd; - retval = -1; + fd = open(opts, O_RDWR | O_NONBLOCK); + if (fd < 0 || !isatty(fd)) + return (-1); + sc->tty.rfd = sc->tty.wfd = fd; + sc->tty.opened = true; + +#ifndef WITHOUT_CAPSICUM + cap_rights_init(&rights, CAP_EVENT, CAP_IOCTL, CAP_READ, CAP_WRITE); + if (caph_rights_limit(fd, &rights) == -1) + errx(EX_OSERR, "Unable to apply rights for sandbox"); + if (caph_ioctls_limit(fd, cmds, nitems(cmds)) == -1) + errx(EX_OSERR, "Unable to apply rights for sandbox"); +#endif + + return (0); +} + +int +uart_set_backend(struct uart_softc *sc, const char *opts) +{ + int retval; + if (opts == NULL) return (0); - if (strcmp("stdio", opts) == 0) { - if (!uart_stdio) { - sc->tty.fd = STDIN_FILENO; - sc->tty.opened = true; - uart_stdio = true; - retval = 0; - } - } else if (uart_tty_backend(sc, opts) == 0) { - retval = 0; - } - - /* Make the backend file descriptor non-blocking */ + if (strcmp("stdio", opts) == 0) + retval = uart_stdio_backend(sc); + else + retval = uart_tty_backend(sc, opts); if (retval == 0) - retval = fcntl(sc->tty.fd, F_SETFL, O_NONBLOCK); - - if (retval == 0) { -#ifndef WITHOUT_CAPSICUM - cap_rights_init(&rights, CAP_EVENT, CAP_IOCTL, CAP_READ, - CAP_WRITE); - if (caph_rights_limit(sc->tty.fd, &rights) == -1) - errx(EX_OSERR, "Unable to apply rights for sandbox"); - if (caph_ioctls_limit(sc->tty.fd, cmds, nitems(cmds)) == -1) - errx(EX_OSERR, "Unable to apply rights for sandbox"); - if (!uart_stdio) { - if (caph_limit_stdin() == -1) - errx(EX_OSERR, - "Unable to apply rights for sandbox"); - } -#endif uart_opentty(sc); - } return (retval); }