Description of problem: When cron runs the chkrootkit job, it is aborting while performing the command ./chkutmp, because of stack smashing (it says).
Version-Release number of selected component (if applicable):
How reproducible: Not sure, have noticed it for two days now
Steps to Reproduce:
1. Install chkrootkit
2. Monitor email
*** stack smashing detected ***: ./chkutmp terminated
======= Backtrace: =========
======= Memory map: ========
00400000-00402000 r-xp 00000000 08:05 263941
00601000-00602000 rw-p 00001000 08:05 263941
01b14000-01b35000 rw-p 01b14000 00:00 0 [heap]
3d64400000-3d6441f000 r-xp 00000000 08:05 148732 /lib64/ld-2.10.1.so
3d6461e000-3d6461f000 r--p 0001e000 08:05 148732 /lib64/ld-2.10.1.so
3d6461f000-3d64620000 rw-p 0001f000 08:05 148732 /lib64/ld-2.10.1.so
3d64800000-3d64964000 r-xp 00000000 08:05 148733 /lib64/libc-2.10.1.so
3d64964000-3d64b64000 ---p 00164000 08:05 148733 /lib64/libc-2.10.1.so
3d64b64000-3d64b68000 r--p 00164000 08:05 148733 /lib64/libc-2.10.1.so
3d64b68000-3d64b69000 rw-p 00168000 08:05 148733 /lib64/libc-2.10.1.so
3d64b69000-3d64b6e000 rw-p 3d64b69000 00:00 0
3d71e00000-3d71e19000 r-xp 00000000 08:05 148800
3d71e19000-3d72019000 ---p 00019000 08:05 148800
3d72019000-3d7201a000 rw-p 00019000 08:05 148800
7f43276f2000-7f43276f4000 rw-p 7f43276f2000 00:00 0
7f4327769000-7f432776b000 rw-p 7f4327769000 00:00 0
7fffe1a92000-7fffe1c04000 rw-p 7fffffe8d000 00:00 0 [stack]
7fffe1c90000-7fffe1c91000 r-xp 7fffe1c90000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
/usr/lib64/chkrootkit-0.48/chkrootkit: line 172: 21136 Aborted ./chkutmp
Finish without problem
This works fine for me on 32-bit. What if you run /usr/lib64/chkrootkit-0.48/chkutmp manually?
Created attachment 354566 [details]
fix buffer overflow in chkutmp
Yes, please run
sudo debuginfo-install chkrootkit
and execute chkutmp manually within gdb to get a detailed backtrace:
There's at least one array out of bounds bug in chkutmp, perhaps even the one fixed by attached patch.
This is only hitting 64-bit, not 32. I've committed and built in rawhide, please test.
Created attachment 354575 [details]
fix another out of bounds condition
It can hit all archs, provided that enough data is found.
This second patch fixes another out of bounds condition. Since the functions
y = fetchps(ps_l);
z = fetchutmp(ut_l);
return the number of entries found, the subsequent for-loop must end at "< y" and "< z" not "<=".
Not sure what I should do now. Do I still need to run anything? It seems you have the problem on the run (if not actually fixed) already.
Per Michael Schwendt, here is the gdb output, though somewhat disappointing.
~ 02:07 PM root 2
# gdb /usr/lib64/chkrootkit-0.48/chkutmp
Starting program: /usr/lib64/chkrootkit-0.48/chkutmp
Detaching after fork from child process 22407.
Program exited normally.
I ran gdb chkrootkit when this came up empty.
The only result that was questionable was
Checking `bindshell'... INFECTED (PORTS: 4000)
The results for chkutmp from running chkrootkit were:
Checking `chkutmp'... The tty of the following user process(es) were not found
in /var/run/utmp !
! RUID PID TTY CMD
! 0 0 1600000147130020 --sm-config-prefix /resapplet-AZ2EwY/ --sm-client-id 10b84d4c1a73c8fd51124786929946981600000147130020 --screen 0 --sm-config-prefix /resapplet-EBxK3J/ --sm-client-id 10b84d4c1a73c8fd51124786929946981600000147130020 --screen 0
chkutmp: nothing deleted
Program exited normally.
Seems the problem has disappeared.
> Program exited normally.
No crash, nothing to debug. ;) That's why reproducibility is important. As soon as one encounters a crash, one should install as many missing -debuginfo packages as possible and get a detailed backtrace.
> Checking `bindshell'... INFECTED (PORTS: 4000)
> False positive???
If you can reproduce it, examine your machine with netstat (as chkrootkit does, too) to see what's using that port. chkrootkit is not bullet-proof, it's just a helper. The more authorized stuff that is running while chkrootkit is being run, the more false positives you can get.
> Checking `chkutmp'... The tty of the following user process(es) were not found in /var/run/utmp !
> ! RUID PID TTY CMD
> ! 0 0 1600000147130020 --sm-config-prefix /resapplet-AZ2EwY/
The value for TTY looks odd, but since the unpatched chkutmp doesn't get the line-count right, this may be symptoms of that bug.
Btw, there are more C coding bugs in chkutmp. The author has got all for-loops wrong. The four more in fetchps() should end at "x < UT_LINESIZE" (three times) and "x < MAXLENGTH", respectively. And even then it exceeds the array bounds when placing a delimiter. The only reason this sloppy coding doesn't overflow the local stack often is that the input data satisfy the additional end-conditions of the loops (that stop at white-space as well as string-end).
d = curp->ps_tty;
for (x = 0; (!isspace(*s)) && (*d++ = *s++) && x <= UT_LINESIZE; x++) /* grab tty */
*d = '\0';
So, what this does is it copies a column from a "ps" line into an array (from s to d):
UT_LINESIZE is 12. It must only write destination pointer d for x from 0 to 11, which is UT_LINESIZE-1 (or x < UT_LINESIZE). Not x <= UT_LINESIZE. With unexpected input, the loop can copy at most 13 chars, two more than fit into the array if one considers the ending zero. First mistake.
However, there are two other end-conditions before that: The !isspace() check only copies non-whitespace characters. If the typical TTY column in ps output is less than 12 characters wide, luck has it that the loop would never overflow the array and stop when it finds space characters.
There's a second mistake. After the for-loop, a string delimiter \0 is appended, disregarding the array size (because the loop may have filled the array with 12 characters already). And the third end-condition? The for-loop terminates when the copied character was zero -- a condition that will be true at the end of the ps line, but it still advances the destination pointer. Afterwards, it appends zero once more. And again, d may have advanced beyond the array end.
Created attachment 354664 [details]
fix column size in ps/utmp structs
A lazy fix for the problem described in the previous comment could look like this and simply increase the max.size of the copied columns +2 to allow for the wrong for-loop end condition and the appended zero.
Patched committed and built in rawhide, let's run this one up the flagpole and see who salutes:
I see the koji build is for F12. Is there any chance this will make it into F11?
After seeing all the coding errors Michael has found, I would like to get the improved version. :-)
If it happens again, I'll run gdb looking for a backtrace. But I see this in the email to root, usually hours after it has happened from the cron job, so I'm not likely to catch anything. I'll try occasionally running gdb chkrootkit at random times to see if I can catch it.
It is beagled listening on port 4000.
Of course. If Michael find no further fault, I'll build for F-11. If he does, I'll patch again. :)
sudo rpm -Uvh http://kojipkgs.fedoraproject.org/packages/chkrootkit/0.48/13.fc12/x86_64/chkrootkit-0.48-13.fc12.x86_64.rpm
It works with Fedora 11 and the i686 build.
chkrootkit-0.48-13.fc11 has been submitted as an update for Fedora 11.
I installed the fc12 package. I've run it a couple of times with no result. When the fc11 package shows up in updates or updates-testing, I'll remove the fc12 package and install the fc11 version.
I'll still run tests to see if I can catch the problem.
You can get it from Koji now:
chkrootkit-0.48-13.fc11 has been pushed to the Fedora 11 testing repository. If problems still persist, please make note of it in this bug report.
If you want to test the update, you can install it with
su -c 'yum --enablerepo=updates-testing update chkrootkit'. You can provide feedback for this update here: http://admin.fedoraproject.org/updates/F11/FEDORA-2009-7968
chkrootkit-0.48-13.fc11 has been pushed to the Fedora 11 stable repository. If problems still persist, please make note of it in this bug report.