From fab5e38f3f3a8dea3b604a6af5f35ef68337973b Mon Sep 17 00:00:00 2001 From: millert <> Date: Fri, 21 Jun 2002 16:37:11 +0000 Subject: [PATCH] login_fbtab(3) fixes: o make first arg const since we don't modify it o use strsep() instead of strtok() as strtok() changes internal state o add some bounds checking and use strlcat() instead of pointer arithmetic o ANSI function headers Originally based on a patch from Lars J. Buitinck but much modified. --- src/lib/libutil/login_fbtab.3 | 17 +++--- src/lib/libutil/login_fbtab.c | 110 ++++++++++++++++++---------------- src/lib/libutil/util.h | 7 +-- 3 files changed, 71 insertions(+), 63 deletions(-) diff --git a/src/lib/libutil/login_fbtab.3 b/src/lib/libutil/login_fbtab.3 index dfb3344c..ed10ba98 100644 --- a/src/lib/libutil/login_fbtab.3 +++ b/src/lib/libutil/login_fbtab.3 @@ -1,4 +1,4 @@ -.\" $OpenBSD: login_fbtab.3,v 1.7 2001/08/06 10:42:26 mpech Exp $ +.\" $OpenBSD: login_fbtab.3,v 1.8 2002/06/21 16:37:11 millert Exp $ .\" .\" Copyright 1995 by Wietse Venema. All rights reserved. Some individual .\" files may be covered by other copyrights. @@ -15,7 +15,7 @@ .\" warranties, including, without limitation, the implied warranties of .\" merchantibility and fitness for any particular purpose. .\" -.Dd November 8, 1999 +.Dd June 14, 2002 .Dt LOGIN_FBTAB 3 .Os .Sh NAME @@ -26,7 +26,7 @@ .Fd #include .Fd #include .Ft void -.Fn login_fbtab "char *tty" "uid_t uid" "gid_t gid" +.Fn login_fbtab "const char *tty" "uid_t uid" "gid_t gid" .Sh DESCRIPTION The .Fn login_fbtab @@ -35,8 +35,6 @@ function reads the file and implements device security as described in the .Xr fbtab 5 manual page. -.Pp -If errors occur a null string is returned. .Sh DIAGNOSTICS Problems are reported via the .Xr syslogd 8 @@ -54,7 +52,10 @@ Wietse Venema (wietse@wzv.win.tue.nl) Eindhoven University of Technology The Netherlands .Ed -.Sh BUGS -This module uses +.Sh CAVEATS +Previous versions of this routine used .Xr strtok 3 , -which may cause conflicts with other uses of that same routine. +which can cause conflicts with other uses of that routine. +This may be an issue when porting programs to +.Ox 3.1 +and below. diff --git a/src/lib/libutil/login_fbtab.c b/src/lib/libutil/login_fbtab.c index d32cc0d9..341228ec 100644 --- a/src/lib/libutil/login_fbtab.c +++ b/src/lib/libutil/login_fbtab.c @@ -1,4 +1,4 @@ -/* $OpenBSD: login_fbtab.c,v 1.8 2002/02/16 21:27:29 millert Exp $ */ +/* $OpenBSD: login_fbtab.c,v 1.9 2002/06/21 16:37:11 millert Exp $ */ /************************************************************************ * Copyright 1995 by Wietse Venema. All rights reserved. Some individual @@ -51,10 +51,6 @@ Problems are reported via the syslog daemon with severity LOG_ERR. - BUGS - This module uses strtok(3), which may cause conflicts with other - uses of that same routine. - AUTHOR Wietse Venema (wietse@wzv.win.tue.nl) Eindhoven University of Technology @@ -63,19 +59,20 @@ #include #include -#include -#include -#include + #include #include -#include +#include #include - -#include "util.h" +#include +#include +#include +#include +#include #define _PATH_FBTAB "/etc/fbtab" -static void login_protect(char *, char *, int, uid_t, gid_t); +static void login_protect(const char *, int, uid_t, gid_t); #define WSPACE " \t\n" @@ -83,37 +80,36 @@ static void login_protect(char *, char *, int, uid_t, gid_t); * login_fbtab - apply protections specified in /etc/fbtab or logindevperm */ void -login_fbtab(tty, uid, gid) - char *tty; - uid_t uid; - gid_t gid; +login_fbtab(const char *tty, uid_t uid, gid_t gid) { FILE *fp; - char buf[BUFSIZ], *devname, *cp, *table; + char buf[BUFSIZ], *bufp, *devname, *cp; int prot; - if ((fp = fopen(table = _PATH_FBTAB, "r")) == NULL) + if ((fp = fopen(_PATH_FBTAB, "r")) == NULL) return; - while (fgets(buf, sizeof(buf), fp)) { + while ((bufp = fgets(buf, sizeof(buf), fp)) != NULL) { if ((cp = strchr(buf, '#'))) *cp = 0; /* strip comment */ - if ((cp = devname = strtok(buf, WSPACE)) == 0) + if ((devname = strsep(&bufp, WSPACE)) == NULL) continue; /* empty or comment */ if (strncmp(devname, _PATH_DEV, sizeof(_PATH_DEV) - 1) != 0 || - (cp = strtok((char *) 0, WSPACE)) == 0 || + (cp = strsep(&bufp, WSPACE)) == NULL || *cp != '0' || sscanf(cp, "%o", &prot) == 0 || prot == 0 || (prot & 0777) != prot || - (cp = strtok((char *) 0, WSPACE)) == 0) { - syslog(LOG_ERR, "%s: bad entry: %s", table, + (cp = strsep(&bufp, WSPACE)) == NULL) { + syslog(LOG_ERR, "%s: bad entry: %s", _PATH_FBTAB, cp ? cp : "(null)"); continue; } - if (strcmp(devname + sizeof(_PATH_DEV) - 1, tty) == 0) - for (cp = strtok(cp, ":"); cp; cp = strtok(NULL, ":")) - login_protect(table, cp, prot, uid, gid); + if (strcmp(devname + sizeof(_PATH_DEV) - 1, tty) == 0) { + bufp = cp; + while ((cp = strsep(&bufp, ":")) != NULL) + login_protect(cp, prot, uid, gid); + } } fclose(fp); } @@ -122,39 +118,51 @@ login_fbtab(tty, uid, gid) * login_protect - protect one device entry */ static void -login_protect(table, path, mask, uid, gid) - char *table; - char *path; - int mask; - uid_t uid; - gid_t gid; +login_protect(const char *path, int mask, uid_t uid, gid_t gid) { - char buf[BUFSIZ]; - int pathlen = strlen(path); - struct dirent *ent; + char buf[PATH_MAX]; + size_t pathlen = strlen(path); DIR *dir; + struct dirent *ent; + + if (pathlen >= sizeof(buf)) { + errno = ENAMETOOLONG; + syslog(LOG_ERR, "%s: %s: %m", _PATH_FBTAB, path); + return; + } if (strcmp("/*", path + pathlen - 2) != 0) { if (chmod(path, mask) && errno != ENOENT) - syslog(LOG_ERR, "%s: chmod(%s): %m", table, path); + syslog(LOG_ERR, "%s: chmod(%s): %m", _PATH_FBTAB, path); if (chown(path, uid, gid) && errno != ENOENT) - syslog(LOG_ERR, "%s: chown(%s): %m", table, path); + syslog(LOG_ERR, "%s: chown(%s): %m", _PATH_FBTAB, path); } else { - strncpy(buf, path, sizeof buf); - buf[pathlen - 1] = 0; - if ((dir = opendir(buf)) == 0) { - syslog(LOG_ERR, "%s: opendir(%s): %m", table, path); - } else { - while ((ent = readdir(dir))) { - if (strcmp(ent->d_name, ".") && - strcmp(ent->d_name, "..")) { - strncpy(buf + pathlen - 1, ent->d_name, - sizeof(buf) - pathlen - 1); - login_protect(table, buf, mask, - uid, gid); - } + /* + * This is a wildcard directory (/path/to/whatever/*). + * Make a copy of path without the trailing '*' (but leave + * the trailing '/' so we can append directory entries.) + */ + memcpy(buf, path, pathlen - 1); + buf[pathlen - 1] = '\0'; + if ((dir = opendir(buf)) == NULL) { + syslog(LOG_ERR, "%s: opendir(%s): %m", _PATH_FBTAB, + path); + return; + } + + while ((ent = readdir(dir)) != NULL) { + if (strcmp(ent->d_name, ".") != 0 && + strcmp(ent->d_name, "..") != 0) { + buf[pathlen - 1] = '\0'; + if (strlcat(buf, ent->d_name, sizeof(buf)) + >= sizeof(buf)) { + errno = ENAMETOOLONG; + syslog(LOG_ERR, "%s: %s: %m", + _PATH_FBTAB, path); + } else + login_protect(buf, mask, uid, gid); } - closedir(dir); } + closedir(dir); } } diff --git a/src/lib/libutil/util.h b/src/lib/libutil/util.h index 7245ed03..ff388e5a 100644 --- a/src/lib/libutil/util.h +++ b/src/lib/libutil/util.h @@ -1,4 +1,4 @@ -/* $OpenBSD: util.h,v 1.21 2002/06/09 22:18:43 fgsch Exp $ */ +/* $OpenBSD: util.h,v 1.22 2002/06/21 16:37:11 millert Exp $ */ /* $NetBSD: util.h,v 1.2 1996/05/16 07:00:22 thorpej Exp $ */ /*- @@ -100,14 +100,13 @@ void pw_copy(int, int, struct passwd *); void pw_getconf(char *, size_t, const char *, const char *); int pw_scan(char *, struct passwd *, int *); void pw_error(const char *, int, int); -int openpty(int *, int *, char *, struct termios *, - struct winsize *); +int openpty(int *, int *, char *, struct termios *, struct winsize *); int opendisk(const char *path, int flags, char *buf, size_t buflen, int iscooked); pid_t forkpty(int *, char *, struct termios *, struct winsize *); int getmaxpartitions(void); int getrawpartition(void); -void login_fbtab(char *, uid_t, gid_t); +void login_fbtab(const char *, uid_t, gid_t); int login_check_expire(struct __sFILE *, struct passwd *, char *, int); char *readlabelfs(char *, int); const char *uu_lockerr(int _uu_lockresult);