[SRU] liblockfile buffer overflow with high pid numbers
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
liblockfile (Ubuntu) |
Fix Released
|
Medium
|
Tyler Hicks | ||
Precise |
Fix Released
|
Undecided
|
Unassigned | ||
Quantal |
Won't Fix
|
Undecided
|
Unassigned |
Bug Description
on our system (Ubuntu-Server 10.04) we set "sysctl -w kernel.pid_max = 4194304". When the pid counter is high, currently >3000000, then cron-apt terminates with a buffer overflow message:
root@sn:~# cron-apt
*** buffer overflow detected ***: dotlockfile terminated
======= Backtrace: =========
/lib/libc.
/lib/libc.
/lib/libc.
/lib/libc.
/lib/libc.
/lib/libc.
/lib/libc.
dotlockfile[
dotlockfile[
/lib/libc.
dotlockfile[
======= Memory map: ========
00400000-00403000 r-xp 00000000 fb:02 2104182 /usr/bin/
00602000-00603000 r--p 00002000 fb:02 2104182 /usr/bin/
00603000-00604000 rw-p 00003000 fb:02 2104182 /usr/bin/
01f80000-01fa1000 rw-p 00000000 00:00 0 [heap]
7f2ae8503000-
7f2ae8519000-
7f2ae8718000-
7f2ae8719000-
7f2ae871a000-
7f2ae8726000-
7f2ae8925000-
7f2ae8926000-
7f2ae8927000-
7f2ae8931000-
7f2ae8b30000-
7f2ae8b31000-
7f2ae8b32000-
7f2ae8b49000-
7f2ae8d48000-
7f2ae8d49000-
7f2ae8d4a000-
7f2ae8d4c000-
7f2ae8d54000-
7f2ae8f53000-
7f2ae8f54000-
7f2ae8f55000-
7f2ae90cf000-
7f2ae92ce000-
7f2ae92d2000-
7f2ae92d3000-
7f2ae92d8000-
7f2ae94eb000-
7f2ae94f5000-
7f2ae94f7000-
7f2ae94f8000-
7f2ae94f9000-
7fff43082000-
7fff431ff000-
ffffffffff60000
Aborted
root@sn:~# uname -a
Linux sn 2.6.35-32-server #68~lucid1-Ubuntu SMP Wed Mar 28 18:33:00 UTC 2012 x86_64 GNU/Linux
root@sn:~# ps
PID TTY TIME CMD
3722057 pts/5 00:00:00 bash
3925974 pts/5 00:00:00 ps
root@sn:~# strace -f -o out cron-apt
*** buffer overflow detected ***: dotlockfile terminated
======= Backtrace: =========
/lib/libc.
/lib/libc.
/lib/libc.
/lib/libc.
/lib/libc.
/lib/libc.
/lib/libc.
dotlockfile[
dotlockfile[
/lib/libc.
dotlockfile[
======= Memory map: ========
00400000-00403000 r-xp 00000000 fb:02 2104182 /usr/bin/
00602000-00603000 r--p 00002000 fb:02 2104182 /usr/bin/
00603000-00604000 rw-p 00003000 fb:02 2104182 /usr/bin/
01a13000-01a34000 rw-p 00000000 00:00 0 [heap]
7f27656a1000-
7f27656b7000-
7f27658b6000-
7f27658b7000-
7f27658b8000-
7f27658c4000-
7f2765ac3000-
7f2765ac4000-
7f2765ac5000-
7f2765acf000-
7f2765cce000-
7f2765ccf000-
7f2765cd0000-
7f2765ce7000-
7f2765ee6000-
7f2765ee7000-
7f2765ee8000-
7f2765eea000-
7f2765ef2000-
7f27660f1000-
7f27660f2000-
7f27660f3000-
7f276626d000-
7f276646c000-
7f2766470000-
7f2766471000-
7f2766476000-
7f2766689000-
7f2766693000-
7f2766695000-
7f2766696000-
7f2766697000-
7fff3660b000-
7fff36765000-
ffffffffff60000
Aborted
When we switch back to a small pid number e.g. by "sysctl -w kernel.pid_max = 32768" cron-apt works again. The Problem also just occurs if the pid counter reached high values. If pid_max is set high but the counter is still low the problem doesn't show up.
[Test Case]
The overflow occurs when the decimal representation of the PID value is 7 characters or higher. So, set pid_max to a value that is 7 characters long, run through PIDs until we get one that is at least 7 characters (the while loop may take a long time), then create a lock file containing the PID (building the string containing the PID is where the overflow occurs). Watch for the `echo $BASHPID` and `cat ${lock}.lock` to print out the same PID number and make sure that it is at least 7 characters long.
Note that this test case obviously depends on a bash'ism, so use bash or adjust it as necessary. :)
$ lock=/var/
$ lockfile-remove $lock
$ sudo sysctl -w kernel.
$ while ([ $BASHPID -lt 1000000 ]); do continue; done
$ (echo $BASHPID; lockfile-create $lock --use-pid; cat ${lock}.lock)
[Regression Potential]
Minimum. We've applied a patch to the same version of liblockfile in 13.04 and that has since been merged to debian with no reports of regressions.
Related branches
- Martin Pitt: Approve
-
Diff: 141 lines (+123/-0)3 files modifieddebian/changelog (+9/-0)
debian/patches/fix-buffer-overflows.patch (+113/-0)
debian/patches/series (+1/-0)
- James Page: Approve
- Ubuntu branches: Pending requested
-
Diff: 790 lines (+686/-10)6 files modified.pc/applied-patches (+1/-0)
.pc/fix-buffer-overflows.patch/lockfile.c (+542/-0)
debian/changelog (+9/-0)
debian/patches/fix-buffer-overflows.patch (+113/-0)
debian/patches/series (+1/-0)
lockfile.c (+20/-10)
affects: | cron-apt (Ubuntu) → liblockfile (Ubuntu) |
Changed in liblockfile (Ubuntu): | |
importance: | Undecided → Medium |
assignee: | nobody → Tyler Hicks (tyhicks) |
status: | New → In Progress |
summary: |
- cron-apt buffer overflow with high pid numbers + [SRU] liblockfile buffer overflow with high pid numbers |
description: | updated |
tags: | added: verification-done-precise |
the following patch on liblockfile's lockfile.c fixes the issue:
--- a/lockfile.c create( const char *lockfile, int retries, int flags) "-1844674407370 9551616" )+2];
+++ b/lockfile.c
@@ -175,7 +175,7 @@ int lockfile_
struct stat st, st1;
char *tmplock;
char sysname[256];
- char buf[8];
+ char buf[sizeof(
char *p;
int sleeptime = 0;
int statfailed = 0;
the fix was done by Stefan Metzmacher.
you should also have a look at this part of the code which looks like it can cause problems, too:
if ((tmplock = (char *)malloc( strlen( lockfile) +32+1)) == NULL)
return L_ERROR;
strcpy( tmplock, lockfile);
p++;
(int) getpid( ), (int)time(NULL) & 15, sysname);
if ((p = strrchr(tmplock, '/')) == NULL)
p = tmplock;
else
sprintf(p, ".lk%05d%x%s",