Message ID | 20210202092059.1361381-1-snovitoll@gmail.com (mailing list archive) |
---|---|
State | Accepted |
Commit | 2a80c15812372e554474b1dba0b1d8e467af295d |
Delegated to: | Netdev Maintainers |
Headers | show |
Series | net/qrtr: restrict user-controlled length in qrtr_tun_write_iter() | expand |
Context | Check | Description |
---|---|---|
netdev/cover_letter | success | Link |
netdev/fixes_present | success | Link |
netdev/patch_count | success | Link |
netdev/tree_selection | success | Guessed tree name to be net-next |
netdev/subject_prefix | warning | Target tree name not specified in the subject |
netdev/cc_maintainers | success | CCed 4 of 4 maintainers |
netdev/source_inline | success | Was 0 now: 0 |
netdev/verify_signedoff | success | Link |
netdev/module_param | success | Was 0 now: 0 |
netdev/build_32bit | success | Errors and warnings before: 0 this patch: 0 |
netdev/kdoc | success | Errors and warnings before: 0 this patch: 0 |
netdev/verify_fixes | success | Link |
netdev/checkpatch | success | total: 0 errors, 0 warnings, 0 checks, 12 lines checked |
netdev/build_allmodconfig_warn | success | Errors and warnings before: 0 this patch: 0 |
netdev/header_inline | success | Link |
netdev/stable | success | Stable not CCed |
On Tue, 2 Feb 2021 15:20:59 +0600 Sabyrzhan Tasbolatov wrote: > syzbot found WARNING in qrtr_tun_write_iter [1] when write_iter length > exceeds KMALLOC_MAX_SIZE causing order >= MAX_ORDER condition. > > Additionally, there is no check for 0 length write. > > [1] > WARNING: mm/page_alloc.c:5011 > [..] > Call Trace: > alloc_pages_current+0x18c/0x2a0 mm/mempolicy.c:2267 > alloc_pages include/linux/gfp.h:547 [inline] > kmalloc_order+0x2e/0xb0 mm/slab_common.c:837 > kmalloc_order_trace+0x14/0x120 mm/slab_common.c:853 > kmalloc include/linux/slab.h:557 [inline] > kzalloc include/linux/slab.h:682 [inline] > qrtr_tun_write_iter+0x8a/0x180 net/qrtr/tun.c:83 > call_write_iter include/linux/fs.h:1901 [inline] > > Reported-by: syzbot+c2a7e5c5211605a90865@syzkaller.appspotmail.com > Signed-off-by: Sabyrzhan Tasbolatov <snovitoll@gmail.com> > --- > net/qrtr/tun.c | 6 ++++++ > 1 file changed, 6 insertions(+) > > diff --git a/net/qrtr/tun.c b/net/qrtr/tun.c > index 15ce9b642b25..b238c40a9984 100644 > --- a/net/qrtr/tun.c > +++ b/net/qrtr/tun.c > @@ -80,6 +80,12 @@ static ssize_t qrtr_tun_write_iter(struct kiocb *iocb, struct iov_iter *from) > ssize_t ret; > void *kbuf; > > + if (!len) > + return -EINVAL; > + > + if (len > KMALLOC_MAX_SIZE) > + return -ENOMEM; > + > kbuf = kzalloc(len, GFP_KERNEL); For potential, separate clean up - this is followed by copy_from_iter_full(len) kzalloc() can probably be replaced by kmalloc()? > if (!kbuf) > return -ENOMEM;
Hello: This patch was applied to netdev/net.git (refs/heads/master): On Tue, 2 Feb 2021 15:20:59 +0600 you wrote: > syzbot found WARNING in qrtr_tun_write_iter [1] when write_iter length > exceeds KMALLOC_MAX_SIZE causing order >= MAX_ORDER condition. > > Additionally, there is no check for 0 length write. > > [1] > WARNING: mm/page_alloc.c:5011 > [..] > Call Trace: > alloc_pages_current+0x18c/0x2a0 mm/mempolicy.c:2267 > alloc_pages include/linux/gfp.h:547 [inline] > kmalloc_order+0x2e/0xb0 mm/slab_common.c:837 > kmalloc_order_trace+0x14/0x120 mm/slab_common.c:853 > kmalloc include/linux/slab.h:557 [inline] > kzalloc include/linux/slab.h:682 [inline] > qrtr_tun_write_iter+0x8a/0x180 net/qrtr/tun.c:83 > call_write_iter include/linux/fs.h:1901 [inline] > > [...] Here is the summary with links: - net/qrtr: restrict user-controlled length in qrtr_tun_write_iter() https://git.kernel.org/netdev/net/c/2a80c1581237 You are awesome, thank you! -- Deet-doot-dot, I am a bot. https://korg.docs.kernel.org/patchwork/pwbot.html
On 2/2/21 10:20 AM, Sabyrzhan Tasbolatov wrote: > syzbot found WARNING in qrtr_tun_write_iter [1] when write_iter length > exceeds KMALLOC_MAX_SIZE causing order >= MAX_ORDER condition. > > Additionally, there is no check for 0 length write. > > [1] > WARNING: mm/page_alloc.c:5011 > [..] > Call Trace: > alloc_pages_current+0x18c/0x2a0 mm/mempolicy.c:2267 > alloc_pages include/linux/gfp.h:547 [inline] > kmalloc_order+0x2e/0xb0 mm/slab_common.c:837 > kmalloc_order_trace+0x14/0x120 mm/slab_common.c:853 > kmalloc include/linux/slab.h:557 [inline] > kzalloc include/linux/slab.h:682 [inline] > qrtr_tun_write_iter+0x8a/0x180 net/qrtr/tun.c:83 > call_write_iter include/linux/fs.h:1901 [inline] > > Reported-by: syzbot+c2a7e5c5211605a90865@syzkaller.appspotmail.com > Signed-off-by: Sabyrzhan Tasbolatov <snovitoll@gmail.com> > --- > net/qrtr/tun.c | 6 ++++++ > 1 file changed, 6 insertions(+) > > diff --git a/net/qrtr/tun.c b/net/qrtr/tun.c > index 15ce9b642b25..b238c40a9984 100644 > --- a/net/qrtr/tun.c > +++ b/net/qrtr/tun.c > @@ -80,6 +80,12 @@ static ssize_t qrtr_tun_write_iter(struct kiocb *iocb, struct iov_iter *from) > ssize_t ret; > void *kbuf; > > + if (!len) > + return -EINVAL; > + > + if (len > KMALLOC_MAX_SIZE) > + return -ENOMEM; Probably not enough. qrtr_endpoint_post() will later attempt a netdev_alloc_skb() which will need some extra space (for struct skb_shared_info) Do we really expect to accept huge lengths here ? > + > kbuf = kzalloc(len, GFP_KERNEL); > if (!kbuf) > return -ENOMEM; >
> Do we really expect to accept huge lengths here ? Sorry for late response but I couldnt find any reference to the max length of incoming data for qrtr TUN interface. > qrtr_endpoint_post() will later attempt a netdev_alloc_skb() which will need > some extra space (for struct skb_shared_info) Thanks, you're right, qrtr_endpoint_post() will alloc another slab buffer. We can check the length of skb allocation but we need to do following: int qrtr_endpoint_post(.., const void *data, size_t len) { .. when QRTR_PROTO_VER_1: hdrlen = sizeof(*data); when QRTR_PROTO_VER_2: hdrlen = sizeof(*data) + data->optlen; len = (KMALLOC_MAX_SIZE - hdrlen) % data->size; skb = netdev_alloc_skb(NULL, len); .. skb_put_data(skb, data + hdrlen, size); So it requires refactoring as in qrtr_tun_write_iter() we just allocate and pass it to qrtr_endpoint_post() and there we need to do len calculation as above *before* netdev_alloc_skb(NULL, len). Perhaps there is a nicer solution though.
On 2/21/21 1:39 PM, Sabyrzhan Tasbolatov wrote: >> Do we really expect to accept huge lengths here ? > > Sorry for late response but I couldnt find any reference to the max > length of incoming data for qrtr TUN interface. > >> qrtr_endpoint_post() will later attempt a netdev_alloc_skb() which will need >> some extra space (for struct skb_shared_info) > > Thanks, you're right, qrtr_endpoint_post() will alloc another slab buffer. > We can check the length of skb allocation but we need to do following: > > int qrtr_endpoint_post(.., const void *data, size_t len) > { > .. > when QRTR_PROTO_VER_1: > hdrlen = sizeof(*data); > when QRTR_PROTO_VER_2: > hdrlen = sizeof(*data) + data->optlen; > > len = (KMALLOC_MAX_SIZE - hdrlen) % data->size; > skb = netdev_alloc_skb(NULL, len); > .. > skb_put_data(skb, data + hdrlen, size); > > > So it requires refactoring as in qrtr_tun_write_iter() we just allocate and > pass it to qrtr_endpoint_post() and there > we need to do len calculation as above *before* netdev_alloc_skb(NULL, len). > > Perhaps there is a nicer solution though. > A protocol requiring contiguous physical memory allocations of up to KMALLOC_MAX_SIZE bytes would be really unreliable. I suggest we simply limit the allocations to 64KB, unless qrtr maintainers shout, or start implementing scatter gather.
diff --git a/net/qrtr/tun.c b/net/qrtr/tun.c index 15ce9b642b25..b238c40a9984 100644 --- a/net/qrtr/tun.c +++ b/net/qrtr/tun.c @@ -80,6 +80,12 @@ static ssize_t qrtr_tun_write_iter(struct kiocb *iocb, struct iov_iter *from) ssize_t ret; void *kbuf; + if (!len) + return -EINVAL; + + if (len > KMALLOC_MAX_SIZE) + return -ENOMEM; + kbuf = kzalloc(len, GFP_KERNEL); if (!kbuf) return -ENOMEM;
syzbot found WARNING in qrtr_tun_write_iter [1] when write_iter length exceeds KMALLOC_MAX_SIZE causing order >= MAX_ORDER condition. Additionally, there is no check for 0 length write. [1] WARNING: mm/page_alloc.c:5011 [..] Call Trace: alloc_pages_current+0x18c/0x2a0 mm/mempolicy.c:2267 alloc_pages include/linux/gfp.h:547 [inline] kmalloc_order+0x2e/0xb0 mm/slab_common.c:837 kmalloc_order_trace+0x14/0x120 mm/slab_common.c:853 kmalloc include/linux/slab.h:557 [inline] kzalloc include/linux/slab.h:682 [inline] qrtr_tun_write_iter+0x8a/0x180 net/qrtr/tun.c:83 call_write_iter include/linux/fs.h:1901 [inline] Reported-by: syzbot+c2a7e5c5211605a90865@syzkaller.appspotmail.com Signed-off-by: Sabyrzhan Tasbolatov <snovitoll@gmail.com> --- net/qrtr/tun.c | 6 ++++++ 1 file changed, 6 insertions(+)