| From: Mathias Krause <minipli@googlemail.com> |
| Date: Wed, 15 Aug 2012 11:31:53 +0000 |
| Subject: llc: fix info leak via getsockname() |
| |
| [ Upstream commit 3592aaeb80290bda0f2cf0b5456c97bfc638b192 ] |
| |
| The LLC code wrongly returns 0, i.e. "success", when the socket is |
| zapped. Together with the uninitialized uaddrlen pointer argument from |
| sys_getsockname this leads to an arbitrary memory leak of up to 128 |
| bytes kernel stack via the getsockname() syscall. |
| |
| Return an error instead when the socket is zapped to prevent the info |
| leak. Also remove the unnecessary memset(0). We don't directly write to |
| the memory pointed by uaddr but memcpy() a local structure at the end of |
| the function that is properly initialized. |
| |
| Signed-off-by: Mathias Krause <minipli@googlemail.com> |
| Cc: Arnaldo Carvalho de Melo <acme@ghostprotocols.net> |
| Signed-off-by: David S. Miller <davem@davemloft.net> |
| Signed-off-by: Ben Hutchings <ben@decadent.org.uk> |
| --- |
| net/llc/af_llc.c | 3 +-- |
| 1 file changed, 1 insertion(+), 2 deletions(-) |
| |
| diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c |
| index a18e6c3..99a60d5 100644 |
| --- a/net/llc/af_llc.c |
| +++ b/net/llc/af_llc.c |
| @@ -966,14 +966,13 @@ static int llc_ui_getname(struct socket *sock, struct sockaddr *uaddr, |
| struct sockaddr_llc sllc; |
| struct sock *sk = sock->sk; |
| struct llc_sock *llc = llc_sk(sk); |
| - int rc = 0; |
| + int rc = -EBADF; |
| |
| memset(&sllc, 0, sizeof(sllc)); |
| lock_sock(sk); |
| if (sock_flag(sk, SOCK_ZAPPED)) |
| goto out; |
| *uaddrlen = sizeof(sllc); |
| - memset(uaddr, 0, *uaddrlen); |
| if (peer) { |
| rc = -ENOTCONN; |
| if (sk->sk_state != TCP_ESTABLISHED) |