|
Vulnerability top Affected OpenBSD, FreeBSD Description Following is based on a FreeBSD-SA-00:62 Security Advisory and it was originally found by vort via OpenBSD. top is a utility for displaying current system resource statistics such as process CPU and memory use. It is externally-maintained, contributed software which is included in *BSD by default. A "format string vulnerability" was discovered in the top(1) utility which allows unprivileged local users to cause the top process to execute arbitrary code. The top utility runs with increased privileges as a member of the kmem group, which allows it to read from kernel memory (but not write to it). A process with the ability to read from kernel memory can monitor privileged data such as network traffic, disk buffers and terminal activity, and may be able to leverage this to obtain further privileges on the local system or on other systems, including root privileges. All released versions of FreeBSD prior to the correction date including 4.0, 4.1, 4.1.1 and 3.5.1 are vulnerable to this problem, but it was fixed in the 4.1.1-STABLE branch prior to the release of FreeBSD 4.2-RELEASE. This has been fixed in OpenBSD 2.7 is some patch. Local users can read privileged data from kernel memory which may provide information allowing them to further increase their local or remote system access privileges. Solution Remove the setgid bit on the top utilities. This has the side-effect that users who are not a member of the kmem group or who are not the superuser cannot use the top utility. For FreeBSD: 1) Upgrade your vulnerable FreeBSD system to 4.1.1-STABLE or 3.5.1-STABLE after the respective correction dates 2000/10/04 (FreeBSD 4.1.1-STABLE) and 2000/10/04 (FreeBSD 3.5.1-STABLE) 2) Apply the patch below and recompile the relevant files: # cd /usr/src/contrib/top # patch -p < /path/to/patch_or_advisory # cd /usr/src/usr.bin/top # make depend && make all install Index: display.c =================================================================== RCS file: /mnt/ncvs/src/contrib/top/display.c,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- display.c 1999/01/09 20:20:33 1.4 +++ display.c 2000/10/04 23:34:16 1.5 @@ -829,7 +831,7 @@ register int i; /* first, format the message */ - (void) sprintf(next_msg, msgfmt, a1, a2, a3); + (void) snprintf(next_msg, sizeof(next_msg), msgfmt, a1, a2, a3); if (msglen > 0) { Index: top.c =================================================================== RCS file: /mnt/ncvs/src/contrib/top/top.c,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- top.c 1999/01/09 20:20:34 1.4 +++ top.c 2000/10/04 23:34:16 1.5 @@ -807,7 +809,7 @@ { if ((errmsg = kill_procs(tempbuf2)) != NULL) { - new_message(MT_standout, errmsg); + new_message(MT_standout, "%s", errmsg); putchar('\r'); no_command = Yes; } Index: top.c =================================================================== RCS file: /mnt/ncvs/src/contrib/top/top.c,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- top.c 2000/10/04 23:34:16 1.5 +++ top.c 2000/11/03 22:00:10 1.6 @@ -826,7 +826,7 @@ { if ((errmsg = renice_procs(tempbuf2)) != NULL) { - new_message(MT_standout, errmsg); + new_message(MT_standout, "%s", errmsg); putchar('\r'); no_command = Yes; }