On Tue, May 10, 2011 at 08:46:04AM -0400, Kenneth R Westerback wrote: > On Tue, May 10, 2011 at 06:57:29AM +0200, Otto Moerbeek wrote: > > On Mon, May 09, 2011 at 08:51:01PM -0400, Lawrence Teo wrote: > > > > > In the load_entry() function in cron's entry.c, calloc() is called > > > but its return value is never checked to see if it is NULL, > > > potentially causing a NULL pointer dereference. Since crontab(1) > > > shares code with cron, it is affected as well. > > > > > > The following diff adds the check for NULL, and also moves the > > > cleanup code that addresses this condition to free_entry() in order > > > to remove duplicate code. > > > > > > Any thoughts or comments? > > > > Have to look in detail for the stuctural changes, but free(NULL) has > > ben OK for ages. > > > > -Otto > > > > Ditto. I think the calloc() return value check is good as e is referenced > in following code. But free_entry should be ok if you ensure you don't > pass it NULL. > > .... Ken
Otto and Ken, Thank you for your helpful comments. I have revised the diff according to your feedback. I did include a check in free_entry() to ensure that e->envp is not NULL before passing it to env_free(), since env_free(NULL) would cause a segfault. In addition, I modified crontab.c to use free_entry(e) instead of free(e). This keeps the cleanup code for e consistent throughout the program. What do you think of the revised diff? Would appreciate your thoughts. Thank you, Lawrence Index: crontab.c =================================================================== RCS file: /cvs/src/usr.sbin/cron/crontab.c,v retrieving revision 1.61 diff -u -p -r1.61 crontab.c --- crontab.c 4 Apr 2011 15:17:52 -0000 1.61 +++ crontab.c 11 May 2011 01:40:11 -0000 @@ -547,7 +547,7 @@ replace_cmd(void) { case FALSE: e = load_entry(tmp, check_error, pw, envp); if (e) - free(e); + free_entry(e); break; case TRUE: break; Index: entry.c =================================================================== RCS file: /cvs/src/usr.sbin/cron/entry.c,v retrieving revision 1.32 diff -u -p -r1.32 entry.c --- entry.c 29 Oct 2009 18:56:47 -0000 1.32 +++ entry.c 11 May 2011 01:40:11 -0000 @@ -59,7 +59,8 @@ void free_entry(entry *e) { free(e->cmd); free(e->pwd); - env_free(e->envp); + if (e->envp) + env_free(e->envp); free(e); } @@ -103,6 +104,10 @@ load_entry(FILE *file, void (*error_func */ e = (entry *) calloc(sizeof(entry), sizeof(char)); + if (e == NULL) { + ecode = e_memory; + goto eof; + } if (ch == '@') { /* all of these should be flagged and load-limited; i.e., @@ -387,13 +392,8 @@ load_entry(FILE *file, void (*error_func return (e); eof: - if (e->envp) - env_free(e->envp); - if (e->pwd) - free(e->pwd); - if (e->cmd) - free(e->cmd); - free(e); + if (e) + free_entry(e); while (ch != '\n' && !feof(file)) ch = get_char(file); if (ecode != e_none && error_func)