03 Dec, 2020

1 commit

  • The .x25_addr[] address comes from the user and is not necessarily
    NUL terminated. This leads to a couple problems. The first problem is
    that the strlen() in x25_bind() can read beyond the end of the buffer.

    The second problem is more subtle and could result in memory corruption.
    The call tree is:
    x25_connect()
    --> x25_write_internal()
    --> x25_addr_aton()

    The .x25_addr[] buffers are copied to the "addresses" buffer from
    x25_write_internal() so it will lead to stack corruption.

    Verify that the strings are NUL terminated and return -EINVAL if they
    are not.

    Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
    Fixes: a9288525d2ae ("X25: Dont let x25_bind use addresses containing characters")
    Reported-by: "kiyin(尹亮)"
    Signed-off-by: Dan Carpenter
    Acked-by: Martin Schiller
    Link: https://lore.kernel.org/r/X8ZeAKm8FnFpN//B@mwanda
    Signed-off-by: Jakub Kicinski

    Dan Carpenter
     

13 Nov, 2020

1 commit

  • The x25_disconnect function in x25_subr.c would decrease the refcount of
    "x25->neighbour" (struct x25_neigh) and reset this pointer to NULL.

    However, the x25_rx_call_request function in af_x25.c, which is called
    when we receive a connection request, does not increase the refcount when
    it assigns the pointer.

    Fix this issue by increasing the refcount of "struct x25_neigh" in
    x25_rx_call_request.

    This patch fixes frequent kernel crashes when using AF_X25 sockets.

    Fixes: 4becb7ee5b3d ("net/x25: Fix x25_neigh refcnt leak when x25 disconnect")
    Cc: Martin Schiller
    Signed-off-by: Xie He
    Link: https://lore.kernel.org/r/20201112103506.5875-1-xie.he.0141@gmail.com
    Signed-off-by: Jakub Kicinski

    Xie He
     

12 Nov, 2020

1 commit

  • This fixes a regression for blocking connects introduced by commit
    4becb7ee5b3d ("net/x25: Fix x25_neigh refcnt leak when x25 disconnect").

    The x25->neighbour is already set to "NULL" by x25_disconnect() now,
    while a blocking connect is waiting in
    x25_wait_for_connection_establishment(). Therefore x25->neighbour must
    not be accessed here again and x25->state is also already set to
    X25_STATE_0 by x25_disconnect().

    Fixes: 4becb7ee5b3d ("net/x25: Fix x25_neigh refcnt leak when x25 disconnect")
    Signed-off-by: Martin Schiller
    Reviewed-by: Xie He
    Link: https://lore.kernel.org/r/20201109065449.9014-1-ms@dev.tdt.de
    Signed-off-by: Jakub Kicinski

    Martin Schiller
     

24 Aug, 2020

1 commit

  • Replace the existing /* fall through */ comments and its variants with
    the new pseudo-keyword macro fallthrough[1]. Also, remove unnecessary
    fall-through markings when it is the case.

    [1] https://www.kernel.org/doc/html/v5.7/process/deprecated.html?highlight=fallthrough#implicit-switch-case-fall-through

    Signed-off-by: Gustavo A. R. Silva

    Gustavo A. R. Silva
     

25 Jul, 2020

1 commit

  • Rework the remaining setsockopt code to pass a sockptr_t instead of a
    plain user pointer. This removes the last remaining set_fs(KERNEL_DS)
    outside of architecture specific code.

    Signed-off-by: Christoph Hellwig
    Acked-by: Stefan Schmidt [ieee802154]
    Acked-by: Matthieu Baerts
    Signed-off-by: David S. Miller

    Christoph Hellwig
     

14 Jul, 2020

1 commit


08 Jul, 2020

1 commit

  • Rationale:
    Reduces attack surface on kernel devs opening the links for MITM
    as HTTPS traffic is much harder to manipulate.

    Deterministic algorithm:
    For each file:
    If not .svg:
    For each line:
    If doesn't contain `\bxmlns\b`:
    For each link, `\bhttp://[^# \t\r\n]*(?:\w|/)`:
    If both the HTTP and HTTPS versions
    return 200 OK and serve the same content:
    Replace HTTP with HTTPS.

    Signed-off-by: Alexander A. Klimov
    Signed-off-by: David S. Miller

    Alexander A. Klimov
     

14 Jun, 2020

1 commit

  • Since commit 84af7a6194e4 ("checkpatch: kconfig: prefer 'help' over
    '---help---'"), the number of '---help---' has been gradually
    decreasing, but there are still more than 2400 instances.

    This commit finishes the conversion. While I touched the lines,
    I also fixed the indentation.

    There are a variety of indentation styles found.

    a) 4 spaces + '---help---'
    b) 7 spaces + '---help---'
    c) 8 spaces + '---help---'
    d) 1 space + 1 tab + '---help---'
    e) 1 tab + '---help---' (correct indentation)
    f) 1 tab + 1 space + '---help---'
    g) 1 tab + 2 spaces + '---help---'

    In order to convert all of them to 1 tab + 'help', I ran the
    following commend:

    $ find . -name 'Kconfig*' | xargs sed -i 's/^[[:space:]]*---help---/\thelp/'

    Signed-off-by: Masahiro Yamada

    Masahiro Yamada
     

07 May, 2020

1 commit


02 May, 2020

2 commits


29 Apr, 2020

1 commit

  • We should check null before do x25_neigh_put in x25_disconnect,
    otherwise may cause null-ptr-deref like this:

    #include
    #include

    int main() {
    int sck_x25;
    sck_x25 = socket(AF_X25, SOCK_SEQPACKET, 0);
    close(sck_x25);
    return 0;
    }

    BUG: kernel NULL pointer dereference, address: 00000000000000d8
    CPU: 0 PID: 4817 Comm: t2 Not tainted 5.7.0-rc3+ #159
    Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.9.3-
    RIP: 0010:x25_disconnect+0x91/0xe0
    Call Trace:
    x25_release+0x18a/0x1b0
    __sock_release+0x3d/0xc0
    sock_close+0x13/0x20
    __fput+0x107/0x270
    ____fput+0x9/0x10
    task_work_run+0x6d/0xb0
    exit_to_usermode_loop+0x102/0x110
    do_syscall_64+0x23c/0x260
    entry_SYSCALL_64_after_hwframe+0x49/0xb3

    Reported-by: syzbot+6db548b615e5aeefdce2@syzkaller.appspotmail.com
    Fixes: 4becb7ee5b3d ("net/x25: Fix x25_neigh refcnt leak when x25 disconnect")
    Signed-off-by: YueHaibing
    Signed-off-by: David S. Miller

    YueHaibing
     

28 Apr, 2020

1 commit

  • x25_connect() invokes x25_get_neigh(), which returns a reference of the
    specified x25_neigh object to "x25->neighbour" with increased refcnt.

    When x25 connect success and returns, the reference still be hold by
    "x25->neighbour", so the refcount should be decreased in
    x25_disconnect() to keep refcount balanced.

    The reference counting issue happens in x25_disconnect(), which forgets
    to decrease the refcnt increased by x25_get_neigh() in x25_connect(),
    causing a refcnt leak.

    Fix this issue by calling x25_neigh_put() before x25_disconnect()
    returns.

    Signed-off-by: Xiyu Yang
    Signed-off-by: Xin Tan
    Signed-off-by: David S. Miller

    Xiyu Yang
     

24 Apr, 2020

1 commit

  • x25_lapb_receive_frame() invokes x25_get_neigh(), which returns a
    reference of the specified x25_neigh object to "nb" with increased
    refcnt.

    When x25_lapb_receive_frame() returns, local variable "nb" becomes
    invalid, so the refcount should be decreased to keep refcount balanced.

    The reference counting issue happens in one path of
    x25_lapb_receive_frame(). When pskb_may_pull() returns false, the
    function forgets to decrease the refcnt increased by x25_get_neigh(),
    causing a refcnt leak.

    Fix this issue by calling x25_neigh_put() when pskb_may_pull() returns
    false.

    Fixes: cb101ed2c3c7 ("x25: Handle undersized/fragmented skbs")
    Signed-off-by: Xiyu Yang
    Signed-off-by: Xin Tan
    Signed-off-by: David S. Miller

    Xiyu Yang
     

17 Feb, 2020

1 commit


10 Jan, 2020

1 commit

  • This patch fixes 2 issues in x25_connect():

    1. It makes absolutely no sense to reset the neighbour and the
    connection state after a (successful) nonblocking call of x25_connect.
    This prevents any connection from being established, since the response
    (call accept) cannot be processed.

    2. Any further calls to x25_connect() while a call is pending should
    simply return, instead of creating new Call Request (on different
    logical channels).

    This patch should also fix the "KASAN: null-ptr-deref Write in
    x25_connect" and "BUG: unable to handle kernel NULL pointer dereference
    in x25_connect" bugs reported by syzbot.

    Signed-off-by: Martin Schiller
    Reported-by: syzbot+429c200ffc8772bfe070@syzkaller.appspotmail.com
    Reported-by: syzbot+eec0c87f31a7c3b66f7b@syzkaller.appspotmail.com
    Signed-off-by: David S. Miller

    Martin Schiller
     

10 Dec, 2019

1 commit

  • This is needed, because if the flag X25_ACCPT_APPRV_FLAG is not set on a
    socket (manual call confirmation) and the channel is cleared by remote
    before the manual call confirmation was sent, this situation needs to
    be handled.

    Signed-off-by: Martin Schiller
    Signed-off-by: David S. Miller

    Martin Schiller
     

07 Nov, 2019

1 commit


10 Oct, 2019

1 commit

  • sk_add_backlog() callers usually read sk->sk_rcvbuf without
    owning the socket lock. This means sk_rcvbuf value can
    be changed by other cpus, and KCSAN complains.

    Add READ_ONCE() annotations to document the lockless nature
    of these reads.

    Note that writes over sk_rcvbuf should also use WRITE_ONCE(),
    but this will be done in separate patches to ease stable
    backports (if we decide this is relevant for stable trees).

    BUG: KCSAN: data-race in tcp_add_backlog / tcp_recvmsg

    write to 0xffff88812ab369f8 of 8 bytes by interrupt on cpu 1:
    __sk_add_backlog include/net/sock.h:902 [inline]
    sk_add_backlog include/net/sock.h:933 [inline]
    tcp_add_backlog+0x45a/0xcc0 net/ipv4/tcp_ipv4.c:1737
    tcp_v4_rcv+0x1aba/0x1bf0 net/ipv4/tcp_ipv4.c:1925
    ip_protocol_deliver_rcu+0x51/0x470 net/ipv4/ip_input.c:204
    ip_local_deliver_finish+0x110/0x140 net/ipv4/ip_input.c:231
    NF_HOOK include/linux/netfilter.h:305 [inline]
    NF_HOOK include/linux/netfilter.h:299 [inline]
    ip_local_deliver+0x133/0x210 net/ipv4/ip_input.c:252
    dst_input include/net/dst.h:442 [inline]
    ip_rcv_finish+0x121/0x160 net/ipv4/ip_input.c:413
    NF_HOOK include/linux/netfilter.h:305 [inline]
    NF_HOOK include/linux/netfilter.h:299 [inline]
    ip_rcv+0x18f/0x1a0 net/ipv4/ip_input.c:523
    __netif_receive_skb_one_core+0xa7/0xe0 net/core/dev.c:5004
    __netif_receive_skb+0x37/0xf0 net/core/dev.c:5118
    netif_receive_skb_internal+0x59/0x190 net/core/dev.c:5208
    napi_skb_finish net/core/dev.c:5671 [inline]
    napi_gro_receive+0x28f/0x330 net/core/dev.c:5704
    receive_buf+0x284/0x30b0 drivers/net/virtio_net.c:1061
    virtnet_receive drivers/net/virtio_net.c:1323 [inline]
    virtnet_poll+0x436/0x7d0 drivers/net/virtio_net.c:1428
    napi_poll net/core/dev.c:6352 [inline]
    net_rx_action+0x3ae/0xa50 net/core/dev.c:6418

    read to 0xffff88812ab369f8 of 8 bytes by task 7271 on cpu 0:
    tcp_recvmsg+0x470/0x1a30 net/ipv4/tcp.c:2047
    inet_recvmsg+0xbb/0x250 net/ipv4/af_inet.c:838
    sock_recvmsg_nosec net/socket.c:871 [inline]
    sock_recvmsg net/socket.c:889 [inline]
    sock_recvmsg+0x92/0xb0 net/socket.c:885
    sock_read_iter+0x15f/0x1e0 net/socket.c:967
    call_read_iter include/linux/fs.h:1864 [inline]
    new_sync_read+0x389/0x4f0 fs/read_write.c:414
    __vfs_read+0xb1/0xc0 fs/read_write.c:427
    vfs_read fs/read_write.c:461 [inline]
    vfs_read+0x143/0x2c0 fs/read_write.c:446
    ksys_read+0xd5/0x1b0 fs/read_write.c:587
    __do_sys_read fs/read_write.c:597 [inline]
    __se_sys_read fs/read_write.c:595 [inline]
    __x64_sys_read+0x4c/0x60 fs/read_write.c:595
    do_syscall_64+0xcf/0x2f0 arch/x86/entry/common.c:296
    entry_SYSCALL_64_after_hwframe+0x44/0xa9

    Reported by Kernel Concurrency Sanitizer on:
    CPU: 0 PID: 7271 Comm: syz-fuzzer Not tainted 5.3.0+ #0
    Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011

    Signed-off-by: Eric Dumazet
    Reported-by: syzbot
    Signed-off-by: Jakub Kicinski

    Eric Dumazet
     

24 May, 2019

1 commit

  • Based on 1 normalized pattern(s):

    this module is free software you can redistribute it and or modify
    it under the terms of the gnu general public license as published by
    the free software foundation either version 2 of the license or at
    your option any later version

    extracted by the scancode license scanner the SPDX license identifier

    GPL-2.0-or-later

    has been chosen to replace the boilerplate/reference in 18 file(s).

    Signed-off-by: Thomas Gleixner
    Reviewed-by: Allison Randal
    Cc: linux-spdx@vger.kernel.org
    Link: https://lkml.kernel.org/r/20190520170858.008906948@linutronix.de
    Signed-off-by: Greg Kroah-Hartman

    Thomas Gleixner
     

21 May, 2019

1 commit


20 Apr, 2019

1 commit

  • The SIOCGSTAMP/SIOCGSTAMPNS ioctl commands are implemented by many
    socket protocol handlers, and all of those end up calling the same
    sock_get_timestamp()/sock_get_timestampns() helper functions, which
    results in a lot of duplicate code.

    With the introduction of 64-bit time_t on 32-bit architectures, this
    gets worse, as we then need four different ioctl commands in each
    socket protocol implementation.

    To simplify that, let's add a new .gettstamp() operation in
    struct proto_ops, and move ioctl implementation into the common
    sock_ioctl()/compat_sock_ioctl_trans() functions that these all go
    through.

    We can reuse the sock_get_timestamp() implementation, but generalize
    it so it can deal with both native and compat mode, as well as
    timeval and timespec structures.

    Acked-by: Stefan Schmidt
    Acked-by: Neil Horman
    Acked-by: Marc Kleine-Budde
    Link: https://lore.kernel.org/lkml/CAK8P3a038aDQQotzua_QtKGhq8O9n+rdiz2=WDCp82ys8eUT+A@mail.gmail.com/
    Signed-off-by: Arnd Bergmann
    Acked-by: Willem de Bruijn
    Signed-off-by: David S. Miller

    Arnd Bergmann
     

12 Mar, 2019

1 commit

  • In case x25_connect() fails and frees the socket neighbour,
    we also need to undo the change done to x25->state.

    Before my last bug fix, we had use-after-free so this
    patch fixes a latent bug.

    syzbot report :

    kasan: CONFIG_KASAN_INLINE enabled
    kasan: GPF could be caused by NULL-ptr deref or user memory access
    general protection fault: 0000 [#1] PREEMPT SMP KASAN
    CPU: 1 PID: 16137 Comm: syz-executor.1 Not tainted 5.0.0+ #117
    Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
    RIP: 0010:x25_write_internal+0x1e8/0xdf0 net/x25/x25_subr.c:173
    Code: 00 40 88 b5 e0 fe ff ff 0f 85 01 0b 00 00 48 8b 8b 80 04 00 00 48 ba 00 00 00 00 00 fc ff df 48 8d 79 1c 48 89 fe 48 c1 ee 03 b6 34 16 48 89 fa 83 e2 07 83 c2 03 40 38 f2 7c 09 40 84 f6 0f
    RSP: 0018:ffff888076717a08 EFLAGS: 00010207
    RAX: ffff88805f2f2292 RBX: ffff8880a0ae6000 RCX: 0000000000000000
    kobject: 'loop5' (0000000018d0d0ee): kobject_uevent_env
    RDX: dffffc0000000000 RSI: 0000000000000003 RDI: 000000000000001c
    RBP: ffff888076717b40 R08: ffff8880950e0580 R09: ffffed100be5e46d
    R10: ffffed100be5e46c R11: ffff88805f2f2363 R12: ffff888065579840
    kobject: 'loop5' (0000000018d0d0ee): fill_kobj_path: path = '/devices/virtual/block/loop5'
    R13: 1ffff1100ece2f47 R14: 0000000000000013 R15: 0000000000000013
    FS: 00007fb88cf43700(0000) GS:ffff8880ae900000(0000) knlGS:0000000000000000
    CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
    CR2: 00007f9a42a41028 CR3: 0000000087a67000 CR4: 00000000001406e0
    DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
    DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
    Call Trace:
    x25_release+0xd0/0x340 net/x25/af_x25.c:658
    __sock_release+0xd3/0x2b0 net/socket.c:579
    sock_close+0x1b/0x30 net/socket.c:1162
    __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
    get_signal+0x1961/0x1d50 kernel/signal.c:2388
    do_signal+0x87/0x1940 arch/x86/kernel/signal.c:816
    exit_to_usermode_loop+0x244/0x2c0 arch/x86/entry/common.c:162
    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
    RIP: 0033:0x457f29
    Code: ad b8 fb ff c3 66 2e 0f 1f 84 00 00 00 00 00 66 90 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 7b b8 fb ff c3 66 2e 0f 1f 84 00 00 00 00
    RSP: 002b:00007fb88cf42c78 EFLAGS: 00000246 ORIG_RAX: 000000000000002a
    RAX: fffffffffffffe00 RBX: 0000000000000003 RCX: 0000000000457f29
    RDX: 0000000000000012 RSI: 0000000020000080 RDI: 0000000000000004
    RBP: 000000000073bf00 R08: 0000000000000000 R09: 0000000000000000
    R10: 0000000000000000 R11: 0000000000000246 R12: 00007fb88cf436d4
    R13: 00000000004be462 R14: 00000000004cec98 R15: 00000000ffffffff
    Modules linked in:

    Fixes: 95d6ebd53c79 ("net/x25: fix use-after-free in x25_device_event()")
    Signed-off-by: Eric Dumazet
    Cc: andrew hendry
    Reported-by: syzbot
    Signed-off-by: David S. Miller

    Eric Dumazet
     

11 Mar, 2019

1 commit

  • In case of failure x25_connect() does a x25_neigh_put(x25->neighbour)
    but forgets to clear x25->neighbour pointer, thus triggering use-after-free.

    Since the socket is visible in x25_list, we need to hold x25_list_lock
    to protect the operation.

    syzbot report :

    BUG: KASAN: use-after-free in x25_kill_by_device net/x25/af_x25.c:217 [inline]
    BUG: KASAN: use-after-free in x25_device_event+0x296/0x2b0 net/x25/af_x25.c:252
    Read of size 8 at addr ffff8880a030edd0 by task syz-executor003/7854

    CPU: 0 PID: 7854 Comm: syz-executor003 Not tainted 5.0.0+ #97
    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_load8_noabort+0x14/0x20 mm/kasan/generic_report.c:135
    x25_kill_by_device net/x25/af_x25.c:217 [inline]
    x25_device_event+0x296/0x2b0 net/x25/af_x25.c:252
    notifier_call_chain+0xc7/0x240 kernel/notifier.c:93
    __raw_notifier_call_chain kernel/notifier.c:394 [inline]
    raw_notifier_call_chain+0x2e/0x40 kernel/notifier.c:401
    call_netdevice_notifiers_info+0x3f/0x90 net/core/dev.c:1739
    call_netdevice_notifiers_extack net/core/dev.c:1751 [inline]
    call_netdevice_notifiers net/core/dev.c:1765 [inline]
    __dev_notify_flags+0x1e9/0x2c0 net/core/dev.c:7607
    dev_change_flags+0x10d/0x170 net/core/dev.c:7643
    dev_ifsioc+0x2b0/0x940 net/core/dev_ioctl.c:237
    dev_ioctl+0x1b8/0xc70 net/core/dev_ioctl.c:488
    sock_do_ioctl+0x1bd/0x300 net/socket.c:995
    sock_ioctl+0x32b/0x610 net/socket.c:1096
    vfs_ioctl fs/ioctl.c:46 [inline]
    file_ioctl fs/ioctl.c:509 [inline]
    do_vfs_ioctl+0xd6e/0x1390 fs/ioctl.c:696
    ksys_ioctl+0xab/0xd0 fs/ioctl.c:713
    __do_sys_ioctl fs/ioctl.c:720 [inline]
    __se_sys_ioctl fs/ioctl.c:718 [inline]
    __x64_sys_ioctl+0x73/0xb0 fs/ioctl.c:718
    do_syscall_64+0x103/0x610 arch/x86/entry/common.c:290
    entry_SYSCALL_64_after_hwframe+0x49/0xbe
    RIP: 0033:0x4467c9
    Code: e8 0c e8 ff ff 48 83 c4 18 c3 0f 1f 80 00 00 00 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 5b 07 fc ff c3 66 2e 0f 1f 84 00 00 00 00
    RSP: 002b:00007fdbea222d98 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
    RAX: ffffffffffffffda RBX: 00000000006dbc58 RCX: 00000000004467c9
    RDX: 0000000020000340 RSI: 0000000000008914 RDI: 0000000000000003
    RBP: 00000000006dbc50 R08: 00007fdbea223700 R09: 0000000000000000
    R10: 00007fdbea223700 R11: 0000000000000246 R12: 00000000006dbc5c
    R13: 6000030030626669 R14: 0000000000000000 R15: 0000000030626669

    Allocated by task 7843:
    save_stack+0x45/0xd0 mm/kasan/common.c:73
    set_track mm/kasan/common.c:85 [inline]
    __kasan_kmalloc mm/kasan/common.c:495 [inline]
    __kasan_kmalloc.constprop.0+0xcf/0xe0 mm/kasan/common.c:468
    kasan_kmalloc+0x9/0x10 mm/kasan/common.c:509
    kmem_cache_alloc_trace+0x151/0x760 mm/slab.c:3615
    kmalloc include/linux/slab.h:545 [inline]
    x25_link_device_up+0x46/0x3f0 net/x25/x25_link.c:249
    x25_device_event+0x116/0x2b0 net/x25/af_x25.c:242
    notifier_call_chain+0xc7/0x240 kernel/notifier.c:93
    __raw_notifier_call_chain kernel/notifier.c:394 [inline]
    raw_notifier_call_chain+0x2e/0x40 kernel/notifier.c:401
    call_netdevice_notifiers_info+0x3f/0x90 net/core/dev.c:1739
    call_netdevice_notifiers_extack net/core/dev.c:1751 [inline]
    call_netdevice_notifiers net/core/dev.c:1765 [inline]
    __dev_notify_flags+0x121/0x2c0 net/core/dev.c:7605
    dev_change_flags+0x10d/0x170 net/core/dev.c:7643
    dev_ifsioc+0x2b0/0x940 net/core/dev_ioctl.c:237
    dev_ioctl+0x1b8/0xc70 net/core/dev_ioctl.c:488
    sock_do_ioctl+0x1bd/0x300 net/socket.c:995
    sock_ioctl+0x32b/0x610 net/socket.c:1096
    vfs_ioctl fs/ioctl.c:46 [inline]
    file_ioctl fs/ioctl.c:509 [inline]
    do_vfs_ioctl+0xd6e/0x1390 fs/ioctl.c:696
    ksys_ioctl+0xab/0xd0 fs/ioctl.c:713
    __do_sys_ioctl fs/ioctl.c:720 [inline]
    __se_sys_ioctl fs/ioctl.c:718 [inline]
    __x64_sys_ioctl+0x73/0xb0 fs/ioctl.c:718
    do_syscall_64+0x103/0x610 arch/x86/entry/common.c:290
    entry_SYSCALL_64_after_hwframe+0x49/0xbe

    Freed by task 7865:
    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:457
    kasan_slab_free+0xe/0x10 mm/kasan/common.c:465
    __cache_free mm/slab.c:3494 [inline]
    kfree+0xcf/0x230 mm/slab.c:3811
    x25_neigh_put include/net/x25.h:253 [inline]
    x25_connect+0x8d8/0xde0 net/x25/af_x25.c:824
    __sys_connect+0x266/0x330 net/socket.c:1685
    __do_sys_connect net/socket.c:1696 [inline]
    __se_sys_connect net/socket.c:1693 [inline]
    __x64_sys_connect+0x73/0xb0 net/socket.c:1693
    do_syscall_64+0x103/0x610 arch/x86/entry/common.c:290
    entry_SYSCALL_64_after_hwframe+0x49/0xbe

    The buggy address belongs to the object at ffff8880a030edc0
    which belongs to the cache kmalloc-256 of size 256
    The buggy address is located 16 bytes inside of
    256-byte region [ffff8880a030edc0, ffff8880a030eec0)
    The buggy address belongs to the page:
    page:ffffea000280c380 count:1 mapcount:0 mapping:ffff88812c3f07c0 index:0x0
    flags: 0x1fffc0000000200(slab)
    raw: 01fffc0000000200 ffffea0002806788 ffffea00027f0188 ffff88812c3f07c0
    raw: 0000000000000000 ffff8880a030e000 000000010000000c 0000000000000000
    page dumped because: kasan: bad access detected

    Signed-off-by: Eric Dumazet
    Reported-by: syzbot+04babcefcd396fabec37@syzkaller.appspotmail.com
    Cc: andrew hendry
    Signed-off-by: David S. Miller

    Eric Dumazet
     

24 Feb, 2019

1 commit

  • syzbot was able to trigger another soft lockup [1]

    I first thought it was the O(N^2) issue I mentioned in my
    prior fix (f657d22ee1f "net/x25: do not hold the cpu
    too long in x25_new_lci()"), but I eventually found
    that x25_bind() was not checking SOCK_ZAPPED state under
    socket lock protection.

    This means that multiple threads can end up calling
    x25_insert_socket() for the same socket, and corrupt x25_list

    [1]
    watchdog: BUG: soft lockup - CPU#0 stuck for 123s! [syz-executor.2:10492]
    Modules linked in:
    irq event stamp: 27515
    hardirqs last enabled at (27514): [] trace_hardirqs_on_thunk+0x1a/0x1c
    hardirqs last disabled at (27515): [] trace_hardirqs_off_thunk+0x1a/0x1c
    softirqs last enabled at (32): [] x25_get_neigh+0xa3/0xd0 net/x25/x25_link.c:336
    softirqs last disabled at (34): [] x25_find_socket+0x23/0x140 net/x25/af_x25.c:341
    CPU: 0 PID: 10492 Comm: syz-executor.2 Not tainted 5.0.0-rc7+ #88
    Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
    RIP: 0010:__sanitizer_cov_trace_pc+0x4/0x50 kernel/kcov.c:97
    Code: f4 ff ff ff e8 11 9f ea ff 48 c7 05 12 fb e5 08 00 00 00 00 e9 c8 e9 ff ff 90 90 90 90 90 90 90 90 90 90 90 90 90 55 48 89 e5 8b 75 08 65 48 8b 04 25 40 ee 01 00 65 8b 15 38 0c 92 7e 81 e2
    RSP: 0018:ffff88806e94fc48 EFLAGS: 00000286 ORIG_RAX: ffffffffffffff13
    RAX: 1ffff1100d84dac5 RBX: 0000000000000001 RCX: ffffc90006197000
    RDX: 0000000000040000 RSI: ffffffff86324bf3 RDI: ffff88806c26d628
    RBP: ffff88806e94fc48 R08: ffff88806c1c6500 R09: fffffbfff1282561
    R10: fffffbfff1282560 R11: ffffffff89412b03 R12: ffff88806c26d628
    R13: ffff888090455200 R14: dffffc0000000000 R15: 0000000000000000
    FS: 00007f3a107e4700(0000) GS:ffff8880ae800000(0000) knlGS:0000000000000000
    CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
    CR2: 00007f3a107e3db8 CR3: 00000000a5544000 CR4: 00000000001406f0
    DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
    DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
    Call Trace:
    __x25_find_socket net/x25/af_x25.c:327 [inline]
    x25_find_socket+0x7d/0x140 net/x25/af_x25.c:342
    x25_new_lci net/x25/af_x25.c:355 [inline]
    x25_connect+0x380/0xde0 net/x25/af_x25.c:784
    __sys_connect+0x266/0x330 net/socket.c:1662
    __do_sys_connect net/socket.c:1673 [inline]
    __se_sys_connect net/socket.c:1670 [inline]
    __x64_sys_connect+0x73/0xb0 net/socket.c:1670
    do_syscall_64+0x103/0x610 arch/x86/entry/common.c:290
    entry_SYSCALL_64_after_hwframe+0x49/0xbe
    RIP: 0033:0x457e29
    Code: ad b8 fb ff c3 66 2e 0f 1f 84 00 00 00 00 00 66 90 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 7b b8 fb ff c3 66 2e 0f 1f 84 00 00 00 00
    RSP: 002b:00007f3a107e3c78 EFLAGS: 00000246 ORIG_RAX: 000000000000002a
    RAX: ffffffffffffffda RBX: 0000000000000003 RCX: 0000000000457e29
    RDX: 0000000000000012 RSI: 0000000020000200 RDI: 0000000000000005
    RBP: 000000000073c040 R08: 0000000000000000 R09: 0000000000000000
    R10: 0000000000000000 R11: 0000000000000246 R12: 00007f3a107e46d4
    R13: 00000000004be362 R14: 00000000004ceb98 R15: 00000000ffffffff
    Sending NMI from CPU 0 to CPUs 1:
    NMI backtrace for cpu 1
    CPU: 1 PID: 10493 Comm: syz-executor.3 Not tainted 5.0.0-rc7+ #88
    Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
    RIP: 0010:__read_once_size include/linux/compiler.h:193 [inline]
    RIP: 0010:queued_write_lock_slowpath+0x143/0x290 kernel/locking/qrwlock.c:86
    Code: 4c 8d 2c 01 41 83 c7 03 41 0f b6 45 00 41 38 c7 7c 08 84 c0 0f 85 0c 01 00 00 8b 03 3d 00 01 00 00 74 1a f3 90 41 0f b6 55 00 38 d7 7c eb 84 d2 74 e7 48 89 df e8 cc aa 4e 00 eb dd be 04 00
    RSP: 0018:ffff888085c47bd8 EFLAGS: 00000206
    RAX: 0000000000000300 RBX: ffffffff89412b00 RCX: 1ffffffff1282560
    RDX: 0000000000000000 RSI: 0000000000000004 RDI: ffffffff89412b00
    RBP: ffff888085c47c70 R08: 1ffffffff1282560 R09: fffffbfff1282561
    R10: fffffbfff1282560 R11: ffffffff89412b03 R12: 00000000000000ff
    R13: fffffbfff1282560 R14: 1ffff11010b88f7d R15: 0000000000000003
    FS: 00007fdd04086700(0000) GS:ffff8880ae900000(0000) knlGS:0000000000000000
    CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
    CR2: 00007fdd04064db8 CR3: 0000000090be0000 CR4: 00000000001406e0
    DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
    DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
    Call Trace:
    queued_write_lock include/asm-generic/qrwlock.h:104 [inline]
    do_raw_write_lock+0x1d6/0x290 kernel/locking/spinlock_debug.c:203
    __raw_write_lock_bh include/linux/rwlock_api_smp.h:204 [inline]
    _raw_write_lock_bh+0x3b/0x50 kernel/locking/spinlock.c:312
    x25_insert_socket+0x21/0xe0 net/x25/af_x25.c:267
    x25_bind+0x273/0x340 net/x25/af_x25.c:703
    __sys_bind+0x23f/0x290 net/socket.c:1481
    __do_sys_bind net/socket.c:1492 [inline]
    __se_sys_bind net/socket.c:1490 [inline]
    __x64_sys_bind+0x73/0xb0 net/socket.c:1490
    do_syscall_64+0x103/0x610 arch/x86/entry/common.c:290
    entry_SYSCALL_64_after_hwframe+0x49/0xbe
    RIP: 0033:0x457e29

    Fixes: 90c27297a9bf ("X.25 remove bkl in bind")
    Signed-off-by: Eric Dumazet
    Cc: andrew hendry
    Signed-off-by: David S. Miller

    Eric Dumazet
     

12 Feb, 2019

1 commit

  • Due to quadratic behavior of x25_new_lci(), syzbot was able
    to trigger an rcu stall.

    Fix this by not blocking BH for the whole duration of
    the function, and inserting a reschedule point when possible.

    If we care enough, using a bitmap could get rid of the quadratic
    behavior.

    syzbot report :

    rcu: INFO: rcu_preempt self-detected stall on CPU
    rcu: 0-...!: (10500 ticks this GP) idle=4fa/1/0x4000000000000002 softirq=283376/283376 fqs=0
    rcu: (t=10501 jiffies g=383105 q=136)
    rcu: rcu_preempt kthread starved for 10502 jiffies! g383105 f0x0 RCU_GP_WAIT_FQS(5) ->state=0x402 ->cpu=0
    rcu: RCU grace-period kthread stack dump:
    rcu_preempt I28928 10 2 0x80000000
    Call Trace:
    context_switch kernel/sched/core.c:2844 [inline]
    __schedule+0x817/0x1cc0 kernel/sched/core.c:3485
    schedule+0x92/0x180 kernel/sched/core.c:3529
    schedule_timeout+0x4db/0xfd0 kernel/time/timer.c:1803
    rcu_gp_fqs_loop kernel/rcu/tree.c:1948 [inline]
    rcu_gp_kthread+0x956/0x17a0 kernel/rcu/tree.c:2105
    kthread+0x357/0x430 kernel/kthread.c:246
    ret_from_fork+0x3a/0x50 arch/x86/entry/entry_64.S:352
    NMI backtrace for cpu 0
    CPU: 0 PID: 8759 Comm: syz-executor2 Not tainted 5.0.0-rc4+ #51
    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
    nmi_cpu_backtrace.cold+0x63/0xa4 lib/nmi_backtrace.c:101
    nmi_trigger_cpumask_backtrace+0x1be/0x236 lib/nmi_backtrace.c:62
    arch_trigger_cpumask_backtrace+0x14/0x20 arch/x86/kernel/apic/hw_nmi.c:38
    trigger_single_cpu_backtrace include/linux/nmi.h:164 [inline]
    rcu_dump_cpu_stacks+0x183/0x1cf kernel/rcu/tree.c:1211
    print_cpu_stall kernel/rcu/tree.c:1348 [inline]
    check_cpu_stall kernel/rcu/tree.c:1422 [inline]
    rcu_pending kernel/rcu/tree.c:3018 [inline]
    rcu_check_callbacks.cold+0x500/0xa4a kernel/rcu/tree.c:2521
    update_process_times+0x32/0x80 kernel/time/timer.c:1635
    tick_sched_handle+0xa2/0x190 kernel/time/tick-sched.c:161
    tick_sched_timer+0x47/0x130 kernel/time/tick-sched.c:1271
    __run_hrtimer kernel/time/hrtimer.c:1389 [inline]
    __hrtimer_run_queues+0x33e/0xde0 kernel/time/hrtimer.c:1451
    hrtimer_interrupt+0x314/0x770 kernel/time/hrtimer.c:1509
    local_apic_timer_interrupt arch/x86/kernel/apic/apic.c:1035 [inline]
    smp_apic_timer_interrupt+0x120/0x570 arch/x86/kernel/apic/apic.c:1060
    apic_timer_interrupt+0xf/0x20 arch/x86/entry/entry_64.S:807

    RIP: 0010:__read_once_size include/linux/compiler.h:193 [inline]
    RIP: 0010:queued_write_lock_slowpath+0x13e/0x290 kernel/locking/qrwlock.c:86
    Code: 00 00 fc ff df 4c 8d 2c 01 41 83 c7 03 41 0f b6 45 00 41 38 c7 7c 08 84 c0 0f 85 0c 01 00 00 8b 03 3d 00 01 00 00 74 1a f3 90 0f b6 55 00 41 38 d7 7c eb 84 d2 74 e7 48 89 df e8 6c 0f 4f 00
    RSP: 0018:ffff88805f117bd8 EFLAGS: 00000206 ORIG_RAX: ffffffffffffff13
    RAX: 0000000000000300 RBX: ffffffff89413ba0 RCX: 1ffffffff1282774
    RDX: 0000000000000000 RSI: 0000000000000004 RDI: ffffffff89413ba0
    RBP: ffff88805f117c70 R08: 1ffffffff1282774 R09: fffffbfff1282775
    R10: fffffbfff1282774 R11: ffffffff89413ba3 R12: 00000000000000ff
    R13: fffffbfff1282774 R14: 1ffff1100be22f7d R15: 0000000000000003
    queued_write_lock include/asm-generic/qrwlock.h:104 [inline]
    do_raw_write_lock+0x1d6/0x290 kernel/locking/spinlock_debug.c:203
    __raw_write_lock_bh include/linux/rwlock_api_smp.h:204 [inline]
    _raw_write_lock_bh+0x3b/0x50 kernel/locking/spinlock.c:312
    x25_insert_socket+0x21/0xe0 net/x25/af_x25.c:267
    x25_bind+0x273/0x340 net/x25/af_x25.c:705
    __sys_bind+0x23f/0x290 net/socket.c:1505
    __do_sys_bind net/socket.c:1516 [inline]
    __se_sys_bind net/socket.c:1514 [inline]
    __x64_sys_bind+0x73/0xb0 net/socket.c:1514
    do_syscall_64+0x103/0x610 arch/x86/entry/common.c:290
    entry_SYSCALL_64_after_hwframe+0x49/0xbe
    RIP: 0033:0x457e39
    Code: ad b8 fb ff c3 66 2e 0f 1f 84 00 00 00 00 00 66 90 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 7b b8 fb ff c3 66 2e 0f 1f 84 00 00 00 00
    RSP: 002b:00007fafccd0dc78 EFLAGS: 00000246 ORIG_RAX: 0000000000000031
    RAX: ffffffffffffffda RBX: 0000000000000003 RCX: 0000000000457e39
    RDX: 0000000000000012 RSI: 0000000020000240 RDI: 0000000000000004
    RBP: 000000000073bf00 R08: 0000000000000000 R09: 0000000000000000
    R10: 0000000000000000 R11: 0000000000000246 R12: 00007fafccd0e6d4
    R13: 00000000004bdf8b R14: 00000000004ce4b8 R15: 00000000ffffffff
    Sending NMI from CPU 0 to CPUs 1:
    NMI backtrace for cpu 1
    CPU: 1 PID: 8752 Comm: syz-executor4 Not tainted 5.0.0-rc4+ #51
    Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
    RIP: 0010:__x25_find_socket+0x78/0x120 net/x25/af_x25.c:328
    Code: 89 f8 48 c1 e8 03 80 3c 18 00 0f 85 a6 00 00 00 4d 8b 64 24 68 4d 85 e4 74 7f e8 03 97 3d fb 49 83 ec 68 74 74 e8 f8 96 3d fb 8d bc 24 88 04 00 00 48 89 f8 48 c1 e8 03 0f b6 04 18 84 c0 74
    RSP: 0018:ffff8880639efc58 EFLAGS: 00000246
    RAX: 0000000000040000 RBX: dffffc0000000000 RCX: ffffc9000e677000
    RDX: 0000000000040000 RSI: ffffffff863244b8 RDI: ffff88806a764628
    RBP: ffff8880639efc80 R08: ffff8880a80d05c0 R09: fffffbfff1282775
    R10: fffffbfff1282774 R11: ffffffff89413ba3 R12: ffff88806a7645c0
    R13: 0000000000000001 R14: ffff88809f29ac00 R15: 0000000000000000
    FS: 00007fe8d0c58700(0000) GS:ffff8880ae900000(0000) knlGS:0000000000000000
    CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
    CR2: 0000001b32823000 CR3: 00000000672eb000 CR4: 00000000001406e0
    DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
    DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
    Call Trace:
    x25_new_lci net/x25/af_x25.c:357 [inline]
    x25_connect+0x374/0xdf0 net/x25/af_x25.c:786
    __sys_connect+0x266/0x330 net/socket.c:1686
    __do_sys_connect net/socket.c:1697 [inline]
    __se_sys_connect net/socket.c:1694 [inline]
    __x64_sys_connect+0x73/0xb0 net/socket.c:1694
    do_syscall_64+0x103/0x610 arch/x86/entry/common.c:290
    entry_SYSCALL_64_after_hwframe+0x49/0xbe
    RIP: 0033:0x457e39
    Code: ad b8 fb ff c3 66 2e 0f 1f 84 00 00 00 00 00 66 90 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 7b b8 fb ff c3 66 2e 0f 1f 84 00 00 00 00
    RSP: 002b:00007fe8d0c57c78 EFLAGS: 00000246 ORIG_RAX: 000000000000002a
    RAX: ffffffffffffffda RBX: 0000000000000003 RCX: 0000000000457e39
    RDX: 0000000000000012 RSI: 0000000020000200 RDI: 0000000000000004
    RBP: 000000000073bf00 R08: 0000000000000000 R09: 0000000000000000
    R10: 0000000000000000 R11: 0000000000000246 R12: 00007fe8d0c586d4
    R13: 00000000004be378 R14: 00000000004ceb00 R15: 00000000ffffffff

    Signed-off-by: Eric Dumazet
    Reported-by: syzbot
    Cc: Andrew Hendry
    Cc: linux-x25@vger.kernel.org
    Signed-off-by: David S. Miller

    Eric Dumazet
     

30 Nov, 2018

3 commits


25 Jul, 2018

1 commit


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
     

05 Jun, 2018

1 commit

  • 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
     

26 May, 2018

1 commit


16 May, 2018

1 commit


27 Mar, 2018

1 commit

  • Prefer the direct use of octal for permissions.

    Done with checkpatch -f --types=SYMBOLIC_PERMS --fix-inplace
    and some typing.

    Miscellanea:

    o Whitespace neatening around these conversions.

    Signed-off-by: Joe Perches
    Signed-off-by: David S. Miller

    Joe Perches
     

21 Feb, 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
     

22 Nov, 2017

2 commits

  • With all callbacks converted, and the timer callback prototype
    switched over, the TIMER_FUNC_TYPE cast is no longer needed,
    so remove it. Conversion was done with the following scripts:

    perl -pi -e 's|\(TIMER_FUNC_TYPE\)||g' \
    $(git grep TIMER_FUNC_TYPE | cut -d: -f1 | sort -u)

    perl -pi -e 's|\(TIMER_DATA_TYPE\)||g' \
    $(git grep TIMER_DATA_TYPE | cut -d: -f1 | sort -u)

    The now unused macros are also dropped from include/linux/timer.h.

    Signed-off-by: Kees Cook

    Kees Cook
     
  • This converts all remaining cases of the old setup_timer() API into using
    timer_setup(), where the callback argument is the structure already
    holding the struct timer_list. These should have no behavioral changes,
    since they just change which pointer is passed into the callback with
    the same available pointers after conversion. It handles the following
    examples, in addition to some other variations.

    Casting from unsigned long:

    void my_callback(unsigned long data)
    {
    struct something *ptr = (struct something *)data;
    ...
    }
    ...
    setup_timer(&ptr->my_timer, my_callback, ptr);

    and forced object casts:

    void my_callback(struct something *ptr)
    {
    ...
    }
    ...
    setup_timer(&ptr->my_timer, my_callback, (unsigned long)ptr);

    become:

    void my_callback(struct timer_list *t)
    {
    struct something *ptr = from_timer(ptr, t, my_timer);
    ...
    }
    ...
    timer_setup(&ptr->my_timer, my_callback, 0);

    Direct function assignments:

    void my_callback(unsigned long data)
    {
    struct something *ptr = (struct something *)data;
    ...
    }
    ...
    ptr->my_timer.function = my_callback;

    have a temporary cast added, along with converting the args:

    void my_callback(struct timer_list *t)
    {
    struct something *ptr = from_timer(ptr, t, my_timer);
    ...
    }
    ...
    ptr->my_timer.function = (TIMER_FUNC_TYPE)my_callback;

    And finally, callbacks without a data assignment:

    void my_callback(unsigned long data)
    {
    ...
    }
    ...
    setup_timer(&ptr->my_timer, my_callback, 0);

    have their argument renamed to verify they're unused during conversion:

    void my_callback(struct timer_list *unused)
    {
    ...
    }
    ...
    timer_setup(&ptr->my_timer, my_callback, 0);

    The conversion is done with the following Coccinelle script:

    spatch --very-quiet --all-includes --include-headers \
    -I ./arch/x86/include -I ./arch/x86/include/generated \
    -I ./include -I ./arch/x86/include/uapi \
    -I ./arch/x86/include/generated/uapi -I ./include/uapi \
    -I ./include/generated/uapi --include ./include/linux/kconfig.h \
    --dir . \
    --cocci-file ~/src/data/timer_setup.cocci

    @fix_address_of@
    expression e;
    @@

    setup_timer(
    -&(e)
    +&e
    , ...)

    // Update any raw setup_timer() usages that have a NULL callback, but
    // would otherwise match change_timer_function_usage, since the latter
    // will update all function assignments done in the face of a NULL
    // function initialization in setup_timer().
    @change_timer_function_usage_NULL@
    expression _E;
    identifier _timer;
    type _cast_data;
    @@

    (
    -setup_timer(&_E->_timer, NULL, _E);
    +timer_setup(&_E->_timer, NULL, 0);
    |
    -setup_timer(&_E->_timer, NULL, (_cast_data)_E);
    +timer_setup(&_E->_timer, NULL, 0);
    |
    -setup_timer(&_E._timer, NULL, &_E);
    +timer_setup(&_E._timer, NULL, 0);
    |
    -setup_timer(&_E._timer, NULL, (_cast_data)&_E);
    +timer_setup(&_E._timer, NULL, 0);
    )

    @change_timer_function_usage@
    expression _E;
    identifier _timer;
    struct timer_list _stl;
    identifier _callback;
    type _cast_func, _cast_data;
    @@

    (
    -setup_timer(&_E->_timer, _callback, _E);
    +timer_setup(&_E->_timer, _callback, 0);
    |
    -setup_timer(&_E->_timer, &_callback, _E);
    +timer_setup(&_E->_timer, _callback, 0);
    |
    -setup_timer(&_E->_timer, _callback, (_cast_data)_E);
    +timer_setup(&_E->_timer, _callback, 0);
    |
    -setup_timer(&_E->_timer, &_callback, (_cast_data)_E);
    +timer_setup(&_E->_timer, _callback, 0);
    |
    -setup_timer(&_E->_timer, (_cast_func)_callback, _E);
    +timer_setup(&_E->_timer, _callback, 0);
    |
    -setup_timer(&_E->_timer, (_cast_func)&_callback, _E);
    +timer_setup(&_E->_timer, _callback, 0);
    |
    -setup_timer(&_E->_timer, (_cast_func)_callback, (_cast_data)_E);
    +timer_setup(&_E->_timer, _callback, 0);
    |
    -setup_timer(&_E->_timer, (_cast_func)&_callback, (_cast_data)_E);
    +timer_setup(&_E->_timer, _callback, 0);
    |
    -setup_timer(&_E._timer, _callback, (_cast_data)_E);
    +timer_setup(&_E._timer, _callback, 0);
    |
    -setup_timer(&_E._timer, _callback, (_cast_data)&_E);
    +timer_setup(&_E._timer, _callback, 0);
    |
    -setup_timer(&_E._timer, &_callback, (_cast_data)_E);
    +timer_setup(&_E._timer, _callback, 0);
    |
    -setup_timer(&_E._timer, &_callback, (_cast_data)&_E);
    +timer_setup(&_E._timer, _callback, 0);
    |
    -setup_timer(&_E._timer, (_cast_func)_callback, (_cast_data)_E);
    +timer_setup(&_E._timer, _callback, 0);
    |
    -setup_timer(&_E._timer, (_cast_func)_callback, (_cast_data)&_E);
    +timer_setup(&_E._timer, _callback, 0);
    |
    -setup_timer(&_E._timer, (_cast_func)&_callback, (_cast_data)_E);
    +timer_setup(&_E._timer, _callback, 0);
    |
    -setup_timer(&_E._timer, (_cast_func)&_callback, (_cast_data)&_E);
    +timer_setup(&_E._timer, _callback, 0);
    |
    _E->_timer@_stl.function = _callback;
    |
    _E->_timer@_stl.function = &_callback;
    |
    _E->_timer@_stl.function = (_cast_func)_callback;
    |
    _E->_timer@_stl.function = (_cast_func)&_callback;
    |
    _E._timer@_stl.function = _callback;
    |
    _E._timer@_stl.function = &_callback;
    |
    _E._timer@_stl.function = (_cast_func)_callback;
    |
    _E._timer@_stl.function = (_cast_func)&_callback;
    )

    // callback(unsigned long arg)
    @change_callback_handle_cast
    depends on change_timer_function_usage@
    identifier change_timer_function_usage._callback;
    identifier change_timer_function_usage._timer;
    type _origtype;
    identifier _origarg;
    type _handletype;
    identifier _handle;
    @@

    void _callback(
    -_origtype _origarg
    +struct timer_list *t
    )
    {
    (
    ... when != _origarg
    _handletype *_handle =
    -(_handletype *)_origarg;
    +from_timer(_handle, t, _timer);
    ... when != _origarg
    |
    ... when != _origarg
    _handletype *_handle =
    -(void *)_origarg;
    +from_timer(_handle, t, _timer);
    ... when != _origarg
    |
    ... when != _origarg
    _handletype *_handle;
    ... when != _handle
    _handle =
    -(_handletype *)_origarg;
    +from_timer(_handle, t, _timer);
    ... when != _origarg
    |
    ... when != _origarg
    _handletype *_handle;
    ... when != _handle
    _handle =
    -(void *)_origarg;
    +from_timer(_handle, t, _timer);
    ... when != _origarg
    )
    }

    // callback(unsigned long arg) without existing variable
    @change_callback_handle_cast_no_arg
    depends on change_timer_function_usage &&
    !change_callback_handle_cast@
    identifier change_timer_function_usage._callback;
    identifier change_timer_function_usage._timer;
    type _origtype;
    identifier _origarg;
    type _handletype;
    @@

    void _callback(
    -_origtype _origarg
    +struct timer_list *t
    )
    {
    + _handletype *_origarg = from_timer(_origarg, t, _timer);
    +
    ... when != _origarg
    - (_handletype *)_origarg
    + _origarg
    ... when != _origarg
    }

    // Avoid already converted callbacks.
    @match_callback_converted
    depends on change_timer_function_usage &&
    !change_callback_handle_cast &&
    !change_callback_handle_cast_no_arg@
    identifier change_timer_function_usage._callback;
    identifier t;
    @@

    void _callback(struct timer_list *t)
    { ... }

    // callback(struct something *handle)
    @change_callback_handle_arg
    depends on change_timer_function_usage &&
    !match_callback_converted &&
    !change_callback_handle_cast &&
    !change_callback_handle_cast_no_arg@
    identifier change_timer_function_usage._callback;
    identifier change_timer_function_usage._timer;
    type _handletype;
    identifier _handle;
    @@

    void _callback(
    -_handletype *_handle
    +struct timer_list *t
    )
    {
    + _handletype *_handle = from_timer(_handle, t, _timer);
    ...
    }

    // If change_callback_handle_arg ran on an empty function, remove
    // the added handler.
    @unchange_callback_handle_arg
    depends on change_timer_function_usage &&
    change_callback_handle_arg@
    identifier change_timer_function_usage._callback;
    identifier change_timer_function_usage._timer;
    type _handletype;
    identifier _handle;
    identifier t;
    @@

    void _callback(struct timer_list *t)
    {
    - _handletype *_handle = from_timer(_handle, t, _timer);
    }

    // We only want to refactor the setup_timer() data argument if we've found
    // the matching callback. This undoes changes in change_timer_function_usage.
    @unchange_timer_function_usage
    depends on change_timer_function_usage &&
    !change_callback_handle_cast &&
    !change_callback_handle_cast_no_arg &&
    !change_callback_handle_arg@
    expression change_timer_function_usage._E;
    identifier change_timer_function_usage._timer;
    identifier change_timer_function_usage._callback;
    type change_timer_function_usage._cast_data;
    @@

    (
    -timer_setup(&_E->_timer, _callback, 0);
    +setup_timer(&_E->_timer, _callback, (_cast_data)_E);
    |
    -timer_setup(&_E._timer, _callback, 0);
    +setup_timer(&_E._timer, _callback, (_cast_data)&_E);
    )

    // If we fixed a callback from a .function assignment, fix the
    // assignment cast now.
    @change_timer_function_assignment
    depends on change_timer_function_usage &&
    (change_callback_handle_cast ||
    change_callback_handle_cast_no_arg ||
    change_callback_handle_arg)@
    expression change_timer_function_usage._E;
    identifier change_timer_function_usage._timer;
    identifier change_timer_function_usage._callback;
    type _cast_func;
    typedef TIMER_FUNC_TYPE;
    @@

    (
    _E->_timer.function =
    -_callback
    +(TIMER_FUNC_TYPE)_callback
    ;
    |
    _E->_timer.function =
    -&_callback
    +(TIMER_FUNC_TYPE)_callback
    ;
    |
    _E->_timer.function =
    -(_cast_func)_callback;
    +(TIMER_FUNC_TYPE)_callback
    ;
    |
    _E->_timer.function =
    -(_cast_func)&_callback
    +(TIMER_FUNC_TYPE)_callback
    ;
    |
    _E._timer.function =
    -_callback
    +(TIMER_FUNC_TYPE)_callback
    ;
    |
    _E._timer.function =
    -&_callback;
    +(TIMER_FUNC_TYPE)_callback
    ;
    |
    _E._timer.function =
    -(_cast_func)_callback
    +(TIMER_FUNC_TYPE)_callback
    ;
    |
    _E._timer.function =
    -(_cast_func)&_callback
    +(TIMER_FUNC_TYPE)_callback
    ;
    )

    // Sometimes timer functions are called directly. Replace matched args.
    @change_timer_function_calls
    depends on change_timer_function_usage &&
    (change_callback_handle_cast ||
    change_callback_handle_cast_no_arg ||
    change_callback_handle_arg)@
    expression _E;
    identifier change_timer_function_usage._timer;
    identifier change_timer_function_usage._callback;
    type _cast_data;
    @@

    _callback(
    (
    -(_cast_data)_E
    +&_E->_timer
    |
    -(_cast_data)&_E
    +&_E._timer
    |
    -_E
    +&_E->_timer
    )
    )

    // If a timer has been configured without a data argument, it can be
    // converted without regard to the callback argument, since it is unused.
    @match_timer_function_unused_data@
    expression _E;
    identifier _timer;
    identifier _callback;
    @@

    (
    -setup_timer(&_E->_timer, _callback, 0);
    +timer_setup(&_E->_timer, _callback, 0);
    |
    -setup_timer(&_E->_timer, _callback, 0L);
    +timer_setup(&_E->_timer, _callback, 0);
    |
    -setup_timer(&_E->_timer, _callback, 0UL);
    +timer_setup(&_E->_timer, _callback, 0);
    |
    -setup_timer(&_E._timer, _callback, 0);
    +timer_setup(&_E._timer, _callback, 0);
    |
    -setup_timer(&_E._timer, _callback, 0L);
    +timer_setup(&_E._timer, _callback, 0);
    |
    -setup_timer(&_E._timer, _callback, 0UL);
    +timer_setup(&_E._timer, _callback, 0);
    |
    -setup_timer(&_timer, _callback, 0);
    +timer_setup(&_timer, _callback, 0);
    |
    -setup_timer(&_timer, _callback, 0L);
    +timer_setup(&_timer, _callback, 0);
    |
    -setup_timer(&_timer, _callback, 0UL);
    +timer_setup(&_timer, _callback, 0);
    |
    -setup_timer(_timer, _callback, 0);
    +timer_setup(_timer, _callback, 0);
    |
    -setup_timer(_timer, _callback, 0L);
    +timer_setup(_timer, _callback, 0);
    |
    -setup_timer(_timer, _callback, 0UL);
    +timer_setup(_timer, _callback, 0);
    )

    @change_callback_unused_data
    depends on match_timer_function_unused_data@
    identifier match_timer_function_unused_data._callback;
    type _origtype;
    identifier _origarg;
    @@

    void _callback(
    -_origtype _origarg
    +struct timer_list *unused
    )
    {
    ... when != _origarg
    }

    Signed-off-by: Kees Cook

    Kees Cook
     

04 Nov, 2017

1 commit