03 Apr, 2019

1 commit

  • [ Upstream commit fae846e2b7124d4b076ef17791c73addf3b26350 ]

    The device ID alone does not uniquely identify a device. Test both the
    vendor and device ID to make sure we don't mistakenly think some other
    vendor's 0xB410 device is a Digium HFC4S. Also, instead of the bare hex
    ID, use the same constant (PCI_DEVICE_ID_DIGIUM_HFC4S) used in the device
    ID table.

    No functional change intended.

    Signed-off-by: Bjorn Helgaas
    Signed-off-by: David S. Miller
    Signed-off-by: Greg Kroah-Hartman

    Bjorn Helgaas
     

27 Feb, 2019

2 commits

  • [ Upstream commit 7afa81c55fca0cad589722cb4bce698b4803b0e1 ]

    A recent commit in Clang expanded the -Wstring-plus-int warning, showing
    some odd behavior in this file.

    drivers/isdn/hardware/avm/b1.c:426:30: warning: adding 'int' to a string does not append to the string [-Wstring-plus-int]
    cinfo->version[j] = "\0\0" + 1;
    ~~~~~~~^~~
    drivers/isdn/hardware/avm/b1.c:426:30: note: use array indexing to silence this warning
    cinfo->version[j] = "\0\0" + 1;
    ^
    & [ ]
    1 warning generated.

    This is equivalent to just "\0". Nick pointed out that it is smarter to
    use "" instead of "\0" because "" is used elsewhere in the kernel and
    can be deduplicated at the linking stage.

    Link: https://github.com/ClangBuiltLinux/linux/issues/309
    Suggested-by: Nick Desaulniers
    Signed-off-by: Nathan Chancellor
    Signed-off-by: David S. Miller
    Signed-off-by: Sasha Levin

    Nathan Chancellor
     
  • [ Upstream commit 2ff33d6637393fe9348357285931811b76e1402f ]

    The functions isdn_tty_tiocmset() and isdn_tty_set_termios() may be
    concurrently executed.

    isdn_tty_tiocmset
    isdn_tty_modem_hup
    line 719: kfree(info->dtmf_state);
    line 721: kfree(info->silence_state);
    line 723: kfree(info->adpcms);
    line 725: kfree(info->adpcmr);

    isdn_tty_set_termios
    isdn_tty_modem_hup
    line 719: kfree(info->dtmf_state);
    line 721: kfree(info->silence_state);
    line 723: kfree(info->adpcms);
    line 725: kfree(info->adpcmr);

    Thus, some concurrency double-free bugs may occur.

    These possible bugs are found by a static tool written by myself and
    my manual code review.

    To fix these possible bugs, the mutex lock "modem_info_mutex" used in
    isdn_tty_tiocmset() is added in isdn_tty_set_termios().

    Signed-off-by: Jia-Ju Bai
    Signed-off-by: David S. Miller
    Signed-off-by: Sasha Levin

    Jia-Ju Bai
     

23 Feb, 2019

1 commit

  • commit bdcc5bc25548ef6b08e2e43937148f907c212292 upstream.

    Since mISDN_close() uses dev->pending to iterate over active
    timers, there is a chance that one timer got removed from the
    ->pending list in dev_expire_timer() but that the thread
    has not called yet wake_up_interruptible()

    So mISDN_close() could miss this and free dev before
    completion of at least one dev_expire_timer()

    syzbot was able to catch this race :

    BUG: KASAN: use-after-free in register_lock_class+0x140c/0x1bf0 kernel/locking/lockdep.c:827
    Write of size 8 at addr ffff88809fc18948 by task syz-executor1/24769

    CPU: 1 PID: 24769 Comm: syz-executor1 Not tainted 5.0.0-rc5 #60
    Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
    Call Trace:

    __dump_stack lib/dump_stack.c:77 [inline]
    dump_stack+0x172/0x1f0 lib/dump_stack.c:113
    print_address_description.cold+0x7c/0x20d mm/kasan/report.c:187
    kasan_report.cold+0x1b/0x40 mm/kasan/report.c:317
    __asan_report_store8_noabort+0x17/0x20 mm/kasan/generic_report.c:140
    register_lock_class+0x140c/0x1bf0 kernel/locking/lockdep.c:827
    __lock_acquire+0x11f/0x4700 kernel/locking/lockdep.c:3224
    lock_acquire+0x16f/0x3f0 kernel/locking/lockdep.c:3841
    __raw_spin_lock_irqsave include/linux/spinlock_api_smp.h:110 [inline]
    _raw_spin_lock_irqsave+0x95/0xcd kernel/locking/spinlock.c:152
    __wake_up_common_lock+0xc7/0x190 kernel/sched/wait.c:120
    __wake_up+0xe/0x10 kernel/sched/wait.c:145
    dev_expire_timer+0xe4/0x3b0 drivers/isdn/mISDN/timerdev.c:174
    call_timer_fn+0x190/0x720 kernel/time/timer.c:1325
    protocol 88fb is buggy, dev hsr_slave_0
    protocol 88fb is buggy, dev hsr_slave_1
    expire_timers kernel/time/timer.c:1362 [inline]
    __run_timers kernel/time/timer.c:1681 [inline]
    __run_timers kernel/time/timer.c:1649 [inline]
    run_timer_softirq+0x652/0x1700 kernel/time/timer.c:1694
    __do_softirq+0x266/0x95a kernel/softirq.c:292
    invoke_softirq kernel/softirq.c:373 [inline]
    irq_exit+0x180/0x1d0 kernel/softirq.c:413
    exiting_irq arch/x86/include/asm/apic.h:536 [inline]
    smp_apic_timer_interrupt+0x14a/0x570 arch/x86/kernel/apic/apic.c:1062
    apic_timer_interrupt+0xf/0x20 arch/x86/entry/entry_64.S:807

    RIP: 0010:__sanitizer_cov_trace_pc+0x26/0x50 kernel/kcov.c:101
    Code: 90 90 90 90 55 48 89 e5 48 8b 75 08 65 48 8b 04 25 40 ee 01 00 65 8b 15 98 12 92 7e 81 e2 00 01 1f 00 75 2b 8b 90 d8 12 00 00 fa 02 75 20 48 8b 88 e0 12 00 00 8b 80 dc 12 00 00 48 8b 11 48
    RSP: 0018:ffff8880589b7a60 EFLAGS: 00000246 ORIG_RAX: ffffffffffffff13
    RAX: ffff888087ce25c0 RBX: 0000000000000001 RCX: ffffffff818f8ca3
    RDX: 0000000000000000 RSI: ffffffff818f8b48 RDI: 0000000000000001
    RBP: ffff8880589b7a60 R08: ffff888087ce25c0 R09: ffffed1015d25bd0
    R10: ffffed1015d25bcf R11: ffff8880ae92de7b R12: ffffea0001ae4680
    R13: ffffea0001ae4688 R14: 0000000000000000 R15: ffffea0001b41648
    PageIdle include/linux/page-flags.h:398 [inline]
    page_is_idle include/linux/page_idle.h:29 [inline]
    mark_page_accessed+0x618/0x1140 mm/swap.c:398
    touch_buffer fs/buffer.c:59 [inline]
    __find_get_block+0x312/0xcc0 fs/buffer.c:1298
    sb_find_get_block include/linux/buffer_head.h:338 [inline]
    recently_deleted fs/ext4/ialloc.c:682 [inline]
    find_inode_bit.isra.0+0x202/0x510 fs/ext4/ialloc.c:722
    __ext4_new_inode+0x14ad/0x52c0 fs/ext4/ialloc.c:914
    ext4_symlink+0x3f8/0xbe0 fs/ext4/namei.c:3096
    vfs_symlink fs/namei.c:4126 [inline]
    vfs_symlink+0x378/0x5d0 fs/namei.c:4112
    do_symlinkat+0x22b/0x290 fs/namei.c:4153
    __do_sys_symlink fs/namei.c:4172 [inline]
    __se_sys_symlink fs/namei.c:4170 [inline]
    __x64_sys_symlink+0x59/0x80 fs/namei.c:4170
    do_syscall_64+0x103/0x610 arch/x86/entry/common.c:290
    entry_SYSCALL_64_after_hwframe+0x49/0xbe
    RIP: 0033:0x457b67
    Code: 0f 1f 00 b8 5c 00 00 00 0f 05 48 3d 01 f0 ff ff 0f 83 6d bb fb ff c3 66 2e 0f 1f 84 00 00 00 00 00 66 90 b8 58 00 00 00 0f 05 3d 01 f0 ff ff 0f 83 4d bb fb ff c3 66 2e 0f 1f 84 00 00 00 00
    RSP: 002b:00007fff045ce0f8 EFLAGS: 00000202 ORIG_RAX: 0000000000000058
    RAX: ffffffffffffffda RBX: 0000000000000001 RCX: 0000000000457b67
    RDX: 00007fff045ce173 RSI: 00000000004bd63f RDI: 00007fff045ce160
    RBP: 0000000000000000 R08: 0000000000000000 R09: 0000000000000013
    R10: 0000000000000075 R11: 0000000000000202 R12: 0000000000000000
    R13: 0000000000000001 R14: 000000000000029b R15: 0000000000000001

    Allocated by task 24763:
    save_stack+0x45/0xd0 mm/kasan/common.c:73
    set_track mm/kasan/common.c:85 [inline]
    __kasan_kmalloc mm/kasan/common.c:496 [inline]
    __kasan_kmalloc.constprop.0+0xcf/0xe0 mm/kasan/common.c:469
    kasan_kmalloc+0x9/0x10 mm/kasan/common.c:504
    kmem_cache_alloc_trace+0x151/0x760 mm/slab.c:3609
    kmalloc include/linux/slab.h:545 [inline]
    mISDN_open+0x9a/0x270 drivers/isdn/mISDN/timerdev.c:59
    misc_open+0x398/0x4c0 drivers/char/misc.c:141
    chrdev_open+0x247/0x6b0 fs/char_dev.c:417
    do_dentry_open+0x47d/0x1130 fs/open.c:771
    vfs_open+0xa0/0xd0 fs/open.c:880
    do_last fs/namei.c:3418 [inline]
    path_openat+0x10d7/0x4690 fs/namei.c:3534
    do_filp_open+0x1a1/0x280 fs/namei.c:3564
    do_sys_open+0x3fe/0x5d0 fs/open.c:1063
    __do_sys_openat fs/open.c:1090 [inline]
    __se_sys_openat fs/open.c:1084 [inline]
    __x64_sys_openat+0x9d/0x100 fs/open.c:1084
    do_syscall_64+0x103/0x610 arch/x86/entry/common.c:290
    entry_SYSCALL_64_after_hwframe+0x49/0xbe

    Freed by task 24762:
    save_stack+0x45/0xd0 mm/kasan/common.c:73
    set_track mm/kasan/common.c:85 [inline]
    __kasan_slab_free+0x102/0x150 mm/kasan/common.c:458
    kasan_slab_free+0xe/0x10 mm/kasan/common.c:466
    __cache_free mm/slab.c:3487 [inline]
    kfree+0xcf/0x230 mm/slab.c:3806
    mISDN_close+0x2a1/0x390 drivers/isdn/mISDN/timerdev.c:97
    __fput+0x2df/0x8d0 fs/file_table.c:278
    ____fput+0x16/0x20 fs/file_table.c:309
    task_work_run+0x14a/0x1c0 kernel/task_work.c:113
    tracehook_notify_resume include/linux/tracehook.h:188 [inline]
    exit_to_usermode_loop+0x273/0x2c0 arch/x86/entry/common.c:166
    prepare_exit_to_usermode arch/x86/entry/common.c:197 [inline]
    syscall_return_slowpath arch/x86/entry/common.c:268 [inline]
    do_syscall_64+0x52d/0x610 arch/x86/entry/common.c:293
    entry_SYSCALL_64_after_hwframe+0x49/0xbe

    The buggy address belongs to the object at ffff88809fc18900
    which belongs to the cache kmalloc-192 of size 192
    The buggy address is located 72 bytes inside of
    192-byte region [ffff88809fc18900, ffff88809fc189c0)
    The buggy address belongs to the page:
    page:ffffea00027f0600 count:1 mapcount:0 mapping:ffff88812c3f0040 index:0xffff88809fc18000
    flags: 0x1fffc0000000200(slab)
    raw: 01fffc0000000200 ffffea000269f648 ffffea00029f7408 ffff88812c3f0040
    raw: ffff88809fc18000 ffff88809fc18000 000000010000000b 0000000000000000
    page dumped because: kasan: bad access detected

    Memory state around the buggy address:
    ffff88809fc18800: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    ffff88809fc18880: 00 fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
    >ffff88809fc18900: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
    ^
    ffff88809fc18980: fb fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc
    ffff88809fc18a00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

    Signed-off-by: Eric Dumazet
    Cc: Karsten Keil
    Reported-by: syzbot
    Signed-off-by: David S. Miller
    Signed-off-by: Greg Kroah-Hartman

    Eric Dumazet
     

13 Feb, 2019

1 commit

  • [ Upstream commit 7418e6520f22a2e35815122fa5a53d5bbfa2c10f ]

    In drivers/isdn/hisax/hfc_pci.c, the functions hfcpci_interrupt() and
    HFCPCI_l1hw() may be concurrently executed.

    HFCPCI_l1hw()
    line 1173: if (!cs->tx_skb)

    hfcpci_interrupt()
    line 942: spin_lock_irqsave();
    line 1066: dev_kfree_skb_irq(cs->tx_skb);

    Thus, a possible concurrency use-after-free bug may occur
    in HFCPCI_l1hw().

    To fix these bugs, the calls to spin_lock_irqsave() and
    spin_unlock_irqrestore() are added in HFCPCI_l1hw(), to protect the
    access to cs->tx_skb.

    Signed-off-by: Jia-Ju Bai
    Signed-off-by: David S. Miller
    Signed-off-by: Sasha Levin

    Jia-Ju Bai
     

10 Jan, 2019

1 commit

  • [ Upstream commit d63967e475ae10f286dbd35e189cb241e0b1f284 ]

    Since capi_ioctl() copies 64 bytes after calling
    capi20_get_manufacturer() we need to ensure to not leak
    information to user.

    BUG: KMSAN: kernel-infoleak in _copy_to_user+0x16b/0x1f0 lib/usercopy.c:32
    CPU: 0 PID: 11245 Comm: syz-executor633 Not tainted 4.20.0-rc7+ #2
    Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
    Call Trace:
    __dump_stack lib/dump_stack.c:77 [inline]
    dump_stack+0x173/0x1d0 lib/dump_stack.c:113
    kmsan_report+0x12e/0x2a0 mm/kmsan/kmsan.c:613
    kmsan_internal_check_memory+0x9d4/0xb00 mm/kmsan/kmsan.c:704
    kmsan_copy_to_user+0xab/0xc0 mm/kmsan/kmsan_hooks.c:601
    _copy_to_user+0x16b/0x1f0 lib/usercopy.c:32
    capi_ioctl include/linux/uaccess.h:177 [inline]
    capi_unlocked_ioctl+0x1a0b/0x1bf0 drivers/isdn/capi/capi.c:939
    do_vfs_ioctl+0xebd/0x2bf0 fs/ioctl.c:46
    ksys_ioctl fs/ioctl.c:713 [inline]
    __do_sys_ioctl fs/ioctl.c:720 [inline]
    __se_sys_ioctl+0x1da/0x270 fs/ioctl.c:718
    __x64_sys_ioctl+0x4a/0x70 fs/ioctl.c:718
    do_syscall_64+0xbc/0xf0 arch/x86/entry/common.c:291
    entry_SYSCALL_64_after_hwframe+0x63/0xe7
    RIP: 0033:0x440019
    Code: 18 89 d0 c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 3d 01 f0 ff ff 0f 83 fb 13 fc ff c3 66 2e 0f 1f 84 00 00 00 00
    RSP: 002b:00007ffdd4659fb8 EFLAGS: 00000213 ORIG_RAX: 0000000000000010
    RAX: ffffffffffffffda RBX: 00000000004002c8 RCX: 0000000000440019
    RDX: 0000000020000080 RSI: 00000000c0044306 RDI: 0000000000000003
    RBP: 00000000006ca018 R08: 0000000000000000 R09: 00000000004002c8
    R10: 0000000000000000 R11: 0000000000000213 R12: 00000000004018a0
    R13: 0000000000401930 R14: 0000000000000000 R15: 0000000000000000

    Local variable description: ----data.i@capi_unlocked_ioctl
    Variable was created at:
    capi_ioctl drivers/isdn/capi/capi.c:747 [inline]
    capi_unlocked_ioctl+0x82/0x1bf0 drivers/isdn/capi/capi.c:939
    do_vfs_ioctl+0xebd/0x2bf0 fs/ioctl.c:46

    Bytes 12-63 of 64 are uninitialized
    Memory access of size 64 starts at ffff88807ac5fce8
    Data copied to user address 0000000020000080

    Signed-off-by: Eric Dumazet
    Reported-by: syzbot
    Cc: Karsten Keil
    Signed-off-by: David S. Miller
    Signed-off-by: Greg Kroah-Hartman

    Eric Dumazet
     

17 Aug, 2018

1 commit

  • It was possible to directly leak the kernel address where the isdn_dev
    structure pointer was stored. This is a kernel ASLR bypass for anyone
    with access to the ioctl. The code had been present since the beginning
    of git history, though this shouldn't ever be needed for normal operation,
    therefore remove it.

    Reported-by: Al Viro
    Cc: Karsten Keil
    Signed-off-by: Kees Cook
    Signed-off-by: David S. Miller

    Kees Cook
     

27 Jul, 2018

4 commits


08 Jul, 2018

1 commit

  • Fix build warnings in drivers/isdn/capi/ when CONFIG_PROC_FS is not
    enabled by marking the unused functions as __maybe_unused.

    ../drivers/isdn/capi/capi.c:1324:12: warning: 'capi20_proc_show' defined but not used [-Wunused-function]
    ../drivers/isdn/capi/capi.c:1347:12: warning: 'capi20ncci_proc_show' defined but not used [-Wunused-function]
    ../drivers/isdn/capi/capidrv.c:2454:12: warning: 'capidrv_proc_show' defined but not used [-Wunused-function]

    Signed-off-by: Randy Dunlap
    Cc: Karsten Keil
    Cc: isdn4linux@listserv.isdn4linux.de (subscribers-only)
    Cc: netdev@vger.kernel.org
    Signed-off-by: David S. Miller

    Randy Dunlap
     

04 Jul, 2018

1 commit


03 Jul, 2018

1 commit


02 Jul, 2018

1 commit

  • gcc 8.1.0 complains:

    drivers/isdn/i4l/isdn_tty.c: In function 'isdn_tty_suspend.isra.1':
    drivers/isdn/i4l/isdn_tty.c:790:3: warning:
    'strncpy' output truncated before terminating nul copying
    as many bytes from a string as its length
    drivers/isdn/i4l/isdn_tty.c:778:6: note: length computed here

    drivers/isdn/i4l/isdn_tty.c: In function 'isdn_tty_resume':
    drivers/isdn/i4l/isdn_tty.c:880:3: warning:
    'strncpy' output truncated before terminating nul copying
    as many bytes from a string as its length
    drivers/isdn/i4l/isdn_tty.c:817:6: note: length computed here

    Using strncpy() is indeed less than perfect since the length of data to
    be copied has already been determined with strlen(). Replace strncpy()
    with memcpy() to address the warning and optimize the code a little.

    Signed-off-by: Guenter Roeck
    Signed-off-by: David S. Miller

    Guenter Roeck
     

29 Jun, 2018

1 commit

  • The poll() changes were not well thought out, and completely
    unexplained. They also caused a huge performance regression, because
    "->poll()" was no longer a trivial file operation that just called down
    to the underlying file operations, but instead did at least two indirect
    calls.

    Indirect calls are sadly slow now with the Spectre mitigation, but the
    performance problem could at least be largely mitigated by changing the
    "->get_poll_head()" operation to just have a per-file-descriptor pointer
    to the poll head instead. That gets rid of one of the new indirections.

    But that doesn't fix the new complexity that is completely unwarranted
    for the regular case. The (undocumented) reason for the poll() changes
    was some alleged AIO poll race fixing, but we don't make the common case
    slower and more complex for some uncommon special case, so this all
    really needs way more explanations and most likely a fundamental
    redesign.

    [ This revert is a revert of about 30 different commits, not reverted
    individually because that would just be unnecessarily messy - Linus ]

    Cc: Al Viro
    Cc: Christoph Hellwig
    Signed-off-by: Linus Torvalds

    Linus Torvalds
     

22 Jun, 2018

4 commits

  • The USB completion callback does not disable interrupts while acquiring
    the ->lock. We want to remove the local_irq_disable() invocation from
    __usb_hcd_giveback_urb() and therefore it is required for the callback
    handler to disable the interrupts while acquiring the lock.
    The callback may be invoked either in IRQ or BH context depending on the
    USB host controller.
    Use the _irqsave() variant of the locking primitives.

    Cc: Karsten Keil
    Cc: netdev@vger.kernel.org
    Signed-off-by: Sebastian Andrzej Siewior
    Signed-off-by: David S. Miller

    Sebastian Andrzej Siewior
     
  • Using usb_fill_int_urb() helps to find code which initializes an
    URB. A grep for members of the struct (like ->complete) reveal lots
    of other things, too.

    Cc: Karsten Keil
    Cc: netdev@vger.kernel.org
    Signed-off-by: Sebastian Andrzej Siewior
    Signed-off-by: David S. Miller

    Sebastian Andrzej Siewior
     
  • Using usb_fill_int_urb() helps to find code which initializes an
    URB. A grep for members of the struct (like ->complete) reveal lots
    of other things, too.

    The `interval' parameter is now set differently on HS and SS. The
    argument is fed from bInterval so it should be the right thing to do.

    Cc: Karsten Keil
    Cc: netdev@vger.kernel.org
    Signed-off-by: Sebastian Andrzej Siewior
    Signed-off-by: David S. Miller

    Sebastian Andrzej Siewior
     
  • Using usb_fill_int_urb() helps to find code which initializes an
    URB. A grep for members of the struct (like ->complete) reveal lots
    of other things, too.

    Cc: Paul Bolle
    Cc: Karsten Keil
    Cc: gigaset307x-common@lists.sourceforge.net
    Cc: netdev@vger.kernel.org
    Signed-off-by: Sebastian Andrzej Siewior
    Signed-off-by: David S. Miller

    Sebastian Andrzej Siewior
     

13 Jun, 2018

3 commits

  • The vmalloc() function has no 2-factor argument form, so multiplication
    factors need to be wrapped in array_size(). This patch replaces cases of:

    vmalloc(a * b)

    with:
    vmalloc(array_size(a, b))

    as well as handling cases of:

    vmalloc(a * b * c)

    with:

    vmalloc(array3_size(a, b, c))

    This does, however, attempt to ignore constant size factors like:

    vmalloc(4 * 1024)

    though any constants defined via macros get caught up in the conversion.

    Any factors with a sizeof() of "unsigned char", "char", and "u8" were
    dropped, since they're redundant.

    The Coccinelle script used for this was:

    // Fix redundant parens around sizeof().
    @@
    type TYPE;
    expression THING, E;
    @@

    (
    vmalloc(
    - (sizeof(TYPE)) * E
    + sizeof(TYPE) * E
    , ...)
    |
    vmalloc(
    - (sizeof(THING)) * E
    + sizeof(THING) * E
    , ...)
    )

    // Drop single-byte sizes and redundant parens.
    @@
    expression COUNT;
    typedef u8;
    typedef __u8;
    @@

    (
    vmalloc(
    - sizeof(u8) * (COUNT)
    + COUNT
    , ...)
    |
    vmalloc(
    - sizeof(__u8) * (COUNT)
    + COUNT
    , ...)
    |
    vmalloc(
    - sizeof(char) * (COUNT)
    + COUNT
    , ...)
    |
    vmalloc(
    - sizeof(unsigned char) * (COUNT)
    + COUNT
    , ...)
    |
    vmalloc(
    - sizeof(u8) * COUNT
    + COUNT
    , ...)
    |
    vmalloc(
    - sizeof(__u8) * COUNT
    + COUNT
    , ...)
    |
    vmalloc(
    - sizeof(char) * COUNT
    + COUNT
    , ...)
    |
    vmalloc(
    - sizeof(unsigned char) * COUNT
    + COUNT
    , ...)
    )

    // 2-factor product with sizeof(type/expression) and identifier or constant.
    @@
    type TYPE;
    expression THING;
    identifier COUNT_ID;
    constant COUNT_CONST;
    @@

    (
    vmalloc(
    - sizeof(TYPE) * (COUNT_ID)
    + array_size(COUNT_ID, sizeof(TYPE))
    , ...)
    |
    vmalloc(
    - sizeof(TYPE) * COUNT_ID
    + array_size(COUNT_ID, sizeof(TYPE))
    , ...)
    |
    vmalloc(
    - sizeof(TYPE) * (COUNT_CONST)
    + array_size(COUNT_CONST, sizeof(TYPE))
    , ...)
    |
    vmalloc(
    - sizeof(TYPE) * COUNT_CONST
    + array_size(COUNT_CONST, sizeof(TYPE))
    , ...)
    |
    vmalloc(
    - sizeof(THING) * (COUNT_ID)
    + array_size(COUNT_ID, sizeof(THING))
    , ...)
    |
    vmalloc(
    - sizeof(THING) * COUNT_ID
    + array_size(COUNT_ID, sizeof(THING))
    , ...)
    |
    vmalloc(
    - sizeof(THING) * (COUNT_CONST)
    + array_size(COUNT_CONST, sizeof(THING))
    , ...)
    |
    vmalloc(
    - sizeof(THING) * COUNT_CONST
    + array_size(COUNT_CONST, sizeof(THING))
    , ...)
    )

    // 2-factor product, only identifiers.
    @@
    identifier SIZE, COUNT;
    @@

    vmalloc(
    - SIZE * COUNT
    + array_size(COUNT, SIZE)
    , ...)

    // 3-factor product with 1 sizeof(type) or sizeof(expression), with
    // redundant parens removed.
    @@
    expression THING;
    identifier STRIDE, COUNT;
    type TYPE;
    @@

    (
    vmalloc(
    - sizeof(TYPE) * (COUNT) * (STRIDE)
    + array3_size(COUNT, STRIDE, sizeof(TYPE))
    , ...)
    |
    vmalloc(
    - sizeof(TYPE) * (COUNT) * STRIDE
    + array3_size(COUNT, STRIDE, sizeof(TYPE))
    , ...)
    |
    vmalloc(
    - sizeof(TYPE) * COUNT * (STRIDE)
    + array3_size(COUNT, STRIDE, sizeof(TYPE))
    , ...)
    |
    vmalloc(
    - sizeof(TYPE) * COUNT * STRIDE
    + array3_size(COUNT, STRIDE, sizeof(TYPE))
    , ...)
    |
    vmalloc(
    - sizeof(THING) * (COUNT) * (STRIDE)
    + array3_size(COUNT, STRIDE, sizeof(THING))
    , ...)
    |
    vmalloc(
    - sizeof(THING) * (COUNT) * STRIDE
    + array3_size(COUNT, STRIDE, sizeof(THING))
    , ...)
    |
    vmalloc(
    - sizeof(THING) * COUNT * (STRIDE)
    + array3_size(COUNT, STRIDE, sizeof(THING))
    , ...)
    |
    vmalloc(
    - sizeof(THING) * COUNT * STRIDE
    + array3_size(COUNT, STRIDE, sizeof(THING))
    , ...)
    )

    // 3-factor product with 2 sizeof(variable), with redundant parens removed.
    @@
    expression THING1, THING2;
    identifier COUNT;
    type TYPE1, TYPE2;
    @@

    (
    vmalloc(
    - sizeof(TYPE1) * sizeof(TYPE2) * COUNT
    + array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
    , ...)
    |
    vmalloc(
    - sizeof(TYPE1) * sizeof(THING2) * (COUNT)
    + array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
    , ...)
    |
    vmalloc(
    - sizeof(THING1) * sizeof(THING2) * COUNT
    + array3_size(COUNT, sizeof(THING1), sizeof(THING2))
    , ...)
    |
    vmalloc(
    - sizeof(THING1) * sizeof(THING2) * (COUNT)
    + array3_size(COUNT, sizeof(THING1), sizeof(THING2))
    , ...)
    |
    vmalloc(
    - sizeof(TYPE1) * sizeof(THING2) * COUNT
    + array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
    , ...)
    |
    vmalloc(
    - sizeof(TYPE1) * sizeof(THING2) * (COUNT)
    + array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
    , ...)
    )

    // 3-factor product, only identifiers, with redundant parens removed.
    @@
    identifier STRIDE, SIZE, COUNT;
    @@

    (
    vmalloc(
    - (COUNT) * STRIDE * SIZE
    + array3_size(COUNT, STRIDE, SIZE)
    , ...)
    |
    vmalloc(
    - COUNT * (STRIDE) * SIZE
    + array3_size(COUNT, STRIDE, SIZE)
    , ...)
    |
    vmalloc(
    - COUNT * STRIDE * (SIZE)
    + array3_size(COUNT, STRIDE, SIZE)
    , ...)
    |
    vmalloc(
    - (COUNT) * (STRIDE) * SIZE
    + array3_size(COUNT, STRIDE, SIZE)
    , ...)
    |
    vmalloc(
    - COUNT * (STRIDE) * (SIZE)
    + array3_size(COUNT, STRIDE, SIZE)
    , ...)
    |
    vmalloc(
    - (COUNT) * STRIDE * (SIZE)
    + array3_size(COUNT, STRIDE, SIZE)
    , ...)
    |
    vmalloc(
    - (COUNT) * (STRIDE) * (SIZE)
    + array3_size(COUNT, STRIDE, SIZE)
    , ...)
    |
    vmalloc(
    - COUNT * STRIDE * SIZE
    + array3_size(COUNT, STRIDE, SIZE)
    , ...)
    )

    // Any remaining multi-factor products, first at least 3-factor products
    // when they're not all constants...
    @@
    expression E1, E2, E3;
    constant C1, C2, C3;
    @@

    (
    vmalloc(C1 * C2 * C3, ...)
    |
    vmalloc(
    - E1 * E2 * E3
    + array3_size(E1, E2, E3)
    , ...)
    )

    // And then all remaining 2 factors products when they're not all constants.
    @@
    expression E1, E2;
    constant C1, C2;
    @@

    (
    vmalloc(C1 * C2, ...)
    |
    vmalloc(
    - E1 * E2
    + array_size(E1, E2)
    , ...)
    )

    Signed-off-by: Kees Cook

    Kees Cook
     
  • The kzalloc() function has a 2-factor argument form, kcalloc(). This
    patch replaces cases of:

    kzalloc(a * b, gfp)

    with:
    kcalloc(a * b, gfp)

    as well as handling cases of:

    kzalloc(a * b * c, gfp)

    with:

    kzalloc(array3_size(a, b, c), gfp)

    as it's slightly less ugly than:

    kzalloc_array(array_size(a, b), c, gfp)

    This does, however, attempt to ignore constant size factors like:

    kzalloc(4 * 1024, gfp)

    though any constants defined via macros get caught up in the conversion.

    Any factors with a sizeof() of "unsigned char", "char", and "u8" were
    dropped, since they're redundant.

    The Coccinelle script used for this was:

    // Fix redundant parens around sizeof().
    @@
    type TYPE;
    expression THING, E;
    @@

    (
    kzalloc(
    - (sizeof(TYPE)) * E
    + sizeof(TYPE) * E
    , ...)
    |
    kzalloc(
    - (sizeof(THING)) * E
    + sizeof(THING) * E
    , ...)
    )

    // Drop single-byte sizes and redundant parens.
    @@
    expression COUNT;
    typedef u8;
    typedef __u8;
    @@

    (
    kzalloc(
    - sizeof(u8) * (COUNT)
    + COUNT
    , ...)
    |
    kzalloc(
    - sizeof(__u8) * (COUNT)
    + COUNT
    , ...)
    |
    kzalloc(
    - sizeof(char) * (COUNT)
    + COUNT
    , ...)
    |
    kzalloc(
    - sizeof(unsigned char) * (COUNT)
    + COUNT
    , ...)
    |
    kzalloc(
    - sizeof(u8) * COUNT
    + COUNT
    , ...)
    |
    kzalloc(
    - sizeof(__u8) * COUNT
    + COUNT
    , ...)
    |
    kzalloc(
    - sizeof(char) * COUNT
    + COUNT
    , ...)
    |
    kzalloc(
    - sizeof(unsigned char) * COUNT
    + COUNT
    , ...)
    )

    // 2-factor product with sizeof(type/expression) and identifier or constant.
    @@
    type TYPE;
    expression THING;
    identifier COUNT_ID;
    constant COUNT_CONST;
    @@

    (
    - kzalloc
    + kcalloc
    (
    - sizeof(TYPE) * (COUNT_ID)
    + COUNT_ID, sizeof(TYPE)
    , ...)
    |
    - kzalloc
    + kcalloc
    (
    - sizeof(TYPE) * COUNT_ID
    + COUNT_ID, sizeof(TYPE)
    , ...)
    |
    - kzalloc
    + kcalloc
    (
    - sizeof(TYPE) * (COUNT_CONST)
    + COUNT_CONST, sizeof(TYPE)
    , ...)
    |
    - kzalloc
    + kcalloc
    (
    - sizeof(TYPE) * COUNT_CONST
    + COUNT_CONST, sizeof(TYPE)
    , ...)
    |
    - kzalloc
    + kcalloc
    (
    - sizeof(THING) * (COUNT_ID)
    + COUNT_ID, sizeof(THING)
    , ...)
    |
    - kzalloc
    + kcalloc
    (
    - sizeof(THING) * COUNT_ID
    + COUNT_ID, sizeof(THING)
    , ...)
    |
    - kzalloc
    + kcalloc
    (
    - sizeof(THING) * (COUNT_CONST)
    + COUNT_CONST, sizeof(THING)
    , ...)
    |
    - kzalloc
    + kcalloc
    (
    - sizeof(THING) * COUNT_CONST
    + COUNT_CONST, sizeof(THING)
    , ...)
    )

    // 2-factor product, only identifiers.
    @@
    identifier SIZE, COUNT;
    @@

    - kzalloc
    + kcalloc
    (
    - SIZE * COUNT
    + COUNT, SIZE
    , ...)

    // 3-factor product with 1 sizeof(type) or sizeof(expression), with
    // redundant parens removed.
    @@
    expression THING;
    identifier STRIDE, COUNT;
    type TYPE;
    @@

    (
    kzalloc(
    - sizeof(TYPE) * (COUNT) * (STRIDE)
    + array3_size(COUNT, STRIDE, sizeof(TYPE))
    , ...)
    |
    kzalloc(
    - sizeof(TYPE) * (COUNT) * STRIDE
    + array3_size(COUNT, STRIDE, sizeof(TYPE))
    , ...)
    |
    kzalloc(
    - sizeof(TYPE) * COUNT * (STRIDE)
    + array3_size(COUNT, STRIDE, sizeof(TYPE))
    , ...)
    |
    kzalloc(
    - sizeof(TYPE) * COUNT * STRIDE
    + array3_size(COUNT, STRIDE, sizeof(TYPE))
    , ...)
    |
    kzalloc(
    - sizeof(THING) * (COUNT) * (STRIDE)
    + array3_size(COUNT, STRIDE, sizeof(THING))
    , ...)
    |
    kzalloc(
    - sizeof(THING) * (COUNT) * STRIDE
    + array3_size(COUNT, STRIDE, sizeof(THING))
    , ...)
    |
    kzalloc(
    - sizeof(THING) * COUNT * (STRIDE)
    + array3_size(COUNT, STRIDE, sizeof(THING))
    , ...)
    |
    kzalloc(
    - sizeof(THING) * COUNT * STRIDE
    + array3_size(COUNT, STRIDE, sizeof(THING))
    , ...)
    )

    // 3-factor product with 2 sizeof(variable), with redundant parens removed.
    @@
    expression THING1, THING2;
    identifier COUNT;
    type TYPE1, TYPE2;
    @@

    (
    kzalloc(
    - sizeof(TYPE1) * sizeof(TYPE2) * COUNT
    + array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
    , ...)
    |
    kzalloc(
    - sizeof(TYPE1) * sizeof(THING2) * (COUNT)
    + array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
    , ...)
    |
    kzalloc(
    - sizeof(THING1) * sizeof(THING2) * COUNT
    + array3_size(COUNT, sizeof(THING1), sizeof(THING2))
    , ...)
    |
    kzalloc(
    - sizeof(THING1) * sizeof(THING2) * (COUNT)
    + array3_size(COUNT, sizeof(THING1), sizeof(THING2))
    , ...)
    |
    kzalloc(
    - sizeof(TYPE1) * sizeof(THING2) * COUNT
    + array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
    , ...)
    |
    kzalloc(
    - sizeof(TYPE1) * sizeof(THING2) * (COUNT)
    + array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
    , ...)
    )

    // 3-factor product, only identifiers, with redundant parens removed.
    @@
    identifier STRIDE, SIZE, COUNT;
    @@

    (
    kzalloc(
    - (COUNT) * STRIDE * SIZE
    + array3_size(COUNT, STRIDE, SIZE)
    , ...)
    |
    kzalloc(
    - COUNT * (STRIDE) * SIZE
    + array3_size(COUNT, STRIDE, SIZE)
    , ...)
    |
    kzalloc(
    - COUNT * STRIDE * (SIZE)
    + array3_size(COUNT, STRIDE, SIZE)
    , ...)
    |
    kzalloc(
    - (COUNT) * (STRIDE) * SIZE
    + array3_size(COUNT, STRIDE, SIZE)
    , ...)
    |
    kzalloc(
    - COUNT * (STRIDE) * (SIZE)
    + array3_size(COUNT, STRIDE, SIZE)
    , ...)
    |
    kzalloc(
    - (COUNT) * STRIDE * (SIZE)
    + array3_size(COUNT, STRIDE, SIZE)
    , ...)
    |
    kzalloc(
    - (COUNT) * (STRIDE) * (SIZE)
    + array3_size(COUNT, STRIDE, SIZE)
    , ...)
    |
    kzalloc(
    - COUNT * STRIDE * SIZE
    + array3_size(COUNT, STRIDE, SIZE)
    , ...)
    )

    // Any remaining multi-factor products, first at least 3-factor products,
    // when they're not all constants...
    @@
    expression E1, E2, E3;
    constant C1, C2, C3;
    @@

    (
    kzalloc(C1 * C2 * C3, ...)
    |
    kzalloc(
    - (E1) * E2 * E3
    + array3_size(E1, E2, E3)
    , ...)
    |
    kzalloc(
    - (E1) * (E2) * E3
    + array3_size(E1, E2, E3)
    , ...)
    |
    kzalloc(
    - (E1) * (E2) * (E3)
    + array3_size(E1, E2, E3)
    , ...)
    |
    kzalloc(
    - E1 * E2 * E3
    + array3_size(E1, E2, E3)
    , ...)
    )

    // And then all remaining 2 factors products when they're not all constants,
    // keeping sizeof() as the second factor argument.
    @@
    expression THING, E1, E2;
    type TYPE;
    constant C1, C2, C3;
    @@

    (
    kzalloc(sizeof(THING) * C2, ...)
    |
    kzalloc(sizeof(TYPE) * C2, ...)
    |
    kzalloc(C1 * C2 * C3, ...)
    |
    kzalloc(C1 * C2, ...)
    |
    - kzalloc
    + kcalloc
    (
    - sizeof(TYPE) * (E2)
    + E2, sizeof(TYPE)
    , ...)
    |
    - kzalloc
    + kcalloc
    (
    - sizeof(TYPE) * E2
    + E2, sizeof(TYPE)
    , ...)
    |
    - kzalloc
    + kcalloc
    (
    - sizeof(THING) * (E2)
    + E2, sizeof(THING)
    , ...)
    |
    - kzalloc
    + kcalloc
    (
    - sizeof(THING) * E2
    + E2, sizeof(THING)
    , ...)
    |
    - kzalloc
    + kcalloc
    (
    - (E1) * E2
    + E1, E2
    , ...)
    |
    - kzalloc
    + kcalloc
    (
    - (E1) * (E2)
    + E1, E2
    , ...)
    |
    - kzalloc
    + kcalloc
    (
    - E1 * E2
    + E1, E2
    , ...)
    )

    Signed-off-by: Kees Cook

    Kees Cook
     
  • The kmalloc() function has a 2-factor argument form, kmalloc_array(). This
    patch replaces cases of:

    kmalloc(a * b, gfp)

    with:
    kmalloc_array(a * b, gfp)

    as well as handling cases of:

    kmalloc(a * b * c, gfp)

    with:

    kmalloc(array3_size(a, b, c), gfp)

    as it's slightly less ugly than:

    kmalloc_array(array_size(a, b), c, gfp)

    This does, however, attempt to ignore constant size factors like:

    kmalloc(4 * 1024, gfp)

    though any constants defined via macros get caught up in the conversion.

    Any factors with a sizeof() of "unsigned char", "char", and "u8" were
    dropped, since they're redundant.

    The tools/ directory was manually excluded, since it has its own
    implementation of kmalloc().

    The Coccinelle script used for this was:

    // Fix redundant parens around sizeof().
    @@
    type TYPE;
    expression THING, E;
    @@

    (
    kmalloc(
    - (sizeof(TYPE)) * E
    + sizeof(TYPE) * E
    , ...)
    |
    kmalloc(
    - (sizeof(THING)) * E
    + sizeof(THING) * E
    , ...)
    )

    // Drop single-byte sizes and redundant parens.
    @@
    expression COUNT;
    typedef u8;
    typedef __u8;
    @@

    (
    kmalloc(
    - sizeof(u8) * (COUNT)
    + COUNT
    , ...)
    |
    kmalloc(
    - sizeof(__u8) * (COUNT)
    + COUNT
    , ...)
    |
    kmalloc(
    - sizeof(char) * (COUNT)
    + COUNT
    , ...)
    |
    kmalloc(
    - sizeof(unsigned char) * (COUNT)
    + COUNT
    , ...)
    |
    kmalloc(
    - sizeof(u8) * COUNT
    + COUNT
    , ...)
    |
    kmalloc(
    - sizeof(__u8) * COUNT
    + COUNT
    , ...)
    |
    kmalloc(
    - sizeof(char) * COUNT
    + COUNT
    , ...)
    |
    kmalloc(
    - sizeof(unsigned char) * COUNT
    + COUNT
    , ...)
    )

    // 2-factor product with sizeof(type/expression) and identifier or constant.
    @@
    type TYPE;
    expression THING;
    identifier COUNT_ID;
    constant COUNT_CONST;
    @@

    (
    - kmalloc
    + kmalloc_array
    (
    - sizeof(TYPE) * (COUNT_ID)
    + COUNT_ID, sizeof(TYPE)
    , ...)
    |
    - kmalloc
    + kmalloc_array
    (
    - sizeof(TYPE) * COUNT_ID
    + COUNT_ID, sizeof(TYPE)
    , ...)
    |
    - kmalloc
    + kmalloc_array
    (
    - sizeof(TYPE) * (COUNT_CONST)
    + COUNT_CONST, sizeof(TYPE)
    , ...)
    |
    - kmalloc
    + kmalloc_array
    (
    - sizeof(TYPE) * COUNT_CONST
    + COUNT_CONST, sizeof(TYPE)
    , ...)
    |
    - kmalloc
    + kmalloc_array
    (
    - sizeof(THING) * (COUNT_ID)
    + COUNT_ID, sizeof(THING)
    , ...)
    |
    - kmalloc
    + kmalloc_array
    (
    - sizeof(THING) * COUNT_ID
    + COUNT_ID, sizeof(THING)
    , ...)
    |
    - kmalloc
    + kmalloc_array
    (
    - sizeof(THING) * (COUNT_CONST)
    + COUNT_CONST, sizeof(THING)
    , ...)
    |
    - kmalloc
    + kmalloc_array
    (
    - sizeof(THING) * COUNT_CONST
    + COUNT_CONST, sizeof(THING)
    , ...)
    )

    // 2-factor product, only identifiers.
    @@
    identifier SIZE, COUNT;
    @@

    - kmalloc
    + kmalloc_array
    (
    - SIZE * COUNT
    + COUNT, SIZE
    , ...)

    // 3-factor product with 1 sizeof(type) or sizeof(expression), with
    // redundant parens removed.
    @@
    expression THING;
    identifier STRIDE, COUNT;
    type TYPE;
    @@

    (
    kmalloc(
    - sizeof(TYPE) * (COUNT) * (STRIDE)
    + array3_size(COUNT, STRIDE, sizeof(TYPE))
    , ...)
    |
    kmalloc(
    - sizeof(TYPE) * (COUNT) * STRIDE
    + array3_size(COUNT, STRIDE, sizeof(TYPE))
    , ...)
    |
    kmalloc(
    - sizeof(TYPE) * COUNT * (STRIDE)
    + array3_size(COUNT, STRIDE, sizeof(TYPE))
    , ...)
    |
    kmalloc(
    - sizeof(TYPE) * COUNT * STRIDE
    + array3_size(COUNT, STRIDE, sizeof(TYPE))
    , ...)
    |
    kmalloc(
    - sizeof(THING) * (COUNT) * (STRIDE)
    + array3_size(COUNT, STRIDE, sizeof(THING))
    , ...)
    |
    kmalloc(
    - sizeof(THING) * (COUNT) * STRIDE
    + array3_size(COUNT, STRIDE, sizeof(THING))
    , ...)
    |
    kmalloc(
    - sizeof(THING) * COUNT * (STRIDE)
    + array3_size(COUNT, STRIDE, sizeof(THING))
    , ...)
    |
    kmalloc(
    - sizeof(THING) * COUNT * STRIDE
    + array3_size(COUNT, STRIDE, sizeof(THING))
    , ...)
    )

    // 3-factor product with 2 sizeof(variable), with redundant parens removed.
    @@
    expression THING1, THING2;
    identifier COUNT;
    type TYPE1, TYPE2;
    @@

    (
    kmalloc(
    - sizeof(TYPE1) * sizeof(TYPE2) * COUNT
    + array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
    , ...)
    |
    kmalloc(
    - sizeof(TYPE1) * sizeof(THING2) * (COUNT)
    + array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
    , ...)
    |
    kmalloc(
    - sizeof(THING1) * sizeof(THING2) * COUNT
    + array3_size(COUNT, sizeof(THING1), sizeof(THING2))
    , ...)
    |
    kmalloc(
    - sizeof(THING1) * sizeof(THING2) * (COUNT)
    + array3_size(COUNT, sizeof(THING1), sizeof(THING2))
    , ...)
    |
    kmalloc(
    - sizeof(TYPE1) * sizeof(THING2) * COUNT
    + array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
    , ...)
    |
    kmalloc(
    - sizeof(TYPE1) * sizeof(THING2) * (COUNT)
    + array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
    , ...)
    )

    // 3-factor product, only identifiers, with redundant parens removed.
    @@
    identifier STRIDE, SIZE, COUNT;
    @@

    (
    kmalloc(
    - (COUNT) * STRIDE * SIZE
    + array3_size(COUNT, STRIDE, SIZE)
    , ...)
    |
    kmalloc(
    - COUNT * (STRIDE) * SIZE
    + array3_size(COUNT, STRIDE, SIZE)
    , ...)
    |
    kmalloc(
    - COUNT * STRIDE * (SIZE)
    + array3_size(COUNT, STRIDE, SIZE)
    , ...)
    |
    kmalloc(
    - (COUNT) * (STRIDE) * SIZE
    + array3_size(COUNT, STRIDE, SIZE)
    , ...)
    |
    kmalloc(
    - COUNT * (STRIDE) * (SIZE)
    + array3_size(COUNT, STRIDE, SIZE)
    , ...)
    |
    kmalloc(
    - (COUNT) * STRIDE * (SIZE)
    + array3_size(COUNT, STRIDE, SIZE)
    , ...)
    |
    kmalloc(
    - (COUNT) * (STRIDE) * (SIZE)
    + array3_size(COUNT, STRIDE, SIZE)
    , ...)
    |
    kmalloc(
    - COUNT * STRIDE * SIZE
    + array3_size(COUNT, STRIDE, SIZE)
    , ...)
    )

    // Any remaining multi-factor products, first at least 3-factor products,
    // when they're not all constants...
    @@
    expression E1, E2, E3;
    constant C1, C2, C3;
    @@

    (
    kmalloc(C1 * C2 * C3, ...)
    |
    kmalloc(
    - (E1) * E2 * E3
    + array3_size(E1, E2, E3)
    , ...)
    |
    kmalloc(
    - (E1) * (E2) * E3
    + array3_size(E1, E2, E3)
    , ...)
    |
    kmalloc(
    - (E1) * (E2) * (E3)
    + array3_size(E1, E2, E3)
    , ...)
    |
    kmalloc(
    - E1 * E2 * E3
    + array3_size(E1, E2, E3)
    , ...)
    )

    // And then all remaining 2 factors products when they're not all constants,
    // keeping sizeof() as the second factor argument.
    @@
    expression THING, E1, E2;
    type TYPE;
    constant C1, C2, C3;
    @@

    (
    kmalloc(sizeof(THING) * C2, ...)
    |
    kmalloc(sizeof(TYPE) * C2, ...)
    |
    kmalloc(C1 * C2 * C3, ...)
    |
    kmalloc(C1 * C2, ...)
    |
    - kmalloc
    + kmalloc_array
    (
    - sizeof(TYPE) * (E2)
    + E2, sizeof(TYPE)
    , ...)
    |
    - kmalloc
    + kmalloc_array
    (
    - sizeof(TYPE) * E2
    + E2, sizeof(TYPE)
    , ...)
    |
    - kmalloc
    + kmalloc_array
    (
    - sizeof(THING) * (E2)
    + E2, sizeof(THING)
    , ...)
    |
    - kmalloc
    + kmalloc_array
    (
    - sizeof(THING) * E2
    + E2, sizeof(THING)
    , ...)
    |
    - kmalloc
    + kmalloc_array
    (
    - (E1) * E2
    + E1, E2
    , ...)
    |
    - kmalloc
    + kmalloc_array
    (
    - (E1) * (E2)
    + E1, E2
    , ...)
    |
    - kmalloc
    + kmalloc_array
    (
    - E1 * E2
    + E1, E2
    , ...)
    )

    Signed-off-by: Kees Cook

    Kees Cook
     

05 Jun, 2018

2 commits

  • Pull aio updates from Al Viro:
    "Majority of AIO stuff this cycle. aio-fsync and aio-poll, mostly.

    The only thing I'm holding back for a day or so is Adam's aio ioprio -
    his last-minute fixup is trivial (missing stub in !CONFIG_BLOCK case),
    but let it sit in -next for decency sake..."

    * 'work.aio-1' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (46 commits)
    aio: sanitize the limit checking in io_submit(2)
    aio: fold do_io_submit() into callers
    aio: shift copyin of iocb into io_submit_one()
    aio_read_events_ring(): make a bit more readable
    aio: all callers of aio_{read,write,fsync,poll} treat 0 and -EIOCBQUEUED the same way
    aio: take list removal to (some) callers of aio_complete()
    aio: add missing break for the IOCB_CMD_FDSYNC case
    random: convert to ->poll_mask
    timerfd: convert to ->poll_mask
    eventfd: switch to ->poll_mask
    pipe: convert to ->poll_mask
    crypto: af_alg: convert to ->poll_mask
    net/rxrpc: convert to ->poll_mask
    net/iucv: convert to ->poll_mask
    net/phonet: convert to ->poll_mask
    net/nfc: convert to ->poll_mask
    net/caif: convert to ->poll_mask
    net/bluetooth: convert to ->poll_mask
    net/sctp: convert to ->poll_mask
    net/tipc: convert to ->poll_mask
    ...

    Linus Torvalds
     
  • Pull procfs updates from Al Viro:
    "Christoph's proc_create_... cleanups series"

    * 'hch.procfs' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (44 commits)
    xfs, proc: hide unused xfs procfs helpers
    isdn/gigaset: add back gigaset_procinfo assignment
    proc: update SIZEOF_PDE_INLINE_NAME for the new pde fields
    tty: replace ->proc_fops with ->proc_show
    ide: replace ->proc_fops with ->proc_show
    ide: remove ide_driver_proc_write
    isdn: replace ->proc_fops with ->proc_show
    atm: switch to proc_create_seq_private
    atm: simplify procfs code
    bluetooth: switch to proc_create_seq_data
    netfilter/x_tables: switch to proc_create_seq_private
    netfilter/xt_hashlimit: switch to proc_create_{seq,single}_data
    neigh: switch to proc_create_seq_data
    hostap: switch to proc_create_{seq,single}_data
    bonding: switch to proc_create_seq_data
    rtc/proc: switch to proc_create_single_data
    drbd: switch to proc_create_single
    resource: switch to proc_create_seq_data
    staging/rtl8192u: simplify procfs code
    jfs: simplify procfs code
    ...

    Linus Torvalds
     

26 May, 2018

2 commits


23 May, 2018

1 commit

  • In divasmain.c, the function divas_write() firstly invokes the function
    diva_xdi_open_adapter() to open the adapter that matches with the adapter
    number provided by the user, and then invokes the function diva_xdi_write()
    to perform the write operation using the matched adapter. The two functions
    diva_xdi_open_adapter() and diva_xdi_write() are located in diva.c.

    In diva_xdi_open_adapter(), the user command is copied to the object 'msg'
    from the userspace pointer 'src' through the function pointer 'cp_fn',
    which eventually calls copy_from_user() to do the copy. Then, the adapter
    number 'msg.adapter' is used to find out a matched adapter from the
    'adapter_queue'. A matched adapter will be returned if it is found.
    Otherwise, NULL is returned to indicate the failure of the verification on
    the adapter number.

    As mentioned above, if a matched adapter is returned, the function
    diva_xdi_write() is invoked to perform the write operation. In this
    function, the user command is copied once again from the userspace pointer
    'src', which is the same as the 'src' pointer in diva_xdi_open_adapter() as
    both of them are from the 'buf' pointer in divas_write(). Similarly, the
    copy is achieved through the function pointer 'cp_fn', which finally calls
    copy_from_user(). After the successful copy, the corresponding command
    processing handler of the matched adapter is invoked to perform the write
    operation.

    It is obvious that there are two copies here from userspace, one is in
    diva_xdi_open_adapter(), and one is in diva_xdi_write(). Plus, both of
    these two copies share the same source userspace pointer, i.e., the 'buf'
    pointer in divas_write(). Given that a malicious userspace process can race
    to change the content pointed by the 'buf' pointer, this can pose potential
    security issues. For example, in the first copy, the user provides a valid
    adapter number to pass the verification process and a valid adapter can be
    found. Then the user can modify the adapter number to an invalid number.
    This way, the user can bypass the verification process of the adapter
    number and inject inconsistent data.

    This patch reuses the data copied in
    diva_xdi_open_adapter() and passes it to diva_xdi_write(). This way, the
    above issues can be avoided.

    Signed-off-by: Wenwen Wang
    Signed-off-by: David S. Miller

    Wenwen Wang
     

18 May, 2018

1 commit


16 May, 2018

3 commits


13 Apr, 2018

1 commit

  • There's an ongoing effort to remove VLAs[1] from the kernel to eventually
    turn on -Wvla. Remove the VLAs from the mISDN code by switching to using
    kstrdup in one place and using an upper bound in another.

    Signed-off-by: Laura Abbott
    Signed-off-by: David S. Miller

    Laura Abbott
     

04 Apr, 2018

1 commit

  • Pull networking updates from David Miller:

    1) Support offloading wireless authentication to userspace via
    NL80211_CMD_EXTERNAL_AUTH, from Srinivas Dasari.

    2) A lot of work on network namespace setup/teardown from Kirill Tkhai.
    Setup and cleanup of namespaces now all run asynchronously and thus
    performance is significantly increased.

    3) Add rx/tx timestamping support to mv88e6xxx driver, from Brandon
    Streiff.

    4) Support zerocopy on RDS sockets, from Sowmini Varadhan.

    5) Use denser instruction encoding in x86 eBPF JIT, from Daniel
    Borkmann.

    6) Support hw offload of vlan filtering in mvpp2 dreiver, from Maxime
    Chevallier.

    7) Support grafting of child qdiscs in mlxsw driver, from Nogah
    Frankel.

    8) Add packet forwarding tests to selftests, from Ido Schimmel.

    9) Deal with sub-optimal GSO packets better in BBR congestion control,
    from Eric Dumazet.

    10) Support 5-tuple hashing in ipv6 multipath routing, from David Ahern.

    11) Add path MTU tests to selftests, from Stefano Brivio.

    12) Various bits of IPSEC offloading support for mlx5, from Aviad
    Yehezkel, Yossi Kuperman, and Saeed Mahameed.

    13) Support RSS spreading on ntuple filters in SFC driver, from Edward
    Cree.

    14) Lots of sockmap work from John Fastabend. Applications can use eBPF
    to filter sendmsg and sendpage operations.

    15) In-kernel receive TLS support, from Dave Watson.

    16) Add XDP support to ixgbevf, this is significant because it should
    allow optimized XDP usage in various cloud environments. From Tony
    Nguyen.

    17) Add new Intel E800 series "ice" ethernet driver, from Anirudh
    Venkataramanan et al.

    18) IP fragmentation match offload support in nfp driver, from Pieter
    Jansen van Vuuren.

    19) Support XDP redirect in i40e driver, from Björn Töpel.

    20) Add BPF_RAW_TRACEPOINT program type for accessing the arguments of
    tracepoints in their raw form, from Alexei Starovoitov.

    21) Lots of striding RQ improvements to mlx5 driver with many
    performance improvements, from Tariq Toukan.

    22) Use rhashtable for inet frag reassembly, from Eric Dumazet.

    * git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next: (1678 commits)
    net: mvneta: improve suspend/resume
    net: mvneta: split rxq/txq init and txq deinit into SW and HW parts
    ipv6: frags: fix /proc/sys/net/ipv6/ip6frag_low_thresh
    net: bgmac: Fix endian access in bgmac_dma_tx_ring_free()
    net: bgmac: Correctly annotate register space
    route: check sysctl_fib_multipath_use_neigh earlier than hash
    fix typo in command value in drivers/net/phy/mdio-bitbang.
    sky2: Increase D3 delay to sky2 stops working after suspend
    net/mlx5e: Set EQE based as default TX interrupt moderation mode
    ibmvnic: Disable irqs before exiting reset from closed state
    net: sched: do not emit messages while holding spinlock
    vlan: also check phy_driver ts_info for vlan's real device
    Bluetooth: Mark expected switch fall-throughs
    Bluetooth: Set HCI_QUIRK_SIMULTANEOUS_DISCOVERY for BTUSB_QCA_ROME
    Bluetooth: btrsi: remove unused including
    Bluetooth: hci_bcm: Remove DMI quirk for the MINIX Z83-4
    sh_eth: kill useless check in __sh_eth_get_regs()
    sh_eth: add sh_eth_cpu_data::no_xdfar flag
    ipv6: factorize sk_wmem_alloc updates done by __ip6_append_data()
    ipv4: factorize sk_wmem_alloc updates done by __ip_append_data()
    ...

    Linus Torvalds
     

26 Mar, 2018

1 commit


13 Feb, 2018

1 commit

  • Changes since v1:
    Added changes in these files:
    drivers/infiniband/hw/usnic/usnic_transport.c
    drivers/staging/lustre/lnet/lnet/lib-socket.c
    drivers/target/iscsi/iscsi_target_login.c
    drivers/vhost/net.c
    fs/dlm/lowcomms.c
    fs/ocfs2/cluster/tcp.c
    security/tomoyo/network.c

    Before:
    All these functions either return a negative error indicator,
    or store length of sockaddr into "int *socklen" parameter
    and return zero on success.

    "int *socklen" parameter is awkward. For example, if caller does not
    care, it still needs to provide on-stack storage for the value
    it does not need.

    None of the many FOO_getname() functions of various protocols
    ever used old value of *socklen. They always just overwrite it.

    This change drops this parameter, and makes all these functions, on success,
    return length of sockaddr. It's always >= 0 and can be differentiated
    from an error.

    Tests in callers are changed from "if (err)" to "if (err < 0)", where needed.

    rpc_sockname() lost "int buflen" parameter, since its only use was
    to be passed to kernel_getsockname() as &buflen and subsequently
    not used in any way.

    Userspace API is not changed.

    text data bss dec hex filename
    30108430 2633624 873672 33615726 200ef6e vmlinux.before.o
    30108109 2633612 873672 33615393 200ee21 vmlinux.o

    Signed-off-by: Denys Vlasenko
    CC: David S. Miller
    CC: linux-kernel@vger.kernel.org
    CC: netdev@vger.kernel.org
    CC: linux-bluetooth@vger.kernel.org
    CC: linux-decnet-user@lists.sourceforge.net
    CC: linux-wireless@vger.kernel.org
    CC: linux-rdma@vger.kernel.org
    CC: linux-sctp@vger.kernel.org
    CC: linux-nfs@vger.kernel.org
    CC: linux-x25@vger.kernel.org
    Signed-off-by: David S. Miller

    Denys Vlasenko
     

12 Feb, 2018

1 commit

  • This is the mindless scripted replacement of kernel use of POLL*
    variables as described by Al, done by this script:

    for V in IN OUT PRI ERR RDNORM RDBAND WRNORM WRBAND HUP RDHUP NVAL MSG; do
    L=`git grep -l -w POLL$V | grep -v '^t' | grep -v /um/ | grep -v '^sa' | grep -v '/poll.h$'|grep -v '^D'`
    for f in $L; do sed -i "-es/^\([^\"]*\)\(\\)/\\1E\\2/" $f; done
    done

    with de-mangling cleanups yet to come.

    NOTE! On almost all architectures, the EPOLL* constants have the same
    values as the POLL* constants do. But they keyword here is "almost".
    For various bad reasons they aren't the same, and epoll() doesn't
    actually work quite correctly in some cases due to this on Sparc et al.

    The next patch from Al will sort out the final differences, and we
    should be all done.

    Scripted-by: Al Viro
    Signed-off-by: Linus Torvalds

    Linus Torvalds
     

31 Jan, 2018

1 commit

  • Pull kern_recvmsg reduction from Al Viro:
    "kernel_recvmsg() is a set_fs()-using wrapper for sock_recvmsg(). In
    all but one case that is not needed - use of ITER_KVEC for ->msg_iter
    takes care of the data and does not care about set_fs(). The only
    exception is svc_udp_recvfrom() where we want cmsg to be store into
    kernel object; everything else can just use sock_recvmsg() and be done
    with that.

    A followup converting svc_udp_recvfrom() away from set_fs() (and
    killing kernel_recvmsg() off) is *NOT* in here - I'd like to hear what
    netdev folks think of the approach proposed in that followup)"

    * 'work.sock_recvmsg' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
    tipc: switch to sock_recvmsg()
    smc: switch to sock_recvmsg()
    ipvs: switch to sock_recvmsg()
    mISDN: switch to sock_recvmsg()
    drbd: switch to sock_recvmsg()
    lustre lnet_sock_read(): switch to sock_recvmsg()
    cfs2: switch to sock_recvmsg()
    ncpfs: switch to sock_recvmsg()
    dlm: switch to sock_recvmsg()
    svc_recvfrom(): switch to sock_recvmsg()

    Linus Torvalds
     

03 Dec, 2017

1 commit


29 Nov, 2017

1 commit