Patchwork 4 bytes kernel memory disclosure in SO_BSDCOMPAT gsopt try #2

login
register
mail settings
Submitter Clement LECIGNE
Date Feb. 12, 2009, 12:35 p.m.
Message ID <20090212123545.GA46788@clem1.netasq.com>
Download mbox | patch
Permalink /patch/23013/
State Accepted
Delegated to: David Miller
Headers show

Comments

Clement LECIGNE - Feb. 12, 2009, 12:35 p.m.
Hi,

In function sock_getsockopt() located in net/core/sock.c, optval v.val
is not correctly initialized and directly returned in userland in case
we have SO_BSDCOMPAT option set.

This dummy code should trigger the bug:

int main(void)
{
	unsigned char buf[4] = { 0, 0, 0, 0 };
	int len;
	int sock;
	sock = socket(33, 2, 2);
	getsockopt(sock, 1, SO_BSDCOMPAT, &buf, &len);
	printf("%x%x%x%x\n", buf[0], buf[1], buf[2], buf[3]);
	close(sock);
}

Here is a patch that fix this bug by initalizing v.val just after its declaration.


Signed-off-by: Clément Lecigne <clement.lecigne@netasq.com>
David Miller - Feb. 13, 2009, 12:59 a.m.
From: Clement LECIGNE <clement.lecigne@netasq.com>
Date: Thu, 12 Feb 2009 13:35:45 +0100

> In function sock_getsockopt() located in net/core/sock.c, optval v.val
> is not correctly initialized and directly returned in userland in case
> we have SO_BSDCOMPAT option set.
> 
> This dummy code should trigger the bug:
> 
> int main(void)
> {
> 	unsigned char buf[4] = { 0, 0, 0, 0 };
> 	int len;
> 	int sock;
> 	sock = socket(33, 2, 2);
> 	getsockopt(sock, 1, SO_BSDCOMPAT, &buf, &len);
> 	printf("%x%x%x%x\n", buf[0], buf[1], buf[2], buf[3]);
> 	close(sock);
> }
> 
> Here is a patch that fix this bug by initalizing v.val just after its declaration.

Applied, thank you.
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Patch

--- linux/net/core/sock.c.orig	2008-12-12 12:27:46.000000000 -0800
+++ linux/net/core/sock.c	2008-12-12 12:27:50.000000000 -0800
@@ -695,6 +695,8 @@  int sock_getsockopt(struct socket *sock,
 	if (len < 0)
 		return -EINVAL;
 
+	v.val = 0;
+
 	switch(optname) {
 	case SO_DEBUG:
 		v.val = sock_flag(sk, SOCK_DBG);