Browse Source

Add getptmfd(), fdopenpty(), fdforkpty() functions. These allow programs

to separate the open(/dev/ptm) from the ioctl(PTMGET) for privilege
separation or pledge().
Based on a diff from reyk@.
ok deraadt millert
OPENBSD_6_2
nicm 7 years ago
parent
commit
cddf1b0fbc
4 changed files with 96 additions and 19 deletions
  1. +46
    -7
      src/lib/libutil/openpty.3
  2. +44
    -10
      src/lib/libutil/pty.c
  3. +1
    -1
      src/lib/libutil/shlib_version
  4. +5
    -1
      src/lib/libutil/util.h

+ 46
- 7
src/lib/libutil/openpty.3 View File

@ -1,4 +1,4 @@
.\" $OpenBSD: openpty.3,v 1.17 2015/08/28 19:54:06 kettenis Exp $
.\" $OpenBSD: openpty.3,v 1.18 2017/04/20 17:48:30 nicm Exp $
.\" Copyright (c) 1995
.\" The Regents of the University of California. All rights reserved.
.\"
@ -30,7 +30,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.Dd $Mdocdate: August 28 2015 $
.Dd $Mdocdate: April 20 2017 $
.Dt OPENPTY 3
.Os
.Sh NAME
@ -42,11 +42,17 @@
.In termios.h
.In util.h
.Ft int
.Fn getptmfd "void"
.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"
.Ft pid_t
.Fn fdforkpty "int ptmfd" "int *amaster" "char *name" "struct termios *termp" "struct winsize *winp"
.Sh DESCRIPTION
The
.Fn openpty ,
@ -90,6 +96,22 @@ uses of that device are revoked (see
for details).
.Pp
The
.Fn fdopenpty
and
.Fn fdforkpty
functions work like
.Fn openpty
and
.Fn forkpty
but expect a
.Pa /dev/ptm
file descriptor
.Fa ptmfd
obtained from the
.Fn getptmfd
function.
.Pp
The
.Fn login_tty
function prepares for a login on the tty
.Fa fd
@ -151,25 +173,42 @@ slave pseudo terminals
pseudo terminal management device
.El
.Sh ERRORS
.Fn getptmfd
may fail and set
.Va errno
for any of the errors specified for the routine
.Xr open 2 .
.Pp
.Fn openpty
and
.Fn fdopenpty
will fail if:
.Bl -tag -width Er
.It Bq Er ENOENT
There are no available ttys.
.El
.Pp
.Fn login_tty
.Fn fdopenpty
and
.Fn fdforkpty
will fail if
.Fn ioctl
fails to set
.Fa fd
to the controlling terminal of the current process.
.Fn getptmfd
fails.
.Fn forkpty
and
.Fn fdforkpty
will fail if either
.Fn openpty
or
.Fn fork
fails.
.Pp
.Fn login_tty
will fail if
.Fn ioctl
fails to set
.Fa fd
to the controlling terminal of the current process.
.Sh SEE ALSO
.Xr fork 2 ,
.Xr revoke 2 ,


+ 44
- 10
src/lib/libutil/pty.c View File

@ -1,4 +1,4 @@
/* $OpenBSD: pty.c,v 1.20 2016/08/30 14:44:45 guenther Exp $ */
/* $OpenBSD: pty.c,v 1.21 2017/04/20 17:48:30 nicm Exp $ */
/*-
* Copyright (c) 1990, 1993
@ -43,25 +43,42 @@
#include "util.h"
int
getptmfd(void)
{
return (open(PATH_PTMDEV, O_RDWR|O_CLOEXEC));
}
int
openpty(int *amaster, int *aslave, char *name, struct termios *termp,
struct winsize *winp)
{
int master, slave, fd;
int ptmfd;
if ((ptmfd = getptmfd()) == -1)
return (-1);
if (fdopenpty(ptmfd, amaster, aslave, name, termp, winp) == -1) {
close(ptmfd);
return (-1);
}
close(ptmfd);
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.
*/
fd = open(PATH_PTMDEV, O_RDWR|O_CLOEXEC);
if (fd == -1)
if (ioctl(ptmfd, PTMGET, &ptm) == -1)
return (-1);
if ((ioctl(fd, PTMGET, &ptm) == -1)) {
close(fd);
return (-1);
}
close(fd);
master = ptm.cfd;
slave = ptm.sfd;
if (name) {
@ -81,11 +98,28 @@ openpty(int *amaster, int *aslave, char *name, struct termios *termp,
pid_t
forkpty(int *amaster, char *name, struct termios *termp, struct winsize *winp)
{
int ptmfd;
pid_t pid;
if ((ptmfd = getptmfd()) == -1)
return (-1);
if ((pid = fdforkpty(ptmfd, amaster, name, termp, winp)) == -1) {
close(ptmfd);
return (-1);
}
close(ptmfd);
return (pid);
}
pid_t
fdforkpty(int ptmfd, int *amaster, char *name, struct termios *termp,
struct winsize *winp)
{
int master, slave;
pid_t pid;
if (openpty(&master, &slave, name, termp, winp) == -1)
if (fdopenpty(ptmfd, &master, &slave, name, termp, winp) == -1)
return (-1);
switch (pid = fork()) {
case -1:


+ 1
- 1
src/lib/libutil/shlib_version View File

@ -1,2 +1,2 @@
major=12
minor=1
minor=2

+ 5
- 1
src/lib/libutil/util.h View File

@ -1,4 +1,4 @@
/* $OpenBSD: util.h,v 1.34 2013/06/03 21:07:02 tedu Exp $ */
/* $OpenBSD: util.h,v 1.35 2017/04/20 17:48:30 nicm Exp $ */
/* $NetBSD: util.h,v 1.2 1996/05/16 07:00:22 thorpej Exp $ */
/*-
@ -98,9 +98,13 @@ void pw_prompt(void);
void pw_copy(int, int, const struct passwd *, const struct passwd *);
int pw_scan(char *, struct passwd *, int *);
void pw_error(const char *, int, int);
int getptmfd(void);
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 *);
pid_t fdforkpty(int, int *, char *, struct termios *, struct winsize *);
int getmaxpartitions(void);
int getrawpartition(void);
void login_fbtab(const char *, uid_t, gid_t);


Loading…
Cancel
Save