COMMAND
cron, crontab
SYSTEMS AFFECTED
FreeBSD 1.0, 1.1, 2.1.0, 2.1.5, 2.1.6, 2.1.6.1
PROBLEM
The programs in question store user-supplied information in
internal buffers. There is no range checking on length of the
data copied into these buffers. A malicious user may be able to
overflow these buffers through the use of command line options or
via enviornment variables and insert and execute their own code
fragment which could be used to obtain unauthorized access to the
system. The programs in question may be subverted to allow an
unprivileged user to gain root access to the system.
For some exploit code see crontab #1, #2 and #3 on this Security
Bugware page and for ppp see ppp.
SOLUTION
Remove setuid privileges:
crontab: # chmod ug-s /usr/bin/crontab
Also remove cron from rc and kill active.
The following patches fixes the vulnerabilities. It should
apply cleanly to all FreeBSD 2.1.x systems. It has not been
tested with FreeBSD 1.x.
After applying these patches, recompile and re-install the
affected utilities.
*** usr.sbin/cron/cron/database.c 1994/08/27 13:43:03 1.1.1.1
--- usr.sbin/cron/cron/database.c 1996/09/10 03:38:20 1.3
***************
*** 112,119 ****
if (dp->d_name[0] == '.')
continue;
! (void) strcpy(fname, dp->d_name);
! sprintf(tabname, CRON_TAB(fname));
process_crontab(fname, fname, tabname,
&statbuf, &new_db, old_db);
--- 112,119 ----
if (dp->d_name[0] == '.')
continue;
! (void)snprintf(fname, sizeof fname, "%s", dp->d_name);
! (void)snprintf(tabname, sizeof tabname, CRON_TAB(fname));
process_crontab(fname, fname, tabname,
&statbuf, &new_db, old_db);
*** usr.sbin/cron/crontab/crontab.c 1996/04/09 21:23:11 1.3.4.1
--- usr.sbin/cron/crontab/crontab.c 1996/08/05 00:50:02 1.6
***************
*** 167,173 ****
ProgramName, optarg);
exit(ERROR_EXIT);
}
! (void) strcpy(User, optarg);
break;
case 'l':
if (Option != opt_unknown)
--- 165,171 ----
ProgramName, optarg);
exit(ERROR_EXIT);
}
! (void) snprintf(User, sizeof(user), "%s", optarg);
break;
case 'l':
if (Option != opt_unknown)
***************
*** 198,204 ****
} else {
if (argv[optind] != NULL) {
Option = opt_replace;
! (void) strcpy (Filename, argv[optind]);
} else {
usage("file name must be specified for replace");
}
--- 196,203 ----
} else {
if (argv[optind] != NULL) {
Option = opt_replace;
! (void) snprintf(Filename, sizeof(Filename), "%s",
! argv[optind]);
} else {
usage("file name must be specified for replace");
}
***************
*** 480,486 ****
ProgramName, Filename);
goto done;
default:
! fprintf(stderr, "%s: panic: bad switch() in replace_cmd()\n");
goto fatal;
}
remove:
--- 479,486 ----
ProgramName, Filename);
goto done;
default:
! fprintf(stderr, "%s: panic: bad switch() in replace_cmd()\n",
! ProgramName);
goto fatal;
}
remove:
--- usr.sbin/cron/lib/env.c 1994/08/27 13:43:02 1.1.1.1
+++ usr.sbin/cron/lib/env.c 1996/12/16 18:11:57
@@ -115,7 +115,7 @@
{
long filepos;
int fileline;
- char name[MAX_TEMPSTR], val[MAX_ENVSTR];
+ char name[MAX_ENVSTR], val[MAX_ENVSTR];
int fields;
filepos = ftell(f);