diff options
author | Jerry Jelinek <jerry.jelinek@joyent.com> | 2020-04-20 11:31:07 +0000 |
---|---|---|
committer | Jerry Jelinek <jerry.jelinek@joyent.com> | 2020-04-20 11:31:07 +0000 |
commit | 0aa1be3052902c4b4d76eaf6eb2a5c4b38dc09ef (patch) | |
tree | 407bd5ffe8e8ecec2a9cc8d4ae03b5aab22053cd /usr/src | |
parent | f22763a77aeb04df3d683e094615740a079cfe4c (diff) | |
parent | fc3fd29d04595458a24c7d90eb46ce039660a44f (diff) | |
download | illumos-joyent-0aa1be3052902c4b4d76eaf6eb2a5c4b38dc09ef.tar.gz |
[illumos-gate merge]
commit 745679391d7a234b12343aa2407c382709f6d4bd
12524 fm: unsigned is never less than zero
commit b531f6d16eb39863e7bbc34773fb7ef7a282a0a2
12427 stand: smatch and NULL pointer errors
commit 6a79a30125dbfeba7eb8ef0a9cd3a8206f644043
12523 Buffer overflow in w and whodo
commit 6e2e67256d436ef900becfa771aee283e7e55430
12477 ctxops should use stack ordering for save/restore
12478 installctx needs kpreempt_disable protection
Conflicts:
usr/src/cmd/mdb/common/modules/genunix/ctxop.c
Diffstat (limited to 'usr/src')
27 files changed, 581 insertions, 296 deletions
diff --git a/usr/src/cmd/w/w.c b/usr/src/cmd/w/w.c index c062190a21..f945415688 100644 --- a/usr/src/cmd/w/w.c +++ b/usr/src/cmd/w/w.c @@ -23,6 +23,8 @@ * * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * + * Copyright 2020 Joyent, Inc. */ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ @@ -58,6 +60,7 @@ #include <ctype.h> #include <fcntl.h> #include <time.h> +#include <err.h> #include <errno.h> #include <sys/types.h> #include <utmpx.h> @@ -69,6 +72,7 @@ #include <sys/loadavg.h> #include <limits.h> #include <priv_utils.h> +#include <sys/sysmacros.h> /* * Use the full lengths from utmpx for user and line. @@ -130,6 +134,10 @@ static void calctotals(struct uproc *); static void prttime(time_t, int); static void prtat(time_t *time); +static int priv_proc_open(const char *, int); +static int priv_proc_openat(int, const char *, int); +static boolean_t do_proc_read(int, void *, size_t); + static char *prog; /* pointer to invocation name */ static int header = 1; /* true if -h flag: don't print heading */ static int lflag = 1; /* set if -l flag; 0 for -s flag: short form */ @@ -146,6 +154,18 @@ static time_t proctime; /* cpu time of process in doing */ static pid_t curpid, empty; static int add_times; /* boolean: add the cpu times or not */ +/* + * Basic privs we never need and can drop. This is likely not exhaustive, + * but should significantly reduce any potential attack surfaces. + */ +static const char *drop_privs[] = { + PRIV_FILE_WRITE, + PRIV_NET_ACCESS, + PRIV_PROC_EXEC, + PRIV_PROC_FORK, + PRIV_FILE_LINK_ANY +}; + #if SIGQUIT > SIGINT #define ACTSIZE SIGQUIT #else @@ -163,24 +183,64 @@ main(int argc, char *argv[]) struct psinfo info; struct sigaction actinfo[ACTSIZE]; struct pstatus statinfo; - size_t size; struct stat sbuf; DIR *dirp; struct dirent *dp; - char pname[64]; - char *fname; + char pname[PATH_MAX]; int procfd; + int dirfd; char *cp; int i; int days, hrs, mins; int entries; double loadavg[3]; + priv_set_t *pset; + + if (__init_suid_priv(PU_CLEARLIMITSET, PRIV_PROC_OWNER, NULL) != 0) { + err(EXIT_FAILURE, "failed to enable privilege bracketing"); + } + + /* + * After setting up privilege bracketing, we can further reduce the + * privileges in use. The effective set is set to the basic set minus + * the privs in drop_privs. The permitted set is the effective set + * plus PRIV_PROC_OWNER (i.e. the privilege being bracketed). + */ + pset = priv_allocset(); + if (pset == NULL) + err(EXIT_FAILURE, "priv_allocset failed"); + + priv_basicset(pset); + for (i = 0; i < ARRAY_SIZE(drop_privs); i++) { + if (priv_delset(pset, drop_privs[i]) != 0) { + err(EXIT_FAILURE, + "failed to remove %s privilege from privilege set", + drop_privs[i]); + } + } + + if (setppriv(PRIV_SET, PRIV_EFFECTIVE, pset) < 0) + err(EXIT_FAILURE, "failed setting effective privilege set"); + + if (priv_addset(pset, PRIV_PROC_OWNER) != 0) { + err(EXIT_FAILURE, + "failed to add PRIV_PROC_OWNER privilege to privilege set"); + } + + if (setppriv(PRIV_SET, PRIV_PERMITTED, pset) < 0) + err(EXIT_FAILURE, "failed to set permitted privilege set"); /* - * This program needs the proc_owner privilege + * Unfortunately, when run as root, privilege bracketing is a no-op, + * so we have to add PRIV_PROC_OWNER into our effective set for things + * to work. */ - (void) __init_suid_priv(PU_CLEARLIMITSET, PRIV_PROC_OWNER, - (char *)NULL); + if (getuid() == 0 && setppriv(PRIV_SET, PRIV_EFFECTIVE, pset) < 0) { + err(EXIT_FAILURE, "failed to set effective privilege set"); + } + + priv_freeset(pset); + pset = NULL; (void) setlocale(LC_ALL, ""); #if !defined(TEXT_DOMAIN) @@ -235,23 +295,17 @@ main(int argc, char *argv[]) /* * read the UTMPX_FILE (contains information about each logged in user) */ - if (stat(UTMPX_FILE, &sbuf) == ERR) { - (void) fprintf(stderr, gettext("%s: stat error of %s: %s\n"), - prog, UTMPX_FILE, strerror(errno)); - exit(1); - } + if (stat(UTMPX_FILE, &sbuf) < 0) + err(EXIT_FAILURE, gettext("stat error of %s"), UTMPX_FILE); + entries = sbuf.st_size / sizeof (struct futmpx); - size = sizeof (struct utmpx) * entries; - if ((ut = malloc(size)) == NULL) { - (void) fprintf(stderr, gettext("%s: malloc error of %s: %s\n"), - prog, UTMPX_FILE, strerror(errno)); - exit(1); - } + if ((ut = calloc(entries, sizeof (struct utmpx))) == NULL) + err(EXIT_FAILURE, gettext("calloc error of %s"), UTMPX_FILE); (void) utmpxname(UTMPX_FILE); utmpbegin = ut; - utmpend = (struct utmpx *)((char *)utmpbegin + size); + utmpend = utmpbegin + entries; setutxent(); while ((ut < utmpend) && ((utp = getutxent()) != NULL)) @@ -317,8 +371,7 @@ main(int argc, char *argv[]) } if (fflush(stdout) == EOF) { - perror((gettext("%s: fflush failed\n"), prog)); - exit(1); + err(EXIT_FAILURE, "fflush failed"); } } @@ -326,68 +379,63 @@ main(int argc, char *argv[]) * loop through /proc, reading info about each process * and build the parent/child tree */ - if (!(dirp = opendir(PROCDIR))) { - (void) fprintf(stderr, gettext("%s: could not open %s: %s\n"), - prog, PROCDIR, strerror(errno)); - exit(1); - } + if ((dirp = opendir(PROCDIR)) == NULL) + err(EXIT_FAILURE, gettext("could not open %s"), PROCDIR); while ((dp = readdir(dirp)) != NULL) { if (dp->d_name[0] == '.') continue; -retry: - (void) sprintf(pname, "%s/%s/", PROCDIR, dp->d_name); - fname = pname + strlen(pname); - (void) strcpy(fname, "psinfo"); - if ((procfd = open(pname, O_RDONLY)) < 0) + + if (snprintf(pname, sizeof (pname), "%s/%s", PROCDIR, + dp->d_name) > sizeof (pname)) continue; - if (read(procfd, &info, sizeof (info)) != sizeof (info)) { - int err = errno; - (void) close(procfd); - if (err == EAGAIN) - goto retry; - if (err != ENOENT) - (void) fprintf(stderr, gettext( - "%s: read() failed on %s: %s \n"), - prog, pname, strerror(err)); + + dirfd = priv_proc_open(pname, O_RDONLY | O_DIRECTORY); + + if (dirfd < 0) { + if (errno == ENOENT) + continue; + warn(gettext("failed to open %s"), pname); + continue; + } + + procfd = priv_proc_openat(dirfd, "psinfo", O_RDONLY); + if (procfd < 0) { + (void) close(dirfd); + continue; + } + + if (!do_proc_read(procfd, &info, sizeof (info))) { + warn(gettext("read() failed on %s"), pname); + (void) close(dirfd); continue; } (void) close(procfd); up = findhash(info.pr_pid); up->p_ttyd = info.pr_ttydev; - up->p_state = (info.pr_nlwp == 0? ZOMBIE : RUNNING); + up->p_state = (info.pr_nlwp == 0 ? ZOMBIE : RUNNING); up->p_time = 0; up->p_ctime = 0; up->p_igintr = 0; - (void) strncpy(up->p_comm, info.pr_fname, - sizeof (info.pr_fname)); + (void) strlcpy(up->p_comm, info.pr_fname, + sizeof (up->p_comm)); up->p_args[0] = 0; if (up->p_state != NONE && up->p_state != ZOMBIE) { - (void) strcpy(fname, "status"); - - /* now we need the proc_owner privilege */ - (void) __priv_bracket(PRIV_ON); - - procfd = open(pname, O_RDONLY); - - /* drop proc_owner privilege after open */ - (void) __priv_bracket(PRIV_OFF); - - if (procfd < 0) + procfd = priv_proc_openat(dirfd, "status", O_RDONLY); + if (procfd < 0) { + (void) close(dirfd); continue; + } + + if (!do_proc_read(procfd, &statinfo, + sizeof (statinfo))) { + warn(gettext("read() failed on %s/status"), + pname); - if (read(procfd, &statinfo, sizeof (statinfo)) - != sizeof (statinfo)) { - int err = errno; (void) close(procfd); - if (err == EAGAIN) - goto retry; - if (err != ENOENT) - (void) fprintf(stderr, gettext( - "%s: read() failed on %s: %s \n"), - prog, pname, strerror(err)); + (void) close(dirfd); continue; } (void) close(procfd); @@ -397,33 +445,22 @@ retry: up->p_ctime = statinfo.pr_cutime.tv_sec + statinfo.pr_cstime.tv_sec; - (void) strcpy(fname, "sigact"); - - /* now we need the proc_owner privilege */ - (void) __priv_bracket(PRIV_ON); - - procfd = open(pname, O_RDONLY); - - /* drop proc_owner privilege after open */ - (void) __priv_bracket(PRIV_OFF); - - if (procfd < 0) + procfd = priv_proc_openat(dirfd, "sigact", O_RDONLY); + if (procfd < 0) { + (void) close(dirfd); continue; + } + + if (!do_proc_read(procfd, actinfo, sizeof (actinfo))) { + warn(gettext("read() failed on %s/sigact"), + pname); - if (read(procfd, actinfo, sizeof (actinfo)) - != sizeof (actinfo)) { - int err = errno; (void) close(procfd); - if (err == EAGAIN) - goto retry; - if (err != ENOENT) - (void) fprintf(stderr, gettext( - "%s: read() failed on %s: %s \n"), - prog, pname, strerror(err)); + (void) close(dirfd); continue; } (void) close(procfd); - + (void) close(dirfd); up->p_igintr = actinfo[SIGINT-1].sa_handler == SIG_IGN && actinfo[SIGQUIT-1].sa_handler == SIG_IGN; @@ -431,15 +468,19 @@ retry: /* * Process args. */ - up->p_args[0] = 0; + up->p_args[0] = '\0'; clnarglist(info.pr_psargs); - (void) strcat(up->p_args, info.pr_psargs); + (void) strlcpy(up->p_args, info.pr_psargs, + sizeof (up->p_args)); if (up->p_args[0] == 0 || up->p_args[0] == '-' && up->p_args[1] <= ' ' || up->p_args[0] == '?') { - (void) strcat(up->p_args, " ("); - (void) strcat(up->p_args, up->p_comm); - (void) strcat(up->p_args, ")"); + (void) strlcat(up->p_args, " (", + sizeof (up->p_args)); + (void) strlcat(up->p_args, up->p_comm, + sizeof (up->p_args)); + (void) strlcat(up->p_args, ")", + sizeof (up->p_args)); } } @@ -466,7 +507,34 @@ retry: } /* revert to non-privileged user after opening */ - (void) __priv_relinquish(); + __priv_relinquish(); + if (getuid() == 0) { + /* + * Since the privilege bracketing functions are effectively + * no-ops when running as root, we must explicitly + * relinquish PRIV_PROC_OWNER ourselves. + */ + pset = priv_allocset(); + if (pset == NULL) { + err(EXIT_FAILURE, + gettext("failed to allocate privilege set")); + } + + priv_emptyset(pset); + + if (priv_addset(pset, PRIV_PROC_OWNER) != 0) { + err(EXIT_FAILURE, gettext("failed to add " + "PRIV_PROC_OWNER to privilege set")); + } + + if (setppriv(PRIV_OFF, PRIV_PERMITTED, pset) != 0) { + err(EXIT_FAILURE, + gettext("failed to set permitted privilege set")); + } + + priv_freeset(pset); + pset = NULL; + } (void) closedir(dirp); (void) time(&now); /* get current time */ @@ -509,10 +577,9 @@ retry: prttime(idle, 8); showtotals(findhash(ut->ut_pid)); } - if (fclose(stdout) == EOF) { - perror((gettext("%s: fclose failed"), prog)); - exit(1); - } + if (fclose(stdout) == EOF) + err(EXIT_FAILURE, gettext("fclose failed")); + return (0); } @@ -579,9 +646,9 @@ calctotals(struct uproc *up) if (up->p_upid > curpid && (!up->p_igintr || empty)) { curpid = up->p_upid; if (lflag) - (void) strcpy(doing, up->p_args); + (void) strlcpy(doing, up->p_args, sizeof (doing)); else - (void) strcpy(doing, up->p_comm); + (void) strlcpy(doing, up->p_comm, sizeof (doing)); } if (add_times == 1) { @@ -625,11 +692,9 @@ findhash(pid_t pid) return (tp); } tp = malloc(sizeof (*tp)); /* add new node */ - if (!tp) { - (void) fprintf(stderr, gettext("%s: out of memory!: %s\n"), - prog, strerror(errno)); - exit(1); - } + if (tp == NULL) + err(EXIT_FAILURE, gettext("out of memory!")); + (void) memset(tp, 0, sizeof (*tp)); tp->p_upid = pid; tp->p_state = NONE; @@ -662,7 +727,7 @@ prttime(time_t tim, int width) } else if (tim > 0) { (void) snprintf(value, sizeof (value), "%d", (int)tim); } else { - (void) strcpy(value, "0"); + (void) strlcpy(value, "0", sizeof (value)); } width = (width > 2) ? width - 1 : 1; PRINTF(("%*s ", width, value)); @@ -711,8 +776,8 @@ findidle(char *devname) time_t lastaction, diff; char ttyname[64]; - (void) strcpy(ttyname, "/dev/"); - (void) strcat(ttyname, devname); + (void) strlcpy(ttyname, "/dev/", sizeof (ttyname)); + (void) strlcat(ttyname, devname, sizeof (ttyname)); if (stat(ttyname, &stbuf) != -1) { lastaction = stbuf.st_atime; diff = now - lastaction; @@ -744,3 +809,66 @@ clnarglist(char *arglist) } } } + +static int +priv_proc_open(const char *path, int oflag) +{ + int fd, errsave = 0; + + if (__priv_bracket(PRIV_ON) != 0) + err(EXIT_FAILURE, gettext("privilege bracketing failed")); + + do { + fd = open(path, oflag); + if (fd < 0) + errsave = errno; + } while (fd < 0 && errno == EAGAIN); + + if (__priv_bracket(PRIV_OFF) != 0) + err(EXIT_FAILURE, gettext("privilege bracketing failed")); + + if (fd < 0) + errno = errsave; + + return (fd); +} + +static int +priv_proc_openat(int dfd, const char *path, int mode) +{ + int fd, errsave = 0; + + if (__priv_bracket(PRIV_ON) != 0) + err(EXIT_FAILURE, gettext("privilege bracketing failed")); + + do { + fd = openat(dfd, path, mode); + if (fd < 0) + errsave = errno; + } while (fd < 0 && errno == EAGAIN); + + if (__priv_bracket(PRIV_OFF) != 0) + err(EXIT_FAILURE, gettext("privilege bracketing failed")); + + if (fd < 0) + errno = errsave; + + return (fd); +} + +static boolean_t +do_proc_read(int fd, void *buf, size_t bufsize) +{ + ssize_t n; + + do { + n = pread(fd, buf, bufsize, 0); + if (n == bufsize) + return (B_TRUE); + /* + * Retry on a partial read or EAGAIN, otherwise fail + */ + } while (n >= 0 || errno == EAGAIN); + + return (B_FALSE); +} diff --git a/usr/src/cmd/whodo/whodo.c b/usr/src/cmd/whodo/whodo.c index fe097ace23..98abc0792d 100644 --- a/usr/src/cmd/whodo/whodo.c +++ b/usr/src/cmd/whodo/whodo.c @@ -23,6 +23,8 @@ * * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * + * Copyright 2020 Joyent, Inc. */ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ @@ -55,9 +57,11 @@ #include <ctype.h> #include <fcntl.h> #include <time.h> +#include <err.h> #include <errno.h> #include <sys/types.h> #include <utmpx.h> +#include <sys/sysmacros.h> #include <sys/utsname.h> #include <sys/stat.h> #include <sys/mkdev.h> @@ -95,8 +99,8 @@ #define ZOMBIE 'z' /* zombie process */ #define VISITED 'v' /* marked node as visited */ -static int ndevs; /* number of configured devices */ -static int maxdev; /* slots for configured devices */ +static uint_t ndevs; /* number of configured devices */ +static uint_t maxdev; /* slots for configured devices */ #define DNINCR 100 static struct devl { /* device list */ char dname[DEVNAMELEN]; /* device name */ @@ -136,6 +140,10 @@ static char *getty(dev_t); static void prttime(time_t, int); static void prtat(time_t *); +static int priv_proc_open(const char *, int); +static int priv_proc_openat(int, const char *, int); +static boolean_t do_proc_read(int, void *, size_t); + static char *prog; static int header = 1; /* true if -h flag: don't print heading */ static int lflag = 0; /* true if -l flag: w command format */ @@ -150,6 +158,18 @@ static time_t proctime; /* cpu time of process in doing */ static int empty; static pid_t curpid; +/* + * Basic privs we never need and can drop. This is likely not exhaustive, + * but should significantly reduce any potential attack surfaces. + */ +static const char *drop_privs[] = { + PRIV_FILE_WRITE, + PRIV_NET_ACCESS, + PRIV_PROC_EXEC, + PRIV_PROC_FORK, + PRIV_FILE_LINK_ANY +}; + #if SIGQUIT > SIGINT #define ACTSIZE SIGQUIT #else @@ -168,23 +188,62 @@ main(int argc, char *argv[]) struct psinfo info; struct sigaction actinfo[ACTSIZE]; struct pstatus statinfo; - size_t size; struct stat sbuf; struct utsname uts; DIR *dirp; struct dirent *dp; - char pname[64]; - char *fname; - int procfd; + char pname[PATH_MAX]; + int procfd, dirfd; int i; int days, hrs, mins; int entries; + priv_set_t *pset; + + if (__init_suid_priv(PU_CLEARLIMITSET, PRIV_PROC_OWNER, NULL) != 0) { + err(EXIT_FAILURE, "failed to enable privilege bracketing"); + } + + /* + * After setting up privilege bracketing, we can further reduce the + * privileges in use. The effective set is set to the basic set minus + * the privs in drop_privs. The permitted set is the effective set + * plus PRIV_PROC_OWNER (i.e. the privilege being bracketed). + */ + pset = priv_allocset(); + if (pset == NULL) + err(EXIT_FAILURE, "priv_allocset failed"); + + priv_basicset(pset); + for (i = 0; i < ARRAY_SIZE(drop_privs); i++) { + if (priv_delset(pset, drop_privs[i]) != 0) { + err(EXIT_FAILURE, + "failed to remove %s privilege from privilege set", + drop_privs[i]); + } + } + + if (setppriv(PRIV_SET, PRIV_EFFECTIVE, pset) < 0) + err(EXIT_FAILURE, "failed setting effective privilege set"); + + if (priv_addset(pset, PRIV_PROC_OWNER) != 0) { + err(EXIT_FAILURE, + "failed to add PRIV_PROC_OWNER privilege to privilege set"); + } + + if (setppriv(PRIV_SET, PRIV_PERMITTED, pset) < 0) + err(EXIT_FAILURE, "failed to set permitted privilege set"); /* - * This program needs the proc_owner privilege + * Unfortunately, when run as root, privilege bracketing is a no-op, + * so we have to add PRIV_PROC_OWNER into our effective set for things + * to work. */ - (void) __init_suid_priv(PU_CLEARLIMITSET, PRIV_PROC_OWNER, - (char *)NULL); + if (getuid() == 0 && setppriv(PRIV_SET, PRIV_EFFECTIVE, pset) < 0) { + err(EXIT_FAILURE, "failed to set effective privilege set"); + } + + priv_freeset(pset); + pset = NULL; (void) setlocale(LC_ALL, ""); #if !defined(TEXT_DOMAIN) @@ -229,25 +288,18 @@ main(int argc, char *argv[]) * read the UTMPX_FILE (contains information about * each logged in user) */ - if (stat(UTMPX_FILE, &sbuf) == ERR) { - (void) fprintf(stderr, gettext("%s: stat error of %s: %s\n"), - prog, UTMPX_FILE, strerror(errno)); - exit(1); - } + if (stat(UTMPX_FILE, &sbuf) < 0) + err(EXIT_FAILURE, gettext("stat error of %s"), UTMPX_FILE); + entries = sbuf.st_size / sizeof (struct futmpx); - size = sizeof (struct utmpx) * entries; - if ((ut = malloc(size)) == NULL) { - (void) fprintf(stderr, gettext("%s: malloc error of %s: %s\n"), - prog, UTMPX_FILE, strerror(errno)); - exit(1); - } + if ((ut = calloc(entries, sizeof (struct utmpx))) == NULL) + err(EXIT_FAILURE, gettext("calloc error of %s"), UTMPX_FILE); (void) utmpxname(UTMPX_FILE); utmpbegin = ut; - /* LINTED pointer cast may result in improper alignment */ - utmpend = (struct utmpx *)((char *)utmpbegin + size); + utmpend = utmpbegin + entries; setutxent(); while ((ut < utmpend) && ((utp = getutxent()) != NULL)) @@ -306,31 +358,36 @@ main(int argc, char *argv[]) * loop through /proc, reading info about each process * and build the parent/child tree */ - if (!(dirp = opendir(PROCDIR))) { - (void) fprintf(stderr, gettext("%s: could not open %s: %s\n"), - prog, PROCDIR, strerror(errno)); - exit(1); - } + if ((dirp = opendir(PROCDIR)) == NULL) + err(EXIT_FAILURE, gettext("could not open %s"), PROCDIR); while ((dp = readdir(dirp)) != NULL) { if (dp->d_name[0] == '.') continue; -retry: - (void) snprintf(pname, sizeof (pname), - "%s/%s/", PROCDIR, dp->d_name); - fname = pname + strlen(pname); - (void) strcpy(fname, "psinfo"); - if ((procfd = open(pname, O_RDONLY)) < 0) + + if (snprintf(pname, sizeof (pname), "%s/%s", PROCDIR, + dp->d_name) > sizeof (pname)) continue; - if (read(procfd, &info, sizeof (info)) != sizeof (info)) { - int err = errno; - (void) close(procfd); - if (err == EAGAIN) - goto retry; - if (err != ENOENT) - (void) fprintf(stderr, gettext( - "%s: read() failed on %s: %s\n"), - prog, pname, strerror(err)); + + dirfd = priv_proc_open(pname, O_RDONLY | O_DIRECTORY); + + if (dirfd < 0) { + if (errno == ENOENT) + continue; + warn(gettext("failed to open %s"), pname); + continue; + } + + + procfd = priv_proc_openat(dirfd, "psinfo", O_RDONLY); + if (procfd < 0) { + (void) close(dirfd); + continue; + } + + if (!do_proc_read(procfd, &info, sizeof (info))) { + warn(gettext("read() failed on %s"), pname); + (void) close(dirfd); continue; } (void) close(procfd); @@ -341,34 +398,24 @@ retry: up->p_time = 0; up->p_ctime = 0; up->p_igintr = 0; - (void) strncpy(up->p_comm, info.pr_fname, - sizeof (info.pr_fname)); + (void) strlcpy(up->p_comm, info.pr_fname, + sizeof (up->p_comm)); up->p_args[0] = 0; if (up->p_state != NONE && up->p_state != ZOMBIE) { - (void) strcpy(fname, "status"); - - /* now we need the proc_owner privilege */ - (void) __priv_bracket(PRIV_ON); - - procfd = open(pname, O_RDONLY); - - /* drop proc_owner privilege after open */ - (void) __priv_bracket(PRIV_OFF); - - if (procfd < 0) + procfd = priv_proc_openat(dirfd, "status", O_RDONLY); + if (procfd < 0) { + (void) close(dirfd); continue; + } + + if (!do_proc_read(procfd, &statinfo, + sizeof (statinfo))) { + warn(gettext("read() failed on %s/status"), + pname); - if (read(procfd, &statinfo, sizeof (statinfo)) - != sizeof (statinfo)) { - int err = errno; (void) close(procfd); - if (err == EAGAIN) - goto retry; - if (err != ENOENT) - (void) fprintf(stderr, gettext( - "%s: read() failed on %s: %s \n"), - prog, pname, strerror(err)); + (void) close(dirfd); continue; } (void) close(procfd); @@ -378,31 +425,22 @@ retry: up->p_ctime = statinfo.pr_cutime.tv_sec + statinfo.pr_cstime.tv_sec; - (void) strcpy(fname, "sigact"); - - /* now we need the proc_owner privilege */ - (void) __priv_bracket(PRIV_ON); - - procfd = open(pname, O_RDONLY); + procfd = priv_proc_openat(dirfd, "sigact", O_RDONLY); + if (procfd < 0) { + (void) close(dirfd); + continue; + } - /* drop proc_owner privilege after open */ - (void) __priv_bracket(PRIV_OFF); + if (!do_proc_read(procfd, actinfo, sizeof (actinfo))) { + warn(gettext("read() failed on %s/sigact"), + pname); - if (procfd < 0) - continue; - if (read(procfd, actinfo, sizeof (actinfo)) - != sizeof (actinfo)) { - int err = errno; (void) close(procfd); - if (err == EAGAIN) - goto retry; - if (err != ENOENT) - (void) fprintf(stderr, gettext( - "%s: read() failed on %s: %s \n"), - prog, pname, strerror(err)); + (void) close(dirfd); continue; } (void) close(procfd); + (void) close(dirfd); up->p_igintr = actinfo[SIGINT-1].sa_handler == SIG_IGN && @@ -415,14 +453,18 @@ retry: */ if (lflag) { /* w command needs args */ clnarglist(info.pr_psargs); - (void) strcpy(up->p_args, info.pr_psargs); + (void) strlcpy(up->p_args, info.pr_psargs, + sizeof (up->p_args)); if (up->p_args[0] == 0 || up->p_args[0] == '-' && up->p_args[1] <= ' ' || up->p_args[0] == '?') { - (void) strcat(up->p_args, " ("); - (void) strcat(up->p_args, up->p_comm); - (void) strcat(up->p_args, ")"); + (void) strlcat(up->p_args, " (", + sizeof (up->p_args)); + (void) strlcat(up->p_args, up->p_comm, + sizeof (up->p_args)); + (void) strlcat(up->p_args, ")", + sizeof (up->p_args)); } } @@ -452,7 +494,34 @@ retry: } /* revert to non-privileged user */ - (void) __priv_relinquish(); + __priv_relinquish(); + if (getuid() == 0) { + /* + * Since the privilege bracketing functions are effectively + * no-ops when running as root, we must explicitly + * relinquish PRIV_PROC_OWNER ourselves. + */ + pset = priv_allocset(); + if (pset == NULL) { + err(EXIT_FAILURE, + gettext("failed to allocate privilege set")); + } + + priv_emptyset(pset); + + if (priv_addset(pset, PRIV_PROC_OWNER) != 0) { + err(EXIT_FAILURE, gettext("failed to add " + "PRIV_PROC_OWNER to privilege set")); + } + + if (setppriv(PRIV_OFF, PRIV_PERMITTED, pset) != 0) { + err(EXIT_FAILURE, + gettext("failed to set permitted privilege set")); + } + + priv_freeset(pset); + pset = NULL; + } (void) closedir(dirp); (void) time(&now); /* get current time */ @@ -553,7 +622,9 @@ showtotals(struct uproc *up) proctime = 0; empty = 1; curpid = -1; - (void) strcpy(doing, "-"); /* default act: normally never prints */ + + /* default act: normally never prints */ + (void) strlcpy(doing, "-", sizeof (doing)); calctotals(up); /* print CPU time for all processes & children */ @@ -598,7 +669,7 @@ calctotals(struct uproc *up) if (up->p_upid > curpid && (!up->p_igintr || empty)) { curpid = up->p_upid; - (void) strcpy(doing, up->p_args); + (void) strlcpy(doing, up->p_args, sizeof (doing)); } /* descend for its children */ @@ -610,34 +681,36 @@ calctotals(struct uproc *up) } static char * -devadd(char *name, dev_t ddev) +devadd(const char *name, dev_t ddev) { struct devl *dp; int leng, start, i; if (ndevs == maxdev) { - maxdev += DNINCR; - dp = realloc(devl, maxdev * sizeof (struct devl)); - if (!dp) { - (void) fprintf(stderr, - gettext("%s: out of memory!: %s\n"), - prog, strerror(errno)); - exit(1); - } + uint_t newdev; + + newdev = maxdev + DNINCR; + if (newdev < DNINCR) + errx(EXIT_FAILURE, gettext("devadd overflow")); + + dp = recallocarray(devl, maxdev, newdev, sizeof (struct devl)); + if (dp == NULL) + err(EXIT_FAILURE, gettext("out of memory!")); + maxdev = newdev; devl = dp; } dp = &devl[ndevs++]; dp->ddev = ddev; if (name == NULL) { - (void) strcpy(dp->dname, " ? "); + (void) strlcpy(dp->dname, " ? ", sizeof (dp->dname)); return (dp->dname); } leng = strlen(name); if (leng < DEVNAMELEN + 4) { /* strip off "/dev/" */ - (void) strcpy(dp->dname, &name[5]); + (void) strlcpy(dp->dname, &name[5], sizeof (dp->dname)); } else { /* strip enough off the front to fit */ start = leng - DEVNAMELEN - 1; @@ -645,9 +718,9 @@ devadd(char *name, dev_t ddev) for (i = start; i < leng && name[i] != '/'; i++) ; if (i == leng) - (void) strncpy(dp->dname, &name[start], DEVNAMELEN); + (void) strlcpy(dp->dname, &name[start], DEVNAMELEN); else - (void) strncpy(dp->dname, &name[i+1], DEVNAMELEN); + (void) strlcpy(dp->dname, &name[i+1], DEVNAMELEN); } return (dp->dname); } @@ -715,11 +788,9 @@ findhash(pid_t pid) } } tp = malloc(sizeof (*tp)); /* add new node */ - if (!tp) { - (void) fprintf(stderr, gettext("%s: out of memory!: %s\n"), - prog, strerror(errno)); - exit(1); - } + if (tp == NULL) + err(EXIT_FAILURE, gettext("out of memory!")); + (void) memset((char *)tp, 0, sizeof (*tp)); tp->p_upid = pid; tp->p_state = NONE; @@ -802,8 +873,8 @@ findidle(char *devname) time_t lastaction, diff; char ttyname[64]; - (void) strcpy(ttyname, "/dev/"); - (void) strcat(ttyname, devname); + (void) strlcpy(ttyname, "/dev/", sizeof (ttyname)); + (void) strlcat(ttyname, devname, sizeof (ttyname)); if (stat(ttyname, &stbuf) != -1) { lastaction = stbuf.st_atime; diff = now - lastaction; @@ -835,3 +906,66 @@ clnarglist(char *arglist) } } } + +static int +priv_proc_open(const char *path, int oflag) +{ + int fd, errsave = 0; + + if (__priv_bracket(PRIV_ON) != 0) + err(EXIT_FAILURE, gettext("privilege bracketing failed")); + + do { + fd = open(path, oflag); + if (fd < 0) + errsave = errno; + } while (fd < 0 && errno == EAGAIN); + + if (__priv_bracket(PRIV_OFF) != 0) + err(EXIT_FAILURE, gettext("privilege bracketing failed")); + + if (fd < 0) + errno = errsave; + + return (fd); +} + +static int +priv_proc_openat(int dfd, const char *path, int mode) +{ + int fd, errsave = 0; + + if (__priv_bracket(PRIV_ON) != 0) + err(EXIT_FAILURE, gettext("privilege bracketing failed")); + + do { + fd = openat(dfd, path, mode); + if (fd < 0) + errsave = errno; + } while (fd < 0 && errno == EAGAIN); + + if (__priv_bracket(PRIV_OFF) != 0) + err(EXIT_FAILURE, gettext("privilege bracketing failed")); + + if (fd < 0) + errno = errsave; + + return (fd); +} + +static boolean_t +do_proc_read(int fd, void *buf, size_t bufsize) +{ + ssize_t n; + + do { + n = pread(fd, buf, bufsize, 0); + if (n == bufsize) + return (B_TRUE); + /* + * Retry on a partial read or EAGAIN, otherwise fail + */ + } while (n >= 0 || errno == EAGAIN); + + return (B_FALSE); +} diff --git a/usr/src/lib/fm/topo/modules/sun4v/chip/chip_sun4v.c b/usr/src/lib/fm/topo/modules/sun4v/chip/chip_sun4v.c index ffcd6071ef..1860094bbe 100644 --- a/usr/src/lib/fm/topo/modules/sun4v/chip/chip_sun4v.c +++ b/usr/src/lib/fm/topo/modules/sun4v/chip/chip_sun4v.c @@ -353,7 +353,7 @@ chip_create(topo_mod_t *mod, tnode_t *rnode, const char *name, md_proc_t *procp; topo_mod_dprintf(mod, "enumerating cmp chip\n"); - if (min < 0 || max < 0 || min > max) { + if (min > max) { topo_mod_dprintf(mod, "Invalid chip range(%d,%d)\n", min, max); return (-1); } diff --git a/usr/src/lib/fm/topo/modules/sun4v/hostbridge/hb_sun4v.c b/usr/src/lib/fm/topo/modules/sun4v/hostbridge/hb_sun4v.c index 9e1d48d5f6..fe8afd14c8 100644 --- a/usr/src/lib/fm/topo/modules/sun4v/hostbridge/hb_sun4v.c +++ b/usr/src/lib/fm/topo/modules/sun4v/hostbridge/hb_sun4v.c @@ -291,7 +291,7 @@ platform_hb_enum(topo_mod_t *mod, tnode_t *parent, const char *name, int nrcs, nrcnode = 0; busorrc_t *rcs; - if (imin < 0 || imax < 0 || imin > imax) { + if (imin > imax) { topo_mod_dprintf(mod, "Invalid hb range(%d,%d)\n", imin, imax); return (-1); } diff --git a/usr/src/psm/stand/boot/common/heap_kmem.c b/usr/src/psm/stand/boot/common/heap_kmem.c index 344325ca99..4edf98b367 100644 --- a/usr/src/psm/stand/boot/common/heap_kmem.c +++ b/usr/src/psm/stand/boot/common/heap_kmem.c @@ -24,8 +24,6 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #if 1 #undef DEBUG #endif @@ -682,7 +680,6 @@ prtree(kmem_info.free_root, "kmem_free"); * as "ptr == neigh_block" */ prom_panic("kmem_free: block already free as neighbor"); - return; } /* else */ neighbor = *np; } /* while */ diff --git a/usr/src/psm/stand/boot/common/readfile.c b/usr/src/psm/stand/boot/common/readfile.c index b06173fe3d..7a68ae91d2 100644 --- a/usr/src/psm/stand/boot/common/readfile.c +++ b/usr/src/psm/stand/boot/common/readfile.c @@ -469,7 +469,7 @@ read_elf32(int fd, int print, Elf32_Ehdr *elfhdrp) * the kernel image. */ if ((loadaddr = (uintptr_t) - kmem_alloc(phdr->p_memsz, 0)) == NULL) + kmem_alloc(phdr->p_memsz, 0)) == 0) goto elferror; /* * Save this to pass on @@ -659,7 +659,7 @@ read_elf32(int fd, int print, Elf32_Ehdr *elfhdrp) } /* use uintptr_t to suppress the gcc warning */ if ((elfbootvec->eb_un.eb_ptr = - (Elf32_Addr)(uintptr_t)kmem_alloc(size, 0)) == NULL) { + (Elf32_Addr)(uintptr_t)kmem_alloc(size, 0)) == 0) { kmem_free(elfbootvec, vsize); goto elferror; } @@ -680,7 +680,7 @@ read_elf32(int fd, int print, Elf32_Ehdr *elfhdrp) size = (av - auxv) * sizeof (auxv64_t); /* use uintptr_t to suppress the gcc warning */ if ((elfbootvecELF32_64->eb_un.eb_ptr = - (Elf32_Addr)(uintptr_t)kmem_alloc(size, 0)) == NULL) { + (Elf32_Addr)(uintptr_t)kmem_alloc(size, 0)) == 0) { kmem_free(elfbootvecELF32_64, vsize); goto elferror; } else { @@ -877,10 +877,10 @@ read_elf64(int fd, int print, Elf64_Ehdr *elfhdrp) #ifdef BOOTAMD64 if ((loadaddr = (Elf64_Addr) (ADDR_XTND(kmem_alloc(phdr->p_memsz, 0)))) - == NULL) + == 0) #else /* !BOOTAMD64 */ if ((loadaddr = (Elf64_Addr)(uintptr_t) - kmem_alloc(phdr->p_memsz, 0)) == NULL) + kmem_alloc(phdr->p_memsz, 0)) == 0) #endif /* BOOTAMD64 */ goto elf64error; @@ -1069,7 +1069,7 @@ read_elf64(int fd, int print, Elf64_Ehdr *elfhdrp) (char *)ADDR_TRUNC((elfbootvecELF64->eb_un.eb_ptr)), size); #else /* !BOOTAMD64 */ if ((elfbootvecELF64->eb_un.eb_ptr = - (Elf64_Addr)kmem_alloc(size, 0)) == NULL) { + (Elf64_Addr)kmem_alloc(size, 0)) == 0) { kmem_free(elfbootvecELF64, vsize); goto elf64error; } @@ -1348,7 +1348,7 @@ iload64(char *rtld, Elf64_Phdr *thdr, Elf64_Phdr *dhdr, auxv64_t **avp) sp->sh_addralign); #endif /* BOOTAMD64 */ - if (load == NULL) { + if (load == 0) { printf("boot: allocating memory for section %d " "failed\n", i); goto error; diff --git a/usr/src/psm/stand/cpr/sparcv9/sun4u/machdep.c b/usr/src/psm/stand/cpr/sparcv9/sun4u/machdep.c index 640dbc4902..325fe77037 100644 --- a/usr/src/psm/stand/cpr/sparcv9/sun4u/machdep.c +++ b/usr/src/psm/stand/cpr/sparcv9/sun4u/machdep.c @@ -170,7 +170,7 @@ restore_tlb(struct sun4u_tlb *utp, int cpu_id) } for (tail = utp + CPR_MAX_TLB; utp < tail; utp++) { - if (utp->va_tag == NULL) + if (utp->va_tag == 0) continue; virt = (caddr_t)utp->va_tag; (*tfunc)(utp->index, virt, &utp->tte); diff --git a/usr/src/psm/stand/cpr/sparcv9/sun4u/util.c b/usr/src/psm/stand/cpr/sparcv9/sun4u/util.c index 79b98a9e36..b52e0ab7de 100644 --- a/usr/src/psm/stand/cpr/sparcv9/sun4u/util.c +++ b/usr/src/psm/stand/cpr/sparcv9/sun4u/util.c @@ -23,8 +23,6 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <sys/cpr.h> #include <sys/promimpl.h> #include "cprboot.h" @@ -491,7 +489,7 @@ int cb_usb_setup(void) { char sp[OBP_MAXPATHLEN]; - static char cb_nulldev[] = { + static char cb_nulldev[] = "\" /\" select-dev " "new-device " "\" nulldev\" device-name " @@ -503,8 +501,7 @@ cb_usb_setup(void) ": write 2drop 0 ; " ": restore ; " "finish-device " - "unselect-dev" - }; + "unselect-dev"; CB_VENTRY(cb_usb_setup); diff --git a/usr/src/stand/lib/fs/hsfs/hsfsops.c b/usr/src/stand/lib/fs/hsfs/hsfsops.c index 21f8c37081..e6b0c1b6e3 100644 --- a/usr/src/stand/lib/fs/hsfs/hsfsops.c +++ b/usr/src/stand/lib/fs/hsfs/hsfsops.c @@ -424,7 +424,7 @@ boot_hsfs_read(int fd, caddr_t buf, size_t count) while (i > 0) { /* If we need to reload the buffer, do so */ if ((j = filep->fi_count) == 0) { - getblock(filep, buf, i, &rcount); + (void) getblock(filep, buf, i, &rcount); i -= rcount; buf += rcount; filep->fi_offset += rcount; @@ -936,8 +936,8 @@ parse_susp(char *bufp, uint_t *ce_len, struct hs_direct *hsdep) } break; } - cur_off += susp_len; - break; + cur_off += susp_len; + break; } } if (i > hsfs_num_sig) { @@ -1041,7 +1041,8 @@ boot_hsfs_getdents(int fd, struct dirent *dep, unsigned size) size -= n; cnt += 1; - (void) strcpy(dep->d_name, hdp->hs_ufs_dir.d_name); + (void) strlcpy(dep->d_name, hdp->hs_ufs_dir.d_name, + strlen(hdp->hs_ufs_dir.d_name) + 1); dep->d_ino = hdp->hs_ufs_dir.d_ino; dep->d_off = dir.loc; dep->d_reclen = (unsigned short)n; diff --git a/usr/src/stand/lib/fs/nfs/auth_unix.c b/usr/src/stand/lib/fs/nfs/auth_unix.c index 1f28656a9a..56b72d36ba 100644 --- a/usr/src/stand/lib/fs/nfs/auth_unix.c +++ b/usr/src/stand/lib/fs/nfs/auth_unix.c @@ -32,8 +32,6 @@ * under license from the Regents of the University of California. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * Adapted for use by the boot program. * @@ -93,13 +91,11 @@ authunix_create(char *machname, uid_t uid, gid_t gid, int len, gid_t *aup_gids) auth = (AUTH *) bkmem_alloc(sizeof (*auth)); if (auth == NULL) { prom_panic("authunix_create: Cannot allocate memory."); - return (NULL); } au = (struct audata *)bkmem_alloc(sizeof (*au)); if (au == NULL) { prom_panic("authunix_create: Cannot allocate memory."); - return (NULL); } /* setup authenticator. */ @@ -127,17 +123,11 @@ authunix_create(char *machname, uid_t uid, gid_t gid, int len, gid_t *aup_gids) xdrmem_create(&xdrs, mymem, MAX_AUTH_BYTES, XDR_ENCODE); if (!xdr_authunix_parms(&xdrs, &aup)) { prom_panic("authunix_create: xdr_authunix_parms failed"); - bkmem_free(auth->ah_private, sizeof (struct audata)); - bkmem_free((caddr_t)auth, sizeof (*auth)); - return ((AUTH *)0); } au->au_origcred.oa_length = len = XDR_GETPOS(&xdrs); au->au_origcred.oa_flavor = (uint_t)AUTH_UNIX; if ((au->au_origcred.oa_base = bkmem_alloc((uint_t)len)) == NULL) { prom_panic("authunix_create: memory alloc failed"); - bkmem_free(auth->ah_private, sizeof (struct audata)); - bkmem_free((caddr_t)auth, sizeof (*auth)); - return ((AUTH *)0); } (void) bcopy(mymem, au->au_origcred.oa_base, (uint_t)len); @@ -222,7 +212,7 @@ authunix_refresh(AUTH *auth, struct rpc_msg *msg, cred_t *cr) /* update the time and serialize in place */ aup.aup_time = (prom_gettime() / 1000); xdrs.x_op = XDR_ENCODE; - XDR_SETPOS(&xdrs, 0); + (void) XDR_SETPOS(&xdrs, 0); stat = xdr_authunix_parms(&xdrs, &aup); if (!stat) goto done; diff --git a/usr/src/stand/lib/fs/nfs/bootparams.c b/usr/src/stand/lib/fs/nfs/bootparams.c index c2f7d12767..199cb8b752 100644 --- a/usr/src/stand/lib/fs/nfs/bootparams.c +++ b/usr/src/stand/lib/fs/nfs/bootparams.c @@ -24,8 +24,6 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * This file contains routines responsible for getting the system's * name and boot params. Most of it comes from the SVR4 diskless boot @@ -166,7 +164,7 @@ whoami(void) if (namelen > 0) { if (boothowto & RB_VERBOSE) printf("hostname: %s\n", bp.client_name); - sethostname(bp.client_name, namelen); + (void) sethostname(bp.client_name, namelen); } else { dprintf("whoami: no host name\n"); retval = FALSE; diff --git a/usr/src/stand/lib/fs/nfs/clnt_btcp.c b/usr/src/stand/lib/fs/nfs/clnt_btcp.c index b69808393c..3058e4ce50 100644 --- a/usr/src/stand/lib/fs/nfs/clnt_btcp.c +++ b/usr/src/stand/lib/fs/nfs/clnt_btcp.c @@ -32,8 +32,6 @@ * under license from the Regents of the University of California. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * Boot subsystem client side rpc (TCP) */ @@ -181,7 +179,7 @@ clntbtcp_create( rpc_createerr.cf_stat = RPC_SYSTEMERROR; rpc_createerr.cf_error.re_errno = errno; if (*sockp > 0) - close(*sockp); + (void) close(*sockp); goto fooy; } @@ -190,7 +188,7 @@ clntbtcp_create( rpc_createerr.cf_stat = RPC_SYSTEMERROR; rpc_createerr.cf_error.re_errno = errno; if (*sockp > 0) - close(*sockp); + (void) close(*sockp); goto fooy; } diff --git a/usr/src/stand/lib/fs/nfs/clnt_budp.c b/usr/src/stand/lib/fs/nfs/clnt_budp.c index cfd14574ff..e101b29d7c 100644 --- a/usr/src/stand/lib/fs/nfs/clnt_budp.c +++ b/usr/src/stand/lib/fs/nfs/clnt_budp.c @@ -32,8 +32,6 @@ * under license from the Regents of the University of California. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * Boot subsystem client side rpc */ @@ -272,7 +270,7 @@ clntbudp_call(cl, proc, xargs, argsp, xresults, resultsp, utimeout) call_again: xdrs = &(cu->cu_outxdrs); xdrs->x_op = XDR_ENCODE; - XDR_SETPOS(xdrs, cu->cu_xdrpos); + (void) XDR_SETPOS(xdrs, cu->cu_xdrpos); /* * the transaction is the first thing in the out buffer */ diff --git a/usr/src/stand/lib/fs/nfs/getdents.c b/usr/src/stand/lib/fs/nfs/getdents.c index fa9d36302c..3d229bba84 100644 --- a/usr/src/stand/lib/fs/nfs/getdents.c +++ b/usr/src/stand/lib/fs/nfs/getdents.c @@ -26,8 +26,6 @@ * Stuff relating to directory reading ... */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <rpc/types.h> #include <rpc/auth.h> #include <rpc/xdr.h> @@ -170,7 +168,8 @@ nfsgetdents(struct nfs_file *nfp, struct dirent *dep, unsigned size) return (cnt); size -= n; - (void) strcpy(dep->d_name, ep->name); + (void) strlcpy(dep->d_name, ep->name, + strlen(ep->name) + 1); dep->d_ino = ep->fileid; bcopy(ep->cookie, &offset, sizeof (nfscookie)); dep->d_off = offset; diff --git a/usr/src/stand/lib/fs/nfs/getdents3.c b/usr/src/stand/lib/fs/nfs/getdents3.c index e3c24e3d84..2fb2bc5952 100644 --- a/usr/src/stand/lib/fs/nfs/getdents3.c +++ b/usr/src/stand/lib/fs/nfs/getdents3.c @@ -26,8 +26,6 @@ * Stuff relating to NFSv3 directory reading ... */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <rpc/types.h> #include <rpc/auth.h> #include <rpc/xdr.h> @@ -171,7 +169,8 @@ nfs3getdents(struct nfs_file *nfp, struct dirent *dep, unsigned size) return (cnt); size -= n; - (void) strcpy(dep->d_name, ep->name); + (void) strlcpy(dep->d_name, ep->name, + strlen(ep->name) + 1); dep->d_ino = ep->fileid; dep->d_off = (off_t)ep->cookie; dep->d_reclen = (ushort_t)n; diff --git a/usr/src/stand/lib/fs/nfs/lookup.c b/usr/src/stand/lib/fs/nfs/lookup.c index a7f226f460..da185657d3 100644 --- a/usr/src/stand/lib/fs/nfs/lookup.c +++ b/usr/src/stand/lib/fs/nfs/lookup.c @@ -287,7 +287,7 @@ next: if (error) goto bad; - stpn_get(pathp, &linkpath); + (void) stpn_get(pathp, &linkpath); if (stpn_pathleft(&linkpath) == 0) (void) stpn_set(&linkpath, "."); diff --git a/usr/src/stand/lib/fs/nfs/mount.c b/usr/src/stand/lib/fs/nfs/mount.c index 2c394b98ab..8bfa073be5 100644 --- a/usr/src/stand/lib/fs/nfs/mount.c +++ b/usr/src/stand/lib/fs/nfs/mount.c @@ -27,8 +27,6 @@ /* Copyright (c) 1988 AT&T */ /* All Rights Reserved */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <sys/utsname.h> #include <sys/types.h> #include <sys/socket.h> @@ -653,7 +651,7 @@ boot_nfs_mountroot(char *str) * Assumes we've configured the stack and thus know our * IP address/hostname, either by using DHCP or rarp/bootparams. */ - gethostname(my_hostname, sizeof (my_hostname)); + (void) gethostname(my_hostname, sizeof (my_hostname)); wait.tv_sec = RPC_RCVWAIT_MSEC / 1000; wait.tv_usec = 0; diff --git a/usr/src/stand/lib/fs/nfs/nfs4ops.c b/usr/src/stand/lib/fs/nfs/nfs4ops.c index cf1cabab87..1935e50fca 100644 --- a/usr/src/stand/lib/fs/nfs/nfs4ops.c +++ b/usr/src/stand/lib/fs/nfs/nfs4ops.c @@ -25,8 +25,6 @@ * Simple nfs V4 ops */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <rpc/types.h> #include <rpc/auth.h> #include <sys/t_lock.h> @@ -118,7 +116,8 @@ nfs4read(struct nfs_file *filep, char *buf, size_t size) timeout); if (status == RPC_TIMEDOUT) { - dprintf("NFS read(%d) timed out. Retrying...\n", readargs.r_count); + dprintf("NFS read(%d) timed out. Retrying...\n", + readargs.r_count); if (errno == ETIMEDOUT) framing_errs++; diff --git a/usr/src/stand/lib/fs/nfs/pmap.c b/usr/src/stand/lib/fs/nfs/pmap.c index 1fffd0ff2a..dc6257125f 100644 --- a/usr/src/stand/lib/fs/nfs/pmap.c +++ b/usr/src/stand/lib/fs/nfs/pmap.c @@ -24,8 +24,6 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * This file contains the routines that maintain a linked list of known * program to udp port mappings. There are three static members initialized @@ -246,10 +244,10 @@ xdr_rmtcall_args(XDR *xdrs, struct rmtcallargs *cap) return (FALSE); position = XDR_GETPOS(xdrs); cap->arglen = position - argposition; - XDR_SETPOS(xdrs, lenposition); + (void) XDR_SETPOS(xdrs, lenposition); if (!xdr_u_int(xdrs, &(cap->arglen))) return (FALSE); - XDR_SETPOS(xdrs, position); + (void) XDR_SETPOS(xdrs, position); return (TRUE); } return (FALSE); @@ -299,10 +297,10 @@ xdr_rpcb_rmtcallargs(XDR *xdrs, struct rpcb_rmtcallargs *objp) return (FALSE); position = XDR_GETPOS(xdrs); objp->arglen = position - argposition; - XDR_SETPOS(xdrs, lenposition); + (void) XDR_SETPOS(xdrs, lenposition); if (!xdr_u_int(xdrs, &(objp->arglen))) return (FALSE); - XDR_SETPOS(xdrs, position); + (void) XDR_SETPOS(xdrs, position); return (TRUE); } diff --git a/usr/src/stand/lib/fs/nfs/rpc.c b/usr/src/stand/lib/fs/nfs/rpc.c index db813a2d1d..244c4a2206 100644 --- a/usr/src/stand/lib/fs/nfs/rpc.c +++ b/usr/src/stand/lib/fs/nfs/rpc.c @@ -27,8 +27,6 @@ * used. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <sys/sysmacros.h> #include <rpc/types.h> #include <errno.h> @@ -301,7 +299,7 @@ brpc_call( * Assumes we've configured the stack and thus know our * IP address/hostname, either by using DHCP or rarp/bootparams. */ - gethostname(hostname, sizeof (hostname)); + (void) gethostname(hostname, sizeof (hostname)); xmit_auth = authunix_create(hostname, 0, 1, 1, &fake_gids); break; default: diff --git a/usr/src/stand/lib/fs/ufs/lufsboot.c b/usr/src/stand/lib/fs/ufs/lufsboot.c index 0bbcf88cd8..00df083f61 100644 --- a/usr/src/stand/lib/fs/ufs/lufsboot.c +++ b/usr/src/stand/lib/fs/ufs/lufsboot.c @@ -23,8 +23,6 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <sys/param.h> #include <sys/vnode.h> #include <sys/fs/ufs_fsdir.h> @@ -484,7 +482,7 @@ lufs_boot_init(fileid_t *filep) */ if (!lufs_support || sb != (struct fs *)&filep->fi_devp->un_fs.di_fs || - sb->fs_clean != FSLOG || sb->fs_logbno == NULL) { + sb->fs_clean != FSLOG || sb->fs_logbno == 0) { return; } @@ -596,7 +594,7 @@ lufs_logscan_read(int32_t *addr, struct delta *d) *addr = lufs_read_log(*addr, (caddr_t)d, sizeof (struct delta)); if (*addr == 0 || - d->d_typ < DT_NONE || d->d_typ > DT_MAX || + (int)d->d_typ < DT_NONE || d->d_typ > DT_MAX || d->d_nb >= odi.od_logsize) return (0); @@ -632,7 +630,7 @@ lufs_logscan_skip(int32_t *addr, struct delta *d) *addr = lufs_read_log(*addr, NULL, d->d_nb); } - return (*addr != NULL); + return (*addr != 0); } static void diff --git a/usr/src/stand/lib/fs/ufs/ufsops.c b/usr/src/stand/lib/fs/ufs/ufsops.c index 5a1079816a..46ee35d65e 100644 --- a/usr/src/stand/lib/fs/ufs/ufsops.c +++ b/usr/src/stand/lib/fs/ufs/ufsops.c @@ -567,7 +567,7 @@ boot_ufs_read(int fd, caddr_t buf, size_t count) while (i > 0) { /* If we need to reload the buffer, do so */ if ((j = filep->fi_count) == 0) { - getblock(filep, buf, i, &rcount); + (void) getblock(filep, buf, i, &rcount); i -= rcount; buf += rcount; filep->fi_offset += rcount; @@ -697,11 +697,11 @@ boot_ufs_open(char *filename, int flags) inode = find(filep, filename); if (inode == (ino_t)0) { - boot_ufs_close(filep->fi_filedes); + (void) boot_ufs_close(filep->fi_filedes); return (-1); } if (openi(filep, inode)) { - boot_ufs_close(filep->fi_filedes); + (void) boot_ufs_close(filep->fi_filedes); return (-1); } @@ -945,7 +945,8 @@ boot_ufs_getdents(int fd, struct dirent *dep, unsigned size) size -= n; cnt += 1; - (void) strcpy(dep->d_name, dp->d_name); + (void) strlcpy(dep->d_name, dp->d_name, + strlen(dp->d_name) + 1); dep->d_off = dir.loc; dep->d_reclen = (ushort_t)n; diff --git a/usr/src/stand/lib/inet/ipv4.c b/usr/src/stand/lib/inet/ipv4.c index 195da4ca73..89efef62ad 100644 --- a/usr/src/stand/lib/inet/ipv4.c +++ b/usr/src/stand/lib/inet/ipv4.c @@ -25,8 +25,6 @@ * ipv4.c, Code implementing the IPv4 internet protocol. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <sys/types.h> #include <socket_impl.h> #include <socket_inet.h> @@ -1140,7 +1138,7 @@ again: else base = 8; } - while ((c = *cp) != NULL) { + while ((c = *cp) != '\0') { if (isdigit(c)) { if ((c - '0') >= base) break; diff --git a/usr/src/stand/lib/tcp/Makefile b/usr/src/stand/lib/tcp/Makefile index 30ad308f52..c94b1a753e 100644 --- a/usr/src/stand/lib/tcp/Makefile +++ b/usr/src/stand/lib/tcp/Makefile @@ -36,4 +36,7 @@ CPPFLAGS += -I../inet $(SOCKCPPFLAGS) CERRWARN += -_gcc=-Wno-unused-label CERRWARN += $(CNOWARN_UNINIT) +# tcp.c is too hairy. +SMATCH=off + include ../Makefile.targ diff --git a/usr/src/stand/lib/tcp/tcp.c b/usr/src/stand/lib/tcp/tcp.c index d18044c050..9c398df600 100644 --- a/usr/src/stand/lib/tcp/tcp.c +++ b/usr/src/stand/lib/tcp/tcp.c @@ -27,8 +27,6 @@ * tcp.c, Code implementing the TCP protocol. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <sys/types.h> #include <socket_impl.h> #include <socket_inet.h> @@ -1734,7 +1732,7 @@ retry: } while ((in_gram = sockets[sock_id].inq) != NULL) { - if (tcp != NULL && tcp->tcp_state == state) + if (tcp->tcp_state == state) break; /* Remove unknown inetgrams from the head of inq. */ @@ -3943,7 +3941,6 @@ fin_acked: DISP_ADDR_AND_PORT)); /* We should never get here... */ prom_panic("tcp_rput_data"); - return; } goto pre_swnd_update; } @@ -5989,8 +5986,9 @@ tcp_xmit_mp(tcp_t *tcp, mblk_t *mp, int32_t max_to_send, int32_t *offset, tcp->tcp_state = TCPS_LAST_ACK; break; } - if (tcp->tcp_suna == tcp->tcp_snxt) + if (tcp->tcp_suna == tcp->tcp_snxt) { TCP_TIMER_RESTART(tcp, tcp->tcp_rto); + } tcp->tcp_snxt = tcp->tcp_fss + 1; } } diff --git a/usr/src/uts/common/os/cyclic.c b/usr/src/uts/common/os/cyclic.c index 58db0d5edf..a35dbd8e3b 100644 --- a/usr/src/uts/common/os/cyclic.c +++ b/usr/src/uts/common/os/cyclic.c @@ -3203,6 +3203,61 @@ cyclic_move_here(cyclic_id_t id) cyclic_juggle_one_to(idp, dest->cpu_cyclic); } +/* + * void cyclic_move_here(cyclic_id_t) + * + * Overview + * + * cyclic_move_here() attempts to shuffle a cyclic onto the current CPU. + * + * Arguments and notes + * + * The first argument is a cyclic_id returned from cyclic_add(). + * cyclic_move_here() may _not_ be called on a cyclic_id returned from + * cyclic_add_omni() or one bound to a CPU or partition via cyclic_bind(). + * + * This cyclic shuffling is performed on a best-effort basis. If for some + * reason the current CPU is unsuitable or the thread migrates between CPUs + * during the call, the function may return with the cyclic residing on some + * other CPU. + * + * Return value + * + * None; cyclic_move_here() always reports success. + * + * Caller's context + * + * cpu_lock must be held by the caller, and the caller must not be in + * interrupt context. The caller may not hold any locks which are also + * grabbed by any cyclic handler. + */ +void +cyclic_move_here(cyclic_id_t id) +{ + cyc_id_t *idp = (cyc_id_t *)id; + cyc_cpu_t *cc = idp->cyi_cpu; + cpu_t *dest = CPU; + + ASSERT(MUTEX_HELD(&cpu_lock)); + CYC_PTRACE("move_here", idp, dest); + VERIFY3P(cc, !=, NULL); + VERIFY3U(cc->cyp_cyclics[idp->cyi_ndx].cy_flags & + (CYF_CPU_BOUND|CYF_PART_BOUND), ==, 0); + + if (cc->cyp_cpu == dest) { + return; + } + + /* Is the destination CPU suitable for a migration target? */ + if (dest->cpu_cyclic == NULL || + dest->cpu_cyclic->cyp_state == CYS_OFFLINE || + (dest->cpu_flags & CPU_ENABLE) == 0) { + return; + } + + cyclic_juggle_one_to(idp, dest->cpu_cyclic); +} + hrtime_t cyclic_getres() { diff --git a/usr/src/uts/common/rpc/xdr.c b/usr/src/uts/common/rpc/xdr.c index 6720324cdd..4996b71446 100644 --- a/usr/src/uts/common/rpc/xdr.c +++ b/usr/src/uts/common/rpc/xdr.c @@ -80,7 +80,7 @@ xdr_free(xdrproc_t proc, char *objp) XDR x; x.x_op = XDR_FREE; - (*proc)(&x, objp); + (void) (*proc)(&x, objp); } /* |