Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f89e8a64 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'infoleaks'



Mathias Krause says:

====================
a few more info leak fixes in the recvmsg path. The error pattern here
is the protocol specific recvmsg function is missing the msg_namelen
assignment -- either completely or in early exit paths that do not
result in errors in __sys_recvmsg()/sys_recvfrom() and, in turn, make
them call move_addr_to_user(), leaking the then still uninitialized
sockaddr_storage stack variable to userland.

My audit was initiated by a rather coarse fix of the leak that can be
found in the grsecurity patch, putting a penalty on protocols complying
to the rules of recvmsg. So credits for finding the leak in the recvmsg
path in __sys_recvmsg() should go to Brad!

The buggy protocols/subsystems are rather obscure anyway. As a missing
assignment of msg_namelen coupled with a missing filling of msg_name
would only result in garbage -- the leak -- in case userland would care
about that information, i.e. would provide a msg_name pointer. But
obviously current userland does not.

While auditing the code for the above pattern I found a few more
'uninitialized members' kind of leaks related to the msg_name filling.
Those are fixed in this series, too.

I have to admit, I failed to test all of the patches due to missing
hardware, e.g. iucv depends on S390 -- hardware I've no access to :/
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 50a75a89 d5e0d0f6
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -531,6 +531,8 @@ int vcc_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
	struct sk_buff *skb;
	int copied, error = -EINVAL;

	msg->msg_namelen = 0;

	if (sock->state != SS_CONNECTED)
		return -ENOTCONN;

+1 −0
Original line number Diff line number Diff line
@@ -1642,6 +1642,7 @@ static int ax25_recvmsg(struct kiocb *iocb, struct socket *sock,
		ax25_address src;
		const unsigned char *mac = skb_mac_header(skb);

		memset(sax, 0, sizeof(struct full_sockaddr_ax25));
		ax25_addr_parse(mac + 1, skb->data - mac - 1, &src, NULL,
				&digi, NULL, NULL);
		sax->sax25_family = AF_AX25;
+2 −2
Original line number Diff line number Diff line
@@ -230,6 +230,8 @@ int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
	if (flags & (MSG_OOB))
		return -EOPNOTSUPP;

	msg->msg_namelen = 0;

	skb = skb_recv_datagram(sk, flags, noblock, &err);
	if (!skb) {
		if (sk->sk_shutdown & RCV_SHUTDOWN)
@@ -237,8 +239,6 @@ int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
		return err;
	}

	msg->msg_namelen = 0;

	copied = skb->len;
	if (len < copied) {
		msg->msg_flags |= MSG_TRUNC;
+1 −0
Original line number Diff line number Diff line
@@ -608,6 +608,7 @@ static int rfcomm_sock_recvmsg(struct kiocb *iocb, struct socket *sock,

	if (test_and_clear_bit(RFCOMM_DEFER_SETUP, &d->flags)) {
		rfcomm_dlc_accept(d);
		msg->msg_namelen = 0;
		return 0;
	}

+1 −0
Original line number Diff line number Diff line
@@ -665,6 +665,7 @@ static int sco_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
	    test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) {
		hci_conn_accept(pi->conn->hcon, 0);
		sk->sk_state = BT_CONFIG;
		msg->msg_namelen = 0;

		release_sock(sk);
		return 0;
Loading