oss-sec mailing list archives

Re: Vixie/ISC Cron group crontab to root escalation


From: Solar Designer <solar () openwall com>
Date: Fri, 9 Jun 2017 18:27:29 +0200

On Fri, Jun 09, 2017 at 11:47:55AM -0400, Christos Zoulas wrote:
In this patch:
http://cvsweb.openwall.com/cgi/cvsweb.cgi/Owl/packages/vixie-cron/vixie-cron-4.1.20040916-owl-crond.diff

Why do:

+     if (lstat(tabname, &lstatbuf) < OK) {
+             log_it(fname, getpid(), "CAN'T LSTAT", tabname);
+             goto next_crontab;
+     }
+     if (!S_ISREG(lstatbuf.st_mode)) {
+             log_it(fname, getpid(), "NOT REGULAR", tabname);
+             goto next_crontab;
+     }
+     if ((!pw && (lstatbuf.st_mode & 07533) != 0400) ||
+         (pw && (lstatbuf.st_mode & 07577) != 0400)) {
+             log_it(fname, getpid(), "BAD FILE MODE", tabname);
+             goto next_crontab;
+     }
+     if (lstatbuf.st_nlink != 1) {
+             log_it(fname, getpid(), "BAD LINK COUNT", tabname);
+             goto next_crontab;
+     }
+
      if ((crontab_fd = open(tabname, O_RDONLY|O_NONBLOCK|O_NOFOLLOW, 0)) < OK) {
              /* crontab not accessible?
               */

Instead of doing the open first and then fstat(2) to prevent TOCTOU?

Oh, I did in fact mention this in the private discussion, so I'll quote:

| Another detail: somehow in Owl we introduced lstat() prior to open, and
| check lstat()'s struct for all the required properties before proceeding
| with open() with O_NOFOLLOW.  Then we check that st_dev/st_ino stayed
| the same.  We also kept the post-open() checks.  I don't recall exactly
| why we added this, but maybe because of the possibility of side-effects
| on open() for hard links to device files (like with tape drives).  And
| it looks like we neglected to add the same for at jobs (perhaps didn't
| revisit this when support for at jobs appeared via our update to later
| OpenBSD code) - maybe we should.

Alexander


Current thread: