diff options
author | Shruti Sampat <shrutisampat@gmail.com> | 2014-12-25 23:58:27 +0530 |
---|---|---|
committer | Robert Mustacchi <rm@joyent.com> | 2015-01-13 10:15:35 -0800 |
commit | 0d435d6202242b0a06dc4bc41a1117591a9405f8 (patch) | |
tree | c313641f21c45469e05496d404cc19df91556352 /usr/src | |
parent | 244781f10dcd82684fd8163c016540667842f203 (diff) | |
download | illumos-joyent-0d435d6202242b0a06dc4bc41a1117591a9405f8.tar.gz |
5375 utmpd(1M) core dumps when WTMPX_UPDATE_FREQ is zero
Reviewed by: Robert Mustacchi <rm@joyent.com>
Reviewed by: Marcel Telka <marcel@telka.sk>
Approved by: Dan McDonald <danmcd@omniti.com>
Diffstat (limited to 'usr/src')
-rw-r--r-- | usr/src/cmd/utmpd/svc-utmpd | 1 | ||||
-rw-r--r-- | usr/src/cmd/utmpd/utmpd.c | 138 | ||||
-rw-r--r-- | usr/src/cmd/utmpd/utmpd.dfl | 1 | ||||
-rw-r--r-- | usr/src/man/man1m/utmpd.1m | 13 |
4 files changed, 94 insertions, 59 deletions
diff --git a/usr/src/cmd/utmpd/svc-utmpd b/usr/src/cmd/utmpd/svc-utmpd index 9f7c1ad520..d5f391c79d 100644 --- a/usr/src/cmd/utmpd/svc-utmpd +++ b/usr/src/cmd/utmpd/svc-utmpd @@ -23,7 +23,6 @@ # Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # -# ident "%Z%%M% %I% %E% SMI" . /lib/svc/share/smf_include.sh diff --git a/usr/src/cmd/utmpd/utmpd.c b/usr/src/cmd/utmpd/utmpd.c index ba23b04aa5..f6e6d13a41 100644 --- a/usr/src/cmd/utmpd/utmpd.c +++ b/usr/src/cmd/utmpd/utmpd.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2014 Shruti V Sampat <shrutisampat@gmail.com> + * Copyright 2014, 2015 Shruti V Sampat <shrutisampat@gmail.com> */ /* @@ -78,6 +78,7 @@ #include <deflt.h> #include <procfs.h> #include <sys/resource.h> +#include <limits.h> #define dprintf(x) if (Debug) (void) printf x @@ -108,10 +109,10 @@ /* * pd_type's */ -#define ADDPID 1 -#define REMPID 2 +#define ADDPID 1 +#define REMPID 2 -struct pidrec { +struct pidrec { int pd_type; /* Command type */ pid_t pd_pid; /* pid to add or remove */ }; @@ -125,9 +126,9 @@ struct pidrec { * open fd. These tables are kept sorted by process ID for quick lookups. */ -struct pidentry { +struct pidentry { pid_t pl_pid; /* pid to watch for */ - int pl_status; /* Exit status of proc */ + int pl_status; /* Exit status of proc */ }; static struct pidentry *pidtable = NULL; @@ -139,7 +140,7 @@ static char *prog_name; /* To save the invocation name away */ static char *UTMPPIPE_DIR = "/var/run"; static char *UTMPPIPE = "/var/run/utmppipe"; static int Pfd = -1; /* File descriptor of named pipe */ -static int Poll_timeout = POLL_TIMEOUT; +static int Poll_timeout = POLL_TIMEOUT; static int WTMPXfd = -1; /* File descriptor of WTMPX_FILE */ static int WTMPX_ufreq = WTMPX_UFREQ; static int Debug = 0; /* Set by command line argument */ @@ -151,7 +152,7 @@ static int Max_fds = MAX_FDS; * (Uses a named pipe to get messages) * Watcher - Use poll(2) to watch for processes to die so they * can be cleaned up (get marked as DEAD_PROCESS) - * Scanner - periodically scans the utmpx file for stale entries + * Scanner - periodically scans the utmpx file for stale entries * or live entries that we don't know about. */ @@ -176,6 +177,9 @@ static void print_tables(); /* Prints out internal tables for Debug */ static int proc_is_alive(pid_t pid); /* Check if a process is alive */ static void warn_utmp(void); +/* Validate defaults from file and assign */ +static int validate_default(char *defp, int *flag); + /* * main() - Main does basic setup and calls wait_for_pids() to do the work */ @@ -187,6 +191,7 @@ main(int argc, char *argv[]) struct rlimit rlim; int i; time_t curtime, now; + char msg[256]; prog_name = argv[0]; /* Save invocation name */ @@ -210,28 +215,40 @@ main(int argc, char *argv[]) } /* - * Read defaults file for poll timeout + * Read defaults file for poll timeout, WTMPX update frequency + * and maximum number of processes to monitor. */ if (defopen(UTMP_DEFAULT) == 0) { - if ((defp = defread("SCAN_PERIOD=")) != NULL) { - Poll_timeout = atol(defp); - dprintf(("Poll timeout set to %d\n", Poll_timeout)); - } - - if ((defp = defread("WTMPX_UPDATE_FREQ=")) != NULL) { - WTMPX_ufreq = atol(defp); - dprintf(("WTMPX update frequency set to %d\n", - WTMPX_ufreq)); - } + if ((defp = defread("SCAN_PERIOD=")) != NULL) + if (validate_default(defp, &Poll_timeout) == -1) { + (void) snprintf(msg, sizeof (msg), "SCAN_PERIOD" + " should be a positive integer, found %s", + defp); + nonfatal(msg); + } + dprintf(("Poll timeout set to %d\n", Poll_timeout)); + + if ((defp = defread("WTMPX_UPDATE_FREQ=")) != NULL) + if (validate_default(defp, &WTMPX_ufreq) == -1) { + (void) snprintf(msg, sizeof (msg), + "WTMPX_UPDATE_FREQ should be a positive " + "integer, found %s", defp); + nonfatal(msg); + } + dprintf(("WTMPX update frequency set to %d\n", WTMPX_ufreq)); /* * Paranoia - if polling on large number of FDs is expensive / * buggy the number can be set lower in the field. */ - if ((defp = defread("MAX_FDS=")) != NULL) { - Max_fds = atol(defp); - dprintf(("Max_fds set to %d\n", Max_fds)); - } + if ((defp = defread("MAX_FDS=")) != NULL) + if (validate_default(defp, &Max_fds) == -1) { + (void) snprintf(msg, sizeof (msg), "MAX_FDS " + "should be a positive integer, found %s", + defp); + nonfatal(msg); + } + dprintf(("Max fds set to %d\n", Max_fds)); (void) defopen((char *)NULL); } @@ -281,7 +298,7 @@ main(int argc, char *argv[]) (void) enable_extended_FILE_stdio(-1, -1); if ((WTMPXfd = open(WTMPX_FILE, O_RDONLY)) < 0) - nonfatal("WARNING: unable to open " WTMPX_FILE "for update."); + nonfatal("WARNING: unable to open " WTMPX_FILE " for update."); /* * Loop here scanning the utmpx file and waiting for processes @@ -682,8 +699,7 @@ drain_pipe() * */ static void -add_pid(pid) - pid_t pid; +add_pid(pid_t pid) { int fd = 0; int i = 0, move_amt; @@ -740,9 +756,9 @@ add_pid(pid) */ if (move_amt != 0) { (void) memmove(&pidtable[i+1], &pidtable[i], - move_amt * sizeof (struct pidentry)); + move_amt * sizeof (struct pidentry)); (void) memmove(&fdtable[i+1], &fdtable[i], - move_amt * sizeof (pollfd_t)); + move_amt * sizeof (pollfd_t)); } } } @@ -761,7 +777,7 @@ add_pid(pid) pidcnt++; /* Bump the pid count */ dprintf((" add_pid: pid = %d fd = %d index = %d pidcnt = %d\n", - (int)pid, fd, i, pidcnt)); + (int)pid, fd, i, pidcnt)); } @@ -769,13 +785,16 @@ add_pid(pid) * rem_pid - Remove an entry from the table and check to see if its * not in the utmpx file. * If i != -1 don't look up the pid, use i as index + * + * pid - Pid of process to clean or 0 if we don't know it + * + * i - Index into table or -1 if we need to look it up + * + * clean_it - Clean the entry, or just remove from table? */ static void -rem_pid(pid, i, clean_it) - pid_t pid; /* Pid of process to clean or 0 if we don't know it */ - int i; /* Index into table or -1 if we need to look it up */ - int clean_it; /* Clean the entry, or just remove from table? */ +rem_pid(pid_t pid, int i, int clean_it) { int move_amt; @@ -802,10 +821,10 @@ rem_pid(pid, i, clean_it) * Remove entries from the tables. */ (void) memmove(&pidtable[i], &pidtable[i+1], - move_amt * sizeof (struct pidentry)); + move_amt * sizeof (struct pidentry)); (void) memmove(&fdtable[i], &fdtable[i+1], - move_amt * sizeof (pollfd_t)); + move_amt * sizeof (pollfd_t)); /* * decrement the pid count - one less pid to worry about @@ -823,9 +842,7 @@ rem_pid(pid, i, clean_it) */ static int -find_pid(pid, i) - pid_t pid; - int *i; +find_pid(pid_t pid, int *i) { struct pidentry pe; struct pidentry *p; @@ -847,8 +864,7 @@ find_pid(pid, i) */ static int -pidcmp(a, b) - struct pidentry *a, *b; +pidcmp(struct pidentry *a, struct pidentry *b) { if (b == NULL || a == NULL) return (0); @@ -861,8 +877,7 @@ pidcmp(a, b) * /proc file for the specified process. */ static int -proc_to_fd(pid) - pid_t pid; +proc_to_fd(pid_t pid) { char procname[64]; int fd, dfd; @@ -911,8 +926,7 @@ proc_to_fd(pid) * into the pid_table. */ static void -clean_entry(i) - int i; +clean_entry(int i) { struct utmpx *u; @@ -925,8 +939,8 @@ clean_entry(i) * Double check if the process is dead. */ if (proc_is_alive(pidtable[i].pl_pid)) { - dprintf((" Bad attempt to clean %d\n", \ - (int)pidtable[i].pl_pid)); + dprintf((" Bad attempt to clean %d\n", + (int)pidtable[i].pl_pid)); return; } @@ -951,8 +965,7 @@ clean_entry(i) */ static void -clean_utmpx_ent(u) - struct utmpx *u; +clean_utmpx_ent(struct utmpx *u) { dprintf((" clean_utmpx_ent: %d\n", (int)u->ut_pid)); u->ut_type = DEAD_PROCESS; @@ -1033,8 +1046,7 @@ print_tables() */ static int -proc_is_alive(pid) - pid_t pid; +proc_is_alive(pid_t pid) { char psinfoname[64]; int fd; @@ -1083,3 +1095,29 @@ warn_utmp() "utmp(4) for more information"); } } + +/* + * validate_default - validate and assign defaults. + */ + +static int +validate_default(char *defp, int *flag) +{ + long lval; + char *endptr; + + errno = 0; + lval = strtol(defp, &endptr, 10); + + if (errno != 0 || lval > INT_MAX || lval <= 0) + return (-1); + + while (isspace(*endptr) != 0) + endptr++; + + if (*endptr != '\0') + return (-1); + + *flag = lval; + return (0); +} diff --git a/usr/src/cmd/utmpd/utmpd.dfl b/usr/src/cmd/utmpd/utmpd.dfl index a23ba29e13..1bc56c5a7d 100644 --- a/usr/src/cmd/utmpd/utmpd.dfl +++ b/usr/src/cmd/utmpd/utmpd.dfl @@ -2,6 +2,5 @@ # Copyright 1994 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # -#pragma ident "%Z%%M% %I% %E% SMI" SCAN_PERIOD=300 diff --git a/usr/src/man/man1m/utmpd.1m b/usr/src/man/man1m/utmpd.1m index ded08a039e..7d5a9b29ee 100644 --- a/usr/src/man/man1m/utmpd.1m +++ b/usr/src/man/man1m/utmpd.1m @@ -1,10 +1,11 @@ '\" te +.\" Copyright 2015 Shruti V Sampat <shrutisampat@gmail.com> .\" Copyright (c) 2004, Sun Microsystems, Inc. All Rights Reserved .\" Copyright 1989 AT&T .\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License. .\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License. .\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner] -.TH UTMPD 1M "Jun 4, 2008" +.TH UTMPD 1M "Jan 01, 2015" .SH NAME utmpd \- utmpx monitoring daemon .SH SYNOPSIS @@ -14,7 +15,6 @@ utmpd \- utmpx monitoring daemon .fi .SH DESCRIPTION -.sp .LP The \fButmpd\fR daemon monitors the \fB/var/adm/utmpx\fR file. See \fButmpx\fR(4) (and \fButmp\fR(4) for historical information). @@ -29,7 +29,6 @@ terminated, it checks that the process has removed its \fButmpx\fR entry from \fB/var/adm/utmpx\fR file, \fButmpd\fR also monitors processes that are not in its table. .SH OPTIONS -.sp .ne 2 .na \fB\fB-debug\fR\fR @@ -41,7 +40,6 @@ Write debugging information to standard output. .RE .SH EXIT STATUS -.sp .LP The following exit values are returned: .sp @@ -65,7 +63,6 @@ An error occurred. .RE .SH FILES -.sp .ne 2 .na \fB\fB/etc/default/utmpd\fR\fR @@ -75,6 +72,10 @@ An error occurred. You can set default values for the flags listed below. For example: \fBSCAN_PERIOD=600\fR .sp +The values for these flags should be greater than 0. If values read +from the file are found to be less than or equal to 0, or containing +invalid characters, the default values mentioned below are retained. +.sp .ne 2 .na \fB\fBSCAN_PERIOD\fR\fR @@ -134,13 +135,11 @@ monitored. .RE .SH SEE ALSO -.sp .LP \fBsvcs\fR(1), \fBinit\fR(1M), \fBsvcadm\fR(1M), \fBpoll\fR(2), \fBpututxline\fR(3C), \fBproc\fR(4), \fButmp\fR(4), \fButmpx\fR(4), \fBattributes\fR(5), \fBsmf\fR(5) .SH NOTES -.sp .LP If the filesystem holding \fB/var/adm/wtmpx\fR is mounted with options which inhibit or defer access time updates, an unknown amount of error will be |