diff --git a/usr.sbin/cron/lib/entry.c b/usr.sbin/cron/lib/entry.c index 9150a0d4ac56..ef05c14c2de3 100644 --- a/usr.sbin/cron/lib/entry.c +++ b/usr.sbin/cron/lib/entry.c @@ -35,7 +35,7 @@ static const char rcsid[] = typedef enum ecode { e_none, e_minute, e_hour, e_dom, e_month, e_dow, - e_cmd, e_timespec, e_username, e_group + e_cmd, e_timespec, e_username, e_group, e_mem #ifdef LOGIN_CAP , e_class #endif @@ -58,6 +58,7 @@ static char *ecodes[] = "bad time specifier", "bad username", "bad group name", + "out of memory", #ifdef LOGIN_CAP "bad class name", #endif @@ -106,6 +107,7 @@ load_entry(file, error_func, pw, envp) int ch; char cmd[MAX_COMMAND]; char envstr[MAX_ENVSTR]; + char **prev_env; Debug(DPARS, ("load_entry()...about to eat comments\n")) @@ -122,6 +124,11 @@ load_entry(file, error_func, pw, envp) e = (entry *) calloc(sizeof(entry), sizeof(char)); + if (e == NULL) { + warn("load_entry: calloc failed"); + return NULL; + } + if (ch == '@') { /* all of these should be flagged and load-limited; i.e., * instead of @hourly meaning "0 * * * *" it should mean @@ -269,8 +276,17 @@ load_entry(file, error_func, pw, envp) if ((s = strrchr(username, '/')) != NULL) { *s = '\0'; e->class = strdup(s + 1); - } else + if (e->class == NULL) + warn("strdup(\"%s\")", s + 1); + } else { e->class = strdup(RESOURCE_RC); + if (e->class == NULL) + warn("strdup(\"%s\")", RESOURCE_RC); + } + if (e->class == NULL) { + ecode = e_mem; + goto eof; + } if (login_getclass(e->class) == NULL) { ecode = e_class; goto eof; @@ -310,21 +326,61 @@ load_entry(file, error_func, pw, envp) * others are overrides. */ e->envp = env_copy(envp); + if (e->envp == NULL) { + warn("env_copy"); + ecode = e_mem; + goto eof; + } if (!env_get("SHELL", e->envp)) { + prev_env = e->envp; sprintf(envstr, "SHELL=%s", _PATH_BSHELL); e->envp = env_set(e->envp, envstr); + if (e->envp == NULL) { + warn("env_set(%s)", envstr); + env_free(prev_env); + ecode = e_mem; + goto eof; + } } + prev_env = e->envp; sprintf(envstr, "HOME=%s", pw->pw_dir); e->envp = env_set(e->envp, envstr); + if (e->envp == NULL) { + warn("env_set(%s)", envstr); + env_free(prev_env); + ecode = e_mem; + goto eof; + } if (!env_get("PATH", e->envp)) { + prev_env = e->envp; sprintf(envstr, "PATH=%s", _PATH_DEFPATH); e->envp = env_set(e->envp, envstr); + if (e->envp == NULL) { + warn("env_set(%s)", envstr); + env_free(prev_env); + ecode = e_mem; + goto eof; + } } + prev_env = e->envp; sprintf(envstr, "%s=%s", "LOGNAME", pw->pw_name); e->envp = env_set(e->envp, envstr); + if (e->envp == NULL) { + warn("env_set(%s)", envstr); + env_free(prev_env); + ecode = e_mem; + goto eof; + } #if defined(BSD) + prev_env = e->envp; sprintf(envstr, "%s=%s", "USER", pw->pw_name); e->envp = env_set(e->envp, envstr); + if (e->envp == NULL) { + warn("env_set(%s)", envstr); + env_free(prev_env); + ecode = e_mem; + goto eof; + } #endif Debug(DPARS, ("load_entry()...about to parse command\n")) @@ -339,6 +395,7 @@ load_entry(file, error_func, pw, envp) /* a file without a \n before the EOF is rude, so we'll complain... */ if (ch == EOF) { + env_free(e->envp); ecode = e_cmd; goto eof; } @@ -346,7 +403,12 @@ load_entry(file, error_func, pw, envp) /* got the command in the 'cmd' string; save it in *e. */ e->cmd = strdup(cmd); - + if (e->cmd == NULL) { + warn("strdup(\"%d\")", cmd); + env_free(e->envp); + ecode = e_mem; + goto eof; + } Debug(DPARS, ("load_entry()...returning successfully\n")) /* success, fini, return pointer to the entry we just created... diff --git a/usr.sbin/cron/lib/misc.c b/usr.sbin/cron/lib/misc.c index eca9604bafc1..f8538ea3f346 100644 --- a/usr.sbin/cron/lib/misc.c +++ b/usr.sbin/cron/lib/misc.c @@ -463,34 +463,39 @@ log_it(username, xpid, event, detail) + strlen(detail) + MAX_TEMPSTR); - if (LogFD < OK) { - LogFD = open(LOG_FILE, O_WRONLY|O_APPEND|O_CREAT, 0600); + if (msg == NULL) + warnx("failed to allocate memory for log message"); + else { if (LogFD < OK) { - warn("can't open log file %s", LOG_FILE); - } else { - (void) fcntl(LogFD, F_SETFD, 1); + LogFD = open(LOG_FILE, O_WRONLY|O_APPEND|O_CREAT, 0600); + if (LogFD < OK) { + warn("can't open log file %s", LOG_FILE); + } else { + (void) fcntl(LogFD, F_SETFD, 1); + } } + + /* we have to sprintf() it because fprintf() doesn't always + * write everything out in one chunk and this has to be + * atomically appended to the log file. + */ + sprintf(msg, "%s (%02d/%02d-%02d:%02d:%02d-%d) %s (%s)\n", + username, + t->tm_mon+1, t->tm_mday, t->tm_hour, t->tm_min, + t->tm_sec, pid, event, detail); + + /* we have to run strlen() because sprintf() returns (char*) + * on old BSD. + */ + if (LogFD < OK || write(LogFD, msg, strlen(msg)) < OK) { + if (LogFD >= OK) + warn("%s", LOG_FILE); + warnx("can't write to log file"); + write(STDERR, msg, strlen(msg)); + } + + free(msg); } - - /* we have to sprintf() it because fprintf() doesn't always write - * everything out in one chunk and this has to be atomically appended - * to the log file. - */ - sprintf(msg, "%s (%02d/%02d-%02d:%02d:%02d-%d) %s (%s)\n", - username, - t->tm_mon+1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec, pid, - event, detail); - - /* we have to run strlen() because sprintf() returns (char*) on old BSD - */ - if (LogFD < OK || write(LogFD, msg, strlen(msg)) < OK) { - if (LogFD >= OK) - warn("%s", LOG_FILE); - warnx("can't write to log file"); - write(STDERR, msg, strlen(msg)); - } - - free(msg); #endif /*LOG_FILE*/ #if defined(SYSLOG) @@ -603,7 +608,8 @@ mkprints(src, len) { register char *dst = malloc(len*4 + 1); - mkprint(dst, src, len); + if (dst != NULL) + mkprint(dst, src, len); return dst; }