Skip to content

Commit

Permalink
net: add validation for the socket syscall protocol argument
Browse files Browse the repository at this point in the history
郭永刚 reported that one could simply crash the kernel as root by
using a simple program:

	int socket_fd;
	struct sockaddr_in addr;
	addr.sin_port = 0;
	addr.sin_addr.s_addr = INADDR_ANY;
	addr.sin_family = 10;

	socket_fd = socket(10,3,0x40000000);
	connect(socket_fd , &addr,16);

AF_INET, AF_INET6 sockets actually only support 8-bit protocol
identifiers. inet_sock's skc_protocol field thus is sized accordingly,
thus larger protocol identifiers simply cut off the higher bits and
store a zero in the protocol fields.

This could lead to e.g. NULL function pointer because as a result of
the cut off inet_num is zero and we call down to inet_autobind, which
is NULL for raw sockets.

kernel: Call Trace:
kernel:  [<ffffffff816db90e>] ? inet_autobind+0x2e/0x70
kernel:  [<ffffffff816db9a4>] inet_dgram_connect+0x54/0x80
kernel:  [<ffffffff81645069>] SYSC_connect+0xd9/0x110
kernel:  [<ffffffff810ac51b>] ? ptrace_notify+0x5b/0x80
kernel:  [<ffffffff810236d8>] ? syscall_trace_enter_phase2+0x108/0x200
kernel:  [<ffffffff81645e0e>] SyS_connect+0xe/0x10
kernel:  [<ffffffff81779515>] tracesys_phase2+0x84/0x89

I found no particular commit which introduced this problem.

CVE: CVE-2015-8543
Cc: Cong Wang <cwang@twopensource.com>
Reported-by: 郭永刚 <guoyonggang@360.cn>
Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
strssndktn authored and davem330 committed Dec 14, 2015
1 parent 20b08e1 commit 79462ad
Show file tree
Hide file tree
Showing 6 changed files with 16 additions and 0 deletions.
1 change: 1 addition & 0 deletions include/net/sock.h
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,7 @@ struct sock {
sk_no_check_rx : 1,
sk_userlocks : 4,
sk_protocol : 8,
#define SK_PROTOCOL_MAX U8_MAX
sk_type : 16;
kmemcheck_bitfield_end(flags);
int sk_wmem_queued;
Expand Down
3 changes: 3 additions & 0 deletions net/ax25/af_ax25.c
Original file line number Diff line number Diff line change
Expand Up @@ -805,6 +805,9 @@ static int ax25_create(struct net *net, struct socket *sock, int protocol,
struct sock *sk;
ax25_cb *ax25;

if (protocol < 0 || protocol > SK_PROTOCOL_MAX)
return -EINVAL;

if (!net_eq(net, &init_net))
return -EAFNOSUPPORT;

Expand Down
3 changes: 3 additions & 0 deletions net/decnet/af_decnet.c
Original file line number Diff line number Diff line change
Expand Up @@ -678,6 +678,9 @@ static int dn_create(struct net *net, struct socket *sock, int protocol,
{
struct sock *sk;

if (protocol < 0 || protocol > SK_PROTOCOL_MAX)
return -EINVAL;

if (!net_eq(net, &init_net))
return -EAFNOSUPPORT;

Expand Down
3 changes: 3 additions & 0 deletions net/ipv4/af_inet.c
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,9 @@ static int inet_create(struct net *net, struct socket *sock, int protocol,
int try_loading_module = 0;
int err;

if (protocol < 0 || protocol >= IPPROTO_MAX)
return -EINVAL;

sock->state = SS_UNCONNECTED;

/* Look for the requested type/protocol pair. */
Expand Down
3 changes: 3 additions & 0 deletions net/ipv6/af_inet6.c
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,9 @@ static int inet6_create(struct net *net, struct socket *sock, int protocol,
int try_loading_module = 0;
int err;

if (protocol < 0 || protocol >= IPPROTO_MAX)
return -EINVAL;

/* Look for the requested type/protocol pair. */
lookup_protocol:
err = -ESOCKTNOSUPPORT;
Expand Down
3 changes: 3 additions & 0 deletions net/irda/af_irda.c
Original file line number Diff line number Diff line change
Expand Up @@ -1086,6 +1086,9 @@ static int irda_create(struct net *net, struct socket *sock, int protocol,
struct sock *sk;
struct irda_sock *self;

if (protocol < 0 || protocol > SK_PROTOCOL_MAX)
return -EINVAL;

if (net != &init_net)
return -EAFNOSUPPORT;

Expand Down

0 comments on commit 79462ad

Please sign in to comment.