Bug 2779

Summary: busybox crond: crontab -e edit results in crontab being moved/renamed
Product: Busybox Reporter: Matt Smith <mcs>
Component: OtherAssignee: unassigned
Status: RESOLVED WONTFIX    
Severity: normal CC: busybox-cvs
Priority: P5    
Version: 1.17.x   
Target Milestone: ---   
Hardware: PC   
OS: Linux   
Host: Target:
Build:

Description Matt Smith 2010-11-07 04:03:51 UTC
Originally reported by Luke Stuart here:
http://redmine.alpinelinux.org/issues/436

Essentially what happens is:
- You execute "crontab -e" (as root, for instance)
- Make changes or not: Once the editor is closed, the file /etc/crontabs/cron.update is created with the content "root" (because we edited the root crontab).
- Once crond spots the cron.update file, crond will read through it and see that /etc/crontabs/root essentially needs to be re-read and updated internally.  In the process, crond will remove the cron.update file.

What's happens next:
- /etc/crontabs/root gets moved to /var/spool/cron/cron.root.PID

Result:
Next time crond re-/starts, you have no root crontab!

The trigger:
Simply having the cron.update file; for instance:
# echo "root" > /etc/crontabs/cron.update


To see what's going on, I edited busybox-1.17.3/miscutils/crond.c:
Sample code from ForkJob() - 7 parameters:

816:		rename(mail_filename, mailFile2); // TODO: xrename?
817: +		crondlog(LVL8 "RENAME: mail_filename=%s (old) -> mailFile2=%s (new)", mail_filename, mailFile2);
819:	}


Now, I see the following log messages:

Nov  6 22:03:28 alpine-dev user.info crond[10166]: crond: crond (busybox 1.17.3) started, log level 8
Nov  6 22:15:01 alpine-dev user.info crond[10166]: crond: RENAME: mail_filename=root (old) -> mailFile2=/var/spool/cron/cron.root.10253 (new)
Nov  6 22:15:01 alpine-dev user.info crond[10166]: crond: USER root pid 10253 cmd run-parts /etc/periodic/15min
Nov  6 22:30:01 alpine-dev user.info crond[10166]: crond: RENAME: mail_filename=/var/spool/cron/cron.root.10253 (old) -> mailFile2=/var/spool/cron/cron.root.10283 (new)
Nov  6 22:30:01 alpine-dev user.info crond[10166]: crond: USER root pid 10283 cmd run-parts /etc/periodic/15min
Nov  6 22:45:01 alpine-dev user.info crond[10166]: crond: RENAME: mail_filename=/var/spool/cron/cron.root.10283 (old) -> mailFile2=/var/spool/cron/cron.root.10287 (new)
Nov  6 22:45:01 alpine-dev user.info crond[10166]: crond: USER root pid 10287 cmd run-parts /etc/periodic/15min


Which I don't really understand the first rename from "root" to "cron.root.10253," because line 853 (crond.c) is:
ForkJob(user, line, mailFd, DEFAULT_SHELL, "-c", line->cl_Shell, mailFile);

Where mailFile is set on line 839 like so:
snprintf(mailFile, sizeof(mailFile), "%s/cron.%s.%d", TMPDIR, user, getpid());

How "%s/cron.%s.%d" becomes "root" is beyond me... but maybe I'm missing something.
Comment 1 Matt Smith 2010-11-07 04:20:10 UTC
I should maybe mention that my 1-line log patch bumps the line numbers that follow by one.
Comment 2 Timo Teräs 2011-01-06 06:30:28 UTC
Seems like in busybox-1.18.x and later the relevant code was rewritten and those do not have this bug.

It seems that my patch, available at http://git.alpinelinux.org/cgit/aports/tree/main/busybox/busybox-1.17.4-crond.patch, fixes this issue. You might consider adding this to busybox-1.17.x hot fixes.
Comment 4 Denys Vlasenko 2012-01-10 17:15:19 UTC
I think 1.17.x is a bit too old to continue releasing bugfix releases for it. Closing the bug as WONTFIX (meaning "will not fix in 1.17.x").