Print this page
5375 utmpd(1M) core dumps when WTMPX_UPDATE_FREQ is zero

*** 17,27 **** * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* ! * Copyright 2014 Shruti V Sampat <shrutisampat@gmail.com> */ /* * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. --- 17,27 ---- * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* ! * Copyright 2014, 2015 Shruti V Sampat <shrutisampat@gmail.com> */ /* * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms.
*** 76,85 **** --- 76,86 ---- #include <string.h> #include <poll.h> #include <deflt.h> #include <procfs.h> #include <sys/resource.h> + #include <limits.h> #define dprintf(x) if (Debug) (void) printf x /* * Memory allocation keyed off MAX_FDS
*** 174,183 **** --- 175,187 ---- static void nonfatal(); /* Prints error message */ 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 */ int
*** 185,194 **** --- 189,199 ---- { char *defp; struct rlimit rlim; int i; time_t curtime, now; + char msg[256]; prog_name = argv[0]; /* Save invocation name */ if (getuid() != 0) { (void) fprintf(stderr,
*** 208,239 **** exit(2); } } /* ! * Read defaults file for poll timeout */ 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)); } /* * 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)); } (void) defopen((char *)NULL); } if (Debug == 0) { /* --- 213,256 ---- exit(2); } } /* ! * 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) ! 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) ! 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); } if (Debug == 0) { /*
*** 279,289 **** fatal("getrlimit returned failure"); (void) enable_extended_FILE_stdio(-1, -1); if ((WTMPXfd = open(WTMPX_FILE, O_RDONLY)) < 0) ! nonfatal("WARNING: unable to open " WTMPX_FILE "for update."); /* * Loop here scanning the utmpx file and waiting for processes * to terminate. Most of the activity is directed out of wait_for_pids. * If wait_for_pids fails we reload the table and try again. --- 296,306 ---- fatal("getrlimit returned failure"); (void) enable_extended_FILE_stdio(-1, -1); if ((WTMPXfd = open(WTMPX_FILE, O_RDONLY)) < 0) ! nonfatal("WARNING: unable to open " WTMPX_FILE " for update."); /* * Loop here scanning the utmpx file and waiting for processes * to terminate. Most of the activity is directed out of wait_for_pids. * If wait_for_pids fails we reload the table and try again.
*** 680,691 **** * add_pid - add a pid to the fd table and the pidtable. * these tables are sorted tables for quick lookups. * */ static void ! add_pid(pid) ! pid_t pid; { int fd = 0; int i = 0, move_amt; int j; static int first_time = 1; --- 697,707 ---- * add_pid - add a pid to the fd table and the pidtable. * these tables are sorted tables for quick lookups. * */ static void ! add_pid(pid_t pid) { int fd = 0; int i = 0, move_amt; int j; static int first_time = 1;
*** 767,783 **** /* * 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 */ 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? */ { int move_amt; dprintf((" rem_pid: pid = %d i = %d", (int)pid, i)); --- 783,802 ---- /* * 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_t pid, int i, int clean_it) { int move_amt; dprintf((" rem_pid: pid = %d i = %d", (int)pid, i));
*** 821,833 **** * find_pid - Returns an index into the pidtable of the specifed pid, * else -1 if not found */ static int ! find_pid(pid, i) ! pid_t pid; ! int *i; { struct pidentry pe; struct pidentry *p; pe.pl_pid = pid; --- 840,850 ---- * find_pid - Returns an index into the pidtable of the specifed pid, * else -1 if not found */ static int ! find_pid(pid_t pid, int *i) { struct pidentry pe; struct pidentry *p; pe.pl_pid = pid;
*** 845,856 **** /* * Pidcmp - Used by besearch for sorting and finding process IDs. */ static int ! pidcmp(a, b) ! struct pidentry *a, *b; { if (b == NULL || a == NULL) return (0); return (a->pl_pid - b->pl_pid); } --- 862,872 ---- /* * Pidcmp - Used by besearch for sorting and finding process IDs. */ static int ! pidcmp(struct pidentry *a, struct pidentry *b) { if (b == NULL || a == NULL) return (0); return (a->pl_pid - b->pl_pid); }
*** 859,870 **** /* * proc_to_fd - Take a process ID and return an open file descriptor to the * /proc file for the specified process. */ static int ! proc_to_fd(pid) ! pid_t pid; { char procname[64]; int fd, dfd; (void) sprintf(procname, "/proc/%d/psinfo", (int)pid); --- 875,885 ---- /* * proc_to_fd - Take a process ID and return an open file descriptor to the * /proc file for the specified process. */ static int ! proc_to_fd(pid_t pid) { char procname[64]; int fd, dfd; (void) sprintf(procname, "/proc/%d/psinfo", (int)pid);
*** 909,920 **** /* * Clean_entry - Cleans the specified entry - where i is an index * into the pid_table. */ static void ! clean_entry(i) ! int i; { struct utmpx *u; if (pidcnt == 0) return; --- 924,934 ---- /* * Clean_entry - Cleans the specified entry - where i is an index * into the pid_table. */ static void ! clean_entry(int i) { struct utmpx *u; if (pidcnt == 0) return;
*** 923,933 **** /* * 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)); return; } /* --- 937,947 ---- /* * 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)); return; } /*
*** 949,960 **** /* * clean_utmpx_ent - Clean a utmpx entry */ static void ! clean_utmpx_ent(u) ! struct utmpx *u; { dprintf((" clean_utmpx_ent: %d\n", (int)u->ut_pid)); u->ut_type = DEAD_PROCESS; (void) time(&u->ut_xtime); (void) pututxline(u); --- 963,973 ---- /* * clean_utmpx_ent - Clean a utmpx entry */ static void ! clean_utmpx_ent(struct utmpx *u) { dprintf((" clean_utmpx_ent: %d\n", (int)u->ut_pid)); u->ut_type = DEAD_PROCESS; (void) time(&u->ut_xtime); (void) pututxline(u);
*** 1031,1042 **** * not a zombie. Returns 1 if process is alive * and zero if it is dead or a zombie. */ static int ! proc_is_alive(pid) ! pid_t pid; { char psinfoname[64]; int fd; psinfo_t psinfo; --- 1044,1054 ---- * not a zombie. Returns 1 if process is alive * and zero if it is dead or a zombie. */ static int ! proc_is_alive(pid_t pid) { char psinfoname[64]; int fd; psinfo_t psinfo;
*** 1080,1085 **** --- 1092,1123 ---- if (lstat(UTMP_FILE, &s) == 0 && s.st_size % sizeof (struct utmp) == 0) { nonfatal("WARNING: /var/adm/utmp exists!\nSee " "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); }