1. 30 7月, 2018 1 次提交
    • M
      Bluetooth: hidp: Fix handling of strncpy for hid->name information · b3cadaa4
      Marcel Holtmann 提交于
      This fixes two issues with setting hid->name information.
      
        CC      net/bluetooth/hidp/core.o
      In function ‘hidp_setup_hid’,
          inlined from ‘hidp_session_dev_init’ at net/bluetooth/hidp/core.c:815:9,
          inlined from ‘hidp_session_new’ at net/bluetooth/hidp/core.c:953:8,
          inlined from ‘hidp_connection_add’ at net/bluetooth/hidp/core.c:1366:8:
      net/bluetooth/hidp/core.c:778:2: warning: ‘strncpy’ output may be truncated copying 127 bytes from a string of length 127 [-Wstringop-truncation]
        strncpy(hid->name, req->name, sizeof(req->name) - 1);
        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      
        CC      net/bluetooth/hidp/core.o
      net/bluetooth/hidp/core.c: In function ‘hidp_setup_hid’:
      net/bluetooth/hidp/core.c:778:38: warning: argument to ‘sizeof’ in ‘strncpy’ call is the same expression as the source; did you mean to use the size of the destination? [-Wsizeof-pointer-memaccess]
        strncpy(hid->name, req->name, sizeof(req->name));
                                            ^
      Signed-off-by: NMarcel Holtmann <marcel@holtmann.org>
      Signed-off-by: NJohan Hedberg <johan.hedberg@intel.com>
      b3cadaa4
  2. 22 11月, 2017 1 次提交
    • K
      treewide: setup_timer() -> timer_setup() · e99e88a9
      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: NKees Cook <keescook@chromium.org>
      e99e88a9
  3. 21 11月, 2017 1 次提交
  4. 27 7月, 2017 1 次提交
    • J
      HID: introduce hid_is_using_ll_driver · fc2237a7
      Jason Gerecke 提交于
      Although HID itself is transport-agnostic, occasionally a driver may
      want to interact with the low-level transport that a device is connected
      through. To do this, we need to know what kind of bus is in use. The
      first guess may be to look at the 'bus' field of the 'struct hid_device',
      but this field may be emulated in some cases (e.g. uhid).
      
      More ideally, we can check which ll_driver a device is using. This
      function introduces a 'hid_is_using_ll_driver' function and makes the
      'struct hid_ll_driver' of the four most common transports accessible
      through hid.h.
      Signed-off-by: NJason Gerecke <jason.gerecke@wacom.com>
      Acked-By: NBenjamin Tissoires <benjamin.tissoires@redhat.com>
      Signed-off-by: NJiri Kosina <jkosina@suse.cz>
      fc2237a7
  5. 28 6月, 2017 1 次提交
  6. 20 6月, 2017 1 次提交
    • I
      sched/wait: Rename wait_queue_t => wait_queue_entry_t · ac6424b9
      Ingo Molnar 提交于
      Rename:
      
      	wait_queue_t		=>	wait_queue_entry_t
      
      'wait_queue_t' was always a slight misnomer: its name implies that it's a "queue",
      but in reality it's a queue *entry*. The 'real' queue is the wait queue head,
      which had to carry the name.
      
      Start sorting this out by renaming it to 'wait_queue_entry_t'.
      
      This also allows the real structure name 'struct __wait_queue' to
      lose its double underscore and become 'struct wait_queue_entry',
      which is the more canonical nomenclature for such data types.
      
      Cc: Linus Torvalds <torvalds@linux-foundation.org>
      Cc: Peter Zijlstra <peterz@infradead.org>
      Cc: Thomas Gleixner <tglx@linutronix.de>
      Cc: linux-kernel@vger.kernel.org
      Signed-off-by: NIngo Molnar <mingo@kernel.org>
      ac6424b9
  7. 16 6月, 2017 3 次提交
    • J
      networking: add and use skb_put_u8() · 634fef61
      Johannes Berg 提交于
      Joe and Bjørn suggested that it'd be nicer to not have the
      cast in the fairly common case of doing
      	*(u8 *)skb_put(skb, 1) = c;
      
      Add skb_put_u8() for this case, and use it across the code,
      using the following spatch:
      
          @@
          expression SKB, C, S;
          typedef u8;
          identifier fn = {skb_put};
          fresh identifier fn2 = fn ## "_u8";
          @@
          - *(u8 *)fn(SKB, S) = C;
          + fn2(SKB, C);
      
      Note that due to the "S", the spatch isn't perfect, it should
      have checked that S is 1, but there's also places that use a
      sizeof expression like sizeof(var) or sizeof(u8) etc. Turns
      out that nobody ever did something like
      	*(u8 *)skb_put(skb, 2) = c;
      
      which would be wrong anyway since the second byte wouldn't be
      initialized.
      Suggested-by: NJoe Perches <joe@perches.com>
      Suggested-by: NBjørn Mork <bjorn@mork.no>
      Signed-off-by: NJohannes Berg <johannes.berg@intel.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      634fef61
    • J
      networking: make skb_put & friends return void pointers · 4df864c1
      Johannes Berg 提交于
      It seems like a historic accident that these return unsigned char *,
      and in many places that means casts are required, more often than not.
      
      Make these functions (skb_put, __skb_put and pskb_put) return void *
      and remove all the casts across the tree, adding a (u8 *) cast only
      where the unsigned char pointer was used directly, all done with the
      following spatch:
      
          @@
          expression SKB, LEN;
          typedef u8;
          identifier fn = { skb_put, __skb_put };
          @@
          - *(fn(SKB, LEN))
          + *(u8 *)fn(SKB, LEN)
      
          @@
          expression E, SKB, LEN;
          identifier fn = { skb_put, __skb_put };
          type T;
          @@
          - E = ((T *)(fn(SKB, LEN)))
          + E = fn(SKB, LEN)
      
      which actually doesn't cover pskb_put since there are only three
      users overall.
      
      A handful of stragglers were converted manually, notably a macro in
      drivers/isdn/i4l/isdn_bsdcomp.c and, oddly enough, one of the many
      instances in net/bluetooth/hci_sock.c. In the former file, I also
      had to fix one whitespace problem spatch introduced.
      Signed-off-by: NJohannes Berg <johannes.berg@intel.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      4df864c1
    • J
      networking: introduce and use skb_put_data() · 59ae1d12
      Johannes Berg 提交于
      A common pattern with skb_put() is to just want to memcpy()
      some data into the new space, introduce skb_put_data() for
      this.
      
      An spatch similar to the one for skb_put_zero() converts many
      of the places using it:
      
          @@
          identifier p, p2;
          expression len, skb, data;
          type t, t2;
          @@
          (
          -p = skb_put(skb, len);
          +p = skb_put_data(skb, data, len);
          |
          -p = (t)skb_put(skb, len);
          +p = skb_put_data(skb, data, len);
          )
          (
          p2 = (t2)p;
          -memcpy(p2, data, len);
          |
          -memcpy(p, data, len);
          )
      
          @@
          type t, t2;
          identifier p, p2;
          expression skb, data;
          @@
          t *p;
          ...
          (
          -p = skb_put(skb, sizeof(t));
          +p = skb_put_data(skb, data, sizeof(t));
          |
          -p = (t *)skb_put(skb, sizeof(t));
          +p = skb_put_data(skb, data, sizeof(t));
          )
          (
          p2 = (t2)p;
          -memcpy(p2, data, sizeof(*p));
          |
          -memcpy(p, data, sizeof(*p));
          )
      
          @@
          expression skb, len, data;
          @@
          -memcpy(skb_put(skb, len), data, len);
          +skb_put_data(skb, data, len);
      
      (again, manually post-processed to retain some comments)
      Reviewed-by: NStephen Hemminger <stephen@networkplumber.org>
      Signed-off-by: NJohannes Berg <johannes.berg@intel.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      59ae1d12
  8. 21 10月, 2015 1 次提交
    • D
      Bluetooth: hidp: fix device disconnect on idle timeout · 660f0fc0
      David Herrmann 提交于
      The HIDP specs define an idle-timeout which automatically disconnects a
      device. This has always been implemented in the HIDP layer and forced a
      synchronous shutdown of the hidp-scheduler. This works just fine, but
      lacks a forced disconnect on the underlying l2cap channels. This has been
      broken since:
      
          commit 5205185d
          Author: David Herrmann <dh.herrmann@gmail.com>
          Date:   Sat Apr 6 20:28:47 2013 +0200
      
              Bluetooth: hidp: remove old session-management
      
      The old session-management always forced an l2cap error on the ctrl/intr
      channels when shutting down. The new session-management skips this, as we
      don't want to enforce channel policy on the caller. In other words, if
      user-space removes an HIDP device, the underlying channels (which are
      *owned* and *referenced* by user-space) are still left active. User-space
      needs to call shutdown(2) or close(2) to release them.
      
      Unfortunately, this does not work with idle-timeouts. There is no way to
      signal user-space that the HIDP layer has been stopped. The API simply
      does not support any event-passing except for poll(2). Hence, we restore
      old behavior and force EUNATCH on the sockets if the HIDP layer is
      disconnected due to idle-timeouts (behavior of explicit disconnects
      remains unmodified). User-space can still call
      
          getsockopt(..., SO_ERROR, ...)
      
      ..to retrieve the EUNATCH error and clear sk_err. Hence, the channels can
      still be re-used (which nobody does so far, though). Therefore, the API
      still supports the new behavior, but with this patch it's also compatible
      to the old implicit channel shutdown.
      
      Cc: <stable@vger.kernel.org> # 3.10+
      Reported-by: NMark Haun <haunma@keteu.org>
      Reported-by: NLuiz Augusto von Dentz <luiz.dentz@gmail.com>
      Signed-off-by: NDavid Herrmann <dh.herrmann@gmail.com>
      Signed-off-by: NMarcel Holtmann <marcel@holtmann.org>
      660f0fc0
  9. 05 7月, 2015 1 次提交
    • L
      bluetooth: fix list handling · 9b284cbd
      Linus Torvalds 提交于
      Commit 835a6a2f ("Bluetooth: Stop sabotaging list poisoning")
      thought that the code was sabotaging the list poisoning when NULL'ing
      out the list pointers and removed it.
      
      But what was going on was that the bluetooth code was using NULL
      pointers for the list as a way to mark it empty, and that commit just
      broke it (and replaced the test with NULL with a "list_empty()" test on
      a uninitialized list instead, breaking things even further).
      
      So fix it all up to use the regular and real list_empty() handling
      (which does not use NULL, but a pointer to itself), also making sure to
      initialize the list properly (the previous NULL case was initialized
      implicitly by the session being allocated with kzalloc())
      
      This is a combination of patches by Marcel Holtmann and Tedd Ho-Jeong
      An.
      
      [ I would normally expect to get this through the bt tree, but I'm going
        to release -rc1, so I'm just committing this directly   - Linus ]
      Reported-and-tested-by: NJörg Otte <jrg.otte@gmail.com>
      Cc: Alexey Dobriyan <adobriyan@gmail.com>
      Original-by: NTedd Ho-Jeong An <tedd.an@intel.com>
      Original-by: Marcel Holtmann <marcel@holtmann.org>:
      Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
      9b284cbd
  10. 27 6月, 2015 1 次提交
  11. 18 4月, 2015 1 次提交
  12. 04 4月, 2015 1 次提交
  13. 02 4月, 2015 1 次提交
  14. 19 12月, 2014 1 次提交
  15. 15 11月, 2014 1 次提交
  16. 09 9月, 2014 1 次提交
  17. 31 7月, 2014 1 次提交
  18. 14 3月, 2014 1 次提交
  19. 25 2月, 2014 1 次提交
  20. 18 2月, 2014 1 次提交
    • D
      HID: Bluetooth: hidp: make sure input buffers are big enough · a4b1b587
      David Herrmann 提交于
      HID core expects the input buffers to be at least of size 4096
      (HID_MAX_BUFFER_SIZE). Other sizes will result in buffer-overflows if an
      input-report is smaller than advertised. We could, like i2c, compute the
      biggest report-size instead of using HID_MAX_BUFFER_SIZE, but this will
      blow up if report-descriptors are changed after ->start() has been called.
      So lets be safe and just use the biggest buffer we have.
      
      Note that this adds an additional copy to the HIDP input path. If there is
      a way to make sure the skb-buf is big enough, we should use that instead.
      
      The best way would be to make hid-core honor the @size argument, though,
      that sounds easier than it is. So lets just fix the buffer-overflows for
      now and afterwards look for a faster way for all transport drivers.
      Signed-off-by: NDavid Herrmann <dh.herrmann@gmail.com>
      Signed-off-by: NJiri Kosina <jkosina@suse.cz>
      a4b1b587
  21. 17 2月, 2014 3 次提交
  22. 29 1月, 2014 1 次提交
  23. 14 10月, 2013 1 次提交
  24. 25 7月, 2013 2 次提交
  25. 22 7月, 2013 2 次提交
    • J
      HID: fix unused rsize usage · bc197eed
      Jiri Kosina 提交于
      27ce4050 ("HID: fix data access in implement()") by mistake removed
      a setting of buffer size in hidp. Fix that by putting it back.
      Reported-by: Nkbuild test robot <fengguang.wu@intel.com>
      Signed-off-by: NJiri Kosina <jkosina@suse.cz>
      bc197eed
    • J
      HID: fix data access in implement() · 27ce4050
      Jiri Kosina 提交于
      implement() is setting bytes in LE data stream. In case the data is not
      aligned to 64bits, it reads past the allocated buffer. It doesn't really
      change any value there (it's properly bitmasked), but in case that this
      read past the boundary hits a page boundary, pagefault happens when
      accessing 64bits of 'x' in implement(), and kernel oopses.
      
      This happens much more often when numbered reports are in use, as the
      initial 8bit skip in the buffer makes the whole process work on values
      which are not aligned to 64bits.
      
      This problem dates back to attempts in 2005 and 2006 to make implement()
      and extract() as generic as possible, and even back then the problem
      was realized by Adam Kroperlin, but falsely assumed to be impossible
      to cause any harm:
      
        http://www.mail-archive.com/linux-usb-devel@lists.sourceforge.net/msg47690.html
      
      I have made several attempts at fixing it "on the spot" directly in
      implement(), but the results were horrible; the special casing for processing
      last 64bit chunk and switching to different math makes it unreadable mess.
      
      I therefore took a path to allocate a few bytes more which will never make
      it into final report, but are there as a cushion for all the 64bit math
      operations happening in implement() and extract().
      
      All callers of hid_output_report() are converted at the same time to allocate
      the buffer by newly introduced hid_alloc_report_buf() helper.
      
      Bruno noticed that the whole raw_size test can be dropped as well, as
      hid_alloc_report_buf() makes sure that the buffer is always of a proper
      size.
      Reviewed-by: NBenjamin Tissoires <benjamin.tissoires@redhat.com>
      Acked-by: NGustavo Padovan <gustavo.padovan@collabora.co.uk>
      Signed-off-by: NJiri Kosina <jkosina@suse.cz>
      27ce4050
  26. 23 6月, 2013 1 次提交
  27. 29 5月, 2013 1 次提交
    • D
      HID: Bluetooth: hidp: register HID devices async · 4e713cdf
      David Herrmann 提交于
      While l2cap_user callbacks are running, the whole hci_dev is locked. Even
      if we would add more fine-grained locking to HCI core, it would still be
      called from the non-reentrant rx work-queue and thus block the event
      processing.
      
      However, if we want to perform synchronous I/O during HID device
      registration (eg., to perform device-detection), we need the HCI core
      to be able to dispatch incoming data.
      
      Therefore, we now move device-registration to a separate worker. The HCI
      core can continue running and we add devices asynchronously in another
      kernel thread. Device removal is synchronized and waits for the worker
      to exit before calling the usual device removal functions.
      
      If l2cap_user->remove is called before the thread registered the devices,
      we set "terminate" to true and the thread will skip it. If
      l2cap_user->remove is called after it, we notice this as the device
      is no longer in HIDP_SESSION_PREPARING state and simply unregister the
      device as we did before.
      There is no new deadlock as we now call hidp_session_add_dev() with
      one lock less held (the HCI lock) and it cannot itself call back into
      HCI as it was called with the HCI-lock held before.
      
      One might wonder whether this can block during device unregistration.
      But we set "terminate" to true and wake the HIDP thread up _before_
      unregistering the HID/input devices. Therefore, all pending HID I/O
      operations are canceled. All further I/O attempts will fail with ENODEV
      or EIO. So all latency we can get are few context-switches, but no
      timeouts or blocking I/O waits!
      
      This change also prepares for a long standing HID bug. All HID devices
      that register power_supply devices need to be able to handle callbacks
      during registration (a power_supply oddity that cannot easily be fixed).
      So with this patch available, we can allow HID I/O during registration
      by calling the recently introduced hid_device_io_start/stop helpers,
      which currently are a no-op for bluetooth due to this locking.
      
      Note that we cannot do the same for input devices. input-core doesn't
      allow us to call input_event() asynchronously to input_register_device(),
      which HID-core kindly allows (for good reasons).
      Fixing input-core to allow this isn't as easy as it sounds and is,
      beside simplifying HIDP, not really an improvement. Hence, we still
      register input devices synchronously as we did before. Only HID devices
      are registered asynchronously.
      Signed-off-by: NDavid Herrmann <dh.herrmann@gmail.com>
      Acked-by: NJiri Kosina <jkosina@suse.cz>
      Acked-by: NGustavo Padovan <gustavo.padovan@collabora.co.uk>
      Tested-by: NDaniel Nicoletti <dantti12@gmail.com>
      Signed-off-by: NJiri Kosina <jkosina@suse.cz>
      4e713cdf
  28. 17 4月, 2013 7 次提交
新手
引导
客服 返回
顶部