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);