09 Sep, 2020

1 commit

  • When the file has been open in non-blocking mode, EIO or ERESTARTSYS
    would never be returned even if they should (for example when device
    has been unplugged, you want EIO and not EAGAIN to be returned).

    Move the O_NONBLOCK check after other checks have been performed.

    Based on similar to patches hidraw and hiddev by Founder Fang
    and Jiri Kosina .

    Signed-off-by: Laurent Gauthier
    Signed-off-by: Jiri Kosina

    Laurent Gauthier
     

31 May, 2019

1 commit

  • Based on 1 normalized pattern(s):

    this program 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 this program is distributed in the
    hope that it will be useful but without any warranty without even
    the implied warranty of merchantability or fitness for a particular
    purpose see the gnu general public license for more details you
    should have received a copy of the gnu general public license along
    with this program if not write to the free software foundation inc
    59 temple place suite 330 boston ma 02111 1307 usa

    extracted by the scancode license scanner the SPDX license identifier

    GPL-2.0-or-later

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

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

    Thomas Gleixner
     

19 Mar, 2019

1 commit

  • There is a race condition that could happen if hid_debug_rdesc_show()
    is running while hdev is in the process of going away (device removal,
    system suspend, etc) which could result in NULL pointer dereference:

    BUG: unable to handle kernel paging request at 0000000783316040
    CPU: 1 PID: 1512 Comm: getevent Tainted: G U O 4.19.20-quilt-2e5dc0ac-00029-gc455a447dd55 #1
    RIP: 0010:hid_dump_device+0x9b/0x160
    Call Trace:
    hid_debug_rdesc_show+0x72/0x1d0
    seq_read+0xe0/0x410
    full_proxy_read+0x5f/0x90
    __vfs_read+0x3a/0x170
    vfs_read+0xa0/0x150
    ksys_read+0x58/0xc0
    __x64_sys_read+0x1a/0x20
    do_syscall_64+0x55/0x110
    entry_SYSCALL_64_after_hwframe+0x49/0xbe

    Grab driver_input_lock to make sure the input device exists throughout the
    whole process of dumping the rdesc.

    [jkosina@suse.cz: update changelog a bit]
    Signed-off-by: he, bo
    Signed-off-by: "Zhang, Jun"
    Signed-off-by: Jiri Kosina

    He, Bo
     

29 Jan, 2019

1 commit

  • Ring buffer implementation in hid_debug_event() and hid_debug_events_read()
    is strange allowing lost or corrupted data. After commit 717adfdaf147
    ("HID: debug: check length before copy_to_user()") it is possible to enter
    an infinite loop in hid_debug_events_read() by providing 0 as count, this
    locks up a system. Fix this by rewriting the ring buffer implementation
    with kfifo and simplify the code.

    This fixes CVE-2019-3819.

    v2: fix an execution logic and add a comment
    v3: use __set_current_state() instead of set_current_state()

    Link: https://bugzilla.redhat.com/show_bug.cgi?id=1669187
    Cc: stable@vger.kernel.org # v4.18+
    Fixes: cd667ce24796 ("HID: use debugfs for events/reports dumping")
    Fixes: 717adfdaf147 ("HID: debug: check length before copy_to_user()")
    Signed-off-by: Vladis Dronov
    Reviewed-by: Oleg Nesterov
    Signed-off-by: Benjamin Tissoires

    Vladis Dronov
     

19 Dec, 2018

1 commit


10 Jul, 2018

1 commit

  • Pull HID fixes from Jiri Kosina:

    - spectrev1 pattern fix in hiddev from Gustavo A. R. Silva

    - bounds check fix for hid-debug from Daniel Rosenberg

    - regression fix for HID autobinding from Benjamin Tissoires

    - removal of excessive logging from i2c-hid driver from Jason Andryuk

    - fix specific to 2nd generation of Wacom Intuos devices from Jason
    Gerecke

    * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid:
    HID: hiddev: fix potential Spectre v1
    HID: i2c-hid: Fix "incomplete report" noise
    HID: wacom: Correct touch maximum XY of 2nd-gen Intuos
    HID: debug: check length before copy_to_user()
    HID: core: allow concurrent registration of drivers

    Linus Torvalds
     

03 Jul, 2018

1 commit


13 Jun, 2018

2 commits

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

    kzalloc(a * b, gfp)

    with:
    kcalloc(a * b, gfp)

    as well as handling cases of:

    kzalloc(a * b * c, gfp)

    with:

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

    as it's slightly less ugly than:

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

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

    kzalloc(4 * 1024, gfp)

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

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

    The Coccinelle script used for this was:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    Signed-off-by: Kees Cook

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

    kmalloc(a * b, gfp)

    with:
    kmalloc_array(a * b, gfp)

    as well as handling cases of:

    kmalloc(a * b * c, gfp)

    with:

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

    as it's slightly less ugly than:

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

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

    kmalloc(4 * 1024, gfp)

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

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

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

    The Coccinelle script used for this was:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    Signed-off-by: Kees Cook

    Kees Cook
     

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
     

29 Nov, 2017

1 commit


02 May, 2017

1 commit


30 Mar, 2017

1 commit


02 Mar, 2017

1 commit


27 Nov, 2015

1 commit

  • The code in hid_debug_event() causes horrible code generation. First,
    we do a strlen() call for every byte we copy (we're doing a store to
    global memory, so gcc has no way of proving that strlen(buf) doesn't
    change). Second, since both i, list->tail and HID_DEBUG_BUFSIZE have
    signed type, the modulo computation has to take into account the
    possibility that list->tail+i is negative, so it's not just a simple
    and.

    Fix the former by simply not doing strlen() at all (we have to load
    buf[i] anyway, so testing it is almost free) and the latter by
    changing i to unsigned. This cuts 29% (69 bytes) of the size of the
    function.

    Signed-off-by: Rasmus Villemoes
    Signed-off-by: Jiri Kosina

    Rasmus Villemoes
     

15 Apr, 2015

1 commit

  • Pull input subsystem updates from Dmitry Torokhov:
    "You will get the following new drivers:

    - Qualcomm PM8941 power key drver
    - ChipOne icn8318 touchscreen controller driver
    - Broadcom iProc touchscreen and keypad drivers
    - Semtech SX8654 I2C touchscreen controller driver

    ALPS driver now supports newer SS4 devices; Elantech got a fix that
    should make it work on some ASUS laptops; and a slew of other
    enhancements and random fixes"

    * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: (51 commits)
    Input: alps - non interleaved V2 dualpoint has separate stick button bits
    Input: alps - fix touchpad buttons getting stuck when used with trackpoint
    Input: atkbd - document "no new force-release quirks" policy
    Input: ALPS - make alps_get_pkt_id_ss4_v2() and others static
    Input: ALPS - V7 devices can report 5-finger taps
    Input: ALPS - add support for SS4 touchpad devices
    Input: ALPS - refactor alps_set_abs_params_mt()
    Input: elantech - fix absolute mode setting on some ASUS laptops
    Input: atmel_mxt_ts - split out touchpad initialisation logic
    Input: atmel_mxt_ts - implement support for T100 touch object
    Input: cros_ec_keyb - fix clearing keyboard state on wakeup
    Input: gscps2 - drop pci_ids dependency
    Input: synaptics - allocate 3 slots to keep stability in image sensors
    Input: Revert "Revert "synaptics - use dmax in input_mt_assign_slots""
    Input: MT - make slot assignment work for overcovered solutions
    mfd: tc3589x: enforce device-tree only mode
    Input: tc3589x - localize platform data
    Input: tsc2007 - Convert msecs to jiffies only once
    Input: edt-ft5x06 - remove EV_SYN event report
    Input: edt-ft5x06 - allow to setting the maximum axes value through the DT
    ...

    Linus Torvalds
     

14 Apr, 2015

1 commit


10 Apr, 2015

1 commit

  • In the unlikely case of hdev vanishing while hid_debug_events_read() was
    sleeping, we can't really break out of the case switch as with other cases,
    as on the way out we'll try to remove ourselves from the hdev waitqueue.

    Fix this by taking a shortcut exit path and avoiding cleanup that doesn't
    make sense in case hdev doesn't exist any more anyway.

    Reported-by: Jiri Slaby
    Signed-off-by: Jiri Kosina

    Jiri Kosina
     

12 Mar, 2015

1 commit

  • According to [1], Windows Precision Touchpad devices must supply
    a button type usage in the device capabilities feature report. A
    value of 0 indicates that the device contains a depressible
    button (i.e. it's a click-pad) whereas a value of 1 indicates
    a non-depressible button. Add support for this usage and set
    INPUT_PROP_BUTTONPAD on the touchpad input device whenever a
    depressible button is present.

    [1] https://msdn.microsoft.com/en-us/library/windows/hardware/dn467314(v=vs.85).aspx

    Signed-off-by: Seth Forshee
    Reviewed-by: Benjamin Tissoires
    Signed-off-by: Jiri Kosina

    Seth Forshee
     

07 Mar, 2015

1 commit


21 Oct, 2014

1 commit


03 Jun, 2014

1 commit

  • On Feb 17, 2014, two new usages are approved to HID usage Table 18 -
    Digitizer Page:

    5A Secondary Barrel Switch MC 16.4
    5B Transducer Serial Number SV 16.3.1

    This patch adds relevant definitions to hid/input. It also removes
    outdated comments in hid.h.

    Signed-off-by: Ping Cheng
    Reviewed-by: Benjamin Tissoires
    Signed-off-by: Jiri Kosina

    Ping Cheng
     

28 May, 2014

1 commit


28 Apr, 2014

1 commit

  • Add some missing hid usages from consumer page, add
    some display brightness control usages from approved hid usage
    table request HUTTR41:
    http://www.usb.org/developers/hidpage/HUTRR41.pdf
    and add voice command usage from approved request HUTTR45:
    http://www.usb.org/developers/hidpage/Voice_Command_Usage.pdf

    [jkosina@suse.cz: removed KEY_BRIGHTNESS_TOGGLE / KEY_DISPLAYTOGGLE
    conflict from hid-debug.c]

    Signed-off-by: Olivier Gay
    Signed-off-by: Mathieu Meisser
    Acked-by: Dmitry Torokhov
    Signed-off-by: Jiri Kosina

    Olivier Gay
     

17 Dec, 2013

1 commit


06 May, 2013

1 commit

  • Commit 2353f2bea ("HID: protect hid_debug_list") introduced mutex
    locking around debug_list access to prevent SMP races when debugfs
    nodes are being operated upon by multiple userspace processess.

    mutex is not a proper synchronization primitive though, as the hid-debug
    callbacks are being called from atomic contexts.

    We also have to be careful about disabling IRQs when taking the lock
    to prevent deadlock against IRQ handlers.

    Benjamin reports this has also been reported in RH bugzilla as bug #958935.

    ===============================
    [ INFO: suspicious RCU usage. ]
    3.9.0+ #94 Not tainted
    -------------------------------
    include/linux/rcupdate.h:476 Illegal context switch in RCU read-side critical section!

    other info that might help us debug this:

    rcu_scheduler_active = 1, debug_locks = 0
    4 locks held by Xorg/5502:
    #0: (&evdev->mutex){+.+...}, at: [] evdev_write+0x6d/0x160
    #1: (&(&dev->event_lock)->rlock#2){-.-...}, at: [] input_inject_event+0x5b/0x230
    #2: (rcu_read_lock){.+.+..}, at: [] input_inject_event+0x42/0x230
    #3: (&(&usbhid->lock)->rlock){-.....}, at: [] usb_hidinput_input_event+0x89/0x120

    stack backtrace:
    CPU: 0 PID: 5502 Comm: Xorg Not tainted 3.9.0+ #94
    Hardware name: Dell Inc. OptiPlex 390/0M5DCD, BIOS A09 07/24/2012
    0000000000000001 ffff8800689c7c38 ffffffff816f249f ffff8800689c7c68
    ffffffff810acb1d 0000000000000000 ffffffff81a03ac7 000000000000019d
    0000000000000000 ffff8800689c7c90 ffffffff8107cda7 0000000000000000
    Call Trace:
    [] dump_stack+0x19/0x1b
    [] lockdep_rcu_suspicious+0xfd/0x130
    [] __might_sleep+0xc7/0x230
    [] mutex_lock_nested+0x40/0x3a0
    [] ? vsnprintf+0x354/0x640
    [] hid_debug_event+0x34/0x100
    [] hid_dump_input+0x67/0xa0
    [] hid_set_field+0x50/0x120
    [] usb_hidinput_input_event+0x9a/0x120
    [] input_handle_event+0x8e/0x530
    [] input_inject_event+0x1d0/0x230
    [] ? input_inject_event+0x42/0x230
    [] evdev_write+0xde/0x160
    [] vfs_write+0xc8/0x1f0
    [] SyS_write+0x55/0xa0
    [] system_call_fastpath+0x16/0x1b
    BUG: sleeping function called from invalid context at kernel/mutex.c:413
    in_atomic(): 1, irqs_disabled(): 1, pid: 5502, name: Xorg
    INFO: lockdep is turned off.
    irq event stamp: 1098574
    hardirqs last enabled at (1098573): [] _raw_spin_unlock_irqrestore+0x3f/0x70
    hardirqs last disabled at (1098574): [] _raw_spin_lock_irqsave+0x25/0xa0
    softirqs last enabled at (1098306): [] __do_softirq+0x18f/0x3c0
    softirqs last disabled at (1097867): [] irq_exit+0xa5/0xb0
    CPU: 0 PID: 5502 Comm: Xorg Not tainted 3.9.0+ #94
    Hardware name: Dell Inc. OptiPlex 390/0M5DCD, BIOS A09 07/24/2012
    ffffffff81a03ac7 ffff8800689c7c68 ffffffff816f249f ffff8800689c7c90
    ffffffff8107ce60 0000000000000000 ffff8800689c7fd8 ffff88006a62c800
    ffff8800689c7d10 ffffffff816f7770 ffff8800689c7d00 ffffffff81312ac4
    Call Trace:
    [] dump_stack+0x19/0x1b
    [] __might_sleep+0x180/0x230
    [] mutex_lock_nested+0x40/0x3a0
    [] ? vsnprintf+0x354/0x640
    [] hid_debug_event+0x34/0x100
    [] hid_dump_input+0x67/0xa0
    [] hid_set_field+0x50/0x120
    [] usb_hidinput_input_event+0x9a/0x120
    [] input_handle_event+0x8e/0x530
    [] input_inject_event+0x1d0/0x230
    [] ? input_inject_event+0x42/0x230
    [] evdev_write+0xde/0x160
    [] vfs_write+0xc8/0x1f0
    [] SyS_write+0x55/0xa0
    [] system_call_fastpath+0x16/0x1b

    Reported-by: majianpeng
    Reported-by: Benjamin Tissoires
    Reviewed-by: Dmitry Torokhov
    Signed-off-by: Jiri Kosina

    Jiri Kosina
     

30 Apr, 2013

2 commits


27 Aug, 2012

1 commit


05 Jan, 2012

1 commit


19 Nov, 2011

1 commit


01 Nov, 2011

1 commit


16 Aug, 2011

1 commit


31 Mar, 2011

1 commit


10 Dec, 2010

1 commit

  • Neaten current uses of dev_ by adding and using
    hid specific hid_ macros.

    Convert existing uses of dev_ uses to hid_.
    Convert hid-pidff printk uses to hid_.

    Remove err_hid and use hid_err instead.

    Add missing newlines to logging messages where necessary.
    Coalesce format strings.

    Add and use pr_fmt(fmt) KBUILD_MODNAME ": " fmt

    Other miscellaneous changes:

    Add const struct hid_device * argument to hid-core functions
    extract() and implement() so hid_ can be used by them.
    Fix bad indentation in hid-core hid_input_field function
    that calls extract() function above.

    Signed-off-by: Joe Perches
    Signed-off-by: Jiri Kosina

    Joe Perches
     

24 Oct, 2010

1 commit


15 Oct, 2010

1 commit

  • All file_operations should get a .llseek operation so we can make
    nonseekable_open the default for future file operations without a
    .llseek pointer.

    The three cases that we can automatically detect are no_llseek, seq_lseek
    and default_llseek. For cases where we can we can automatically prove that
    the file offset is always ignored, we use noop_llseek, which maintains
    the current behavior of not returning an error from a seek.

    New drivers should normally not use noop_llseek but instead use no_llseek
    and call nonseekable_open at open time. Existing drivers can be converted
    to do the same when the maintainer knows for certain that no user code
    relies on calling seek on the device file.

    The generated code is often incorrectly indented and right now contains
    comments that clarify for each added line why a specific variant was
    chosen. In the version that gets submitted upstream, the comments will
    be gone and I will manually fix the indentation, because there does not
    seem to be a way to do that using coccinelle.

    Some amount of new code is currently sitting in linux-next that should get
    the same modifications, which I will do at the end of the merge window.

    Many thanks to Julia Lawall for helping me learn to write a semantic
    patch that does all this.

    ===== begin semantic patch =====
    // This adds an llseek= method to all file operations,
    // as a preparation for making no_llseek the default.
    //
    // The rules are
    // - use no_llseek explicitly if we do nonseekable_open
    // - use seq_lseek for sequential files
    // - use default_llseek if we know we access f_pos
    // - use noop_llseek if we know we don't access f_pos,
    // but we still want to allow users to call lseek
    //
    @ open1 exists @
    identifier nested_open;
    @@
    nested_open(...)
    {

    }

    @ open exists@
    identifier open_f;
    identifier i, f;
    identifier open1.nested_open;
    @@
    int open_f(struct inode *i, struct file *f)
    {

    }

    @ read disable optional_qualifier exists @
    identifier read_f;
    identifier f, p, s, off;
    type ssize_t, size_t, loff_t;
    expression E;
    identifier func;
    @@
    ssize_t read_f(struct file *f, char *p, size_t s, loff_t *off)
    {

    }

    @ read_no_fpos disable optional_qualifier exists @
    identifier read_f;
    identifier f, p, s, off;
    type ssize_t, size_t, loff_t;
    @@
    ssize_t read_f(struct file *f, char *p, size_t s, loff_t *off)
    {
    ... when != off
    }

    @ write @
    identifier write_f;
    identifier f, p, s, off;
    type ssize_t, size_t, loff_t;
    expression E;
    identifier func;
    @@
    ssize_t write_f(struct file *f, const char *p, size_t s, loff_t *off)
    {

    }

    @ write_no_fpos @
    identifier write_f;
    identifier f, p, s, off;
    type ssize_t, size_t, loff_t;
    @@
    ssize_t write_f(struct file *f, const char *p, size_t s, loff_t *off)
    {
    ... when != off
    }

    @ fops0 @
    identifier fops;
    @@
    struct file_operations fops = {
    ...
    };

    @ has_llseek depends on fops0 @
    identifier fops0.fops;
    identifier llseek_f;
    @@
    struct file_operations fops = {
    ...
    .llseek = llseek_f,
    ...
    };

    @ has_read depends on fops0 @
    identifier fops0.fops;
    identifier read_f;
    @@
    struct file_operations fops = {
    ...
    .read = read_f,
    ...
    };

    @ has_write depends on fops0 @
    identifier fops0.fops;
    identifier write_f;
    @@
    struct file_operations fops = {
    ...
    .write = write_f,
    ...
    };

    @ has_open depends on fops0 @
    identifier fops0.fops;
    identifier open_f;
    @@
    struct file_operations fops = {
    ...
    .open = open_f,
    ...
    };

    // use no_llseek if we call nonseekable_open
    ////////////////////////////////////////////
    @ nonseekable1 depends on !has_llseek && has_open @
    identifier fops0.fops;
    identifier nso ~= "nonseekable_open";
    @@
    struct file_operations fops = {
    ... .open = nso, ...
    +.llseek = no_llseek, /* nonseekable */
    };

    @ nonseekable2 depends on !has_llseek @
    identifier fops0.fops;
    identifier open.open_f;
    @@
    struct file_operations fops = {
    ... .open = open_f, ...
    +.llseek = no_llseek, /* open uses nonseekable */
    };

    // use seq_lseek for sequential files
    /////////////////////////////////////
    @ seq depends on !has_llseek @
    identifier fops0.fops;
    identifier sr ~= "seq_read";
    @@
    struct file_operations fops = {
    ... .read = sr, ...
    +.llseek = seq_lseek, /* we have seq_read */
    };

    // use default_llseek if there is a readdir
    ///////////////////////////////////////////
    @ fops1 depends on !has_llseek && !nonseekable1 && !nonseekable2 && !seq @
    identifier fops0.fops;
    identifier readdir_e;
    @@
    // any other fop is used that changes pos
    struct file_operations fops = {
    ... .readdir = readdir_e, ...
    +.llseek = default_llseek, /* readdir is present */
    };

    // use default_llseek if at least one of read/write touches f_pos
    /////////////////////////////////////////////////////////////////
    @ fops2 depends on !fops1 && !has_llseek && !nonseekable1 && !nonseekable2 && !seq @
    identifier fops0.fops;
    identifier read.read_f;
    @@
    // read fops use offset
    struct file_operations fops = {
    ... .read = read_f, ...
    +.llseek = default_llseek, /* read accesses f_pos */
    };

    @ fops3 depends on !fops1 && !fops2 && !has_llseek && !nonseekable1 && !nonseekable2 && !seq @
    identifier fops0.fops;
    identifier write.write_f;
    @@
    // write fops use offset
    struct file_operations fops = {
    ... .write = write_f, ...
    + .llseek = default_llseek, /* write accesses f_pos */
    };

    // Use noop_llseek if neither read nor write accesses f_pos
    ///////////////////////////////////////////////////////////

    @ fops4 depends on !fops1 && !fops2 && !fops3 && !has_llseek && !nonseekable1 && !nonseekable2 && !seq @
    identifier fops0.fops;
    identifier read_no_fpos.read_f;
    identifier write_no_fpos.write_f;
    @@
    // write fops use offset
    struct file_operations fops = {
    ...
    .write = write_f,
    .read = read_f,
    ...
    +.llseek = noop_llseek, /* read and write both use no f_pos */
    };

    @ depends on has_write && !has_read && !fops1 && !fops2 && !has_llseek && !nonseekable1 && !nonseekable2 && !seq @
    identifier fops0.fops;
    identifier write_no_fpos.write_f;
    @@
    struct file_operations fops = {
    ... .write = write_f, ...
    +.llseek = noop_llseek, /* write uses no f_pos */
    };

    @ depends on has_read && !has_write && !fops1 && !fops2 && !has_llseek && !nonseekable1 && !nonseekable2 && !seq @
    identifier fops0.fops;
    identifier read_no_fpos.read_f;
    @@
    struct file_operations fops = {
    ... .read = read_f, ...
    +.llseek = noop_llseek, /* read uses no f_pos */
    };

    @ depends on !has_read && !has_write && !fops1 && !fops2 && !has_llseek && !nonseekable1 && !nonseekable2 && !seq @
    identifier fops0.fops;
    @@
    struct file_operations fops = {
    ...
    +.llseek = noop_llseek, /* no read or write fn */
    };
    ===== End semantic patch =====

    Signed-off-by: Arnd Bergmann
    Cc: Julia Lawall
    Cc: Christoph Hellwig

    Arnd Bergmann
     

08 Sep, 2010

1 commit

  • Some devices poke the hid core in a way that causes hid_debug_event to
    be called, while never calling hid_dump_input. Without this wakeup
    addition, tasks reading for hid events through debugfs may never see any
    events. It may be that a well written driver doesn't cause this, but
    then what's the point of debugfs?

    Signed-off-by: Chase Douglas
    Signed-off-by: Jiri Kosina

    Chase Douglas
     

21 Jun, 2010

1 commit

  • The path around the loop ends with the lock held, so the call to mutex_lock
    is moved before the beginning of the loop.

    A simplified version of the semantic match that finds this problem is as
    follows: (http://coccinelle.lip6.fr/)

    //
    @locked@
    expression E1;
    position p;
    @@

    read_lock(E1@p,...);

    @r exists@
    expression x

    Signed-off-by: Julia Lawall
    Signed-off-by: Jiri Kosina

    Julia Lawall
     

21 May, 2010

1 commit