All of lore.kernel.org
 help / color / mirror / Atom feed
From: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
To: Dmitry Vyukov <dvyukov@google.com>
Cc: Neil Horman <nhorman@tuxdriver.com>,
	Vlad Yasevich <vyasevich@gmail.com>,
	"David S. Miller" <davem@davemloft.net>,
	linux-sctp@vger.kernel.org, netdev <netdev@vger.kernel.org>,
	LKML <linux-kernel@vger.kernel.org>,
	syzkaller <syzkaller@googlegroups.com>,
	Kostya Serebryany <kcc@google.com>,
	Alexander Potapenko <glider@google.com>,
	Sasha Levin <sasha.levin@oracle.com>,
	Eric Dumazet <edumazet@google.com>
Subject: Re: net/sctp: out-of-bounds access in sctp_add_bind_addr
Date: Mon, 25 Jan 2016 14:48:02 +0000	[thread overview]
Message-ID: <20160125144802.GA6602@mrl.redhat.com> (raw)
In-Reply-To: <CACT4Y+Z36GoxiRDQdFeVNkEvdRvmTXZC47cRM=TA1FCM+vCDcg@mail.gmail.com>

On Mon, Jan 25, 2016 at 03:42:14PM +0100, Dmitry Vyukov wrote:
> On Mon, Jan 25, 2016 at 3:31 PM, Neil Horman <nhorman@tuxdriver.com> wrote:
> > On Mon, Jan 25, 2016 at 03:02:38PM +0100, Dmitry Vyukov wrote:
> >> Hello,
> >>
> >> I've git the following error report while running syzkaller fuzzer:
> >>
> >> =================================
> >> BUG: KASAN: slab-out-of-bounds in memcpy+0x1d/0x40 at addr ffff88006c6361e8
> >> Read of size 28 by task syz-executor/12551
> >> ======================================> >> BUG kmalloc-16 (Not tainted): kasan: bad access detected
> >> -----------------------------------------------------------------------------
> >>
> >> INFO: Allocated in sctp_setsockopt_bindx+0xd2/0x3e0 age\x12 cpu=2 pid\x12551
> >> [<     inline     >] kmalloc include/linux/slab.h:468
> >> [<      none      >] sctp_setsockopt_bindx+0xd2/0x3e0 net/sctp/socket.c:975
> >> [<      none      >] sctp_setsockopt+0x1493/0x3630 net/sctp/socket.c:3711
> >> [<      none      >] sock_common_setsockopt+0x97/0xd0 net/core/sock.c:2620
> >> [<     inline     >] SYSC_setsockopt net/socket.c:1752
> >> [<      none      >] SyS_setsockopt+0x15b/0x250 net/socket.c:1731
> >> [<      none      >] entry_SYSCALL_64_fastpath+0x16/0x7a
> >> arch/x86/entry/entry_64.S:185
> >>
> >> INFO: Slab 0xffffea0001b18d80 objects\x16 used=4 fp=0xffff88006c6376e0
> >> flags=0x5fffc0000004080
> >> INFO: Object 0xffff88006c6361e8 @offsetH8 fp=0x0000000000000002
> >> Bytes b4 ffff88006c6361d8: 00 00 00 00 00 00 00 00 2f 98 34 88 ff ff
> >> ff ff  ......../.4.....
> >> Object ffff88006c6361e8: 02 00 00 00 00 00 00 00 02 00 ab 07 7f 00 00
> >> 01  ................
> >> CPU: 2 PID: 12551 Comm: syz-executor Tainted: G    B           4.5.0-rc1+ #278
> >> Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
> >>  00000000ffffffff ffff880036397928 ffffffff8299a02d ffff88003e807900
> >>  ffff88006c6361e8 ffff88006c636000 ffff880036397958 ffffffff81752814
> >>  ffff88003e807900 ffffea0001b18d80 ffff88006c6361e8 ffff88006c6361e8
> >>
> >> Call Trace:
> >>  [<ffffffff8175ad54>] __asan_loadN+0x124/0x1a0 mm/kasan/kasan.c:512
> >>  [<ffffffff8175b2dd>] memcpy+0x1d/0x40 mm/kasan/kasan.c:297
> >>  [<ffffffff85dcb249>] sctp_add_bind_addr+0xa9/0x270 net/sctp/bind_addr.c:162
> >>  [<ffffffff85dcfd66>] sctp_do_bind+0x336/0x580 net/sctp/socket.c:389
> >>  [<ffffffff85dd16ec>] sctp_bindx_add+0xac/0x1a0 net/sctp/socket.c:471
> >>  [<ffffffff85dd5cc8>] sctp_setsockopt_bindx+0x2f8/0x3e0 net/sctp/socket.c:1010
> >>  [<ffffffff85dde283>] sctp_setsockopt+0x1493/0x3630 net/sctp/socket.c:3711
> >>  [<ffffffff851f5ae7>] sock_common_setsockopt+0x97/0xd0 net/core/sock.c:2620
> >>  [<     inline     >] SYSC_setsockopt net/socket.c:1752
> >>  [<ffffffff851f2c3b>] SyS_setsockopt+0x15b/0x250 net/socket.c:1731
> >>  [<ffffffff863595f6>] entry_SYSCALL_64_fastpath+0x16/0x7a
> >> arch/x86/entry/entry_64.S:185
> >>
> >> Memory state around the buggy address:
> >>  ffff88006c636080: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
> >>  ffff88006c636100: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
> >> >ffff88006c636180: fc fc fc fc fc fc fc fc fc fc fc fc fc 00 00 fc
> >>                                                                 ^
> >>  ffff88006c636200: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
> >>  ffff88006c636280: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
> >> =================================
> >>
> >>
> >> sctp_setsockopt_bindx verifies that the user-passed address has valid
> >> len for the specified family, but then sctp_add_bind_addr copies whole
> >> sctp_addr from there. This causes heap out-of-bounds access and can
> >> crash kernel. Not sure if it is possible to copy out the trailing
> >> garbage to user-space later.
> >>
> >
> > It does more than that though.  sctp_setsockopt_bindx checks the following:
> > 1) That passed addr_size is greater than zero
> > 2) that the entire range of memory between addrs and addrs+addr_size is readable
> > 3) That at least one address structure worth of data is available (implicit in
> > the while (walk_size < addr_size) loop).
> >
> > Could one of the sockaddr_len fields in one of the addresses have been mangled
> > so that it appeared shorter in the the while loop from (3), so that a copy of
> > sizeof(sctp_addr in sctp_add_bind_addr overrun the allocated memory?
> 
> I may be missing something, but what I see is:
> 
> 1. we check that there is at least family:
> if (walk_size + sizeof(sa_family_t) > addrs_size) {
> 
> 2. get family descriptor:
> af = sctp_get_af_specific(sa_addr->sa_family);
> 
> 3. check that the address size is enough to hold the declared family:
> if (!af || (walk_size + af->sockaddr_len) > addrs_size) {
> 
> 4. then we do sctp_add_bind_addr, which copies whole sctp_addr from addr:
> 
> int sctp_add_bind_addr(struct sctp_bind_addr *bp, union sctp_addr *new,
> ...
> memcpy(&addr->a, new, sizeof(*new));
> 
> Now imagine that the addr is ipv4 (16 or so bytes, that's what we
> checked) and we copy 28 bytes (ipv6) from addr.

Yes, that's pretty much it I think. That memcpy should be limited to
af->sockaddr_len, it's just that af is not readily available in that
function.

  Marcelo


WARNING: multiple messages have this Message-ID (diff)
From: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
To: Dmitry Vyukov <dvyukov@google.com>
Cc: Neil Horman <nhorman@tuxdriver.com>,
	Vlad Yasevich <vyasevich@gmail.com>,
	"David S. Miller" <davem@davemloft.net>,
	linux-sctp@vger.kernel.org, netdev <netdev@vger.kernel.org>,
	LKML <linux-kernel@vger.kernel.org>,
	syzkaller <syzkaller@googlegroups.com>,
	Kostya Serebryany <kcc@google.com>,
	Alexander Potapenko <glider@google.com>,
	Sasha Levin <sasha.levin@oracle.com>,
	Eric Dumazet <edumazet@google.com>
Subject: Re: net/sctp: out-of-bounds access in sctp_add_bind_addr
Date: Mon, 25 Jan 2016 12:48:02 -0200	[thread overview]
Message-ID: <20160125144802.GA6602@mrl.redhat.com> (raw)
In-Reply-To: <CACT4Y+Z36GoxiRDQdFeVNkEvdRvmTXZC47cRM=TA1FCM+vCDcg@mail.gmail.com>

On Mon, Jan 25, 2016 at 03:42:14PM +0100, Dmitry Vyukov wrote:
> On Mon, Jan 25, 2016 at 3:31 PM, Neil Horman <nhorman@tuxdriver.com> wrote:
> > On Mon, Jan 25, 2016 at 03:02:38PM +0100, Dmitry Vyukov wrote:
> >> Hello,
> >>
> >> I've git the following error report while running syzkaller fuzzer:
> >>
> >> ==================================================================
> >> BUG: KASAN: slab-out-of-bounds in memcpy+0x1d/0x40 at addr ffff88006c6361e8
> >> Read of size 28 by task syz-executor/12551
> >> =============================================================================
> >> BUG kmalloc-16 (Not tainted): kasan: bad access detected
> >> -----------------------------------------------------------------------------
> >>
> >> INFO: Allocated in sctp_setsockopt_bindx+0xd2/0x3e0 age=12 cpu=2 pid=12551
> >> [<     inline     >] kmalloc include/linux/slab.h:468
> >> [<      none      >] sctp_setsockopt_bindx+0xd2/0x3e0 net/sctp/socket.c:975
> >> [<      none      >] sctp_setsockopt+0x1493/0x3630 net/sctp/socket.c:3711
> >> [<      none      >] sock_common_setsockopt+0x97/0xd0 net/core/sock.c:2620
> >> [<     inline     >] SYSC_setsockopt net/socket.c:1752
> >> [<      none      >] SyS_setsockopt+0x15b/0x250 net/socket.c:1731
> >> [<      none      >] entry_SYSCALL_64_fastpath+0x16/0x7a
> >> arch/x86/entry/entry_64.S:185
> >>
> >> INFO: Slab 0xffffea0001b18d80 objects=16 used=4 fp=0xffff88006c6376e0
> >> flags=0x5fffc0000004080
> >> INFO: Object 0xffff88006c6361e8 @offset=488 fp=0x0000000000000002
> >> Bytes b4 ffff88006c6361d8: 00 00 00 00 00 00 00 00 2f 98 34 88 ff ff
> >> ff ff  ......../.4.....
> >> Object ffff88006c6361e8: 02 00 00 00 00 00 00 00 02 00 ab 07 7f 00 00
> >> 01  ................
> >> CPU: 2 PID: 12551 Comm: syz-executor Tainted: G    B           4.5.0-rc1+ #278
> >> Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
> >>  00000000ffffffff ffff880036397928 ffffffff8299a02d ffff88003e807900
> >>  ffff88006c6361e8 ffff88006c636000 ffff880036397958 ffffffff81752814
> >>  ffff88003e807900 ffffea0001b18d80 ffff88006c6361e8 ffff88006c6361e8
> >>
> >> Call Trace:
> >>  [<ffffffff8175ad54>] __asan_loadN+0x124/0x1a0 mm/kasan/kasan.c:512
> >>  [<ffffffff8175b2dd>] memcpy+0x1d/0x40 mm/kasan/kasan.c:297
> >>  [<ffffffff85dcb249>] sctp_add_bind_addr+0xa9/0x270 net/sctp/bind_addr.c:162
> >>  [<ffffffff85dcfd66>] sctp_do_bind+0x336/0x580 net/sctp/socket.c:389
> >>  [<ffffffff85dd16ec>] sctp_bindx_add+0xac/0x1a0 net/sctp/socket.c:471
> >>  [<ffffffff85dd5cc8>] sctp_setsockopt_bindx+0x2f8/0x3e0 net/sctp/socket.c:1010
> >>  [<ffffffff85dde283>] sctp_setsockopt+0x1493/0x3630 net/sctp/socket.c:3711
> >>  [<ffffffff851f5ae7>] sock_common_setsockopt+0x97/0xd0 net/core/sock.c:2620
> >>  [<     inline     >] SYSC_setsockopt net/socket.c:1752
> >>  [<ffffffff851f2c3b>] SyS_setsockopt+0x15b/0x250 net/socket.c:1731
> >>  [<ffffffff863595f6>] entry_SYSCALL_64_fastpath+0x16/0x7a
> >> arch/x86/entry/entry_64.S:185
> >>
> >> Memory state around the buggy address:
> >>  ffff88006c636080: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
> >>  ffff88006c636100: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
> >> >ffff88006c636180: fc fc fc fc fc fc fc fc fc fc fc fc fc 00 00 fc
> >>                                                                 ^
> >>  ffff88006c636200: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
> >>  ffff88006c636280: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
> >> ==================================================================
> >>
> >>
> >> sctp_setsockopt_bindx verifies that the user-passed address has valid
> >> len for the specified family, but then sctp_add_bind_addr copies whole
> >> sctp_addr from there. This causes heap out-of-bounds access and can
> >> crash kernel. Not sure if it is possible to copy out the trailing
> >> garbage to user-space later.
> >>
> >
> > It does more than that though.  sctp_setsockopt_bindx checks the following:
> > 1) That passed addr_size is greater than zero
> > 2) that the entire range of memory between addrs and addrs+addr_size is readable
> > 3) That at least one address structure worth of data is available (implicit in
> > the while (walk_size < addr_size) loop).
> >
> > Could one of the sockaddr_len fields in one of the addresses have been mangled
> > so that it appeared shorter in the the while loop from (3), so that a copy of
> > sizeof(sctp_addr in sctp_add_bind_addr overrun the allocated memory?
> 
> I may be missing something, but what I see is:
> 
> 1. we check that there is at least family:
> if (walk_size + sizeof(sa_family_t) > addrs_size) {
> 
> 2. get family descriptor:
> af = sctp_get_af_specific(sa_addr->sa_family);
> 
> 3. check that the address size is enough to hold the declared family:
> if (!af || (walk_size + af->sockaddr_len) > addrs_size) {
> 
> 4. then we do sctp_add_bind_addr, which copies whole sctp_addr from addr:
> 
> int sctp_add_bind_addr(struct sctp_bind_addr *bp, union sctp_addr *new,
> ...
> memcpy(&addr->a, new, sizeof(*new));
> 
> Now imagine that the addr is ipv4 (16 or so bytes, that's what we
> checked) and we copy 28 bytes (ipv6) from addr.

Yes, that's pretty much it I think. That memcpy should be limited to
af->sockaddr_len, it's just that af is not readily available in that
function.

  Marcelo

  reply	other threads:[~2016-01-25 14:48 UTC|newest]

Thread overview: 40+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-01-25 14:02 net/sctp: out-of-bounds access in sctp_add_bind_addr Dmitry Vyukov
2016-01-25 14:02 ` Dmitry Vyukov
2016-01-25 14:31 ` Neil Horman
2016-01-25 14:31   ` Neil Horman
2016-01-25 14:42   ` Dmitry Vyukov
2016-01-25 14:42     ` Dmitry Vyukov
2016-01-25 14:48     ` Marcelo Ricardo Leitner [this message]
2016-01-25 14:48       ` Marcelo Ricardo Leitner
2016-01-25 16:05       ` Neil Horman
2016-01-25 16:05         ` Neil Horman
2016-01-25 16:16         ` Marcelo Ricardo Leitner
2016-01-25 16:16           ` Marcelo Ricardo Leitner
2016-01-25 17:29           ` Neil Horman
2016-01-25 17:29             ` Neil Horman
2016-01-25 17:52             ` [PATCH net] sctp: fix copying more bytes than expected " Marcelo Ricardo Leitner
2016-01-25 17:52               ` Marcelo Ricardo Leitner
2016-01-26 13:28               ` Dmitry Vyukov
2016-01-26 13:28                 ` Dmitry Vyukov
2016-03-07 19:44                 ` Marcelo Ricardo Leitner
2016-03-07 19:44                   ` Marcelo Ricardo Leitner
2016-03-07 19:45                   ` Dmitry Vyukov
2016-03-07 19:45                     ` Dmitry Vyukov
2016-03-07 19:51                     ` Marcelo Ricardo Leitner
2016-03-07 19:51                       ` Marcelo Ricardo Leitner
2016-03-07 19:56                       ` Dmitry Vyukov
2016-03-07 19:56                         ` Dmitry Vyukov
2016-03-07 20:00                         ` Marcelo Ricardo Leitner
2016-03-07 20:00                           ` Marcelo Ricardo Leitner
2016-03-07 20:21                           ` David Miller
2016-03-07 20:21                             ` David Miller
2016-03-07 21:17               ` Marcelo Ricardo Leitner
2016-03-07 21:17                 ` Marcelo Ricardo Leitner
2016-03-07 23:17                 ` [PATCH] sctp: fix noderef.cocci warnings kbuild test robot
2016-03-07 23:17                   ` kbuild test robot
2016-03-07 23:17               ` [PATCH net] sctp: fix copying more bytes than expected in sctp_add_bind_addr kbuild test robot
2016-03-07 23:17                 ` kbuild test robot
2016-03-07 23:27                 ` Marcelo Ricardo Leitner
2016-03-07 23:27                   ` Marcelo Ricardo Leitner
2016-03-08  4:15                   ` David Miller
2016-03-08  4:15                     ` David Miller

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20160125144802.GA6602@mrl.redhat.com \
    --to=marcelo.leitner@gmail.com \
    --cc=davem@davemloft.net \
    --cc=dvyukov@google.com \
    --cc=edumazet@google.com \
    --cc=glider@google.com \
    --cc=kcc@google.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-sctp@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=nhorman@tuxdriver.com \
    --cc=sasha.levin@oracle.com \
    --cc=syzkaller@googlegroups.com \
    --cc=vyasevich@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.