1. 28 1月, 2022 1 次提交
    • V
      usb: gadget: f_fs: Clear ffs_eventfd in ffs_data_clear. · 419b35f6
      Vincent Pelletier 提交于
      stable inclusion
      from stable-v5.10.90
      commit 1c4ace3e6b8575745c50dca9e76e0021e697d645
      bugzilla: 186168 https://gitee.com/openeuler/kernel/issues/I4SHY1
      
      Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=1c4ace3e6b8575745c50dca9e76e0021e697d645
      
      --------------------------------
      
      commit b1e08873 upstream.
      
      ffs_data_clear is indirectly called from both ffs_fs_kill_sb and
      ffs_ep0_release, so it ends up being called twice when userland closes ep0
      and then unmounts f_fs.
      If userland provided an eventfd along with function's USB descriptors, it
      ends up calling eventfd_ctx_put as many times, causing a refcount
      underflow.
      NULL-ify ffs_eventfd to prevent these extraneous eventfd_ctx_put calls.
      
      Also, set epfiles to NULL right after de-allocating it, for readability.
      
      For completeness, ffs_data_clear actually ends up being called thrice, the
      last call being before the whole ffs structure gets freed, so when this
      specific sequence happens there is a second underflow happening (but not
      being reported):
      
      /sys/kernel/debug/tracing# modprobe usb_f_fs
      /sys/kernel/debug/tracing# echo ffs_data_clear > set_ftrace_filter
      /sys/kernel/debug/tracing# echo function > current_tracer
      /sys/kernel/debug/tracing# echo 1 > tracing_on
      (setup gadget, run and kill function userland process, teardown gadget)
      /sys/kernel/debug/tracing# echo 0 > tracing_on
      /sys/kernel/debug/tracing# cat trace
       smartcard-openp-436     [000] .....  1946.208786: ffs_data_clear <-ffs_data_closed
       smartcard-openp-431     [000] .....  1946.279147: ffs_data_clear <-ffs_data_closed
       smartcard-openp-431     [000] .n...  1946.905512: ffs_data_clear <-ffs_data_put
      
      Warning output corresponding to above trace:
      [ 1946.284139] WARNING: CPU: 0 PID: 431 at lib/refcount.c:28 refcount_warn_saturate+0x110/0x15c
      [ 1946.293094] refcount_t: underflow; use-after-free.
      [ 1946.298164] Modules linked in: usb_f_ncm(E) u_ether(E) usb_f_fs(E) hci_uart(E) btqca(E) btrtl(E) btbcm(E) btintel(E) bluetooth(E) nls_ascii(E) nls_cp437(E) vfat(E) fat(E) bcm2835_v4l2(CE) bcm2835_mmal_vchiq(CE) videobuf2_vmalloc(E) videobuf2_memops(E) sha512_generic(E) videobuf2_v4l2(E) sha512_arm(E) videobuf2_common(E) videodev(E) cpufreq_dt(E) snd_bcm2835(CE) brcmfmac(E) mc(E) vc4(E) ctr(E) brcmutil(E) snd_soc_core(E) snd_pcm_dmaengine(E) drbg(E) snd_pcm(E) snd_timer(E) snd(E) soundcore(E) drm_kms_helper(E) cec(E) ansi_cprng(E) rc_core(E) syscopyarea(E) raspberrypi_cpufreq(E) sysfillrect(E) sysimgblt(E) cfg80211(E) max17040_battery(OE) raspberrypi_hwmon(E) fb_sys_fops(E) regmap_i2c(E) ecdh_generic(E) rfkill(E) ecc(E) bcm2835_rng(E) rng_core(E) vchiq(CE) leds_gpio(E) libcomposite(E) fuse(E) configfs(E) ip_tables(E) x_tables(E) autofs4(E) ext4(E) crc16(E) mbcache(E) jbd2(E) crc32c_generic(E) sdhci_iproc(E) sdhci_pltfm(E) sdhci(E)
      [ 1946.399633] CPU: 0 PID: 431 Comm: smartcard-openp Tainted: G         C OE     5.15.0-1-rpi #1  Debian 5.15.3-1
      [ 1946.417950] Hardware name: BCM2835
      [ 1946.425442] Backtrace:
      [ 1946.432048] [<c08d60a0>] (dump_backtrace) from [<c08d62ec>] (show_stack+0x20/0x24)
      [ 1946.448226]  r7:00000009 r6:0000001c r5:c04a948c r4:c0a64e2c
      [ 1946.458412] [<c08d62cc>] (show_stack) from [<c08d9ae0>] (dump_stack+0x28/0x30)
      [ 1946.470380] [<c08d9ab8>] (dump_stack) from [<c0123500>] (__warn+0xe8/0x154)
      [ 1946.482067]  r5:c04a948c r4:c0a71dc8
      [ 1946.490184] [<c0123418>] (__warn) from [<c08d6948>] (warn_slowpath_fmt+0xa0/0xe4)
      [ 1946.506758]  r7:00000009 r6:0000001c r5:c0a71dc8 r4:c0a71e04
      [ 1946.517070] [<c08d68ac>] (warn_slowpath_fmt) from [<c04a948c>] (refcount_warn_saturate+0x110/0x15c)
      [ 1946.535309]  r8:c0100224 r7:c0dfcb84 r6:ffffffff r5:c3b84c00 r4:c24a17c0
      [ 1946.546708] [<c04a937c>] (refcount_warn_saturate) from [<c0380134>] (eventfd_ctx_put+0x48/0x74)
      [ 1946.564476] [<c03800ec>] (eventfd_ctx_put) from [<bf5464e8>] (ffs_data_clear+0xd0/0x118 [usb_f_fs])
      [ 1946.582664]  r5:c3b84c00 r4:c2695b00
      [ 1946.590668] [<bf546418>] (ffs_data_clear [usb_f_fs]) from [<bf547cc0>] (ffs_data_closed+0x9c/0x150 [usb_f_fs])
      [ 1946.609608]  r5:bf54d014 r4:c2695b00
      [ 1946.617522] [<bf547c24>] (ffs_data_closed [usb_f_fs]) from [<bf547da0>] (ffs_fs_kill_sb+0x2c/0x30 [usb_f_fs])
      [ 1946.636217]  r7:c0dfcb84 r6:c3a12260 r5:bf54d014 r4:c229f000
      [ 1946.646273] [<bf547d74>] (ffs_fs_kill_sb [usb_f_fs]) from [<c0326d50>] (deactivate_locked_super+0x54/0x9c)
      [ 1946.664893]  r5:bf54d014 r4:c229f000
      [ 1946.672921] [<c0326cfc>] (deactivate_locked_super) from [<c0326df8>] (deactivate_super+0x60/0x64)
      [ 1946.690722]  r5:c2a09000 r4:c229f000
      [ 1946.698706] [<c0326d98>] (deactivate_super) from [<c0349a28>] (cleanup_mnt+0xe4/0x14c)
      [ 1946.715553]  r5:c2a09000 r4:00000000
      [ 1946.723528] [<c0349944>] (cleanup_mnt) from [<c0349b08>] (__cleanup_mnt+0x1c/0x20)
      [ 1946.739922]  r7:c0dfcb84 r6:c3a12260 r5:c3a126fc r4:00000000
      [ 1946.750088] [<c0349aec>] (__cleanup_mnt) from [<c0143d10>] (task_work_run+0x84/0xb8)
      [ 1946.766602] [<c0143c8c>] (task_work_run) from [<c010bdc8>] (do_work_pending+0x470/0x56c)
      [ 1946.783540]  r7:5ac3c35a r6:c0d0424c r5:c200bfb0 r4:c200a000
      [ 1946.793614] [<c010b958>] (do_work_pending) from [<c01000c0>] (slow_work_pending+0xc/0x20)
      [ 1946.810553] Exception stack(0xc200bfb0 to 0xc200bff8)
      [ 1946.820129] bfa0:                                     00000000 00000000 000000aa b5e21430
      [ 1946.837104] bfc0: bef867a0 00000001 bef86840 00000034 bef86838 bef86790 bef86794 bef867a0
      [ 1946.854125] bfe0: 00000000 bef86798 b67b7a1c b6d626a4 60000010 b5a23760
      [ 1946.865335]  r10:00000000 r9:c200a000 r8:c0100224 r7:00000034 r6:bef86840 r5:00000001
      [ 1946.881914]  r4:bef867a0
      [ 1946.888793] ---[ end trace 7387f2a9725b28d0 ]---
      
      Fixes: 5e33f6fd ("usb: gadget: ffs: add eventfd notification about ffs events")
      Cc: stable <stable@vger.kernel.org>
      Signed-off-by: NVincent Pelletier <plr.vincent@gmail.com>
      Link: https://lore.kernel.org/r/f79eeea29f3f98de6782a064ec0f7351ad2f598f.1639793920.git.plr.vincent@gmail.comSigned-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      Signed-off-by: NChen Jun <chenjun102@huawei.com>
      Signed-off-by: NZheng Zengkai <zhengzengkai@huawei.com>
      419b35f6
  2. 13 10月, 2021 1 次提交
    • A
      usb: gadget: f_fs: Fix setting of device and driver data cross-references · a35cb3f5
      Andrew Gabbasov 提交于
      stable inclusion
      from stable-5.10.50
      commit 8aa1cb46b72e2a6cb6345ffdb696fff412c0cd48
      bugzilla: 174522 https://gitee.com/openeuler/kernel/issues/I4DNFY
      
      Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=8aa1cb46b72e2a6cb6345ffdb696fff412c0cd48
      
      --------------------------------
      
      [ Upstream commit ecfbd7b9 ]
      
      FunctionFS device structure 'struct ffs_dev' and driver data structure
      'struct ffs_data' are bound to each other with cross-reference pointers
      'ffs_data->private_data' and 'ffs_dev->ffs_data'. While the first one
      is supposed to be valid through the whole life of 'struct ffs_data'
      (and while 'struct ffs_dev' exists non-freed), the second one is cleared
      in 'ffs_closed()' (called from 'ffs_data_reset()' or the last
      'ffs_data_put()'). This can be called several times, alternating in
      different order with 'ffs_free_inst()', that, if possible, clears
      the other cross-reference.
      
      As a result, different cases of these calls order may leave stale
      cross-reference pointers, used when the pointed structure is already
      freed. Even if it occasionally doesn't cause kernel crash, this error
      is reported by KASAN-enabled kernel configuration.
      
      For example, the case [last 'ffs_data_put()' - 'ffs_free_inst()'] was
      fixed by commit cdafb6d8 ("usb: gadget: f_fs: Fix use-after-free in
      ffs_free_inst").
      
      The other case ['ffs_data_reset()' - 'ffs_free_inst()' - 'ffs_data_put()']
      now causes KASAN reported error [1], when 'ffs_data_reset()' clears
      'ffs_dev->ffs_data', then 'ffs_free_inst()' frees the 'struct ffs_dev',
      but can't clear 'ffs_data->private_data', which is then accessed
      in 'ffs_closed()' called from 'ffs_data_put()'. This happens since
      'ffs_dev->ffs_data' reference is cleared too early.
      
      Moreover, one more use case, when 'ffs_free_inst()' is called immediately
      after mounting FunctionFS device (that is before the descriptors are
      written and 'ffs_ready()' is called), and then 'ffs_data_reset()'
      or 'ffs_data_put()' is called from accessing "ep0" file or unmounting
      the device. This causes KASAN error report like [2], since
      'ffs_dev->ffs_data' is not yet set when 'ffs_free_inst()' can't properly
      clear 'ffs_data->private_data', that is later accessed to freed structure.
      
      Fix these (and may be other) cases of stale pointers access by moving
      setting and clearing of the mentioned cross-references to the single
      places, setting both of them when 'struct ffs_data' is created and
      bound to 'struct ffs_dev', and clearing both of them when one of the
      structures is destroyed. It seems convenient to make this pointer
      initialization and structures binding in 'ffs_acquire_dev()' and
      make pointers clearing in 'ffs_release_dev()'. This required some
      changes in these functions parameters and return types.
      
      Also, 'ffs_release_dev()' calling requires some cleanup, fixing minor
      issues, like (1) 'ffs_release_dev()' is not called if 'ffs_free_inst()'
      is called without unmounting the device, and "release_dev" callback
      is not called at all, or (2) "release_dev" callback is called before
      "ffs_closed" callback on unmounting, which seems to be not correctly
      nested with "acquire_dev" and "ffs_ready" callbacks.
      Make this cleanup togther with other mentioned 'ffs_release_dev()' changes.
      
      [1]
      
      ==================================================================
      root@rcar-gen3:~# mkdir /dev/cfs
      root@rcar-gen3:~# mkdir /dev/ffs
      root@rcar-gen3:~# modprobe libcomposite
      root@rcar-gen3:~# mount -t configfs none /dev/cfs
      root@rcar-gen3:~# mkdir /dev/cfs/usb_gadget/g1
      root@rcar-gen3:~# mkdir /dev/cfs/usb_gadget/g1/functions/ffs.ffs
      [   64.340664] file system registered
      root@rcar-gen3:~# mount -t functionfs ffs /dev/ffs
      root@rcar-gen3:~# cd /dev/ffs
      root@rcar-gen3:/dev/ffs# /home/root/ffs-test
      ffs-test: info: ep0: writing descriptors (in v2 format)
      [   83.181442] read descriptors
      [   83.186085] read strings
      ffs-test: info: ep0: writing strings
      ffs-test: dbg:  ep1: starting
      ffs-test: dbg:  ep2: starting
      ffs-test: info: ep1: starts
      ffs-test: info: ep2: starts
      ffs-test: info: ep0: starts
      
      ^C
      root@rcar-gen3:/dev/ffs# cd /home/root/
      root@rcar-gen3:~# rmdir /dev/cfs/usb_gadget/g1/functions/ffs.ffs
      [   98.935061] unloading
      root@rcar-gen3:~# umount /dev/ffs
      [  102.734301] ==================================================================
      [  102.742059] BUG: KASAN: use-after-free in ffs_release_dev+0x64/0xa8 [usb_f_fs]
      [  102.749683] Write of size 1 at addr ffff0004d46ff549 by task umount/2997
      [  102.756709]
      [  102.758311] CPU: 0 PID: 2997 Comm: umount Not tainted 5.13.0-rc4+ #8
      [  102.764971] Hardware name: Renesas Salvator-X board based on r8a77951 (DT)
      [  102.772179] Call trace:
      [  102.774779]  dump_backtrace+0x0/0x330
      [  102.778653]  show_stack+0x20/0x2c
      [  102.782152]  dump_stack+0x11c/0x1ac
      [  102.785833]  print_address_description.constprop.0+0x30/0x274
      [  102.791862]  kasan_report+0x14c/0x1c8
      [  102.795719]  __asan_report_store1_noabort+0x34/0x58
      [  102.800840]  ffs_release_dev+0x64/0xa8 [usb_f_fs]
      [  102.805801]  ffs_fs_kill_sb+0x50/0x84 [usb_f_fs]
      [  102.810663]  deactivate_locked_super+0xa0/0xf0
      [  102.815339]  deactivate_super+0x98/0xac
      [  102.819378]  cleanup_mnt+0xd0/0x1b0
      [  102.823057]  __cleanup_mnt+0x1c/0x28
      [  102.826823]  task_work_run+0x104/0x180
      [  102.830774]  do_notify_resume+0x458/0x14e0
      [  102.835083]  work_pending+0xc/0x5f8
      [  102.838762]
      [  102.840357] Allocated by task 2988:
      [  102.844032]  kasan_save_stack+0x28/0x58
      [  102.848071]  kasan_set_track+0x28/0x3c
      [  102.852016]  ____kasan_kmalloc+0x84/0x9c
      [  102.856142]  __kasan_kmalloc+0x10/0x1c
      [  102.860088]  __kmalloc+0x214/0x2f8
      [  102.863678]  kzalloc.constprop.0+0x14/0x20 [usb_f_fs]
      [  102.868990]  ffs_alloc_inst+0x8c/0x208 [usb_f_fs]
      [  102.873942]  try_get_usb_function_instance+0xf0/0x164 [libcomposite]
      [  102.880629]  usb_get_function_instance+0x64/0x68 [libcomposite]
      [  102.886858]  function_make+0x128/0x1ec [libcomposite]
      [  102.892185]  configfs_mkdir+0x330/0x590 [configfs]
      [  102.897245]  vfs_mkdir+0x12c/0x1bc
      [  102.900835]  do_mkdirat+0x180/0x1d0
      [  102.904513]  __arm64_sys_mkdirat+0x80/0x94
      [  102.908822]  invoke_syscall+0xf8/0x25c
      [  102.912772]  el0_svc_common.constprop.0+0x150/0x1a0
      [  102.917891]  do_el0_svc+0xa0/0xd4
      [  102.921386]  el0_svc+0x24/0x34
      [  102.924613]  el0_sync_handler+0xcc/0x154
      [  102.928743]  el0_sync+0x198/0x1c0
      [  102.932238]
      [  102.933832] Freed by task 2996:
      [  102.937144]  kasan_save_stack+0x28/0x58
      [  102.941181]  kasan_set_track+0x28/0x3c
      [  102.945128]  kasan_set_free_info+0x28/0x4c
      [  102.949435]  ____kasan_slab_free+0x104/0x118
      [  102.953921]  __kasan_slab_free+0x18/0x24
      [  102.958047]  slab_free_freelist_hook+0x148/0x1f0
      [  102.962897]  kfree+0x318/0x440
      [  102.966123]  ffs_free_inst+0x164/0x2d8 [usb_f_fs]
      [  102.971075]  usb_put_function_instance+0x84/0xa4 [libcomposite]
      [  102.977302]  ffs_attr_release+0x18/0x24 [usb_f_fs]
      [  102.982344]  config_item_put+0x140/0x1a4 [configfs]
      [  102.987486]  configfs_rmdir+0x3fc/0x518 [configfs]
      [  102.992535]  vfs_rmdir+0x114/0x234
      [  102.996122]  do_rmdir+0x274/0x2b0
      [  102.999617]  __arm64_sys_unlinkat+0x94/0xc8
      [  103.004015]  invoke_syscall+0xf8/0x25c
      [  103.007961]  el0_svc_common.constprop.0+0x150/0x1a0
      [  103.013080]  do_el0_svc+0xa0/0xd4
      [  103.016575]  el0_svc+0x24/0x34
      [  103.019801]  el0_sync_handler+0xcc/0x154
      [  103.023930]  el0_sync+0x198/0x1c0
      [  103.027426]
      [  103.029020] The buggy address belongs to the object at ffff0004d46ff500
      [  103.029020]  which belongs to the cache kmalloc-128 of size 128
      [  103.042079] The buggy address is located 73 bytes inside of
      [  103.042079]  128-byte region [ffff0004d46ff500, ffff0004d46ff580)
      [  103.054236] The buggy address belongs to the page:
      [  103.059262] page:0000000021aa849b refcount:1 mapcount:0 mapping:0000000000000000 index:0xffff0004d46fee00 pfn:0x5146fe
      [  103.070437] head:0000000021aa849b order:1 compound_mapcount:0
      [  103.076456] flags: 0x8000000000010200(slab|head|zone=2)
      [  103.081948] raw: 8000000000010200 fffffc0013521a80 0000000d0000000d ffff0004c0002300
      [  103.090052] raw: ffff0004d46fee00 000000008020001e 00000001ffffffff 0000000000000000
      [  103.098150] page dumped because: kasan: bad access detected
      [  103.103985]
      [  103.105578] Memory state around the buggy address:
      [  103.110602]  ffff0004d46ff400: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
      [  103.118161]  ffff0004d46ff480: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
      [  103.125726] >ffff0004d46ff500: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
      [  103.133284]                                               ^
      [  103.139120]  ffff0004d46ff580: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
      [  103.146679]  ffff0004d46ff600: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
      [  103.154238] ==================================================================
      [  103.161792] Disabling lock debugging due to kernel taint
      [  103.167319] Unable to handle kernel paging request at virtual address 0037801d6000018e
      [  103.175406] Mem abort info:
      [  103.178457]   ESR = 0x96000004
      [  103.181609]   EC = 0x25: DABT (current EL), IL = 32 bits
      [  103.187020]   SET = 0, FnV = 0
      [  103.190185]   EA = 0, S1PTW = 0
      [  103.193417] Data abort info:
      [  103.196385]   ISV = 0, ISS = 0x00000004
      [  103.200315]   CM = 0, WnR = 0
      [  103.203366] [0037801d6000018e] address between user and kernel address ranges
      [  103.210611] Internal error: Oops: 96000004 [#1] PREEMPT SMP
      [  103.216231] Modules linked in: usb_f_fs libcomposite configfs ath9k_htc led_class mac80211 libarc4 ath9k_common ath9k_hw ath cfg80211 aes_ce_blk sata_rc4
      [  103.259233] CPU: 0 PID: 2997 Comm: umount Tainted: G    B             5.13.0-rc4+ #8
      [  103.267031] Hardware name: Renesas Salvator-X board based on r8a77951 (DT)
      [  103.273951] pstate: 00000005 (nzcv daif -PAN -UAO -TCO BTYPE=--)
      [  103.280001] pc : ffs_data_clear+0x138/0x370 [usb_f_fs]
      [  103.285197] lr : ffs_data_clear+0x124/0x370 [usb_f_fs]
      [  103.290385] sp : ffff800014777a80
      [  103.293725] x29: ffff800014777a80 x28: ffff0004d7649c80 x27: 0000000000000000
      [  103.300931] x26: ffff800014777fb0 x25: ffff60009aec9394 x24: ffff0004d7649ca4
      [  103.308136] x23: 1fffe0009a3d063a x22: dfff800000000000 x21: ffff0004d1e831d0
      [  103.315340] x20: e1c000eb00000bb4 x19: ffff0004d1e83000 x18: 0000000000000000
      [  103.322545] x17: 0000000000000000 x16: 0000000000000000 x15: 0000000000000000
      [  103.329748] x14: 0720072007200720 x13: 0720072007200720 x12: 1ffff000012ef658
      [  103.336952] x11: ffff7000012ef658 x10: 0720072007200720 x9 : ffff800011322648
      [  103.344157] x8 : ffff800014777818 x7 : ffff80000977b2c7 x6 : 0000000000000000
      [  103.351359] x5 : 0000000000000001 x4 : ffff7000012ef659 x3 : 0000000000000001
      [  103.358562] x2 : 0000000000000000 x1 : 1c38001d6000018e x0 : e1c000eb00000c70
      [  103.365766] Call trace:
      [  103.368235]  ffs_data_clear+0x138/0x370 [usb_f_fs]
      [  103.373076]  ffs_data_reset+0x20/0x304 [usb_f_fs]
      [  103.377829]  ffs_data_closed+0x1ec/0x244 [usb_f_fs]
      [  103.382755]  ffs_fs_kill_sb+0x70/0x84 [usb_f_fs]
      [  103.387420]  deactivate_locked_super+0xa0/0xf0
      [  103.391905]  deactivate_super+0x98/0xac
      [  103.395776]  cleanup_mnt+0xd0/0x1b0
      [  103.399299]  __cleanup_mnt+0x1c/0x28
      [  103.402906]  task_work_run+0x104/0x180
      [  103.406691]  do_notify_resume+0x458/0x14e0
      [  103.410823]  work_pending+0xc/0x5f8
      [  103.414351] Code: b4000a54 9102f280 12000802 d343fc01 (38f66821)
      [  103.420490] ---[ end trace 57b43a50e8244f57 ]---
      Segmentation fault
      root@rcar-gen3:~#
      ==================================================================
      
      [2]
      ==================================================================
      root@rcar-gen3:~# mkdir /dev/ffs
      root@rcar-gen3:~# modprobe libcomposite
      root@rcar-gen3:~#
      root@rcar-gen3:~# mount -t configfs none /dev/cfs
      root@rcar-gen3:~# mkdir /dev/cfs/usb_gadget/g1
      root@rcar-gen3:~# mkdir /dev/cfs/usb_gadget/g1/functions/ffs.ffs
      [   54.766480] file system registered
      root@rcar-gen3:~# mount -t functionfs ffs /dev/ffs
      root@rcar-gen3:~# rmdir /dev/cfs/usb_gadget/g1/functions/ffs.ffs
      [   63.197597] unloading
      root@rcar-gen3:~# cat /dev/ffs/ep0
      cat: read error:[   67.213506] ==================================================================
      [   67.222095] BUG: KASAN: use-after-free in ffs_data_clear+0x70/0x370 [usb_f_fs]
      [   67.229699] Write of size 1 at addr ffff0004c26e974a by task cat/2994
      [   67.236446]
      [   67.238045] CPU: 0 PID: 2994 Comm: cat Not tainted 5.13.0-rc4+ #8
      [   67.244431] Hardware name: Renesas Salvator-X board based on r8a77951 (DT)
      [   67.251624] Call trace:
      [   67.254212]  dump_backtrace+0x0/0x330
      [   67.258081]  show_stack+0x20/0x2c
      [   67.261579]  dump_stack+0x11c/0x1ac
      [   67.265260]  print_address_description.constprop.0+0x30/0x274
      [   67.271286]  kasan_report+0x14c/0x1c8
      [   67.275143]  __asan_report_store1_noabort+0x34/0x58
      [   67.280265]  ffs_data_clear+0x70/0x370 [usb_f_fs]
      [   67.285220]  ffs_data_reset+0x20/0x304 [usb_f_fs]
      [   67.290172]  ffs_data_closed+0x240/0x244 [usb_f_fs]
      [   67.295305]  ffs_ep0_release+0x40/0x54 [usb_f_fs]
      [   67.300256]  __fput+0x304/0x580
      [   67.303576]  ____fput+0x18/0x24
      [   67.306893]  task_work_run+0x104/0x180
      [   67.310846]  do_notify_resume+0x458/0x14e0
      [   67.315154]  work_pending+0xc/0x5f8
      [   67.318834]
      [   67.320429] Allocated by task 2988:
      [   67.324105]  kasan_save_stack+0x28/0x58
      [   67.328144]  kasan_set_track+0x28/0x3c
      [   67.332090]  ____kasan_kmalloc+0x84/0x9c
      [   67.336217]  __kasan_kmalloc+0x10/0x1c
      [   67.340163]  __kmalloc+0x214/0x2f8
      [   67.343754]  kzalloc.constprop.0+0x14/0x20 [usb_f_fs]
      [   67.349066]  ffs_alloc_inst+0x8c/0x208 [usb_f_fs]
      [   67.354017]  try_get_usb_function_instance+0xf0/0x164 [libcomposite]
      [   67.360705]  usb_get_function_instance+0x64/0x68 [libcomposite]
      [   67.366934]  function_make+0x128/0x1ec [libcomposite]
      [   67.372260]  configfs_mkdir+0x330/0x590 [configfs]
      [   67.377320]  vfs_mkdir+0x12c/0x1bc
      [   67.380911]  do_mkdirat+0x180/0x1d0
      [   67.384589]  __arm64_sys_mkdirat+0x80/0x94
      [   67.388899]  invoke_syscall+0xf8/0x25c
      [   67.392850]  el0_svc_common.constprop.0+0x150/0x1a0
      [   67.397969]  do_el0_svc+0xa0/0xd4
      [   67.401464]  el0_svc+0x24/0x34
      [   67.404691]  el0_sync_handler+0xcc/0x154
      [   67.408819]  el0_sync+0x198/0x1c0
      [   67.412315]
      [   67.413909] Freed by task 2993:
      [   67.417220]  kasan_save_stack+0x28/0x58
      [   67.421257]  kasan_set_track+0x28/0x3c
      [   67.425204]  kasan_set_free_info+0x28/0x4c
      [   67.429513]  ____kasan_slab_free+0x104/0x118
      [   67.434001]  __kasan_slab_free+0x18/0x24
      [   67.438128]  slab_free_freelist_hook+0x148/0x1f0
      [   67.442978]  kfree+0x318/0x440
      [   67.446205]  ffs_free_inst+0x164/0x2d8 [usb_f_fs]
      [   67.451156]  usb_put_function_instance+0x84/0xa4 [libcomposite]
      [   67.457385]  ffs_attr_release+0x18/0x24 [usb_f_fs]
      [   67.462428]  config_item_put+0x140/0x1a4 [configfs]
      [   67.467570]  configfs_rmdir+0x3fc/0x518 [configfs]
      [   67.472626]  vfs_rmdir+0x114/0x234
      [   67.476215]  do_rmdir+0x274/0x2b0
      [   67.479710]  __arm64_sys_unlinkat+0x94/0xc8
      [   67.484108]  invoke_syscall+0xf8/0x25c
      [   67.488055]  el0_svc_common.constprop.0+0x150/0x1a0
      [   67.493175]  do_el0_svc+0xa0/0xd4
      [   67.496671]  el0_svc+0x24/0x34
      [   67.499896]  el0_sync_handler+0xcc/0x154
      [   67.504024]  el0_sync+0x198/0x1c0
      [   67.507520]
      [   67.509114] The buggy address belongs to the object at ffff0004c26e9700
      [   67.509114]  which belongs to the cache kmalloc-128 of size 128
      [   67.522171] The buggy address is located 74 bytes inside of
      [   67.522171]  128-byte region [ffff0004c26e9700, ffff0004c26e9780)
      [   67.534328] The buggy address belongs to the page:
      [   67.539355] page:000000003177a217 refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x5026e8
      [   67.549175] head:000000003177a217 order:1 compound_mapcount:0
      [   67.555195] flags: 0x8000000000010200(slab|head|zone=2)
      [   67.560687] raw: 8000000000010200 fffffc0013037100 0000000c00000002 ffff0004c0002300
      [   67.568791] raw: 0000000000000000 0000000080200020 00000001ffffffff 0000000000000000
      [   67.576890] page dumped because: kasan: bad access detected
      [   67.582725]
      [   67.584318] Memory state around the buggy address:
      [   67.589343]  ffff0004c26e9600: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
      [   67.596903]  ffff0004c26e9680: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
      [   67.604463] >ffff0004c26e9700: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
      [   67.612022]                                               ^
      [   67.617860]  ffff0004c26e9780: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
      [   67.625421]  ffff0004c26e9800: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
      [   67.632981] ==================================================================
      [   67.640535] Disabling lock debugging due to kernel taint
       File descriptor[   67.646100] Unable to handle kernel paging request at virtual address fabb801d4000018d
       in bad state
      [   67.655456] Mem abort info:
      [   67.659619]   ESR = 0x96000004
      [   67.662801]   EC = 0x25: DABT (current EL), IL = 32 bits
      [   67.668225]   SET = 0, FnV = 0
      [   67.671375]   EA = 0, S1PTW = 0
      [   67.674613] Data abort info:
      [   67.677587]   ISV = 0, ISS = 0x00000004
      [   67.681522]   CM = 0, WnR = 0
      [   67.684588] [fabb801d4000018d] address between user and kernel address ranges
      [   67.691849] Internal error: Oops: 96000004 [#1] PREEMPT SMP
      [   67.697470] Modules linked in: usb_f_fs libcomposite configfs ath9k_htc led_class mac80211 libarc4 ath9k_common ath9k_hw ath cfg80211 aes_ce_blk crypto_simd cryptd aes_ce_cipher ghash_ce gf128mul sha2_ce sha1_ce evdev sata_rcar libata xhci_plat_hcd scsi_mod xhci_hcd rene4
      [   67.740467] CPU: 0 PID: 2994 Comm: cat Tainted: G    B             5.13.0-rc4+ #8
      [   67.748005] Hardware name: Renesas Salvator-X board based on r8a77951 (DT)
      [   67.754924] pstate: 00000005 (nzcv daif -PAN -UAO -TCO BTYPE=--)
      [   67.760974] pc : ffs_data_clear+0x138/0x370 [usb_f_fs]
      [   67.766178] lr : ffs_data_clear+0x124/0x370 [usb_f_fs]
      [   67.771365] sp : ffff800014767ad0
      [   67.774706] x29: ffff800014767ad0 x28: ffff800009cf91c0 x27: ffff0004c54861a0
      [   67.781913] x26: ffff0004dc90b288 x25: 1fffe00099ec10f5 x24: 00000000000a801d
      [   67.789118] x23: 1fffe00099f6953a x22: dfff800000000000 x21: ffff0004cfb4a9d0
      [   67.796322] x20: d5e000ea00000bb1 x19: ffff0004cfb4a800 x18: 0000000000000000
      [   67.803526] x17: 0000000000000000 x16: 0000000000000000 x15: 0000000000000000
      [   67.810730] x14: 0720072007200720 x13: 0720072007200720 x12: 1ffff000028ecefa
      [   67.817934] x11: ffff7000028ecefa x10: 0720072007200720 x9 : ffff80001132c014
      [   67.825137] x8 : ffff8000147677d8 x7 : ffff8000147677d7 x6 : 0000000000000000
      [   67.832341] x5 : 0000000000000001 x4 : ffff7000028ecefb x3 : 0000000000000001
      [   67.839544] x2 : 0000000000000005 x1 : 1abc001d4000018d x0 : d5e000ea00000c6d
      [   67.846748] Call trace:
      [   67.849218]  ffs_data_clear+0x138/0x370 [usb_f_fs]
      [   67.854058]  ffs_data_reset+0x20/0x304 [usb_f_fs]
      [   67.858810]  ffs_data_closed+0x240/0x244 [usb_f_fs]
      [   67.863736]  ffs_ep0_release+0x40/0x54 [usb_f_fs]
      [   67.868488]  __fput+0x304/0x580
      [   67.871665]  ____fput+0x18/0x24
      [   67.874837]  task_work_run+0x104/0x180
      [   67.878622]  do_notify_resume+0x458/0x14e0
      [   67.882754]  work_pending+0xc/0x5f8
      [   67.886282] Code: b4000a54 9102f280 12000802 d343fc01 (38f66821)
      [   67.892422] ---[ end trace 6d7cedf53d7abbea ]---
      Segmentation fault
      root@rcar-gen3:~#
      ==================================================================
      
      Fixes: 4b187fce ("usb: gadget: FunctionFS: add devices management code")
      Fixes: 3262ad82 ("usb: gadget: f_fs: Stop ffs_closed NULL pointer dereference")
      Fixes: cdafb6d8 ("usb: gadget: f_fs: Fix use-after-free in ffs_free_inst")
      Reported-by: NBhuvanesh Surachari <bhuvanesh_surachari@mentor.com>
      Tested-by: NEugeniu Rosca <erosca@de.adit-jv.com>
      Reviewed-by: NEugeniu Rosca <erosca@de.adit-jv.com>
      Signed-off-by: NAndrew Gabbasov <andrew_gabbasov@mentor.com>
      Link: https://lore.kernel.org/r/20210603171507.22514-1-andrew_gabbasov@mentor.comSigned-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      Signed-off-by: NSasha Levin <sashal@kernel.org>
      Signed-off-by: NChen Jun <chenjun102@huawei.com>
      Acked-by: NWeilong Chen <chenweilong@huawei.com>
      Signed-off-by: NChen Jun <chenjun102@huawei.com>
      Signed-off-by: NZheng Zengkai <zhengzengkai@huawei.com>
      a35cb3f5
  3. 03 7月, 2021 1 次提交
  4. 03 6月, 2021 1 次提交
  5. 07 1月, 2021 1 次提交
    • J
      usb: gadget: f_fs: Re-use SS descriptors for SuperSpeedPlus · dd47786c
      Jack Pham 提交于
      stable inclusion
      from stable-5.10.3
      commit 4ef3fc712c7702859553e33f9197d70beb3f31c8
      bugzilla: 46871
      
      --------------------------------
      
      commit a353397b upstream.
      
      In many cases a function that supports SuperSpeed can very well
      operate in SuperSpeedPlus, if a gadget controller supports it,
      as the endpoint descriptors (and companion descriptors) are
      generally identical and can be re-used. This is true for two
      commonly used functions: Android's ADB and MTP. So we can simply
      assign the usb_function's ssp_descriptors array to point to its
      ss_descriptors, if available. Similarly, we need to allow an
      epfile's ioctl for FUNCTIONFS_ENDPOINT_DESC to correctly
      return the corresponding SuperSpeed endpoint descriptor in case
      the connected speed is SuperSpeedPlus as well.
      
      The only exception is if a function wants to implement an
      Isochronous endpoint capable of transferring more than 48KB per
      service interval when operating at greater than USB 3.1 Gen1
      speed, in which case it would require an additional SuperSpeedPlus
      Isochronous Endpoint Companion descriptor to be returned as part
      of the Configuration Descriptor. Support for that would need
      to be separately added to the userspace-facing FunctionFS API
      which may not be a trivial task--likely a new descriptor format
      (v3?) may need to be devised to allow for separate SS and SSP
      descriptors to be supplied.
      Signed-off-by: NJack Pham <jackp@codeaurora.org>
      Cc: stable <stable@vger.kernel.org>
      Link: https://lore.kernel.org/r/20201027230731.9073-1-jackp@codeaurora.orgSigned-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      Signed-off-by: NChen Jun <chenjun102@huawei.com>
      Acked-by: NXie XiuQi <xiexiuqi@huawei.com>
      Signed-off-by: NChen Jun <chenjun102@huawei.com>
      dd47786c
  6. 04 12月, 2020 1 次提交
  7. 10 7月, 2020 1 次提交
  8. 09 7月, 2020 1 次提交
    • L
      usb: gadget: function: f_fs: Demote function header which is clearly not kerneldoc · 8f9a0e10
      Lee Jones 提交于
      No attempt has been made to document the demoted function here.
      
      Fixes the following W=1 kernel build warning(s):
      
       drivers/usb/gadget/function/f_fs.c:2361: warning: Function parameter or member 'type' not described in '__ffs_data_do_os_desc'
       drivers/usb/gadget/function/f_fs.c:2361: warning: Function parameter or member 'h' not described in '__ffs_data_do_os_desc'
       drivers/usb/gadget/function/f_fs.c:2361: warning: Function parameter or member 'data' not described in '__ffs_data_do_os_desc'
       drivers/usb/gadget/function/f_fs.c:2361: warning: Function parameter or member 'len' not described in '__ffs_data_do_os_desc'
       drivers/usb/gadget/function/f_fs.c:2361: warning: Function parameter or member 'priv' not described in '__ffs_data_do_os_desc'
      
      Cc: Felipe Balbi <balbi@kernel.org>
      Cc: David Howells <dhowells@redhat.com>
      Cc: Michal Nazarewicz <mina86@mina86.com>
      Signed-off-by: NLee Jones <lee.jones@linaro.org>
      Link: https://lore.kernel.org/r/20200706133341.476881-12-lee.jones@linaro.orgSigned-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      8f9a0e10
  9. 11 6月, 2020 3 次提交
  10. 25 5月, 2020 1 次提交
  11. 16 4月, 2020 1 次提交
  12. 26 3月, 2020 1 次提交
  13. 21 3月, 2020 1 次提交
    • T
      completion: Use simple wait queues · a5c6234e
      Thomas Gleixner 提交于
      completion uses a wait_queue_head_t to enqueue waiters.
      
      wait_queue_head_t contains a spinlock_t to protect the list of waiters
      which excludes it from being used in truly atomic context on a PREEMPT_RT
      enabled kernel.
      
      The spinlock in the wait queue head cannot be replaced by a raw_spinlock
      because:
      
        - wait queues can have custom wakeup callbacks, which acquire other
          spinlock_t locks and have potentially long execution times
      
        - wake_up() walks an unbounded number of list entries during the wake up
          and may wake an unbounded number of waiters.
      
      For simplicity and performance reasons complete() should be usable on
      PREEMPT_RT enabled kernels.
      
      completions do not use custom wakeup callbacks and are usually single
      waiter, except for a few corner cases.
      
      Replace the wait queue in the completion with a simple wait queue (swait),
      which uses a raw_spinlock_t for protecting the waiter list and therefore is
      safe to use inside truly atomic regions on PREEMPT_RT.
      
      There is no semantical or functional change:
      
        - completions use the exclusive wait mode which is what swait provides
      
        - complete() wakes one exclusive waiter
      
        - complete_all() wakes all waiters while holding the lock which protects
          the wait queue against newly incoming waiters. The conversion to swait
          preserves this behaviour.
      
      complete_all() might cause unbound latencies with a large number of waiters
      being woken at once, but most complete_all() usage sites are either in
      testing or initialization code or have only a really small number of
      concurrent waiters which for now does not cause a latency problem. Keep it
      simple for now.
      
      The fixup of the warning check in the USB gadget driver is just a straight
      forward conversion of the lockless waiter check from one waitqueue type to
      the other.
      Signed-off-by: NThomas Gleixner <tglx@linutronix.de>
      Signed-off-by: NPeter Zijlstra (Intel) <peterz@infradead.org>
      Reviewed-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      Reviewed-by: NDavidlohr Bueso <dbueso@suse.de>
      Reviewed-by: NJoel Fernandes (Google) <joel@joelfernandes.org>
      Acked-by: NLinus Torvalds <torvalds@linux-foundation.org>
      Link: https://lkml.kernel.org/r/20200321113242.317954042@linutronix.de
      a5c6234e
  14. 11 2月, 2020 1 次提交
  15. 08 2月, 2020 2 次提交
  16. 15 1月, 2020 1 次提交
    • P
      usb: gadget: f_fs: set req->num_sgs as 0 for non-sg transfer · d2450c69
      Peter Chen 提交于
      The UDC core uses req->num_sgs to judge if scatter buffer list is used.
      Eg: usb_gadget_map_request_by_dev. For f_fs sync io mode, the request
      is re-used for each request, so if the 1st request->length > PAGE_SIZE,
      and the 2nd request->length is <= PAGE_SIZE, the f_fs uses the 1st
      req->num_sgs for the 2nd request, it causes the UDC core get the wrong
      req->num_sgs value (The 2nd request doesn't use sg). For f_fs async
      io mode, it is not harm to initialize req->num_sgs as 0 either, in case,
      the UDC driver doesn't zeroed request structure.
      
      Cc: Jun Li <jun.li@nxp.com>
      Cc: stable <stable@vger.kernel.org>
      Fixes: 772a7a72 ("usb: gadget: f_fs: Allow scatter-gather buffers")
      Signed-off-by: NPeter Chen <peter.chen@nxp.com>
      Signed-off-by: NFelipe Balbi <balbi@kernel.org>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      d2450c69
  17. 10 12月, 2019 1 次提交
  18. 23 10月, 2019 1 次提交
  19. 19 9月, 2019 1 次提交
  20. 18 6月, 2019 2 次提交
    • A
      usb: gadget: Zero ffs_io_data · 50859551
      Andrzej Pietrasiewicz 提交于
      In some cases the "Allocate & copy" block in ffs_epfile_io() is not
      executed. Consequently, in such a case ffs_alloc_buffer() is never called
      and struct ffs_io_data is not initialized properly. This in turn leads to
      problems when ffs_free_buffer() is called at the end of ffs_epfile_io().
      
      This patch uses kzalloc() instead of kmalloc() in the aio case and memset()
      in non-aio case to properly initialize struct ffs_io_data.
      Signed-off-by: NAndrzej Pietrasiewicz <andrzej.p@collabora.com>
      Signed-off-by: NFelipe Balbi <felipe.balbi@linux.intel.com>
      50859551
    • F
      usb: gadget: f_fs: data_len used before properly set · 4833a94e
      Fei Yang 提交于
      The following line of code in function ffs_epfile_io is trying to set
      flag io_data->use_sg in case buffer required is larger than one page.
      
          io_data->use_sg = gadget->sg_supported && data_len > PAGE_SIZE;
      
      However at this point of time the variable data_len has not been set
      to the proper buffer size yet. The consequence is that io_data->use_sg
      is always set regardless what buffer size really is, because the condition
      (data_len > PAGE_SIZE) is effectively an unsigned comparison between
      -EINVAL and PAGE_SIZE which would always result in TRUE.
      
      Fixes: 772a7a72 ("usb: gadget: f_fs: Allow scatter-gather buffers")
      Signed-off-by: NFei Yang <fei.yang@intel.com>
      Cc: stable <stable@vger.kernel.org>
      Signed-off-by: NFelipe Balbi <felipe.balbi@linux.intel.com>
      4833a94e
  21. 03 5月, 2019 1 次提交
    • F
      usb: gadget: f_fs: don't free buffer prematurely · 73103c7f
      Fei Yang 提交于
      The following kernel panic happens due to the io_data buffer gets deallocated
      before the async io is completed. Add a check for the case where io_data buffer
      should be deallocated by ffs_user_copy_worker.
      
      [   41.663334] BUG: unable to handle kernel NULL pointer dereference at 0000000000000048
      [   41.672099] #PF error: [normal kernel read fault]
      [   41.677356] PGD 20c974067 P4D 20c974067 PUD 20c973067 PMD 0
      [   41.683687] Oops: 0000 [#1] PREEMPT SMP
      [   41.687976] CPU: 1 PID: 7 Comm: kworker/u8:0 Tainted: G     U            5.0.0-quilt-2e5dc0ac-00790-gd8c79f2-dirty #2
      [   41.705309] Workqueue: adb ffs_user_copy_worker
      [   41.705316] RIP: 0010:__vunmap+0x2a/0xc0
      [   41.705318] Code: 0f 1f 44 00 00 48 85 ff 0f 84 87 00 00 00 55 f7 c7 ff 0f 00 00 48 89 e5 41 55 41 89 f5 41 54 53 48 89 fb 75 71 e8 56 d7 ff ff <4c> 8b 60 48 4d 85 e4 74 76 48 89 df e8 25 ff ff ff 45 85 ed 74 46
      [   41.705320] RSP: 0018:ffffbc3a40053df0 EFLAGS: 00010286
      [   41.705322] RAX: 0000000000000000 RBX: ffffbc3a406f1000 RCX: 0000000000000000
      [   41.705323] RDX: 0000000000000001 RSI: 0000000000000001 RDI: 00000000ffffffff
      [   41.705324] RBP: ffffbc3a40053e08 R08: 000000000001fb79 R09: 0000000000000037
      [   41.705325] R10: ffffbc3a40053b68 R11: ffffbc3a40053cad R12: fffffffffffffff2
      [   41.705326] R13: 0000000000000001 R14: 0000000000000000 R15: ffffffffffffffff
      [   41.705328] FS:  0000000000000000(0000) GS:ffff9e2977a80000(0000) knlGS:0000000000000000
      [   41.705329] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
      [   41.705330] CR2: 0000000000000048 CR3: 000000020c994000 CR4: 00000000003406e0
      [   41.705331] Call Trace:
      [   41.705338]  vfree+0x50/0xb0
      [   41.705341]  ffs_user_copy_worker+0xe9/0x1c0
      [   41.705344]  process_one_work+0x19f/0x3e0
      [   41.705348]  worker_thread+0x3f/0x3b0
      [   41.829766]  kthread+0x12b/0x150
      [   41.833371]  ? process_one_work+0x3e0/0x3e0
      [   41.838045]  ? kthread_create_worker_on_cpu+0x70/0x70
      [   41.843695]  ret_from_fork+0x3a/0x50
      [   41.847689] Modules linked in: hci_uart bluetooth ecdh_generic rfkill_gpio dwc3_pci dwc3 snd_usb_audio mei_me tpm_crb snd_usbmidi_lib xhci_pci xhci_hcd mei tpm snd_hwdep cfg80211 snd_soc_skl snd_soc_skl_ipc snd_soc_sst_ipc snd_soc_sst_dsp snd_hda_ext_core snd_hda_core videobuf2_dma_sg crlmodule
      [   41.876880] CR2: 0000000000000048
      [   41.880584] ---[ end trace 2bc4addff0f2e673 ]---
      [   41.891346] RIP: 0010:__vunmap+0x2a/0xc0
      [   41.895734] Code: 0f 1f 44 00 00 48 85 ff 0f 84 87 00 00 00 55 f7 c7 ff 0f 00 00 48 89 e5 41 55 41 89 f5 41 54 53 48 89 fb 75 71 e8 56 d7 ff ff <4c> 8b 60 48 4d 85 e4 74 76 48 89 df e8 25 ff ff ff 45 85 ed 74 46
      [   41.916740] RSP: 0018:ffffbc3a40053df0 EFLAGS: 00010286
      [   41.922583] RAX: 0000000000000000 RBX: ffffbc3a406f1000 RCX: 0000000000000000
      [   41.930563] RDX: 0000000000000001 RSI: 0000000000000001 RDI: 00000000ffffffff
      [   41.938540] RBP: ffffbc3a40053e08 R08: 000000000001fb79 R09: 0000000000000037
      [   41.946520] R10: ffffbc3a40053b68 R11: ffffbc3a40053cad R12: fffffffffffffff2
      [   41.954502] R13: 0000000000000001 R14: 0000000000000000 R15: ffffffffffffffff
      [   41.962482] FS:  0000000000000000(0000) GS:ffff9e2977a80000(0000) knlGS:0000000000000000
      [   41.971536] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
      [   41.977960] CR2: 0000000000000048 CR3: 000000020c994000 CR4: 00000000003406e0
      [   41.985930] Kernel panic - not syncing: Fatal exception
      [   41.991817] Kernel Offset: 0x16000000 from 0xffffffff81000000 (relocation range: 0xffffffff80000000-0xffffffffbfffffff)
      [   42.009525] Rebooting in 10 seconds..
      [   52.014376] ACPI MEMORY or I/O RESET_REG.
      
      Fixes: 772a7a72 ("usb: gadget: f_fs: Allow scatter-gather buffers")
      Signed-off-by: NFei Yang <fei.yang@intel.com>
      Reviewed-by: NManu Gautam <mgautam@codeaurora.org>
      Tested-by: NJohn Stultz <john.stultz@linaro.org>
      Signed-off-by: NFelipe Balbi <felipe.balbi@linux.intel.com>
      73103c7f
  22. 11 2月, 2019 1 次提交
    • J
      usb: f_fs: Avoid crash due to out-of-scope stack ptr access · 54f64d5c
      John Stultz 提交于
      Since the 5.0 merge window opened, I've been seeing frequent
      crashes on suspend and reboot with the trace:
      
      [   36.911170] Unable to handle kernel paging request at virtual address ffffff801153d660
      [   36.912769] Unable to handle kernel paging request at virtual address ffffff800004b564
      ...
      [   36.950666] Call trace:
      [   36.950670]  queued_spin_lock_slowpath+0x1cc/0x2c8
      [   36.950681]  _raw_spin_lock_irqsave+0x64/0x78
      [   36.950692]  complete+0x28/0x70
      [   36.950703]  ffs_epfile_io_complete+0x3c/0x50
      [   36.950713]  usb_gadget_giveback_request+0x34/0x108
      [   36.950721]  dwc3_gadget_giveback+0x50/0x68
      [   36.950723]  dwc3_thread_interrupt+0x358/0x1488
      [   36.950731]  irq_thread_fn+0x30/0x88
      [   36.950734]  irq_thread+0x114/0x1b0
      [   36.950739]  kthread+0x104/0x130
      [   36.950747]  ret_from_fork+0x10/0x1c
      
      I isolated this down to in ffs_epfile_io():
      https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/usb/gadget/function/f_fs.c#n1065
      
      Where the completion done is setup on the stack:
        DECLARE_COMPLETION_ONSTACK(done);
      
      Then later we setup a request and queue it, and wait for it:
        if (unlikely(wait_for_completion_interruptible(&done))) {
          /*
          * To avoid race condition with ffs_epfile_io_complete,
          * dequeue the request first then check
          * status. usb_ep_dequeue API should guarantee no race
          * condition with req->complete callback.
          */
          usb_ep_dequeue(ep->ep, req);
          interrupted = ep->status < 0;
        }
      
      The problem is, that we end up being interrupted, dequeue the
      request, and exit.
      
      But then the irq triggers and we try calling complete() on the
      context pointer which points to now random stack space, which
      results in the panic.
      
      Alan Stern pointed out there is a bug here, in that the snippet
      above "assumes that usb_ep_dequeue() waits until the request has
      been completed." And that:
      
          wait_for_completion(&done);
      
      Is needed right after the usb_ep_dequeue().
      
      Thus this patch implements that change. With it I no longer see
      the crashes on suspend or reboot.
      
      This issue seems to have been uncovered by behavioral changes in
      the dwc3 driver in commit fec9095b ("usb: dwc3: gadget:
      remove wait_end_transfer").
      
      Cc: Alan Stern <stern@rowland.harvard.edu>
      Cc: Felipe Balbi <balbi@kernel.org>
      Cc: Zeng Tao <prime.zeng@hisilicon.com>
      Cc: Jack Pham <jackp@codeaurora.org>
      Cc: Thinh Nguyen <thinh.nguyen@synopsys.com>
      Cc: Chen Yu <chenyu56@huawei.com>
      Cc: Jerry Zhang <zhangjerry@google.com>
      Cc: Lars-Peter Clausen <lars@metafoo.de>
      Cc: Vincent Pelletier <plr.vincent@gmail.com>
      Cc: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
      Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
      Cc: Linux USB List <linux-usb@vger.kernel.org>
      Suggested-by: NAlan Stern <stern@rowland.harvard.edu>
      Signed-off-by: NJohn Stultz <john.stultz@linaro.org>
      Signed-off-by: NFelipe Balbi <felipe.balbi@linux.intel.com>
      54f64d5c
  23. 07 2月, 2019 1 次提交
  24. 26 11月, 2018 2 次提交
  25. 14 11月, 2018 1 次提交
  26. 26 7月, 2018 1 次提交
    • J
      usb: gadget: f_fs: Only return delayed status when len is 0 · e610257e
      Jerry Zhang 提交于
      Commit 1b9ba000 ("Allow function drivers to pause control
      transfers") states that USB_GADGET_DELAYED_STATUS is only
      supported if data phase is 0 bytes.
      
      It seems that when the length is not 0 bytes, there is no
      need to explicitly delay the data stage since the transfer
      is not completed until the user responds. However, when the
      length is 0, there is no data stage and the transfer is
      finished once setup() returns, hence there is a need to
      explicitly delay completion.
      
      This manifests as the following bugs:
      
      Prior to 946ef68a ('Let setup() return
      USB_GADGET_DELAYED_STATUS'), when setup is 0 bytes, ffs
      would require user to queue a 0 byte request in order to
      clear setup state. However, that 0 byte request was actually
      not needed and would hang and cause errors in other setup
      requests.
      
      After the above commit, 0 byte setups work since the gadget
      now accepts empty queues to ep0 to clear the delay, but all
      other setups hang.
      
      Fixes: 946ef68a ("Let setup() return USB_GADGET_DELAYED_STATUS")
      Signed-off-by: NJerry Zhang <zhangjerry@google.com>
      Signed-off-by: NFelipe Balbi <felipe.balbi@linux.intel.com>
      e610257e
  27. 20 7月, 2018 1 次提交
    • J
      usb: gadget: f_fs: Only return delayed status when len is 0 · 4d644abf
      Jerry Zhang 提交于
      Commit 1b9ba000 ("Allow function drivers to pause control
      transfers") states that USB_GADGET_DELAYED_STATUS is only
      supported if data phase is 0 bytes.
      
      It seems that when the length is not 0 bytes, there is no
      need to explicitly delay the data stage since the transfer
      is not completed until the user responds. However, when the
      length is 0, there is no data stage and the transfer is
      finished once setup() returns, hence there is a need to
      explicitly delay completion.
      
      This manifests as the following bugs:
      
      Prior to 946ef68a ('Let setup() return
      USB_GADGET_DELAYED_STATUS'), when setup is 0 bytes, ffs
      would require user to queue a 0 byte request in order to
      clear setup state. However, that 0 byte request was actually
      not needed and would hang and cause errors in other setup
      requests.
      
      After the above commit, 0 byte setups work since the gadget
      now accepts empty queues to ep0 to clear the delay, but all
      other setups hang.
      
      Fixes: 946ef68a ("Let setup() return USB_GADGET_DELAYED_STATUS")
      Signed-off-by: NJerry Zhang <zhangjerry@google.com>
      Cc: stable <stable@vger.kernel.org>
      Acked-by: NFelipe Balbi <felipe.balbi@linux.intel.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      4d644abf
  28. 18 6月, 2018 1 次提交
    • V
      usb: gadget: ffs: Fix BUG when userland exits with submitted AIO transfers · d52e4d0c
      Vincent Pelletier 提交于
      This bug happens only when the UDC needs to sleep during usb_ep_dequeue,
      as is the case for (at least) dwc3.
      
      [  382.200896] BUG: scheduling while atomic: screen/1808/0x00000100
      [  382.207124] 4 locks held by screen/1808:
      [  382.211266]  #0:  (rcu_callback){....}, at: [<c10b4ff0>] rcu_process_callbacks+0x260/0x440
      [  382.219949]  #1:  (rcu_read_lock_sched){....}, at: [<c1358ba0>] percpu_ref_switch_to_atomic_rcu+0xb0/0x130
      [  382.230034]  #2:  (&(&ctx->ctx_lock)->rlock){....}, at: [<c11f0c73>] free_ioctx_users+0x23/0xd0
      [  382.230096]  #3:  (&(&ffs->eps_lock)->rlock){....}, at: [<f81e7710>] ffs_aio_cancel+0x20/0x60 [usb_f_fs]
      [  382.230160] Modules linked in: usb_f_fs libcomposite configfs bnep btsdio bluetooth ecdh_generic brcmfmac brcmutil intel_powerclamp coretemp dwc3 kvm_intel ulpi udc_core kvm irqbypass crc32_pclmul crc32c_intel pcbc dwc3_pci aesni_intel aes_i586 crypto_simd cryptd ehci_pci ehci_hcd gpio_keys usbcore basincove_gpadc industrialio usb_common
      [  382.230407] CPU: 1 PID: 1808 Comm: screen Not tainted 4.14.0-edison+ #117
      [  382.230416] Hardware name: Intel Corporation Merrifield/BODEGA BAY, BIOS 542 2015.01.21:18.19.48
      [  382.230425] Call Trace:
      [  382.230438]  <SOFTIRQ>
      [  382.230466]  dump_stack+0x47/0x62
      [  382.230498]  __schedule_bug+0x61/0x80
      [  382.230522]  __schedule+0x43/0x7a0
      [  382.230587]  schedule+0x5f/0x70
      [  382.230625]  dwc3_gadget_ep_dequeue+0x14c/0x270 [dwc3]
      [  382.230669]  ? do_wait_intr_irq+0x70/0x70
      [  382.230724]  usb_ep_dequeue+0x19/0x90 [udc_core]
      [  382.230770]  ffs_aio_cancel+0x37/0x60 [usb_f_fs]
      [  382.230798]  kiocb_cancel+0x31/0x40
      [  382.230822]  free_ioctx_users+0x4d/0xd0
      [  382.230858]  percpu_ref_switch_to_atomic_rcu+0x10a/0x130
      [  382.230881]  ? percpu_ref_exit+0x40/0x40
      [  382.230904]  rcu_process_callbacks+0x2b3/0x440
      [  382.230965]  __do_softirq+0xf8/0x26b
      [  382.231011]  ? __softirqentry_text_start+0x8/0x8
      [  382.231033]  do_softirq_own_stack+0x22/0x30
      [  382.231042]  </SOFTIRQ>
      [  382.231071]  irq_exit+0x45/0xc0
      [  382.231089]  smp_apic_timer_interrupt+0x13c/0x150
      [  382.231118]  apic_timer_interrupt+0x35/0x3c
      [  382.231132] EIP: __copy_user_ll+0xe2/0xf0
      [  382.231142] EFLAGS: 00210293 CPU: 1
      [  382.231154] EAX: bfd4508c EBX: 00000004 ECX: 00000003 EDX: f3d8fe50
      [  382.231165] ESI: f3d8fe51 EDI: bfd4508d EBP: f3d8fe14 ESP: f3d8fe08
      [  382.231176]  DS: 007b ES: 007b FS: 00d8 GS: 0033 SS: 0068
      [  382.231265]  core_sys_select+0x25f/0x320
      [  382.231346]  ? __wake_up_common_lock+0x62/0x80
      [  382.231399]  ? tty_ldisc_deref+0x13/0x20
      [  382.231438]  ? ldsem_up_read+0x1b/0x40
      [  382.231459]  ? tty_ldisc_deref+0x13/0x20
      [  382.231479]  ? tty_write+0x29f/0x2e0
      [  382.231514]  ? n_tty_ioctl+0xe0/0xe0
      [  382.231541]  ? tty_write_unlock+0x30/0x30
      [  382.231566]  ? __vfs_write+0x22/0x110
      [  382.231604]  ? security_file_permission+0x2f/0xd0
      [  382.231635]  ? rw_verify_area+0xac/0x120
      [  382.231677]  ? vfs_write+0x103/0x180
      [  382.231711]  SyS_select+0x87/0xc0
      [  382.231739]  ? SyS_write+0x42/0x90
      [  382.231781]  do_fast_syscall_32+0xd6/0x1a0
      [  382.231836]  entry_SYSENTER_32+0x47/0x71
      [  382.231848] EIP: 0xb7f75b05
      [  382.231857] EFLAGS: 00000246 CPU: 1
      [  382.231868] EAX: ffffffda EBX: 00000400 ECX: bfd4508c EDX: bfd4510c
      [  382.231878] ESI: 00000000 EDI: 00000000 EBP: 00000000 ESP: bfd45020
      [  382.231889]  DS: 007b ES: 007b FS: 0000 GS: 0033 SS: 007b
      [  382.232281] softirq: huh, entered softirq 9 RCU c10b4d90 with preempt_count 00000100, exited with 00000000?
      Tested-by: NSam Protsenko <semen.protsenko@linaro.org>
      Signed-off-by: NVincent Pelletier <plr.vincent@gmail.com>
      Signed-off-by: NFelipe Balbi <felipe.balbi@linux.intel.com>
      d52e4d0c
  29. 06 6月, 2018 1 次提交
    • D
      vfs: change inode times to use struct timespec64 · 95582b00
      Deepa Dinamani 提交于
      struct timespec is not y2038 safe. Transition vfs to use
      y2038 safe struct timespec64 instead.
      
      The change was made with the help of the following cocinelle
      script. This catches about 80% of the changes.
      All the header file and logic changes are included in the
      first 5 rules. The rest are trivial substitutions.
      I avoid changing any of the function signatures or any other
      filesystem specific data structures to keep the patch simple
      for review.
      
      The script can be a little shorter by combining different cases.
      But, this version was sufficient for my usecase.
      
      virtual patch
      
      @ depends on patch @
      identifier now;
      @@
      - struct timespec
      + struct timespec64
        current_time ( ... )
        {
      - struct timespec now = current_kernel_time();
      + struct timespec64 now = current_kernel_time64();
        ...
      - return timespec_trunc(
      + return timespec64_trunc(
        ... );
        }
      
      @ depends on patch @
      identifier xtime;
      @@
       struct \( iattr \| inode \| kstat \) {
       ...
      -       struct timespec xtime;
      +       struct timespec64 xtime;
       ...
       }
      
      @ depends on patch @
      identifier t;
      @@
       struct inode_operations {
       ...
      int (*update_time) (...,
      -       struct timespec t,
      +       struct timespec64 t,
      ...);
       ...
       }
      
      @ depends on patch @
      identifier t;
      identifier fn_update_time =~ "update_time$";
      @@
       fn_update_time (...,
      - struct timespec *t,
      + struct timespec64 *t,
       ...) { ... }
      
      @ depends on patch @
      identifier t;
      @@
      lease_get_mtime( ... ,
      - struct timespec *t
      + struct timespec64 *t
        ) { ... }
      
      @te depends on patch forall@
      identifier ts;
      local idexpression struct inode *inode_node;
      identifier i_xtime =~ "^i_[acm]time$";
      identifier ia_xtime =~ "^ia_[acm]time$";
      identifier fn_update_time =~ "update_time$";
      identifier fn;
      expression e, E3;
      local idexpression struct inode *node1;
      local idexpression struct inode *node2;
      local idexpression struct iattr *attr1;
      local idexpression struct iattr *attr2;
      local idexpression struct iattr attr;
      identifier i_xtime1 =~ "^i_[acm]time$";
      identifier i_xtime2 =~ "^i_[acm]time$";
      identifier ia_xtime1 =~ "^ia_[acm]time$";
      identifier ia_xtime2 =~ "^ia_[acm]time$";
      @@
      (
      (
      - struct timespec ts;
      + struct timespec64 ts;
      |
      - struct timespec ts = current_time(inode_node);
      + struct timespec64 ts = current_time(inode_node);
      )
      
      <+... when != ts
      (
      - timespec_equal(&inode_node->i_xtime, &ts)
      + timespec64_equal(&inode_node->i_xtime, &ts)
      |
      - timespec_equal(&ts, &inode_node->i_xtime)
      + timespec64_equal(&ts, &inode_node->i_xtime)
      |
      - timespec_compare(&inode_node->i_xtime, &ts)
      + timespec64_compare(&inode_node->i_xtime, &ts)
      |
      - timespec_compare(&ts, &inode_node->i_xtime)
      + timespec64_compare(&ts, &inode_node->i_xtime)
      |
      ts = current_time(e)
      |
      fn_update_time(..., &ts,...)
      |
      inode_node->i_xtime = ts
      |
      node1->i_xtime = ts
      |
      ts = inode_node->i_xtime
      |
      <+... attr1->ia_xtime ...+> = ts
      |
      ts = attr1->ia_xtime
      |
      ts.tv_sec
      |
      ts.tv_nsec
      |
      btrfs_set_stack_timespec_sec(..., ts.tv_sec)
      |
      btrfs_set_stack_timespec_nsec(..., ts.tv_nsec)
      |
      - ts = timespec64_to_timespec(
      + ts =
      ...
      -)
      |
      - ts = ktime_to_timespec(
      + ts = ktime_to_timespec64(
      ...)
      |
      - ts = E3
      + ts = timespec_to_timespec64(E3)
      |
      - ktime_get_real_ts(&ts)
      + ktime_get_real_ts64(&ts)
      |
      fn(...,
      - ts
      + timespec64_to_timespec(ts)
      ,...)
      )
      ...+>
      (
      <... when != ts
      - return ts;
      + return timespec64_to_timespec(ts);
      ...>
      )
      |
      - timespec_equal(&node1->i_xtime1, &node2->i_xtime2)
      + timespec64_equal(&node1->i_xtime2, &node2->i_xtime2)
      |
      - timespec_equal(&node1->i_xtime1, &attr2->ia_xtime2)
      + timespec64_equal(&node1->i_xtime2, &attr2->ia_xtime2)
      |
      - timespec_compare(&node1->i_xtime1, &node2->i_xtime2)
      + timespec64_compare(&node1->i_xtime1, &node2->i_xtime2)
      |
      node1->i_xtime1 =
      - timespec_trunc(attr1->ia_xtime1,
      + timespec64_trunc(attr1->ia_xtime1,
      ...)
      |
      - attr1->ia_xtime1 = timespec_trunc(attr2->ia_xtime2,
      + attr1->ia_xtime1 =  timespec64_trunc(attr2->ia_xtime2,
      ...)
      |
      - ktime_get_real_ts(&attr1->ia_xtime1)
      + ktime_get_real_ts64(&attr1->ia_xtime1)
      |
      - ktime_get_real_ts(&attr.ia_xtime1)
      + ktime_get_real_ts64(&attr.ia_xtime1)
      )
      
      @ depends on patch @
      struct inode *node;
      struct iattr *attr;
      identifier fn;
      identifier i_xtime =~ "^i_[acm]time$";
      identifier ia_xtime =~ "^ia_[acm]time$";
      expression e;
      @@
      (
      - fn(node->i_xtime);
      + fn(timespec64_to_timespec(node->i_xtime));
      |
       fn(...,
      - node->i_xtime);
      + timespec64_to_timespec(node->i_xtime));
      |
      - e = fn(attr->ia_xtime);
      + e = fn(timespec64_to_timespec(attr->ia_xtime));
      )
      
      @ depends on patch forall @
      struct inode *node;
      struct iattr *attr;
      identifier i_xtime =~ "^i_[acm]time$";
      identifier ia_xtime =~ "^ia_[acm]time$";
      identifier fn;
      @@
      {
      + struct timespec ts;
      <+...
      (
      + ts = timespec64_to_timespec(node->i_xtime);
      fn (...,
      - &node->i_xtime,
      + &ts,
      ...);
      |
      + ts = timespec64_to_timespec(attr->ia_xtime);
      fn (...,
      - &attr->ia_xtime,
      + &ts,
      ...);
      )
      ...+>
      }
      
      @ depends on patch forall @
      struct inode *node;
      struct iattr *attr;
      struct kstat *stat;
      identifier ia_xtime =~ "^ia_[acm]time$";
      identifier i_xtime =~ "^i_[acm]time$";
      identifier xtime =~ "^[acm]time$";
      identifier fn, ret;
      @@
      {
      + struct timespec ts;
      <+...
      (
      + ts = timespec64_to_timespec(node->i_xtime);
      ret = fn (...,
      - &node->i_xtime,
      + &ts,
      ...);
      |
      + ts = timespec64_to_timespec(node->i_xtime);
      ret = fn (...,
      - &node->i_xtime);
      + &ts);
      |
      + ts = timespec64_to_timespec(attr->ia_xtime);
      ret = fn (...,
      - &attr->ia_xtime,
      + &ts,
      ...);
      |
      + ts = timespec64_to_timespec(attr->ia_xtime);
      ret = fn (...,
      - &attr->ia_xtime);
      + &ts);
      |
      + ts = timespec64_to_timespec(stat->xtime);
      ret = fn (...,
      - &stat->xtime);
      + &ts);
      )
      ...+>
      }
      
      @ depends on patch @
      struct inode *node;
      struct inode *node2;
      identifier i_xtime1 =~ "^i_[acm]time$";
      identifier i_xtime2 =~ "^i_[acm]time$";
      identifier i_xtime3 =~ "^i_[acm]time$";
      struct iattr *attrp;
      struct iattr *attrp2;
      struct iattr attr ;
      identifier ia_xtime1 =~ "^ia_[acm]time$";
      identifier ia_xtime2 =~ "^ia_[acm]time$";
      struct kstat *stat;
      struct kstat stat1;
      struct timespec64 ts;
      identifier xtime =~ "^[acmb]time$";
      expression e;
      @@
      (
      ( node->i_xtime2 \| attrp->ia_xtime2 \| attr.ia_xtime2 \) = node->i_xtime1  ;
      |
       node->i_xtime2 = \( node2->i_xtime1 \| timespec64_trunc(...) \);
      |
       node->i_xtime2 = node->i_xtime1 = node->i_xtime3 = \(ts \| current_time(...) \);
      |
       node->i_xtime1 = node->i_xtime3 = \(ts \| current_time(...) \);
      |
       stat->xtime = node2->i_xtime1;
      |
       stat1.xtime = node2->i_xtime1;
      |
      ( node->i_xtime2 \| attrp->ia_xtime2 \) = attrp->ia_xtime1  ;
      |
      ( attrp->ia_xtime1 \| attr.ia_xtime1 \) = attrp2->ia_xtime2;
      |
      - e = node->i_xtime1;
      + e = timespec64_to_timespec( node->i_xtime1 );
      |
      - e = attrp->ia_xtime1;
      + e = timespec64_to_timespec( attrp->ia_xtime1 );
      |
      node->i_xtime1 = current_time(...);
      |
       node->i_xtime2 = node->i_xtime1 = node->i_xtime3 =
      - e;
      + timespec_to_timespec64(e);
      |
       node->i_xtime1 = node->i_xtime3 =
      - e;
      + timespec_to_timespec64(e);
      |
      - node->i_xtime1 = e;
      + node->i_xtime1 = timespec_to_timespec64(e);
      )
      Signed-off-by: NDeepa Dinamani <deepa.kernel@gmail.com>
      Cc: <anton@tuxera.com>
      Cc: <balbi@kernel.org>
      Cc: <bfields@fieldses.org>
      Cc: <darrick.wong@oracle.com>
      Cc: <dhowells@redhat.com>
      Cc: <dsterba@suse.com>
      Cc: <dwmw2@infradead.org>
      Cc: <hch@lst.de>
      Cc: <hirofumi@mail.parknet.co.jp>
      Cc: <hubcap@omnibond.com>
      Cc: <jack@suse.com>
      Cc: <jaegeuk@kernel.org>
      Cc: <jaharkes@cs.cmu.edu>
      Cc: <jslaby@suse.com>
      Cc: <keescook@chromium.org>
      Cc: <mark@fasheh.com>
      Cc: <miklos@szeredi.hu>
      Cc: <nico@linaro.org>
      Cc: <reiserfs-devel@vger.kernel.org>
      Cc: <richard@nod.at>
      Cc: <sage@redhat.com>
      Cc: <sfrench@samba.org>
      Cc: <swhiteho@redhat.com>
      Cc: <tj@kernel.org>
      Cc: <trond.myklebust@primarydata.com>
      Cc: <tytso@mit.edu>
      Cc: <viro@zeniv.linux.org.uk>
      95582b00
  30. 15 5月, 2018 1 次提交
  31. 13 3月, 2018 2 次提交
    • L
      usb: gadget: ffs: Let setup() return USB_GADGET_DELAYED_STATUS · 946ef68a
      Lars-Peter Clausen 提交于
      Some UDC drivers (like the DWC3) expect that the response to a setup()
      request is queued from within the setup function itself so that it is
      available as soon as setup() has completed.
      
      Upon receiving a setup request the function fs driver creates an event that
      is made available to userspace. And only once userspace has acknowledged
      that event the response to the setup request is queued.
      
      So it violates the requirement of those UDC drivers and random failures can
      be observed. This is basically a race condition and if userspace is able to
      read the event and queue the response fast enough all is good. But if it is
      not, for example because other processes are currently scheduled to run,
      the USB host that sent the setup request will observe an error.
      
      To avoid this the gadget framework provides the USB_GADGET_DELAYED_STATUS
      return code. If a setup() callback returns this value the UDC driver is
      aware that response is not yet available and can uses the appropriate
      methods to handle this case.
      
      Since in the case of function fs the response will never be available when
      the setup() function returns make sure that this status code is used.
      
      This fixed random occasional failures that were previously observed on a
      DWC3 based system under high system load.
      Signed-off-by: NLars-Peter Clausen <lars@metafoo.de>
      Signed-off-by: NFelipe Balbi <felipe.balbi@linux.intel.com>
      946ef68a
    • L
      usb: gadget: ffs: Execute copy_to_user() with USER_DS set · 4058ebf3
      Lars-Peter Clausen 提交于
      When using a AIO read() operation on the function FS gadget driver a URB is
      submitted asynchronously and on URB completion the received data is copied
      to the userspace buffer associated with the read operation.
      
      This is done from a kernel worker thread invoking copy_to_user() (through
      copy_to_iter()). And while the user space process memory is made available
      to the kernel thread using use_mm(), some architecture require in addition
      to this that the operation runs with USER_DS set. Otherwise the userspace
      memory access will fail.
      
      For example on ARM64 with Privileged Access Never (PAN) and User Access
      Override (UAO) enabled the following crash occurs.
      
      	Internal error: Accessing user space memory with fs=KERNEL_DS: 9600004f [#1] SMP
      	Modules linked in:
      	CPU: 2 PID: 1636 Comm: kworker/2:1 Not tainted 4.9.0-04081-g8ab2dfb-dirty #487
      	Hardware name: ZynqMP ZCU102 Rev1.0 (DT)
      	Workqueue: events ffs_user_copy_worker
      	task: ffffffc87afc8080 task.stack: ffffffc87a00c000
      	PC is at __arch_copy_to_user+0x190/0x220
      	LR is at copy_to_iter+0x78/0x3c8
      	[...]
      	[<ffffff800847b790>] __arch_copy_to_user+0x190/0x220
      	[<ffffff80086f25d8>] ffs_user_copy_worker+0x70/0x130
      	[<ffffff80080b8c64>] process_one_work+0x1dc/0x460
      	[<ffffff80080b8f38>] worker_thread+0x50/0x4b0
      	[<ffffff80080bf5a0>] kthread+0xd8/0xf0
      	[<ffffff8008083680>] ret_from_fork+0x10/0x50
      
      Address this by placing a set_fs(USER_DS) before of the copy operation
      and revert it again once the copy operation has finished.
      
      This patch is analogous to commit d7ffde35 ("vhost: use USER_DS in
      vhost_worker thread") which addresses the same underlying issue.
      Signed-off-by: NLars-Peter Clausen <lars@metafoo.de>
      Signed-off-by: NFelipe Balbi <felipe.balbi@linux.intel.com>
      4058ebf3
  32. 05 3月, 2018 1 次提交
    • X
      usb: gadget: f_fs: Fix use-after-free in ffs_fs_kill_sb() · 1a087f03
      Xinyong 提交于
      When I debug a kernel crash issue in funcitonfs, found ffs_data.ref
      overflowed, While functionfs is unmounting, ffs_data is put twice.
      
      Commit 43938613 ("drivers, usb: convert ffs_data.ref from atomic_t to
      refcount_t") can avoid refcount overflow, but that is risk some situations.
      So no need put ffs data in ffs_fs_kill_sb, already put in ffs_data_closed.
      
      The issue can be reproduced in Mediatek mt6763 SoC, ffs for ADB device.
      KASAN enabled configuration reports use-after-free errro.
      
      BUG: KASAN: use-after-free in refcount_dec_and_test+0x14/0xe0 at addr ffffffc0579386a0
      Read of size 4 by task umount/4650
      ====================================================
      BUG kmalloc-512 (Tainted: P        W  O   ): kasan: bad access detected
      -----------------------------------------------------------------------------
      
      INFO: Allocated in ffs_fs_mount+0x194/0x844 age=22856 cpu=2 pid=566
          alloc_debug_processing+0x1ac/0x1e8
          ___slab_alloc.constprop.63+0x640/0x648
          __slab_alloc.isra.57.constprop.62+0x24/0x34
          kmem_cache_alloc_trace+0x1a8/0x2bc
          ffs_fs_mount+0x194/0x844
          mount_fs+0x6c/0x1d0
          vfs_kern_mount+0x50/0x1b4
          do_mount+0x258/0x1034
      INFO: Freed in ffs_data_put+0x25c/0x320 age=0 cpu=3 pid=4650
          free_debug_processing+0x22c/0x434
          __slab_free+0x2d8/0x3a0
          kfree+0x254/0x264
          ffs_data_put+0x25c/0x320
          ffs_data_closed+0x124/0x15c
          ffs_fs_kill_sb+0xb8/0x110
          deactivate_locked_super+0x6c/0x98
          deactivate_super+0xb0/0xbc
      INFO: Object 0xffffffc057938600 @offset=1536 fp=0x          (null)
      ......
      Call trace:
      [<ffffff900808cf5c>] dump_backtrace+0x0/0x250
      [<ffffff900808d3a0>] show_stack+0x14/0x1c
      [<ffffff90084a8c04>] dump_stack+0xa0/0xc8
      [<ffffff900826c2b4>] print_trailer+0x158/0x260
      [<ffffff900826d9d8>] object_err+0x3c/0x40
      [<ffffff90082745f0>] kasan_report_error+0x2a8/0x754
      [<ffffff9008274f84>] kasan_report+0x5c/0x60
      [<ffffff9008273208>] __asan_load4+0x70/0x88
      [<ffffff90084cd81c>] refcount_dec_and_test+0x14/0xe0
      [<ffffff9008d98f9c>] ffs_data_put+0x80/0x320
      [<ffffff9008d9d904>] ffs_fs_kill_sb+0xc8/0x110
      [<ffffff90082852a0>] deactivate_locked_super+0x6c/0x98
      [<ffffff900828537c>] deactivate_super+0xb0/0xbc
      [<ffffff90082af0c0>] cleanup_mnt+0x64/0xec
      [<ffffff90082af1b0>] __cleanup_mnt+0x10/0x18
      [<ffffff90080d9e68>] task_work_run+0xcc/0x124
      [<ffffff900808c8c0>] do_notify_resume+0x60/0x70
      [<ffffff90080866e4>] work_pending+0x10/0x14
      
      Cc: stable@vger.kernel.org
      Signed-off-by: NXinyong <xinyong.fang@linux.alibaba.com>
      Signed-off-by: NFelipe Balbi <felipe.balbi@linux.intel.com>
      1a087f03
  33. 12 2月, 2018 2 次提交
    • J
      usb: gadget: f_fs: Use config_ep_by_speed() · 675272d0
      Jack Pham 提交于
      In commit 2bfa0719 ("usb: gadget: function: f_fs: pass
      companion descriptor along") there is a pointer arithmetic
      bug where the comp_desc is obtained as follows:
      
       comp_desc = (struct usb_ss_ep_comp_descriptor *)(ds +
      	       USB_DT_ENDPOINT_SIZE);
      
      Since ds is a pointer to usb_endpoint_descriptor, adding
      7 to it ends up going out of bounds (7 * sizeof(struct
      usb_endpoint_descriptor), which is actually 7*9 bytes) past
      the SS descriptor. As a result the maxburst value will be
      read incorrectly, and the UDC driver will also get a garbage
      comp_desc (assuming it uses it).
      
      Since Felipe wrote, "Eventually, f_fs.c should be converted
      to use config_ep_by_speed() like all other functions, though",
      let's finally do it. This allows the other usb_ep fields to
      be properly populated, such as maxpacket and mult. It also
      eliminates the awkward speed-based descriptor lookup since
      config_ep_by_speed() does that already using the ones found
      in struct usb_function.
      
      Fixes: 2bfa0719 ("usb: gadget: function: f_fs: pass companion descriptor along")
      Cc: stable@vger.kernel.org
      Signed-off-by: NJack Pham <jackp@codeaurora.org>
      Signed-off-by: NFelipe Balbi <felipe.balbi@linux.intel.com>
      675272d0
    • J
      usb: gadget: f_fs: Process all descriptors during bind · 6cf439e0
      Jack Pham 提交于
      During _ffs_func_bind(), the received descriptors are evaluated
      to prepare for binding with the gadget in order to allocate
      endpoints and optionally set up OS descriptors. However, the
      high- and super-speed descriptors are only parsed based on
      whether the gadget_is_dualspeed() and gadget_is_superspeed()
      calls are true, respectively.
      
      This is a problem in case a userspace program always provides
      all of the {full,high,super,OS} descriptors when configuring a
      function. Then, for example if a gadget device is not capable
      of SuperSpeed, the call to ffs_do_descs() for the SS descriptors
      is skipped, resulting in an incorrect offset calculation for
      the vla_ptr when moving on to the OS descriptors that follow.
      This causes ffs_do_os_descs() to fail as it is now looking at
      the SS descriptors' offset within the raw_descs buffer instead.
      
      _ffs_func_bind() should evaluate the descriptors unconditionally,
      so remove the checks for gadget speed.
      
      Fixes: f0175ab5 ("usb: gadget: f_fs: OS descriptors support")
      Cc: stable@vger.kernel.org
      Co-Developed-by: NMayank Rana <mrana@codeaurora.org>
      Signed-off-by: NMayank Rana <mrana@codeaurora.org>
      Signed-off-by: NJack Pham <jackp@codeaurora.org>
      Signed-off-by: NFelipe Balbi <felipe.balbi@linux.intel.com>
      6cf439e0