When the user is trying to create an extremely large udmabuf, the
allocation of pages/folios arrays may fail. In that case, there is
no need to print any warning trace in the log because such a trace,
although expected, could be considered as evidence of a serious
problem by some users or tools/fuzzers.

This warning trace started showing up after commit 44e9eb5a7621
("dma-buf/udmabuf: Disable the size limit by default") was merged
as this commit changed the maximum size limit for udmabuf to be
INT_MAX by default instead of 64 MB. So, fix this issue by passing
in __GFP_NOWARN flag when allocating pages/folios arrays.

Syzbot was the first to report this issue by triggering the following
warning trace:
        !(flags & __GFP_NOWARN)
        WARNING: mm/slub.c:7013 at __kvmalloc_node_noprof+0x646/0x9b0
        mm/slub.c:7013, CPU#2: syz.0.17/5920
        Modules linked in:
        CPU: 2 UID: 0 PID: 5920 Comm: syz.0.17 Not tainted syzkaller #0
        PREEMPT(full)
        Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS
        1.16.3-debian-1.16.3-2 04/01/2014
        RIP: 0010:__kvmalloc_node_noprof+0x646/0x9b0 mm/slub.c:7013
        Code: c1 e8 2e 07 ff ff 4d 85 f6 0f 85 b6 fd ff ff 48 81 fb ff
        ff ff 7f 0f 86 4d fd ff ff 41 81 e4 00 20 00 00 0f 85 9c fd ff
        ff 90 <0f> 0b 90 e9 93 fd ff ff 41 be 10 00 00 00 e9 88 fd ff ff
        be 42 01
        RSP: 0018:ffffc90003d8fb50 EFLAGS: 00010246
        RAX: 0000000000000001 RBX: 0000008000800018 RCX:
        0000010000000000
        RDX: 0000000000000000 RSI: ffffffff8c61e200 RDI:
        ffffffff8e6ad930
        RBP: 0000000008000800 R08: 00000000000028c0 R09:
        00000000ffffffff
        R10: 0000000000000001 R11: 0000000000000000 R12:
        0000000000000000
        R13: 00000000000028c0 R14: 0000000000000000 R15:
        00000000ffffffff
        FS:  0000000000000000(0000) GS:ffff888096b76000(0063)
        knlGS:00000000579e1480
        CS:  0010 DS: 002b ES: 002b CR0: 0000000080050033
        CR2: 00000000f7113140 CR3: 00000000542cb000 CR4:
        0000000000352ef0
        Call Trace:
         <TASK>
          init_udmabuf drivers/dma-buf/udmabuf.c:193 [inline]
          udmabuf_create+0x2e8/0x12a0 drivers/dma-buf/udmabuf.c:386
          udmabuf_ioctl_create_list drivers/dma-buf/udmabuf.c:484
          [inline]
          udmabuf_ioctl+0x2b2/0x300 drivers/dma-buf/udmabuf.c:499
          __do_compat_sys_ioctl fs/ioctl.c:695 [inline]
          __se_compat_sys_ioctl fs/ioctl.c:638 [inline]
          __ia32_compat_sys_ioctl+0x2cf/0x360 fs/ioctl.c:638
          do_syscall_32_irqs_on arch/x86/entry/syscall_32.c:79
          [inline]
          __do_fast_syscall_32+0x13a/0x8b0
          arch/x86/entry/syscall_32.c:291
          do_fast_syscall_32+0x32/0x70
          arch/x86/entry/syscall_32.c:316
          entry_SYSENTER_compat_after_hwframe+0x84/0x8e
          RIP: 0023:0xf7f03fec
          Code: Unable to access opcode bytes at 0xf7f03fc2.
          RSP: 002b:00000000ffe2d40c EFLAGS: 00000292
          ORIG_RAX: 0000000000000036
          RAX: ffffffffffffffda RBX: 0000000000000003 RCX:
          0000000040087543
          RDX: 0000000080000100 RSI: 0000000000000000 RDI:
          0000000000000000
          RBP: 0000000000000000 R08: 0000000000000000 R09:
          0000000000000000
          R10: 0000000000000000 R11: 0000000000000246 R12:
          0000000000000000
          R13: 0000000000000000 R14: 0000000000000000 R15:
          0000000000000000
         </TASK>

Signed-off-by: Vivek Kasireddy <[email protected]>
Reported-by: [email protected]
Cc: Gerd Hoffmann <[email protected]>
Cc: "Christian König" <[email protected]>
Cc: Robert Mader <[email protected]>
Cc: Xaver Hugl <[email protected]>
Fixes: 44e9eb5a7621 ("dma-buf/udmabuf: Disable the size limit by default")
---
 drivers/dma-buf/udmabuf.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c
index 4a9ab5822ffc..7c4339130eff 100644
--- a/drivers/dma-buf/udmabuf.c
+++ b/drivers/dma-buf/udmabuf.c
@@ -190,11 +190,13 @@ static void unpin_all_folios(struct udmabuf *ubuf)
 
 static __always_inline int init_udmabuf(struct udmabuf *ubuf, pgoff_t pgcnt)
 {
-       ubuf->pages = kvmalloc_objs(*ubuf->pages, pgcnt);
+       gfp_t gfp = GFP_KERNEL | __GFP_NOWARN;
+
+       ubuf->pages = kvmalloc_objs(*ubuf->pages, pgcnt, gfp);
        if (!ubuf->pages)
                return -ENOMEM;
 
-       ubuf->pinned_folios = kvmalloc_objs(*ubuf->pinned_folios, pgcnt);
+       ubuf->pinned_folios = kvmalloc_objs(*ubuf->pinned_folios, pgcnt, gfp);
        if (!ubuf->pinned_folios)
                return -ENOMEM;
 
-- 
2.53.0

Reply via email to