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


22 Nov, 2017

3 commits

  • This converts all remaining setup_timer() calls that use a nested field
    to reach a struct timer_list. Coccinelle does not have an easy way to
    match multiple fields, so a new script is needed to change the matches of
    "&_E->_timer" into "&_E->_field1._timer" in all the rules.

    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-2fields.cocci

    @fix_address_of depends@
    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 _field1;
    identifier _timer;
    type _cast_data;
    @@

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

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

    (
    -setup_timer(&_E->_field1._timer, _callback, _E);
    +timer_setup(&_E->_field1._timer, _callback, 0);
    |
    -setup_timer(&_E->_field1._timer, &_callback, _E);
    +timer_setup(&_E->_field1._timer, _callback, 0);
    |
    -setup_timer(&_E->_field1._timer, _callback, (_cast_data)_E);
    +timer_setup(&_E->_field1._timer, _callback, 0);
    |
    -setup_timer(&_E->_field1._timer, &_callback, (_cast_data)_E);
    +timer_setup(&_E->_field1._timer, _callback, 0);
    |
    -setup_timer(&_E->_field1._timer, (_cast_func)_callback, _E);
    +timer_setup(&_E->_field1._timer, _callback, 0);
    |
    -setup_timer(&_E->_field1._timer, (_cast_func)&_callback, _E);
    +timer_setup(&_E->_field1._timer, _callback, 0);
    |
    -setup_timer(&_E->_field1._timer, (_cast_func)_callback, (_cast_data)_E);
    +timer_setup(&_E->_field1._timer, _callback, 0);
    |
    -setup_timer(&_E->_field1._timer, (_cast_func)&_callback, (_cast_data)_E);
    +timer_setup(&_E->_field1._timer, _callback, 0);
    |
    -setup_timer(&_E._field1._timer, _callback, (_cast_data)_E);
    +timer_setup(&_E._field1._timer, _callback, 0);
    |
    -setup_timer(&_E._field1._timer, _callback, (_cast_data)&_E);
    +timer_setup(&_E._field1._timer, _callback, 0);
    |
    -setup_timer(&_E._field1._timer, &_callback, (_cast_data)_E);
    +timer_setup(&_E._field1._timer, _callback, 0);
    |
    -setup_timer(&_E._field1._timer, &_callback, (_cast_data)&_E);
    +timer_setup(&_E._field1._timer, _callback, 0);
    |
    -setup_timer(&_E._field1._timer, (_cast_func)_callback, (_cast_data)_E);
    +timer_setup(&_E._field1._timer, _callback, 0);
    |
    -setup_timer(&_E._field1._timer, (_cast_func)_callback, (_cast_data)&_E);
    +timer_setup(&_E._field1._timer, _callback, 0);
    |
    -setup_timer(&_E._field1._timer, (_cast_func)&_callback, (_cast_data)_E);
    +timer_setup(&_E._field1._timer, _callback, 0);
    |
    -setup_timer(&_E._field1._timer, (_cast_func)&_callback, (_cast_data)&_E);
    +timer_setup(&_E._field1._timer, _callback, 0);
    |
    _E->_field1._timer@_stl.function = _callback;
    |
    _E->_field1._timer@_stl.function = &_callback;
    |
    _E->_field1._timer@_stl.function = (_cast_func)_callback;
    |
    _E->_field1._timer@_stl.function = (_cast_func)&_callback;
    |
    _E._field1._timer@_stl.function = _callback;
    |
    _E._field1._timer@_stl.function = &_callback;
    |
    _E._field1._timer@_stl.function = (_cast_func)_callback;
    |
    _E._field1._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._field1;
    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, _field1._timer);
    ... when != _origarg
    |
    ... when != _origarg
    _handletype *_handle =
    -(void *)_origarg;
    +from_timer(_handle, t, _field1._timer);
    ... when != _origarg
    |
    ... when != _origarg
    _handletype *_handle;
    ... when != _handle
    _handle =
    -(_handletype *)_origarg;
    +from_timer(_handle, t, _field1._timer);
    ... when != _origarg
    |
    ... when != _origarg
    _handletype *_handle;
    ... when != _handle
    _handle =
    -(void *)_origarg;
    +from_timer(_handle, t, _field1._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._field1;
    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, _field1._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._field1;
    identifier change_timer_function_usage._timer;
    type _handletype;
    identifier _handle;
    @@

    void _callback(
    -_handletype *_handle
    +struct timer_list *t
    )
    {
    + _handletype *_handle = from_timer(_handle, t, _field1._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._field1;
    identifier change_timer_function_usage._timer;
    type _handletype;
    identifier _handle;
    identifier t;
    @@

    void _callback(struct timer_list *t)
    {
    - _handletype *_handle = from_timer(_handle, t, _field1._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._field1;
    identifier change_timer_function_usage._timer;
    identifier change_timer_function_usage._callback;
    type change_timer_function_usage._cast_data;
    @@

    (
    -timer_setup(&_E->_field1._timer, _callback, 0);
    +setup_timer(&_E->_field1._timer, _callback, (_cast_data)_E);
    |
    -timer_setup(&_E._field1._timer, _callback, 0);
    +setup_timer(&_E._field1._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._field1;
    identifier change_timer_function_usage._timer;
    identifier change_timer_function_usage._callback;
    type _cast_func;
    typedef TIMER_FUNC_TYPE;
    @@

    (
    _E->_field1._timer.function =
    -_callback
    +(TIMER_FUNC_TYPE)_callback
    ;
    |
    _E->_field1._timer.function =
    -&_callback
    +(TIMER_FUNC_TYPE)_callback
    ;
    |
    _E->_field1._timer.function =
    -(_cast_func)_callback;
    +(TIMER_FUNC_TYPE)_callback
    ;
    |
    _E->_field1._timer.function =
    -(_cast_func)&_callback
    +(TIMER_FUNC_TYPE)_callback
    ;
    |
    _E._field1._timer.function =
    -_callback
    +(TIMER_FUNC_TYPE)_callback
    ;
    |
    _E._field1._timer.function =
    -&_callback;
    +(TIMER_FUNC_TYPE)_callback
    ;
    |
    _E._field1._timer.function =
    -(_cast_func)_callback
    +(TIMER_FUNC_TYPE)_callback
    ;
    |
    _E._field1._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._field1;
    identifier change_timer_function_usage._timer;
    identifier change_timer_function_usage._callback;
    type _cast_data;
    @@

    _callback(
    (
    -(_cast_data)_E
    +&_E->_field1._timer
    |
    -(_cast_data)&_E
    +&_E._field1._timer
    |
    -_E
    +&_E->_field1._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 _field1;
    identifier _timer;
    identifier _callback;
    @@

    (
    -setup_timer(&_E->_field1._timer, _callback, 0);
    +timer_setup(&_E->_field1._timer, _callback, 0);
    |
    -setup_timer(&_E->_field1._timer, _callback, 0L);
    +timer_setup(&_E->_field1._timer, _callback, 0);
    |
    -setup_timer(&_E->_field1._timer, _callback, 0UL);
    +timer_setup(&_E->_field1._timer, _callback, 0);
    |
    -setup_timer(&_E._field1._timer, _callback, 0);
    +timer_setup(&_E._field1._timer, _callback, 0);
    |
    -setup_timer(&_E._field1._timer, _callback, 0L);
    +timer_setup(&_E._field1._timer, _callback, 0);
    |
    -setup_timer(&_E._field1._timer, _callback, 0UL);
    +timer_setup(&_E._field1._timer, _callback, 0);
    |
    -setup_timer(&_field1._timer, _callback, 0);
    +timer_setup(&_field1._timer, _callback, 0);
    |
    -setup_timer(&_field1._timer, _callback, 0L);
    +timer_setup(&_field1._timer, _callback, 0);
    |
    -setup_timer(&_field1._timer, _callback, 0UL);
    +timer_setup(&_field1._timer, _callback, 0);
    |
    -setup_timer(_field1._timer, _callback, 0);
    +timer_setup(_field1._timer, _callback, 0);
    |
    -setup_timer(_field1._timer, _callback, 0L);
    +timer_setup(_field1._timer, _callback, 0);
    |
    -setup_timer(_field1._timer, _callback, 0UL);
    +timer_setup(_field1._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
     
  • 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
     
  • This mechanically converts all remaining cases of ancient open-coded timer
    setup with the old setup_timer() API, which is the first step in timer
    conversions. This has no behavioral changes, since it ultimately just
    changes the order of assignment to fields of struct timer_list when
    finding variations of:

    init_timer(&t);
    f.function = timer_callback;
    t.data = timer_callback_arg;

    to be converted into:

    setup_timer(&t, timer_callback, timer_callback_arg);

    The conversion is done with the following Coccinelle script, which
    is an improved version of scripts/cocci/api/setup_timer.cocci, in the
    following ways:
    - assignments-before-init_timer() cases
    - limit the .data case removal to the specific struct timer_list instance
    - handling calls by dereference (timer->field vs timer.field)

    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/setup_timer.cocci

    @fix_address_of@
    expression e;
    @@

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

    // Match the common cases first to avoid Coccinelle parsing loops with
    // "... when" clauses.

    @match_immediate_function_data_after_init_timer@
    expression e, func, da;
    @@

    -init_timer
    +setup_timer
    ( \(&e\|e\)
    +, func, da
    );
    (
    -\(e.function\|e->function\) = func;
    -\(e.data\|e->data\) = da;
    |
    -\(e.data\|e->data\) = da;
    -\(e.function\|e->function\) = func;
    )

    @match_immediate_function_data_before_init_timer@
    expression e, func, da;
    @@

    (
    -\(e.function\|e->function\) = func;
    -\(e.data\|e->data\) = da;
    |
    -\(e.data\|e->data\) = da;
    -\(e.function\|e->function\) = func;
    )
    -init_timer
    +setup_timer
    ( \(&e\|e\)
    +, func, da
    );

    @match_function_and_data_after_init_timer@
    expression e, e2, e3, e4, e5, func, da;
    @@

    -init_timer
    +setup_timer
    ( \(&e\|e\)
    +, func, da
    );
    ... when != func = e2
    when != da = e3
    (
    -e.function = func;
    ... when != da = e4
    -e.data = da;
    |
    -e->function = func;
    ... when != da = e4
    -e->data = da;
    |
    -e.data = da;
    ... when != func = e5
    -e.function = func;
    |
    -e->data = da;
    ... when != func = e5
    -e->function = func;
    )

    @match_function_and_data_before_init_timer@
    expression e, e2, e3, e4, e5, func, da;
    @@
    (
    -e.function = func;
    ... when != da = e4
    -e.data = da;
    |
    -e->function = func;
    ... when != da = e4
    -e->data = da;
    |
    -e.data = da;
    ... when != func = e5
    -e.function = func;
    |
    -e->data = da;
    ... when != func = e5
    -e->function = func;
    )
    ... when != func = e2
    when != da = e3
    -init_timer
    +setup_timer
    ( \(&e\|e\)
    +, func, da
    );

    @r1 exists@
    expression t;
    identifier f;
    position p;
    @@

    f(...) { ... when any
    init_timer@p(\(&t\|t\))
    ... when any
    }

    @r2 exists@
    expression r1.t;
    identifier g != r1.f;
    expression e8;
    @@

    g(...) { ... when any
    \(t.data\|t->data\) = e8
    ... when any
    }

    // It is dangerous to use setup_timer if data field is initialized
    // in another function.
    @script:python depends on r2@
    p << r1.p;
    @@

    cocci.include_match(False)

    @r3@
    expression r1.t, func, e7;
    position r1.p;
    @@

    (
    -init_timer@p(&t);
    +setup_timer(&t, func, 0UL);
    ... when != func = e7
    -t.function = func;
    |
    -t.function = func;
    ... when != func = e7
    -init_timer@p(&t);
    +setup_timer(&t, func, 0UL);
    |
    -init_timer@p(t);
    +setup_timer(t, func, 0UL);
    ... when != func = e7
    -t->function = func;
    |
    -t->function = func;
    ... when != func = e7
    -init_timer@p(t);
    +setup_timer(t, func, 0UL);
    )

    Signed-off-by: Kees Cook

    Kees Cook
     

16 Nov, 2017

13 commits


05 Nov, 2017

1 commit


04 Nov, 2017

1 commit


03 Nov, 2017

2 commits

  • In preparation for unconditionally passing the struct timer_list pointer to
    all timer callbacks, switch to using the new timer_setup() and from_timer()
    to pass the timer pointer explicitly.

    Cc: Karsten Keil
    Cc: "David S. Miller"
    Cc: Arvind Yadav
    Cc: Geliang Tang
    Cc: netdev@vger.kernel.org
    Signed-off-by: Kees Cook
    Signed-off-by: David S. Miller

    Kees Cook
     
  • In preparation to enabling -Wimplicit-fallthrough, mark switch cases
    where we are expecting to fall through.

    Addresses-Coverity-ID: 114780
    Addresses-Coverity-ID: 114781
    Addresses-Coverity-ID: 114782
    Addresses-Coverity-ID: 114783
    Addresses-Coverity-ID: 114784
    Addresses-Coverity-ID: 114785
    Addresses-Coverity-ID: 114786
    Addresses-Coverity-ID: 114787
    Addresses-Coverity-ID: 114788
    Addresses-Coverity-ID: 114789
    Addresses-Coverity-ID: 114790
    Addresses-Coverity-ID: 114791
    Addresses-Coverity-ID: 114792
    Addresses-Coverity-ID: 114793
    Addresses-Coverity-ID: 114794
    Addresses-Coverity-ID: 114795
    Addresses-Coverity-ID: 200521
    Signed-off-by: Gustavo A. R. Silva
    Signed-off-by: David S. Miller

    Gustavo A. R. Silva
     

02 Nov, 2017

1 commit

  • Many source files in the tree are missing licensing information, which
    makes it harder for compliance tools to determine the correct license.

    By default all files without license information are under the default
    license of the kernel, which is GPL version 2.

    Update the files which contain no license information with the 'GPL-2.0'
    SPDX license identifier. The SPDX identifier is a legally binding
    shorthand, which can be used instead of the full boiler plate text.

    This patch is based on work done by Thomas Gleixner and Kate Stewart and
    Philippe Ombredanne.

    How this work was done:

    Patches were generated and checked against linux-4.14-rc6 for a subset of
    the use cases:
    - file had no licensing information it it.
    - file was a */uapi/* one with no licensing information in it,
    - file was a */uapi/* one with existing licensing information,

    Further patches will be generated in subsequent months to fix up cases
    where non-standard license headers were used, and references to license
    had to be inferred by heuristics based on keywords.

    The analysis to determine which SPDX License Identifier to be applied to
    a file was done in a spreadsheet of side by side results from of the
    output of two independent scanners (ScanCode & Windriver) producing SPDX
    tag:value files created by Philippe Ombredanne. Philippe prepared the
    base worksheet, and did an initial spot review of a few 1000 files.

    The 4.13 kernel was the starting point of the analysis with 60,537 files
    assessed. Kate Stewart did a file by file comparison of the scanner
    results in the spreadsheet to determine which SPDX license identifier(s)
    to be applied to the file. She confirmed any determination that was not
    immediately clear with lawyers working with the Linux Foundation.

    Criteria used to select files for SPDX license identifier tagging was:
    - Files considered eligible had to be source code files.
    - Make and config files were included as candidates if they contained >5
    lines of source
    - File already had some variant of a license header in it (even if
    Reviewed-by: Philippe Ombredanne
    Reviewed-by: Thomas Gleixner
    Signed-off-by: Greg Kroah-Hartman

    Greg Kroah-Hartman
     

31 Oct, 2017

1 commit

  • Several function prototypes for the set/get functions defined by
    module_param_call() have a slightly wrong argument types. This fixes
    those in an effort to clean up the calls when running under type-enforced
    compiler instrumentation for CFI. This is the result of running the
    following semantic patch:

    @match_module_param_call_function@
    declarer name module_param_call;
    identifier _name, _set_func, _get_func;
    expression _arg, _mode;
    @@

    module_param_call(_name, _set_func, _get_func, _arg, _mode);

    @fix_set_prototype
    depends on match_module_param_call_function@
    identifier match_module_param_call_function._set_func;
    identifier _val, _param;
    type _val_type, _param_type;
    @@

    int _set_func(
    -_val_type _val
    +const char * _val
    ,
    -_param_type _param
    +const struct kernel_param * _param
    ) { ... }

    @fix_get_prototype
    depends on match_module_param_call_function@
    identifier match_module_param_call_function._get_func;
    identifier _val, _param;
    type _val_type, _param_type;
    @@

    int _get_func(
    -_val_type _val
    +char * _val
    ,
    -_param_type _param
    +const struct kernel_param * _param
    ) { ... }

    Two additional by-hand changes are included for places where the above
    Coccinelle script didn't notice them:

    drivers/platform/x86/thinkpad_acpi.c
    fs/lockd/svc.c

    Signed-off-by: Kees Cook
    Signed-off-by: Jessica Yu

    Kees Cook
     

23 Oct, 2017

1 commit

  • While the work callback uses the urb to find cardstate from bas_cardstate,
    this may not be valid for timer callbacks. Instead, introduce a direct
    pointer back to the cardstate from bas_cardstate for use in timer
    callbacks.

    Reported-by: Paul Bolle
    Fixes: 4cfea08e6251 ("isdn/gigaset: Convert timers to use timer_setup()")
    Cc: Paul Bolle
    Cc: Karsten Keil
    Cc: "David S. Miller"
    Cc: Johan Hovold
    Cc: gigaset307x-common@lists.sourceforge.net
    Cc: netdev@vger.kernel.org
    Signed-off-by: Kees Cook
    Signed-off-by: David S. Miller

    Kees Cook
     

18 Oct, 2017

5 commits

  • In preparation for unconditionally passing the struct timer_list pointer to
    all timer callbacks, switch to using the new timer_setup() and from_timer()
    to pass the timer pointer explicitly. Added missing initialization for
    rb_timer.

    Cc: Karsten Keil
    Cc: "David S. Miller"
    Cc: Al Viro
    Cc: Stephen Hemminger
    Cc: Arnd Bergmann
    Cc: Johannes Berg
    Cc: netdev@vger.kernel.org
    Signed-off-by: Kees Cook
    Signed-off-by: David S. Miller

    Kees Cook
     
  • In preparation for unconditionally passing the struct timer_list pointer to
    all timer callbacks, switch to using the new timer_setup() and from_timer()
    to pass the timer pointer explicitly.

    Cc: Paul Bolle
    Cc: Karsten Keil
    Cc: "David S. Miller"
    Cc: Johan Hovold
    Cc: gigaset307x-common@lists.sourceforge.net
    Cc: netdev@vger.kernel.org
    Signed-off-by: Kees Cook
    Signed-off-by: David S. Miller

    Kees Cook
     
  • This replaces a kmalloc followed by a bunch of per-field zeroing with a
    single kzalloc call, reducing the lines of code.

    Cc: Paul Bolle
    Cc: Karsten Keil
    Cc: "David S. Miller"
    Cc: Johan Hovold
    Cc: gigaset307x-common@lists.sourceforge.net
    Cc: netdev@vger.kernel.org
    Signed-off-by: Kees Cook
    Signed-off-by: David S. Miller

    Kees Cook
     
  • In preparation for unconditionally passing the struct timer_list pointer to
    all timer callbacks, switch to using the new timer_setup() and from_timer()
    to pass the timer pointer explicitly.

    Cc: Karsten Keil
    Cc: Geliang Tang
    Cc: "David S. Miller"
    Cc: Masahiro Yamada
    Cc: Andrew Morton
    Cc: Anton Vasilyev
    Cc: Ingo Molnar
    Cc: netdev@vger.kernel.org
    Signed-off-by: Kees Cook
    Signed-off-by: David S. Miller

    Kees Cook
     
  • In preparation for unconditionally passing the struct timer_list pointer to
    all timer callbacks, switch to using the new timer_setup() and from_timer()
    to pass the timer pointer explicitly.

    Cc: Karsten Keil
    Cc: Geliang Tang
    Cc: "David S. Miller"
    Cc: netdev@vger.kernel.org
    Signed-off-by: Kees Cook
    Signed-off-by: David S. Miller

    Kees Cook
     

21 Sep, 2017

1 commit

  • In isdn_ppp_write(), the header (i.e., protobuf) of the buffer is
    fetched twice from userspace. The first fetch is used to peek at the
    protocol of the message and reset the huptimer if necessary; while the
    second fetch copies in the whole buffer. However, given that buf resides
    in userspace memory, a user process can race to change its memory content
    across fetches. By doing so, we can either avoid resetting the huptimer
    for any type of packets (by first setting proto to PPP_LCP and later
    change to the actual type) or force resetting the huptimer for LCP
    packets.

    This patch changes this double-fetch behavior into two single fetches
    decided by condition (lp->isdn_device < 0 || lp->isdn_channel
    Signed-off-by: David S. Miller

    Meng Xu
     

08 Sep, 2017

1 commit

  • gcc-7 found an ancient bug in the loop driver, leading to a condition that
    is always false, meaning we ignore the contents of 'card->flags' here:

    drivers/isdn/isdnloop/isdnloop.c:412:37: error: ?: using integer constants in boolean context, the expression will always evaluate to 'true' [-Werror=int-in-bool-context]

    This changes the braces in the expression to ensure we actually
    compare the flag bits, rather than comparing a constant. As Joe Perches
    pointed out, an earlier patch of mine incorrectly assumed this was a
    false-positive warning.

    Cc: Joe Perches
    Link: https://patchwork.kernel.org/patch/9840289/
    Signed-off-by: Arnd Bergmann
    Signed-off-by: David S. Miller

    Arnd Bergmann
     

16 Aug, 2017

1 commit


12 Aug, 2017

1 commit

  • If mISDN_FsmNew() fails to allocate memory for jumpmatrix
    then null pointer dereference will occur on any write to
    jumpmatrix.

    The patch adds check on successful allocation and
    corresponding error handling.

    Found by Linux Driver Verification project (linuxtesting.org).

    Signed-off-by: Anton Vasilyev
    Signed-off-by: David S. Miller

    Anton Vasilyev