4.14.167-stable review
Subsystems (3)
Greg Kroah-Hartman
maintainercover 4.14.167-stable review
This is the start of the stable review cycle for the 4.14.167 release. There are 65 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Fri, 24 Jan 2020 09:25:24 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
https://www.kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.14.167-rc1.gz
or in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-4.14.y
and the diffstat can be found below.
thanks,
greg k-h
-------------
Pseudo-Shortlog of commits:
Greg Kroah-Hartman <[email protected]>
Linux 4.14.167-rc1
Stephan Gerhold <[email protected]>
regulator: ab8500: Remove SYSCLKREQ from enum ab8505_regulator_id
Masami Hiramatsu <[email protected]>
perf probe: Fix wrong address verification
Bart Van Assche <[email protected]>
scsi: core: scsi_trace: Use get_unaligned_be*()
Martin Wilck <[email protected]>
scsi: qla2xxx: fix rports not being mark as lost in sync fabric scan
Huacai Chen <[email protected]>
scsi: qla2xxx: Fix qla2x00_request_irqs() for MSI
Bart Van Assche <[email protected]>
scsi: target: core: Fix a pr_debug() argument
Pan Bian <[email protected]>
scsi: bnx2i: fix potential use after free
Pan Bian <[email protected]>
scsi: qla4xxx: fix double free bug
Dan Carpenter <[email protected]>
scsi: esas2r: unlock on error in esas2r_nvram_read_direct()
Jeff Mahoney <[email protected]>
reiserfs: fix handling of -EOPNOTSUPP in reiserfs_for_each_xattr
Sudeep Holla <[email protected]>
Revert "arm64: dts: juno: add dma-ranges property"
Eric Dumazet <[email protected]>
tick/sched: Annotate lockless access to last_jiffies_update
Johannes Berg <[email protected]>
cfg80211: check for set_wiphy_params
Christian Hewitt <[email protected]>
arm64: dts: meson-gxl-s905x-khadas-vim: fix gpio-keys-polled node
Dan Carpenter <[email protected]>
cw1200: Fix a signedness bug in cw1200_load_firmware()
Nathan Chancellor <[email protected]>
xen/blkfront: Adjust indentation in xlvbd_alloc_gendisk
Pengcheng Yang <[email protected]>
tcp: fix marked lost packets not being retransmitted
Johan Hovold <[email protected]>
r8152: add missing endpoint sanity check
Vladis Dronov <[email protected]>
ptp: free ptp device pin descriptors properly
Colin Ian King <[email protected]>
net/wan/fsl_ucc_hdlc: fix out of bounds write on array utdm_info
Eric Dumazet <[email protected]>
net: usb: lan78xx: limit size of local TSO packets
Yonglong Liu <[email protected]>
net: hns: fix soft lockup when there is not enough memory
Alexander Lobakin <[email protected]>
net: dsa: tag_qca: fix doubled Tx statistics
Mohammed Gamal <[email protected]>
hv_netvsc: Fix memory leak when removing rndis device
Eric Dumazet <[email protected]>
macvlan: use skb_reset_mac_header() in macvlan_queue_xmit()
Sven Eckelmann <[email protected]>
batman-adv: Fix DAT candidate selection on little endian systems
Johan Hovold <[email protected]>
NFC: pn533: fix bulk-message timeout
Florian Westphal <[email protected]>
netfilter: arp_tables: init netns pointer in xt_tgdtor_param struct
Cong Wang <[email protected]>
netfilter: fix a use-after-free in mtype_destroy()
Felix Fietkau <[email protected]>
cfg80211: fix page refcount issue in A-MSDU decap
Dinh Nguyen <[email protected]>
arm64: dts: agilex/stratix10: fix pmu interrupt numbers
Kirill A. Shutemov <[email protected]>
mm/huge_memory.c: thp: fix conflict of above-47bit hint address and PMD alignment
Bharath Vedartham <[email protected]>
mm/huge_memory.c: make __thp_get_unmapped_area static
Johan Hovold <[email protected]>
USB: serial: io_edgeport: handle unbound ports on URB completion
John Ogness <[email protected]>
USB: serial: io_edgeport: use irqsave() in USB's complete callback
Jose Abreu <[email protected]>
net: stmmac: Enable 16KB buffer size
Jose Abreu <[email protected]>
net: stmmac: 16KB buffer must be 16 byte aligned
Wen Yang <[email protected]>
mm/page-writeback.c: avoid potential division by zero in wb_min_max_ratio()
Johannes Thumshirn <[email protected]>
btrfs: fix memory leak in qgroup accounting
Kirill A. Shutemov <[email protected]>
mm/shmem.c: thp, shmem: fix conflict of above-47bit hint address and PMD alignment
Jin Yao <[email protected]>
perf report: Fix incorrectly added dimensions as switch perf data file
Yuya Fujita <[email protected]>
perf hists: Fix variable name's inconsistency in hists__for_each() macro
Ard Biesheuvel <[email protected]>
x86/efistub: Disable paging at mixed mode entry
Qian Cai <[email protected]>
x86/resctrl: Fix an imbalance in domain_remove_cpu()
Keiya Nobuta <[email protected]>
usb: core: hub: Improved device recognition on remote wakeup
Christian Brauner <[email protected]>
ptrace: reintroduce usage of subjective credentials in ptrace_has_cap()
Dan Carpenter <[email protected]>
scsi: mptfusion: Fix double fetch bug in ioctl
Arnd Bergmann <[email protected]>
scsi: fnic: fix invalid stack access
Johan Hovold <[email protected]>
USB: serial: quatech2: handle unbound ports
Johan Hovold <[email protected]>
USB: serial: keyspan: handle unbound ports
Johan Hovold <[email protected]>
USB: serial: io_edgeport: add missing active-port sanity check
Johan Hovold <[email protected]>
USB: serial: ch341: handle unbound port at reset_resume
Johan Hovold <[email protected]>
USB: serial: suppress driver bind attributes
Reinhard Speyerer <[email protected]>
USB: serial: option: add support for Quectel RM500Q in QDL mode
Johan Hovold <[email protected]>
USB: serial: opticon: fix control-message timeouts
Kristian Evensen <[email protected]>
USB: serial: option: Add support for Quectel RM500Q
Jerónimo Borque <[email protected]>
USB: serial: simple: Add Motorola Solutions TETRA MTP3xxx and MTP85xx
Lars Möllendorf <[email protected]>
iio: buffer: align the size of scan bytes to size of the largest element
Kishon Vijay Abraham I <[email protected]>
ARM: dts: am571x-idk: Fix gpios property to have the correct gpio number
Mikulas Patocka <[email protected]>
block: fix an integer overflow in logical block size
Jari Ruusu <[email protected]>
Fix built-in early-load Intel microcode alignment
Takashi Iwai <[email protected]>
ALSA: seq: Fix racy access for queue timer in proc read
Stephan Gerhold <[email protected]>
ASoC: msm8916-wcd-analog: Fix selected events for MIC BIAS External1
Guenter Roeck <[email protected]>
clk: Don't try to enable critical clocks if prepare failed
Martin Blumenstingl <[email protected]>
dt-bindings: reset: meson8b: fix duplicate reset IDs
-------------
Diffstat:
Makefile | 4 +- arch/arm/boot/dts/am571x-idk.dts | 2 +- arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi | 8 +- .../dts/amlogic/meson-gxl-s905x-khadas-vim.dts | 4 +- arch/arm64/boot/dts/arm/juno-base.dtsi | 1 - arch/x86/boot/compressed/head_64.S | 5 + arch/x86/kernel/cpu/intel_rdt.c | 2 +- block/blk-settings.c | 2 +- drivers/block/xen-blkfront.c | 4 +- drivers/clk/clk.c | 10 +- drivers/iio/industrialio-buffer.c | 6 +- drivers/md/dm-snap-persistent.c | 2 +- drivers/md/raid0.c | 2 +- drivers/message/fusion/mptctl.c | 213 +++++---------------- drivers/net/ethernet/hisilicon/hns/hns_enet.c | 4 +- drivers/net/ethernet/stmicro/stmmac/common.h | 5 +- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 4 +- drivers/net/hyperv/rndis_filter.c | 2 - drivers/net/macvlan.c | 5 +- drivers/net/usb/lan78xx.c | 1 + drivers/net/usb/r8152.c | 3 + drivers/net/wan/fsl_ucc_hdlc.c | 2 +- drivers/net/wireless/st/cw1200/fwio.c | 6 +- drivers/nfc/pn533/usb.c | 2 +- drivers/ptp/ptp_clock.c | 4 +- drivers/scsi/bnx2i/bnx2i_iscsi.c | 2 +- drivers/scsi/esas2r/esas2r_flash.c | 1 + drivers/scsi/fnic/vnic_dev.c | 20 +- drivers/scsi/qla2xxx/qla_init.c | 6 +- drivers/scsi/qla2xxx/qla_isr.c | 6 +- drivers/scsi/qla4xxx/ql4_mbx.c | 3 - drivers/scsi/scsi_trace.c | 113 ++++------- drivers/target/target_core_fabric_lib.c | 2 +- drivers/usb/core/hub.c | 1 + drivers/usb/serial/ch341.c | 6 +- drivers/usb/serial/io_edgeport.c | 33 ++-- drivers/usb/serial/keyspan.c | 4 + drivers/usb/serial/opticon.c | 2 +- drivers/usb/serial/option.c | 6 + drivers/usb/serial/quatech2.c | 6 + drivers/usb/serial/usb-serial-simple.c | 2 + drivers/usb/serial/usb-serial.c | 3 + firmware/Makefile | 2 +- fs/btrfs/qgroup.c | 6 +- fs/reiserfs/xattr.c | 8 +- include/dt-bindings/reset/amlogic,meson8b-reset.h | 6 +- include/linux/blkdev.h | 8 +- include/linux/regulator/ab8500.h | 2 - kernel/ptrace.c | 15 +- kernel/time/tick-sched.c | 14 +- mm/huge_memory.c | 38 ++-- mm/page-writeback.c | 4 +- mm/shmem.c | 7 +- net/batman-adv/distributed-arp-table.c | 4 +- net/dsa/tag_qca.c | 3 - net/ipv4/netfilter/arp_tables.c | 19 +- net/ipv4/tcp_input.c | 7 +- net/netfilter/ipset/ip_set_bitmap_gen.h | 2 +- net/wireless/rdev-ops.h | 4 + net/wireless/util.c | 2 +- sound/core/seq/seq_timer.c | 14 +- sound/soc/codecs/msm8916-wcd-analog.c | 4 +- tools/perf/builtin-report.c | 5 +- tools/perf/util/hist.h | 4 +- tools/perf/util/probe-finder.c | 32 +--- 65 files changed, 320 insertions(+), 409 deletions(-)
Greg Kroah-Hartman
maintainerPATCH 1/65 dt-bindings: reset: meson8b: fix duplicate reset IDs
From: Martin Blumenstingl <[email protected]>
commit 4881873f4cc1460f63d85fa81363d56be328ccdc upstream.
According to the public S805 datasheet the RESET2 register uses the following bits for the PIC_DC, PSC and NAND reset lines:
- PIC_DC is at bit 3 (meaning: RESET_VD_RMEM + 3)
- PSC is at bit 4 (meaning: RESET_VD_RMEM + 4)
- NAND is at bit 5 (meaning: RESET_VD_RMEM + 4)
Update the reset IDs of these three reset lines so they don't conflict with PIC_DC and map to the actual hardware reset lines.
--- include/dt-bindings/reset/amlogic,meson8b-reset.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
include/dt-bindings/reset/amlogic,meson8b-reset.h +3 -3
@@ -95,9 +95,9 @@#define RESET_VD_RMEM 64#define RESET_AUDIN 65#define RESET_DBLK 66 -#define RESET_PIC_DC 66 -#define RESET_PSC 66 -#define RESET_NAND 66 +#define RESET_PIC_DC 67 +#define RESET_PSC 68 +#define RESET_NAND 69#define RESET_GE2D 70#define RESET_PARSER_REG 71#define RESET_PARSER_FETCH 72
Greg Kroah-Hartman
maintainerPATCH 2/65 clk: Dont try to enable critical clocks if prepare failed
In reply to Greg Kroah-HartmanFrom: Guenter Roeck <[email protected]>
commit 12ead77432f2ce32dea797742316d15c5800cb32 upstream.
The following traceback is seen if a critical clock fails to prepare.
bcm2835-clk 3f101000.cprman: plld: couldn't lock PLL
------------[ cut here ]------------ Enabling unprepared plld_per WARNING: CPU: 1 PID: 1 at drivers/clk/clk.c:1014 clk_core_enable+0xcc/0x2c0 ... Call trace: clk_core_enable+0xcc/0x2c0 __clk_register+0x5c4/0x788 devm_clk_hw_register+0x4c/0xb0 bcm2835_register_pll_divider+0xc0/0x150 bcm2835_clk_probe+0x134/0x1e8 platform_drv_probe+0x50/0xa0 really_probe+0xd4/0x308 driver_probe_device+0x54/0xe8 device_driver_attach+0x6c/0x78 __driver_attach+0x54/0xd8
...
Check return values from clk_core_prepare() and clk_core_enable() and bail out if any of those functions returns an error.
--- drivers/clk/clk.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
drivers/clk/clk.c +8 -2
@@ -2482,11 +2482,17 @@ static int __clk_core_init(struct clk_coif (core->flags &CLK_IS_CRITICAL ) {unsigned long flags; -clk_core_prepare (core); + ret =clk_core_prepare (core); +if (ret) + goto out; flags =clk_enable_lock (); -clk_core_enable (core); + ret =clk_core_enable (core);clk_enable_unlock (flags); +if (ret) { +clk_core_unprepare (core); + goto out; + } }/*
Greg Kroah-Hartman
maintainerPATCH 3/65 ASoC: msm8916-wcd-analog: Fix selected events for MIC BIAS External1
In reply to Greg Kroah-HartmanFrom: Stephan Gerhold <[email protected]>
commit e0beec88397b163c7c4ea6fcfb67e8e07a2671dc upstream.
MIC BIAS External1 sets pm8916_wcd_analog_enable_micbias_ext1() as event handler, which ends up in pm8916_wcd_analog_enable_micbias_ext().
But pm8916_wcd_analog_enable_micbias_ext() only handles the POST_PMU event, which is not specified in the event flags for MIC BIAS External1. This means that the code in the event handler is never actually run.
Set SND_SOC_DAPM_POST_PMU as the only event for the handler to fix this.
--- sound/soc/codecs/msm8916-wcd-analog.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
sound/soc/codecs/msm8916-wcd-analog.c +2 -2
@@ -876,10 +876,10 @@ static const struct snd_soc_dapm_widgetSND_SOC_DAPM_SUPPLY ("MIC BIAS External1" ,CDC_A_MICB_1_EN ,7 ,0 , pm8916_wcd_analog_enable_micbias_ext1, -SND_SOC_DAPM_PRE_PMU |SND_SOC_DAPM_POST_PMD ), +SND_SOC_DAPM_POST_PMU ),SND_SOC_DAPM_SUPPLY ("MIC BIAS External2" ,CDC_A_MICB_2_EN ,7 ,0 , pm8916_wcd_analog_enable_micbias_ext2, -SND_SOC_DAPM_POST_PMU |SND_SOC_DAPM_POST_PMD ), +SND_SOC_DAPM_POST_PMU ), SND_SOC_DAPM_ADC_E("ADC1", NULL, CDC_A_TX_1_EN, 7, 0, pm8916_wcd_analog_enable_adc,
Greg Kroah-Hartman
maintainerPATCH 4/65 ALSA: seq: Fix racy access for queue timer in proc read
In reply to Greg Kroah-HartmanFrom: Takashi Iwai <[email protected]>
commit 60adcfde92fa40fcb2dbf7cc52f9b096e0cd109a upstream.
snd_seq_info_timer_read() reads the information of the timer assigned for each queue, but it's done in a racy way which may lead to UAF as spotted by syzkaller.
This patch applies the missing q->timer_mutex lock while accessing the timer object as well as a slight code change to adapt the standard coding style.
--- sound/core/seq/seq_timer.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-)
sound/core/seq/seq_timer.c +9 -5
@@ -479,15 +479,19 @@ void snd_seq_info_timer_read(struct snd_ q =queueptr (idx);if (q ==NULL )continue ; -if ((tmr = q->timer) ==NULL || - (ti = tmr->timeri) ==NULL ) { -queuefree (q); -continue ; - } +mutex_lock (&q->timer_mutex); + tmr = q->timer; +if (!tmr) + goto unlock; + ti = tmr->timeri; +if (!ti) + goto unlock;snd_iprintf (buffer,"Timer for queue %i : %s\n" , q->queue, ti->timer->name); resolution =snd_timer_resolution (ti) * tmr->ticks;snd_iprintf (buffer," Period time : %lu.%09lu\n" , resolution /1000000000 , resolution %1000000000 );snd_iprintf (buffer," Skew : %u / %u\n" , tmr->skew, tmr->skew_base); +unlock: +mutex_unlock (&q->timer_mutex);queuefree (q); } }
Greg Kroah-Hartman
maintainerPATCH 5/65 Fix built-in early-load Intel microcode alignment
In reply to Greg Kroah-HartmanFrom: Jari Ruusu <[email protected]>
commit f5ae2ea6347a308cfe91f53b53682ce635497d0d upstream.
Intel Software Developer's Manual, volume 3, chapter 9.11.6 says:
"Note that the microcode update must be aligned on a 16-byte boundary
and the size of the microcode update must be 1-KByte granular"
When early-load Intel microcode is loaded from initramfs, userspace tool 'iucode_tool' has already 16-byte aligned those microcode bits in that initramfs image. Image that was created something like this:
iucode_tool --write-earlyfw=FOO.cpio microcode-files...
However, when early-load Intel microcode is loaded from built-in firmware BLOB using CONFIG_EXTRA_FIRMWARE= kernel config option, that 16-byte alignment is not guaranteed.
Fix this by forcing all built-in firmware BLOBs to 16-byte alignment.
[ If we end up having other firmware with much bigger alignment
requirements, we might need to introduce some method for the firmware to specify it, this is the minimal "just increase the alignment a bit
to account for this one special case" patch - Linus ]
--- firmware/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
firmware/Makefile +1 -1
@@ -19,7 +19,7 @@ quiet_cmd_fwbin = MK_FW $@ PROGBITS=$(if $(CONFIG_ARM),%,@)progbits; \ echo "/* Generated by firmware/Makefile */" > $@;\ echo " .section .rodata" >>$@;\ - echo " .p2align $${ASM_ALIGN}" >>$@;\ + echo " .p2align 4" >>$@;\ echo "_fw_$${FWSTR}_bin:" >>$@;\ echo " .incbin \"$(2)\"" >>$@;\ echo "_fw_end:" >>$@;\
Greg Kroah-Hartman
maintainerPATCH 6/65 block: fix an integer overflow in logical block size
In reply to Greg Kroah-HartmanFrom: Mikulas Patocka <[email protected]>
commit ad6bf88a6c19a39fb3b0045d78ea880325dfcf15 upstream.
Logical block size has type unsigned short. That means that it can be at most 32768. However, there are architectures that can run with 64k pages (for example arm64) and on these architectures, it may be possible to create block devices with 64k block size.
For exmaple (run this on an architecture with 64k pages):
Mount will fail with this error because it tries to read the superblock using 2-sector access:
device-mapper: writecache: I/O is not aligned, sector 2, size 1024, block size 65536 EXT4-fs (dm-0): unable to read superblock
This patch changes the logical block size from unsigned short to unsigned int to avoid the overflow.
--- block/blk-settings.c | 2 +- drivers/md/dm-snap-persistent.c | 2 +- drivers/md/raid0.c | 2 +- include/linux/blkdev.h | 8 ++++---- 4 files changed, 7 insertions(+), 7 deletions(-)
block/blk-settings.c +1 -1
@@ -379,7 +379,7 @@ EXPORT_SYMBOL(blk_queue_max_segment_size* storage device can address. The default of 512 covers most * hardware. **/ -void blk_queue_logical_block_size (struct request_queue *q,unsigned short size) +void blk_queue_logical_block_size (struct request_queue *q,unsigned int size) { q->limits.logical_block_size = size;
drivers/md/dm-snap-persistent.c +1 -1
@@ -17,7 +17,7 @@#include "dm-bufio.h" #define DM_MSG_PREFIX "persistent snapshot" -#define DM_CHUNK_SIZE_DEFAULT_SECTORS 32/* 16KB */ +#define DM_CHUNK_SIZE_DEFAULT_SECTORS 32U/* 16KB */ #define DM_PREFETCH_CHUNKS 12
drivers/md/raid0.c +1 -1
@@ -94,7 +94,7 @@ static int create_strip_zones(struct mddchar b[BDEVNAME_SIZE ];char b2[BDEVNAME_SIZE ];struct r0conf *conf =kzalloc (sizeof (*conf),GFP_KERNEL ); -unsigned short blksize =512 ; +unsigned blksize =512 ; *private_conf =ERR_PTR (-ENOMEM );if (!conf)
include/linux/blkdev.h +4 -4
@@ -343,6 +343,7 @@ struct queue_limits {unsigned int max_sectors;unsigned int max_segment_size;unsigned int physical_block_size; +unsigned int logical_block_size;unsigned int alignment_offset;unsigned int io_min;unsigned int io_opt;
@@ -353,7 +354,6 @@ struct queue_limits {unsigned int discard_granularity;unsigned int discard_alignment; -unsigned short logical_block_size;unsigned short max_segments;unsigned short max_integrity_segments;unsigned short max_discard_segments;
@@ -1178,7 +1178,7 @@ extern void blk_queue_max_write_same_sec unsigned int max_write_same_sectors);extern void blk_queue_max_write_zeroes_sectors (struct request_queue *q,unsigned int max_write_same_sectors); -extern void blk_queue_logical_block_size (struct request_queue *,unsigned short ); +extern void blk_queue_logical_block_size (struct request_queue *,unsigned int );extern void blk_queue_physical_block_size (struct request_queue *,unsigned int );extern void blk_queue_alignment_offset (struct request_queue *q,unsigned int alignment);
@@ -1436,7 +1436,7 @@ static inline unsigned int queue_max_segreturn q->limits.max_segment_size; } -static inline unsigned short queue_logical_block_size (struct request_queue *q) +static inline unsigned queue_logical_block_size (struct request_queue *q) {int retval =512 ;
@@ -1446,7 +1446,7 @@ static inline unsigned short queue_logicreturn retval; } -static inline unsigned short bdev_logical_block_size (struct block_device *bdev) +static inline unsigned int bdev_logical_block_size (struct block_device *bdev) {return queue_logical_block_size (bdev_get_queue (bdev)); }
Greg Kroah-Hartman
maintainerPATCH 7/65 ARM: dts: am571x-idk: Fix gpios property to have the correct gpio number
In reply to Greg Kroah-HartmanFrom: Kishon Vijay Abraham I <[email protected]>
commit 0c4eb2a6b3c6b0facd0a3bccda5db22e7b3b6f96 upstream.
commit d23f3839fe97d8dce03d ("ARM: dts: DRA7: Add pcie1 dt node for EP mode") while adding the dt node for EP mode for DRA7 platform, added rc node for am571x-idk and populated gpios property with "gpio3 23". However the GPIO_PCIE_SWRST line is actually connected to "gpio5 18". Fix it here. (The patch adding "gpio3 23" was tested with another am57x board in EP mode which doesn't rely on reset from host).
--- arch/arm/boot/dts/am571x-idk.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm/boot/dts/am571x-idk.dts +1 -1
@@ -93,7 +93,7 @@ &pcie1_rc { status = "okay"; - gpios = <&gpio3 23 GPIO_ACTIVE_HIGH>; + gpios = <&gpio5 18 GPIO_ACTIVE_HIGH>; }; &pcie1_ep {
Greg Kroah-Hartman
maintainerPATCH 8/65 iio: buffer: align the size of scan bytes to size of the largest element
In reply to Greg Kroah-HartmanFrom: Lars Möllendorf <[email protected]>
commit 883f616530692d81cb70f8a32d85c0d2afc05f69 upstream.
Previous versions of iio_compute_scan_bytes only aligned each element to its own length (i.e. its own natural alignment). Because multiple consecutive sets of scan elements are buffered this does not work in case the computed scan bytes do not align with the natural alignment of the first scan element in the set.
This commit fixes this by aligning the scan bytes to the natural alignment of the largest scan element in the set.
--- drivers/iio/industrialio-buffer.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/iio/industrialio-buffer.c +5 -1
@@ -570,7 +570,7 @@ static int iio_compute_scan_bytes(struct const unsigned long *mask, bool timestamp) { unsigned bytes = 0; -int length, i; +int length, i, largest =0 ;/* How much space will the demuxed element take? */ for_each_set_bit(i, mask,
@@ -578,13 +578,17 @@ static int iio_compute_scan_bytes(struct length =iio_storage_bytes_for_si (indio_dev, i); bytes =ALIGN (bytes, length); bytes += length; + largest =max (largest, length); }if (timestamp) { length =iio_storage_bytes_for_timestamp (indio_dev); bytes =ALIGN (bytes, length); bytes += length; + largest =max (largest, length); } + + bytes =ALIGN (bytes, largest);return bytes; }
Greg Kroah-Hartman
maintainerPATCH 9/65 USB: serial: simple: Add Motorola Solutions TETRA MTP3xxx and MTP85xx
In reply to Greg Kroah-HartmanFrom: Jerónimo Borque <[email protected]>
commit 260e41ac4dd3e5acb90be624c03ba7f019615b75 upstream.
Add device-ids for the Motorola Solutions TETRA radios MTP3xxx series and MTP85xx series
$ lsusb -vd 0cad:
Bus 001 Device 009: ID 0cad:9015 Motorola CGISS TETRA PEI interface Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.00
bDeviceClass 0 bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize0 64 idVendor 0x0cad Motorola CGISS idProduct 0x9015 bcdDevice 24.16 iManufacturer 1 iProduct 2 iSerial 0 bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 0x0037
bNumInterfaces 2
bConfigurationValue 1
iConfiguration 3
bmAttributes 0x80
(Bus Powered)
MaxPower 500mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 2
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 0
bInterfaceProtocol 0
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x01 EP 1 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 0
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 0
bNumEndpoints 2
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 0
bInterfaceProtocol 0
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x82 EP 2 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x02 EP 2 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 0
Bus 001 Device 010: ID 0cad:9013 Motorola CGISS TETRA PEI interface Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.00
bDeviceClass 0 bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize0 64 idVendor 0x0cad Motorola CGISS idProduct 0x9013 bcdDevice 24.16 iManufacturer 1 iProduct 2 iSerial 0 bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 0x0037
bNumInterfaces 2
bConfigurationValue 1
iConfiguration 3
bmAttributes 0x80
(Bus Powered)
MaxPower 500mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 2
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 0
bInterfaceProtocol 0
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x01 EP 1 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 0
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 0
bNumEndpoints 2
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 0
bInterfaceProtocol 0
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x82 EP 2 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x02 EP 2 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 0
--- drivers/usb/serial/usb-serial-simple.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/usb/serial/usb-serial-simple.c +2 -0
@@ -89,6 +89,8 @@ DEVICE(moto_modem, MOTO_IDS);#define MOTOROLA_TETRA_IDS () \ { USB_DEVICE(0x0cad, 0x9011) },/* Motorola Solutions TETRA PEI */ \ { USB_DEVICE(0x0cad, 0x9012) }, /* MTP6550 */ \ + { USB_DEVICE(0x0cad, 0x9013) }, /* MTP3xxx */ \ + { USB_DEVICE(0x0cad, 0x9015) }, /* MTP85xx */ \ { USB_DEVICE(0x0cad, 0x9016) } /* TPG2200 */DEVICE (motorola_tetra,MOTOROLA_TETRA_IDS );
Greg Kroah-Hartman
maintainerPATCH 10/65 USB: serial: option: Add support for Quectel RM500Q
In reply to Greg Kroah-HartmanFrom: Kristian Evensen <[email protected]>
commit accf227de4d211b52c830a58b2df00d5739f2389 upstream.
RM500Q is a 5G module from Quectel, supporting both standalone and non-standalone modes. Unlike other recent Quectel modems, it is possible to identify the diagnostic interface (bInterfaceProtocol is unique). Thus, there is no need to check for the number of endpoints or reserve interfaces. The interface number is still dynamic though, so matching on interface number is not possible and two entries have to be added to the table.
Output from usb-devices with all interfaces enabled (order is diag, nmea, at_port, modem, rmnet and adb):
Bus 004 Device 007: ID 2c7c:0800 Quectel Wireless Solutions Co., Ltd. Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 3.20
bDeviceClass 0 (Defined at Interface level) bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize0 9 idVendor 0x2c7c Quectel Wireless Solutions Co., Ltd. idProduct 0x0800 bcdDevice 4.14 iManufacturer 1 Quectel iProduct 2 LTE-A Module iSerial 3 40046d60 bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 328
bNumInterfaces 6
bConfigurationValue 1
iConfiguration 4 DIAG_SER_RMNET
bmAttributes 0xa0
(Bus Powered)
Remote Wakeup
MaxPower 224mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 2
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 255 Vendor Specific Subclass
bInterfaceProtocol 48
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0400 1x 1024 bytes
bInterval 0
bMaxBurst 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x01 EP 1 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0400 1x 1024 bytes
bInterval 0
bMaxBurst 0
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 0
bNumEndpoints 3
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 0
bInterfaceProtocol 0
iInterface 0
** UNRECOGNIZED: 05 24 00 10 01
** UNRECOGNIZED: 05 24 01 00 00
** UNRECOGNIZED: 04 24 02 02
** UNRECOGNIZED: 05 24 06 00 00
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x83 EP 3 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x000a 1x 10 bytes
bInterval 9
bMaxBurst 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x82 EP 2 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0400 1x 1024 bytes
bInterval 0
bMaxBurst 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x02 EP 2 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0400 1x 1024 bytes
bInterval 0
bMaxBurst 0
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 2
bAlternateSetting 0
bNumEndpoints 3
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 0
bInterfaceProtocol 0
iInterface 0
** UNRECOGNIZED: 05 24 00 10 01
** UNRECOGNIZED: 05 24 01 00 00
** UNRECOGNIZED: 04 24 02 02
** UNRECOGNIZED: 05 24 06 00 00
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x85 EP 5 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x000a 1x 10 bytes
bInterval 9
bMaxBurst 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x84 EP 4 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0400 1x 1024 bytes
bInterval 0
bMaxBurst 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x03 EP 3 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0400 1x 1024 bytes
bInterval 0
bMaxBurst 0
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 3
bAlternateSetting 0
bNumEndpoints 3
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 0
bInterfaceProtocol 0
iInterface 0
** UNRECOGNIZED: 05 24 00 10 01
** UNRECOGNIZED: 05 24 01 00 00
** UNRECOGNIZED: 04 24 02 02
** UNRECOGNIZED: 05 24 06 00 00
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x87 EP 7 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x000a 1x 10 bytes
bInterval 9
bMaxBurst 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x86 EP 6 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0400 1x 1024 bytes
bInterval 0
bMaxBurst 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x04 EP 4 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0400 1x 1024 bytes
bInterval 0
bMaxBurst 0
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 4
bAlternateSetting 0
bNumEndpoints 3
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 255 Vendor Specific Subclass
bInterfaceProtocol 255 Vendor Specific Protocol
iInterface 5 CDEV Serial
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x88 EP 8 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0008 1x 8 bytes
bInterval 9
bMaxBurst 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x8e EP 14 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0400 1x 1024 bytes
bInterval 0
bMaxBurst 6
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x0f EP 15 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0400 1x 1024 bytes
bInterval 0
bMaxBurst 2
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 5
bAlternateSetting 0
bNumEndpoints 2
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 66
bInterfaceProtocol 1
iInterface 6 ADB Interface
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x05 EP 5 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0400 1x 1024 bytes
bInterval 0
bMaxBurst 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x89 EP 9 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0400 1x 1024 bytes
bInterval 0
bMaxBurst 0
Binary Object Store Descriptor:
bLength 5
bDescriptorType 15
wTotalLength 42
bNumDeviceCaps 3
USB 2.0 Extension Device Capability:
bLength 7
bDescriptorType 16
bDevCapabilityType 2
bmAttributes 0x00000006
Link Power Management (LPM) Supported
SuperSpeed USB Device Capability:
bLength 10
bDescriptorType 16
bDevCapabilityType 3
bmAttributes 0x00
wSpeedsSupported 0x000f
Device can operate at Low Speed (1Mbps)
Device can operate at Full Speed (12Mbps)
Device can operate at High Speed (480Mbps)
Device can operate at SuperSpeed (5Gbps)
bFunctionalitySupport 1
Lowest fully-functional device speed is Full Speed (12Mbps)
bU1DevExitLat 1 micro seconds
bU2DevExitLat 500 micro seconds
** UNRECOGNIZED: 14 10 0a 00 01 00 00 00 00 11 00 00 30 40 0a 00 b0 40 0a 00
Device Status: 0x0000
(Bus Powered)
--- drivers/usb/serial/option.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/usb/serial/option.c +4 -0
@@ -251,6 +251,7 @@ static void option_instat_callback(struc#define QUECTEL_PRODUCT_BG96 0x0296#define QUECTEL_PRODUCT_EP06 0x0306#define QUECTEL_PRODUCT_EM12 0x0512 +#define QUECTEL_PRODUCT_RM500Q 0x0800#define CMOTECH_VENDOR_ID 0x16d8#define CMOTECH_PRODUCT_6001 0x6001
@@ -1107,6 +1108,9 @@ static const struct usb_device_id option { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM12, 0xff, 0xff, 0xff), .driver_info = RSVD(1) | RSVD(2) | RSVD(3) | RSVD(4) | NUMEP2 }, { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM12, 0xff, 0, 0) }, + { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500Q, 0xff, 0xff, 0x30) }, + { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500Q, 0xff, 0, 0) }, + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6001) }, { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CMU_300) }, { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6003),
Greg Kroah-Hartman
maintainerPATCH 11/65 USB: serial: opticon: fix control-message timeouts
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
commit 5e28055f340275a8616eee88ef19186631b4d136 upstream.
The driver was issuing synchronous uninterruptible control requests without using a timeout. This could lead to the driver hanging on open() or tiocmset() due to a malfunctioning (or malicious) device until the device is physically disconnected.
The USB upper limit of five seconds per request should be more than enough.
--- drivers/usb/serial/opticon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/usb/serial/opticon.c +1 -1
@@ -116,7 +116,7 @@ static int send_control_msg(struct usb_s retval =usb_control_msg (serial->dev,usb_sndctrlpipe (serial->dev,0 ), requesttype,USB_DIR_OUT |USB_TYPE_VENDOR |USB_RECIP_INTERFACE , -0 ,0 , buffer,1 ,0 ); +0 ,0 , buffer,1 ,USB_CTRL_SET_TIMEOUT );kfree (buffer);if (retval <0 )
Greg Kroah-Hartman
maintainerPATCH 12/65 USB: serial: option: add support for Quectel RM500Q in QDL mode
In reply to Greg Kroah-HartmanFrom: Reinhard Speyerer <[email protected]>
commit f3eaabbfd093c93d791eb930cc68d9b15246a65e upstream.
Add support for Quectel RM500Q in QDL mode.
T: Bus=02 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 24 Spd=480 MxCh= 0 D: Ver= 2.10 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 P: Vendor=2c7c ProdID=0800 Rev= 0.00 S: Manufacturer=Qualcomm CDMA Technologies MSM S: Product=QUSB_BULK_SN:xxxxxxxx S: SerialNumber=xxxxxxxx C:* #Ifs= 1 Cfg#= 1 Atr=a0 MxPwr= 2mA I:* If#= 0 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=10 Driver=option E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
It is assumed that the ZLP flag required for other Qualcomm-based 5G devices also applies to Quectel RM500Q.
--- drivers/usb/serial/option.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/usb/serial/option.c +2 -0
@@ -1110,6 +1110,8 @@ static const struct usb_device_id option { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM12, 0xff, 0, 0) }, { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500Q, 0xff, 0xff, 0x30) }, { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500Q, 0xff, 0, 0) }, + { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500Q, 0xff, 0xff, 0x10), + .driver_info = ZLP }, { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6001) }, { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CMU_300) },
Greg Kroah-Hartman
maintainerPATCH 13/65 USB: serial: suppress driver bind attributes
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
commit fdb838efa31e1ed9a13ae6ad0b64e30fdbd00570 upstream.
USB-serial drivers must not be unbound from their ports before the corresponding USB driver is unbound from the parent interface so suppress the bind and unbind attributes.
Unbinding a serial driver while it's port is open is a sure way to trigger a crash as any driver state is released on unbind while port hangup is handled on the parent USB interface level. Drivers for multiport devices where ports share a resource such as an interrupt endpoint also generally cannot handle individual ports going away.
--- drivers/usb/serial/usb-serial.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/usb/serial/usb-serial.c +3 -0
@@ -1332,6 +1332,9 @@ static int usb_serial_register(struct usreturn -EINVAL ; } +/* Prevent individual ports from being unbound. */ + driver->driver.suppress_bind_attrs = true; +usb_serial_operations_init (driver);/* Add this device to our list of devices */
Greg Kroah-Hartman
maintainerPATCH 14/65 USB: serial: ch341: handle unbound port at reset_resume
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
commit 4d5ef53f75c22d28f490bcc5c771fcc610a9afa4 upstream.
Check for NULL port data in reset_resume() to avoid dereferencing a NULL pointer in case the port device isn't bound to a driver (e.g. after a failed control request at port probe).
--- drivers/usb/serial/ch341.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/usb/serial/ch341.c +5 -1
@@ -592,9 +592,13 @@ static int ch341_tiocmget(struct tty_strstatic int ch341_reset_resume (struct usb_serial *serial) {struct usb_serial_port *port = serial->port[0 ]; -struct ch341_private *priv =usb_get_serial_port_data (port); +struct ch341_private *priv;int ret; + priv =usb_get_serial_port_data (port); +if (!priv) +return 0 ; +/* reconfigure ch341 serial port after bus-reset */ ch341_configure (serial->dev, priv);
Greg Kroah-Hartman
maintainerPATCH 15/65 USB: serial: io_edgeport: add missing active-port sanity check
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
commit 1568c58d11a7c851bd09341aeefd6a1c308ac40d upstream.
The driver receives the active port number from the device, but never made sure that the port number was valid. This could lead to a NULL-pointer dereference or memory corruption in case a device sends data for an invalid port.
--- drivers/usb/serial/io_edgeport.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-)
drivers/usb/serial/io_edgeport.c +7 -5
@@ -1733,7 +1733,8 @@ static void edge_break(struct tty_structstatic void process_rcvd_data (struct edgeport_serial *edge_serial,unsigned char *buffer,__u16 bufferLength) { -struct device *dev = &edge_serial->serial->dev->dev; +struct usb_serial *serial = edge_serial->serial; +struct device *dev = &serial->dev->dev;struct usb_serial_port *port;struct edgeport_port *edge_port;__u16 lastBufferLength;
@@ -1838,9 +1839,8 @@ static void process_rcvd_data(struct edg/* spit this data back into the tty driver if this port is open */ -if (rxLen) { - port = edge_serial->serial->port[ - edge_serial->rxPort]; +if (rxLen && edge_serial->rxPort < serial->num_ports) { + port = serial->port[edge_serial->rxPort]; edge_port =usb_get_serial_port_data (port);if (edge_port->open) { dev_dbg(dev, "%s - Sending %d bytes to TTY for port %d\n",
@@ -1850,8 +1850,8 @@ static void process_rcvd_data(struct edg rxLen); edge_port->port->icount.rx += rxLen; } - buffer += rxLen; } + buffer += rxLen;break ;case EXPECT_HDR3 :/* Expect 3rd byte of status header */
@@ -1886,6 +1886,8 @@ static void process_rcvd_status(struct e__u8 code = edge_serial->rxStatusCode;/* switch the port pointer to the one being currently talked about */ +if (edge_serial->rxPort >= edge_serial->serial->num_ports) +return ; port = edge_serial->serial->port[edge_serial->rxPort]; edge_port =usb_get_serial_port_data (port);if (edge_port ==NULL ) {
Greg Kroah-Hartman
maintainerPATCH 16/65 USB: serial: keyspan: handle unbound ports
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
commit 3018dd3fa114b13261e9599ddb5656ef97a1fa17 upstream.
Check for NULL port data in the control URB completion handlers to avoid dereferencing a NULL pointer in the unlikely case where a port device isn't bound to a driver (e.g. after an allocation failure on port probe()).
--- drivers/usb/serial/keyspan.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/usb/serial/keyspan.c +4 -0
@@ -1062,6 +1062,8 @@ static void usa49_glocont_callback(strucfor (i =0 ; i < serial->num_ports; ++i) { port = serial->port[i]; p_priv =usb_get_serial_port_data (port); +if (!p_priv) +continue ;if (p_priv->resend_cont) {dev_dbg (&port->dev,"%s - sending setup\n" , __func__);
@@ -1463,6 +1465,8 @@ static void usa67_glocont_callback(strucfor (i =0 ; i < serial->num_ports; ++i) { port = serial->port[i]; p_priv =usb_get_serial_port_data (port); +if (!p_priv) +continue ;if (p_priv->resend_cont) {dev_dbg (&port->dev,"%s - sending setup\n" , __func__);
Greg Kroah-Hartman
maintainerPATCH 17/65 USB: serial: quatech2: handle unbound ports
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
commit 9715a43eea77e42678a1002623f2d9a78f5b81a1 upstream.
Check for NULL port data in the modem- and line-status handlers to avoid dereferencing a NULL pointer in the unlikely case where a port device isn't bound to a driver (e.g. after an allocation failure on port probe).
Note that the other (stubbed) event handlers qt2_process_xmit_empty() and qt2_process_flush() would need similar sanity checks in case they are ever implemented.
--- drivers/usb/serial/quatech2.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/usb/serial/quatech2.c +6 -0
@@ -867,7 +867,10 @@ static void qt2_update_msr(struct usb_seu8 newMSR = (u8) *ch;unsigned long flags; +/* May be called from qt2_process_read_urb() for an unbound port. */ port_priv =usb_get_serial_port_data (port); +if (!port_priv) +return ;spin_lock_irqsave (&port_priv->lock, flags); port_priv->shadowMSR = newMSR;
@@ -895,7 +898,10 @@ static void qt2_update_lsr(struct usb_seunsigned long flags;u8 newLSR = (u8) *ch; +/* May be called from qt2_process_read_urb() for an unbound port. */ port_priv =usb_get_serial_port_data (port); +if (!port_priv) +return ;if (newLSR &UART_LSR_BI ) newLSR &= (u8) (UART_LSR_OE |UART_LSR_BI );
Greg Kroah-Hartman
maintainerPATCH 18/65 scsi: fnic: fix invalid stack access
In reply to Greg Kroah-HartmanFrom: Arnd Bergmann <[email protected]>
commit 42ec15ceaea74b5f7a621fc6686cbf69ca66c4cf upstream.
gcc -O3 warns that some local variables are not properly initialized:
drivers/scsi/fnic/vnic_dev.c: In function 'fnic_dev_hang_notify':drivers/scsi/fnic/vnic_dev.c:511:16: error: 'a0' is used uninitialized in this function [-Werror=uninitialized]
vdev->args[0] = *a0;
~~~~~~~~~~~~~~^~~~~drivers/scsi/fnic/vnic_dev.c:691:6: note: 'a0' was declared here
u64 a0, a1;
^~drivers/scsi/fnic/vnic_dev.c:512:16: error: 'a1' is used uninitialized in this function [-Werror=uninitialized]
vdev->args[1] = *a1;
~~~~~~~~~~~~~~^~~~~drivers/scsi/fnic/vnic_dev.c:691:10: note: 'a1' was declared here
u64 a0, a1;
^~drivers/scsi/fnic/vnic_dev.c: In function 'fnic_dev_mac_addr':drivers/scsi/fnic/vnic_dev.c:512:16: error: 'a1' is used uninitialized in this function [-Werror=uninitialized]
vdev->args[1] = *a1;
~~~~~~~~~~~~~~^~~~~drivers/scsi/fnic/vnic_dev.c:698:10: note: 'a1' was declared here
u64 a0, a1;
^~Apparently the code relies on the local variables occupying adjacent memory locations in the same order, but this is of course not guaranteed.
Use an array of two u64 variables where needed to make it work correctly.
I suspect there is also an endianness bug here, but have not digged in deep enough to be sure.
--- drivers/scsi/fnic/vnic_dev.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-)
drivers/scsi/fnic/vnic_dev.c +10 -10
@@ -445,26 +445,26 @@ int vnic_dev_soft_reset_done(struct vnicint vnic_dev_hang_notify (struct vnic_dev *vdev) { -u64 a0, a1; +u64 a0 =0 , a1 =0 ;int wait =1000 ;return vnic_dev_cmd (vdev,CMD_HANG_NOTIFY , &a0, &a1, wait); }int vnic_dev_mac_addr (struct vnic_dev *vdev,u8 *mac_addr) { -u64 a0, a1; +u64 a[2 ] = {};int wait =1000 ;int err, i;for (i =0 ; i <ETH_ALEN ; i++) mac_addr[i] =0 ; - err =vnic_dev_cmd (vdev,CMD_MAC_ADDR , &a0, &a1, wait); + err =vnic_dev_cmd (vdev,CMD_MAC_ADDR , &a[0 ], &a[1 ], wait);if (err)return err;for (i =0 ; i <ETH_ALEN ; i++) - mac_addr[i] = ((u8 *)&a0)[i]; + mac_addr[i] = ((u8 *)&a)[i];return 0 ; }
@@ -489,30 +489,30 @@ void vnic_dev_packet_filter(struct vnic_void vnic_dev_add_addr (struct vnic_dev *vdev,u8 *addr) { -u64 a0 =0 , a1 =0 ; +u64 a[2 ] = {};int wait =1000 ;int err;int i;for (i =0 ; i <ETH_ALEN ; i++) - ((u8 *)&a0)[i] = addr[i]; + ((u8 *)&a)[i] = addr[i]; - err =vnic_dev_cmd (vdev,CMD_ADDR_ADD , &a0, &a1, wait); + err =vnic_dev_cmd (vdev,CMD_ADDR_ADD , &a[0 ], &a[1 ], wait);if (err)pr_err ("Can't add addr [%pM], %d\n" , addr, err); }void vnic_dev_del_addr (struct vnic_dev *vdev,u8 *addr) { -u64 a0 =0 , a1 =0 ; +u64 a[2 ] = {};int wait =1000 ;int err;int i;for (i =0 ; i <ETH_ALEN ; i++) - ((u8 *)&a0)[i] = addr[i]; + ((u8 *)&a)[i] = addr[i]; - err =vnic_dev_cmd (vdev,CMD_ADDR_DEL , &a0, &a1, wait); + err =vnic_dev_cmd (vdev,CMD_ADDR_DEL , &a[0 ], &a[1 ], wait);if (err)pr_err ("Can't del addr [%pM], %d\n" , addr, err); }
Greg Kroah-Hartman
maintainerPATCH 19/65 scsi: mptfusion: Fix double fetch bug in ioctl
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
commit 28d76df18f0ad5bcf5fa48510b225f0ed262a99b upstream.
Tom Hatskevich reported that we look up "iocp" then, in the called functions we do a second copy_from_user() and look it up again. The problem that could cause is:
drivers/message/fusion/mptctl.c
674 /* All of these commands require an interrupt or
675 * are unknown/illegal.
676 */
677 if ((ret = mptctl_syscall_down(iocp, nonblock)) != 0)
^^^^
We take this lock.
678 return ret;
679
680 if (cmd == MPTFWDOWNLOAD)
681 ret = mptctl_fw_download(arg);
^^^Then the user memory changes and we look up "iocp" again but a different one so now we are holding the incorrect lock and have a race condition.
682 else if (cmd == MPTCOMMAND) 683 ret = mptctl_mpt_command(arg);
The security impact of this bug is not as bad as it could have been because these operations are all privileged and root already has enormous destructive power. But it's still worth fixing.
This patch passes the "iocp" pointer to the functions to avoid the second lookup. That deletes 100 lines of code from the driver so it's a nice clean up as well.
--- drivers/message/fusion/mptctl.c | 213 +++++++++------------------------------- 1 file changed, 50 insertions(+), 163 deletions(-)
drivers/message/fusion/mptctl.c +50 -163
@@ -100,19 +100,19 @@ struct buflist {* Function prototypes. Called from OS entry point mptctl_ioctl. * arg contents specific to function. */ -static int mptctl_fw_download (unsigned long arg); -static int mptctl_getiocinfo (unsigned long arg,unsigned int cmd); -static int mptctl_gettargetinfo (unsigned long arg); -static int mptctl_readtest (unsigned long arg); -static int mptctl_mpt_command (unsigned long arg); -static int mptctl_eventquery (unsigned long arg); -static int mptctl_eventenable (unsigned long arg); -static int mptctl_eventreport (unsigned long arg); -static int mptctl_replace_fw (unsigned long arg); - -static int mptctl_do_reset (unsigned long arg); -static int mptctl_hp_hostinfo (unsigned long arg,unsigned int cmd); -static int mptctl_hp_targetinfo (unsigned long arg); +static int mptctl_fw_download (MPT_ADAPTER *iocp,unsigned long arg); +static int mptctl_getiocinfo (MPT_ADAPTER *iocp,unsigned long arg,unsigned int cmd); +static int mptctl_gettargetinfo (MPT_ADAPTER *iocp,unsigned long arg); +static int mptctl_readtest (MPT_ADAPTER *iocp,unsigned long arg); +static int mptctl_mpt_command (MPT_ADAPTER *iocp,unsigned long arg); +static int mptctl_eventquery (MPT_ADAPTER *iocp,unsigned long arg); +static int mptctl_eventenable (MPT_ADAPTER *iocp,unsigned long arg); +static int mptctl_eventreport (MPT_ADAPTER *iocp,unsigned long arg); +static int mptctl_replace_fw (MPT_ADAPTER *iocp,unsigned long arg); + +static int mptctl_do_reset (MPT_ADAPTER *iocp,unsigned long arg); +static int mptctl_hp_hostinfo (MPT_ADAPTER *iocp,unsigned long arg,unsigned int cmd); +static int mptctl_hp_targetinfo (MPT_ADAPTER *iocp,unsigned long arg);static int mptctl_probe (struct pci_dev *,const struct pci_device_id *);static void mptctl_remove (struct pci_dev *);
@@ -123,8 +123,8 @@ static long compat_mpctl_ioctl(struct fi/* * Private function calls. */ -static int mptctl_do_mpt_command (struct mpt_ioctl_command karg,void __user *mfPtr); -static int mptctl_do_fw_download (int ioc,char __user *ufwbuf,size_t fwlen); +static int mptctl_do_mpt_command (MPT_ADAPTER *iocp,struct mpt_ioctl_command karg,void __user *mfPtr); +static int mptctl_do_fw_download (MPT_ADAPTER *iocp,char __user *ufwbuf,size_t fwlen);static MptSge_t *kbuf_alloc_2_sgl (int bytes,u32 dir,int sge_offset,int *frags,struct buflist **blp,dma_addr_t *sglbuf_dma,MPT_ADAPTER *ioc); static void kfree_sgl(MptSge_t *sgl, dma_addr_t sgl_dma,
@@ -656,19 +656,19 @@ __mptctl_ioctl(struct file *file, unsign* by TM and FW reloads. */ if ((cmd & ~IOCSIZE_MASK ) == (MPTIOCINFO & ~IOCSIZE_MASK )) { -return mptctl_getiocinfo (arg,_IOC_SIZE (cmd)); +return mptctl_getiocinfo (iocp, arg,_IOC_SIZE (cmd)); }else if (cmd ==MPTTARGETINFO ) { -return mptctl_gettargetinfo (arg); +return mptctl_gettargetinfo (iocp, arg); }else if (cmd ==MPTTEST ) { -return mptctl_readtest (arg); +return mptctl_readtest (iocp, arg); }else if (cmd ==MPTEVENTQUERY ) { -return mptctl_eventquery (arg); +return mptctl_eventquery (iocp, arg); }else if (cmd ==MPTEVENTENABLE ) { -return mptctl_eventenable (arg); +return mptctl_eventenable (iocp, arg); }else if (cmd ==MPTEVENTREPORT ) { -return mptctl_eventreport (arg); +return mptctl_eventreport (iocp, arg); }else if (cmd ==MPTFWREPLACE ) { -return mptctl_replace_fw (arg); +return mptctl_replace_fw (iocp, arg); }/* All of these commands require an interrupt or
@@ -678,15 +678,15 @@ __mptctl_ioctl(struct file *file, unsignreturn ret;if (cmd ==MPTFWDOWNLOAD ) - ret =mptctl_fw_download (arg); + ret =mptctl_fw_download (iocp, arg);else if (cmd ==MPTCOMMAND ) - ret =mptctl_mpt_command (arg); + ret =mptctl_mpt_command (iocp, arg);else if (cmd ==MPTHARDRESET ) - ret =mptctl_do_reset (arg); + ret =mptctl_do_reset (iocp, arg);else if ((cmd & ~IOCSIZE_MASK ) == (HP_GETHOSTINFO & ~IOCSIZE_MASK )) - ret =mptctl_hp_hostinfo (arg,_IOC_SIZE (cmd)); + ret =mptctl_hp_hostinfo (iocp, arg,_IOC_SIZE (cmd));else if (cmd ==HP_GETTARGETINFO ) - ret =mptctl_hp_targetinfo (arg); + ret =mptctl_hp_targetinfo (iocp, arg);else ret = -EINVAL ;
@@ -705,11 +705,10 @@ mptctl_ioctl(struct file *file, unsignedreturn ret; } -static int mptctl_do_reset (unsigned long arg) +static int mptctl_do_reset (MPT_ADAPTER *iocp,unsigned long arg) {struct mpt_ioctl_diag_reset __user *urinfo = (void __user *) arg;struct mpt_ioctl_diag_reset krinfo; -MPT_ADAPTER *iocp;if (copy_from_user (&krinfo, urinfo,sizeof (struct mpt_ioctl_diag_reset ))) { printk(KERN_ERR MYNAM "%s@%d::mptctl_do_reset - "
@@ -718,12 +717,6 @@ static int mptctl_do_reset(unsigned longreturn -EFAULT ; } -if (mpt_verify_adapter (krinfo.hdr.iocnum, &iocp) <0 ) { - printk(KERN_DEBUG MYNAM "%s@%d::mptctl_do_reset - ioc%d not found!\n", - __FILE__, __LINE__, krinfo.hdr.iocnum); -return -ENODEV ;/* (-6) No such device or address */ - } -dctlprintk (iocp,printk (MYIOC_s_DEBUG_FMT"mptctl_do_reset called.\n" , iocp->name));
@@ -754,7 +747,7 @@ static int mptctl_do_reset(unsigned long* -ENOMSG if FW upload returned bad status */ static int -mptctl_fw_download (unsigned long arg) +mptctl_fw_download (MPT_ADAPTER *iocp,unsigned long arg) {struct mpt_fw_xfer __user *ufwdl = (void __user *) arg;struct mpt_fw_xfer kfwdl;
@@ -766,7 +759,7 @@ mptctl_fw_download(unsigned long arg)return -EFAULT ; } -return mptctl_do_fw_download (kfwdl.iocnum, kfwdl.bufp, kfwdl.fwlen); +return mptctl_do_fw_download (iocp, kfwdl.bufp, kfwdl.fwlen); }/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -784,11 +777,10 @@ mptctl_fw_download(unsigned long arg)* -ENOMSG if FW upload returned bad status */ static int -mptctl_do_fw_download (int ioc,char __user *ufwbuf,size_t fwlen) +mptctl_do_fw_download (MPT_ADAPTER *iocp,char __user *ufwbuf,size_t fwlen) {FWDownload_t *dlmsg;MPT_FRAME_HDR *mf; -MPT_ADAPTER *iocp;FWDownloadTCSGE_t *ptsge;MptSge_t *sgl, *sgIn;char *sgOut;
@@ -808,17 +800,10 @@ mptctl_do_fw_download(int ioc, char __uspFWDownloadReply_t ReplyMsg =NULL ;unsigned long timeleft; -if (mpt_verify_adapter (ioc, &iocp) <0 ) { - printk(KERN_DEBUG MYNAM "ioctl_fwdl - ioc%d not found!\n", - ioc); -return -ENODEV ;/* (-6) No such device or address */ - }else { - -/* Valid device. Get a message frame and construct the FW download message. -*/ -if ((mf =mpt_get_msg_frame (mptctl_id, iocp)) ==NULL ) -return -EAGAIN ; - } +/* Valid device. Get a message frame and construct the FW download message. +*/ +if ((mf =mpt_get_msg_frame (mptctl_id, iocp)) ==NULL ) +return -EAGAIN ;dctlprintk (iocp,printk (MYIOC_s_DEBUG_FMT"mptctl_do_fwdl called. mptctl_id = %xh.\n" , iocp->name, mptctl_id));
@@ -826,8 +811,6 @@ mptctl_do_fw_download(int ioc, char __us iocp->name, ufwbuf));dctlprintk (iocp,printk (MYIOC_s_DEBUG_FMT"DbG: kfwdl.fwlen = %d\n" , iocp->name, (int )fwlen)); -dctlprintk (iocp,printk (MYIOC_s_DEBUG_FMT"DbG: kfwdl.ioc = %04xh\n" , - iocp->name, ioc)); dlmsg = (FWDownload_t *) mf; ptsge = (FWDownloadTCSGE_t *) &dlmsg->SGL;
@@ -1238,13 +1221,11 @@ kfree_sgl(MptSge_t *sgl, dma_addr_t sgl_* -ENODEV if no such device/adapter */ static int -mptctl_getiocinfo (unsigned long arg,unsigned int data_size) +mptctl_getiocinfo (MPT_ADAPTER *ioc,unsigned long arg,unsigned int data_size) {struct mpt_ioctl_iocinfo __user *uarg = (void __user *) arg;struct mpt_ioctl_iocinfo *karg; -MPT_ADAPTER *ioc;struct pci_dev *pdev; -int iocnum;unsigned int port;int cim_rev;struct scsi_device *sdev;
@@ -1272,14 +1253,6 @@ mptctl_getiocinfo (unsigned long arg, unreturn PTR_ERR (karg); } -if (((iocnum =mpt_verify_adapter (karg->hdr.iocnum, &ioc)) <0 ) || - (ioc ==NULL )) { - printk(KERN_DEBUG MYNAM "%s::mptctl_getiocinfo() @%d - ioc%d not found!\n", - __FILE__, __LINE__, iocnum); -kfree (karg); -return -ENODEV ; - } -/* Verify the data transfer size is correct. */ if (karg->hdr.maxDataSize != data_size) { printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_getiocinfo - "
@@ -1385,15 +1358,13 @@ mptctl_getiocinfo (unsigned long arg, un* -ENODEV if no such device/adapter */ static int -mptctl_gettargetinfo (unsigned long arg) +mptctl_gettargetinfo (MPT_ADAPTER *ioc,unsigned long arg) {struct mpt_ioctl_targetinfo __user *uarg = (void __user *) arg;struct mpt_ioctl_targetinfo karg; -MPT_ADAPTER *ioc;VirtDevice *vdevice;char *pmem;int *pdata; -int iocnum;int numDevices =0 ;int lun;int maxWordsLeft;
@@ -1408,13 +1379,6 @@ mptctl_gettargetinfo (unsigned long arg)return -EFAULT ; } -if (((iocnum =mpt_verify_adapter (karg.hdr.iocnum, &ioc)) <0 ) || - (ioc ==NULL )) { - printk(KERN_DEBUG MYNAM "%s::mptctl_gettargetinfo() @%d - ioc%d not found!\n", - __FILE__, __LINE__, iocnum); -return -ENODEV ; - } -dctlprintk (ioc,printk (MYIOC_s_DEBUG_FMT"mptctl_gettargetinfo called.\n" , ioc->name));/* Get the port number and set the maximum number of bytes
@@ -1510,12 +1474,10 @@ mptctl_gettargetinfo (unsigned long arg)* -ENODEV if no such device/adapter */ static int -mptctl_readtest (unsigned long arg) +mptctl_readtest (MPT_ADAPTER *ioc,unsigned long arg) {struct mpt_ioctl_test __user *uarg = (void __user *) arg;struct mpt_ioctl_test karg; -MPT_ADAPTER *ioc; -int iocnum;if (copy_from_user (&karg, uarg,sizeof (struct mpt_ioctl_test ))) { printk(KERN_ERR MYNAM "%s@%d::mptctl_readtest - "
@@ -1524,13 +1486,6 @@ mptctl_readtest (unsigned long arg)return -EFAULT ; } -if (((iocnum =mpt_verify_adapter (karg.hdr.iocnum, &ioc)) <0 ) || - (ioc ==NULL )) { - printk(KERN_DEBUG MYNAM "%s::mptctl_readtest() @%d - ioc%d not found!\n", - __FILE__, __LINE__, iocnum); -return -ENODEV ; - } -dctlprintk (ioc,printk (MYIOC_s_DEBUG_FMT"mptctl_readtest called.\n" , ioc->name));/* Fill in the data and return the structure to the calling
@@ -1571,12 +1526,10 @@ mptctl_readtest (unsigned long arg)* -ENODEV if no such device/adapter */ static int -mptctl_eventquery (unsigned long arg) +mptctl_eventquery (MPT_ADAPTER *ioc,unsigned long arg) {struct mpt_ioctl_eventquery __user *uarg = (void __user *) arg;struct mpt_ioctl_eventquery karg; -MPT_ADAPTER *ioc; -int iocnum;if (copy_from_user (&karg, uarg,sizeof (struct mpt_ioctl_eventquery ))) { printk(KERN_ERR MYNAM "%s@%d::mptctl_eventquery - "
@@ -1585,13 +1538,6 @@ mptctl_eventquery (unsigned long arg)return -EFAULT ; } -if (((iocnum =mpt_verify_adapter (karg.hdr.iocnum, &ioc)) <0 ) || - (ioc ==NULL )) { - printk(KERN_DEBUG MYNAM "%s::mptctl_eventquery() @%d - ioc%d not found!\n", - __FILE__, __LINE__, iocnum); -return -ENODEV ; - } -dctlprintk (ioc,printk (MYIOC_s_DEBUG_FMT"mptctl_eventquery called.\n" , ioc->name)); karg.eventEntries =MPTCTL_EVENT_LOG_SIZE ;
@@ -1610,12 +1556,10 @@ mptctl_eventquery (unsigned long arg)/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ static int -mptctl_eventenable (unsigned long arg) +mptctl_eventenable (MPT_ADAPTER *ioc,unsigned long arg) {struct mpt_ioctl_eventenable __user *uarg = (void __user *) arg;struct mpt_ioctl_eventenable karg; -MPT_ADAPTER *ioc; -int iocnum;if (copy_from_user (&karg, uarg,sizeof (struct mpt_ioctl_eventenable ))) { printk(KERN_ERR MYNAM "%s@%d::mptctl_eventenable - "
@@ -1624,13 +1568,6 @@ mptctl_eventenable (unsigned long arg)return -EFAULT ; } -if (((iocnum =mpt_verify_adapter (karg.hdr.iocnum, &ioc)) <0 ) || - (ioc ==NULL )) { - printk(KERN_DEBUG MYNAM "%s::mptctl_eventenable() @%d - ioc%d not found!\n", - __FILE__, __LINE__, iocnum); -return -ENODEV ; - } -dctlprintk (ioc,printk (MYIOC_s_DEBUG_FMT"mptctl_eventenable called.\n" , ioc->name));if (ioc->events ==NULL ) {
@@ -1658,12 +1595,10 @@ mptctl_eventenable (unsigned long arg)/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ static int -mptctl_eventreport (unsigned long arg) +mptctl_eventreport (MPT_ADAPTER *ioc,unsigned long arg) {struct mpt_ioctl_eventreport __user *uarg = (void __user *) arg;struct mpt_ioctl_eventreport karg; -MPT_ADAPTER *ioc; -int iocnum;int numBytes, maxEvents, max;if (copy_from_user (&karg, uarg,sizeof (struct mpt_ioctl_eventreport ))) {
@@ -1673,12 +1608,6 @@ mptctl_eventreport (unsigned long arg)return -EFAULT ; } -if (((iocnum =mpt_verify_adapter (karg.hdr.iocnum, &ioc)) <0 ) || - (ioc ==NULL )) { - printk(KERN_DEBUG MYNAM "%s::mptctl_eventreport() @%d - ioc%d not found!\n", - __FILE__, __LINE__, iocnum); -return -ENODEV ; - }dctlprintk (ioc,printk (MYIOC_s_DEBUG_FMT"mptctl_eventreport called.\n" , ioc->name));
@@ -1712,12 +1641,10 @@ mptctl_eventreport (unsigned long arg)/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ static int -mptctl_replace_fw (unsigned long arg) +mptctl_replace_fw (MPT_ADAPTER *ioc,unsigned long arg) {struct mpt_ioctl_replace_fw __user *uarg = (void __user *) arg;struct mpt_ioctl_replace_fw karg; -MPT_ADAPTER *ioc; -int iocnum;int newFwSize;if (copy_from_user (&karg, uarg,sizeof (struct mpt_ioctl_replace_fw ))) {
@@ -1727,13 +1654,6 @@ mptctl_replace_fw (unsigned long arg)return -EFAULT ; } -if (((iocnum =mpt_verify_adapter (karg.hdr.iocnum, &ioc)) <0 ) || - (ioc ==NULL )) { - printk(KERN_DEBUG MYNAM "%s::mptctl_replace_fw() @%d - ioc%d not found!\n", - __FILE__, __LINE__, iocnum); -return -ENODEV ; - } -dctlprintk (ioc,printk (MYIOC_s_DEBUG_FMT"mptctl_replace_fw called.\n" , ioc->name));/* If caching FW, Free the old FW image
@@ -1780,12 +1700,10 @@ mptctl_replace_fw (unsigned long arg)* -ENOMEM if memory allocation error */ static int -mptctl_mpt_command (unsigned long arg) +mptctl_mpt_command (MPT_ADAPTER *ioc,unsigned long arg) {struct mpt_ioctl_command __user *uarg = (void __user *) arg;struct mpt_ioctl_command karg; -MPT_ADAPTER *ioc; -int iocnum;int rc;
@@ -1796,14 +1714,7 @@ mptctl_mpt_command (unsigned long arg)return -EFAULT ; } -if (((iocnum =mpt_verify_adapter (karg.hdr.iocnum, &ioc)) <0 ) || - (ioc ==NULL )) { - printk(KERN_DEBUG MYNAM "%s::mptctl_mpt_command() @%d - ioc%d not found!\n", - __FILE__, __LINE__, iocnum); -return -ENODEV ; - } - - rc =mptctl_do_mpt_command (karg, &uarg->MF); + rc =mptctl_do_mpt_command (ioc, karg, &uarg->MF);return rc; }
@@ -1821,9 +1732,8 @@ mptctl_mpt_command (unsigned long arg)* -EPERM if SCSI I/O and target is untagged */ static int -mptctl_do_mpt_command (struct mpt_ioctl_command karg,void __user *mfPtr) +mptctl_do_mpt_command (MPT_ADAPTER *ioc,struct mpt_ioctl_command karg,void __user *mfPtr) { -MPT_ADAPTER *ioc;MPT_FRAME_HDR *mf =NULL ;MPIHeader_t *hdr;char *psge;
@@ -1832,7 +1742,7 @@ mptctl_do_mpt_command (struct mpt_ioctl_dma_addr_t dma_addr_in;dma_addr_t dma_addr_out;int sgSize =0 ;/* Num SG elements */ -int iocnum, flagsLength; +int flagsLength;int sz, rc =0 ;int msgContext;u16 req_idx;
@@ -1847,13 +1757,6 @@ mptctl_do_mpt_command (struct mpt_ioctl_ bufIn.kptr = bufOut.kptr =NULL ; bufIn.len = bufOut.len =0 ; -if (((iocnum =mpt_verify_adapter (karg.hdr.iocnum, &ioc)) <0 ) || - (ioc ==NULL )) { - printk(KERN_DEBUG MYNAM "%s::mptctl_do_mpt_command() @%d - ioc%d not found!\n", - __FILE__, __LINE__, iocnum); -return -ENODEV ; - } -spin_lock_irqsave (&ioc->taskmgmt_lock, flags);if (ioc->ioc_reset_in_progress) {spin_unlock_irqrestore (&ioc->taskmgmt_lock, flags);
@@ -2418,17 +2321,15 @@ done_free_mem:* -ENOMEM if memory allocation error */ static int -mptctl_hp_hostinfo (unsigned long arg,unsigned int data_size) +mptctl_hp_hostinfo (MPT_ADAPTER *ioc,unsigned long arg,unsigned int data_size) {hp_host_info_t __user *uarg = (void __user *) arg; -MPT_ADAPTER *ioc;struct pci_dev *pdev;char *pbuf=NULL ;dma_addr_t buf_dma;hp_host_info_t karg;CONFIGPARMS cfg;ConfigPageHeader_t hdr; -int iocnum;int rc, cim_rev;ToolboxIstwiReadWriteRequest_t *IstwiRWRequest;MPT_FRAME_HDR *mf =NULL ;
@@ -2452,12 +2353,6 @@ mptctl_hp_hostinfo(unsigned long arg, unreturn -EFAULT ; } -if (((iocnum =mpt_verify_adapter (karg.hdr.iocnum, &ioc)) <0 ) || - (ioc ==NULL )) { - printk(KERN_DEBUG MYNAM "%s::mptctl_hp_hostinfo() @%d - ioc%d not found!\n", - __FILE__, __LINE__, iocnum); -return -ENODEV ; - }dctlprintk (ioc,printk (MYIOC_s_DEBUG_FMT": mptctl_hp_hostinfo called.\n" , ioc->name));
@@ -2670,15 +2565,13 @@ retry_wait:* -ENOMEM if memory allocation error */ static int -mptctl_hp_targetinfo (unsigned long arg) +mptctl_hp_targetinfo (MPT_ADAPTER *ioc,unsigned long arg) {hp_target_info_t __user *uarg = (void __user *) arg;SCSIDevicePage0_t *pg0_alloc;SCSIDevicePage3_t *pg3_alloc; -MPT_ADAPTER *ioc;MPT_SCSI_HOST *hd =NULL ;hp_target_info_t karg; -int iocnum;int data_sz;dma_addr_t page_dma;CONFIGPARMS cfg;
@@ -2692,12 +2585,6 @@ mptctl_hp_targetinfo(unsigned long arg)return -EFAULT ; } -if (((iocnum =mpt_verify_adapter (karg.hdr.iocnum, &ioc)) <0 ) || - (ioc ==NULL )) { - printk(KERN_DEBUG MYNAM "%s::mptctl_hp_targetinfo() @%d - ioc%d not found!\n", - __FILE__, __LINE__, iocnum); -return -ENODEV ; - }if (karg.hdr.id >=MPT_MAX_FC_DEVICES )return -EINVAL ; dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_hp_targetinfo called.\n",
@@ -2865,7 +2752,7 @@ compat_mptfwxfer_ioctl(struct file *filp kfw.fwlen = kfw32.fwlen; kfw.bufp =compat_ptr (kfw32.bufp); - ret =mptctl_do_fw_download (kfw.iocnum, kfw.bufp, kfw.fwlen); + ret =mptctl_do_fw_download (iocp, kfw.bufp, kfw.fwlen);mutex_unlock (&iocp->ioctl_cmds.mutex);
@@ -2919,7 +2806,7 @@ compat_mpt_command(struct file *filp, un/* Pass new structure to do_mpt_command */ - ret =mptctl_do_mpt_command (karg, &uarg->MF); + ret =mptctl_do_mpt_command (iocp, karg, &uarg->MF);mutex_unlock (&iocp->ioctl_cmds.mutex);
Greg Kroah-Hartman
maintainerPATCH 20/65 ptrace: reintroduce usage of subjective credentials in ptrace_has_cap()
In reply to Greg Kroah-HartmanFrom: Christian Brauner <[email protected]>
commit 6b3ad6649a4c75504edeba242d3fd36b3096a57f upstream.
Commit 69f594a38967 ("ptrace: do not audit capability check when outputing /proc/pid/stat") introduced the ability to opt out of audit messages for accesses to various proc files since they are not violations of policy. While doing so it somehow switched the check from ns_capable() to has_ns_capability{_noaudit}(). That means it switched from checking the subjective credentials of the task to using the objective credentials. This is wrong since. ptrace_has_cap() is currently only used in ptrace_may_access() And is used to check whether the calling task (subject) has the CAP_SYS_PTRACE capability in the provided user namespace to operate on the target task (object). According to the cred.h comments this would mean the subjective credentials of the calling task need to be used.
This switches ptrace_has_cap() to use security_capable(). Because we only call ptrace_has_cap() in ptrace_may_access() and in there we already have a stable reference to the calling task's creds under rcu_read_lock() there's no need to go through another series of dereferences and rcu locking done
in ns_capable{_noaudit}().
As one example where this might be particularly problematic, Jann pointed out that in combination with the upcoming IORING_OP_OPENAT feature, this bug might allow unprivileged users to bypass the capability checks while asynchronously opening files like /proc/*/mem, because the capability checks for this would be performed against kernel credentials.
To illustrate on the former point about this being exploitable: When io_uring creates a new context it records the subjective credentials of the caller. Later on, when it starts to do work it creates a kernel thread and registers a callback. The callback runs with kernel creds for ktask->real_cred and ktask->cred. To prevent this from becoming a full-blown 0-day io_uring will call override_cred() and override ktask->cred with the subjective credentials of the creator of the io_uring instance. With ptrace_has_cap() currently looking at ktask->real_cred this override will be ineffective and the caller will be able to open arbitray proc files as mentioned above.
Luckily, this is currently not exploitable but will turn into a 0-day once IORING_OP_OPENAT{2} land in v5.6. Fix it now!
--- kernel/ptrace.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-)
kernel/ptrace.c +10 -5
@@ -258,12 +258,17 @@ static int ptrace_check_attach(struct tareturn ret; } -static int ptrace_has_cap (struct user_namespace *ns,unsigned int mode) +static bool ptrace_has_cap (const struct cred *cred,struct user_namespace *ns, +unsigned int mode) { +int ret; +if (mode &PTRACE_MODE_NOAUDIT ) -return has_ns_capability_noaudit (current, ns,CAP_SYS_PTRACE ); + ret =security_capable (cred, ns,CAP_SYS_PTRACE );else -return has_ns_capability (current, ns,CAP_SYS_PTRACE ); + ret =security_capable (cred, ns,CAP_SYS_PTRACE ); + +return ret ==0 ; }/* Returns 0 on success, -errno on denial. */
@@ -315,7 +320,7 @@ static int __ptrace_may_access(struct ta gid_eq(caller_gid, tcred->sgid) && gid_eq(caller_gid, tcred->gid)) goto ok; -if (ptrace_has_cap (tcred->user_ns, mode)) +if (ptrace_has_cap (cred, tcred->user_ns, mode)) goto ok;rcu_read_unlock ();return -EPERM ;
@@ -334,7 +339,7 @@ ok: mm = task->mm;if (mm && ((get_dumpable (mm) !=SUID_DUMP_USER ) && - !ptrace_has_cap (mm->user_ns, mode))) + !ptrace_has_cap (cred, mm->user_ns, mode)))return -EPERM ;return security_ptrace_access_check (task, mode);
Re: [PATCH 4.14 20/65] ptrace: reintroduce usage of subjective credentials in ptrace_has_cap()
Quoted 64 lines · Greg Kroah-Hartman
From: Christian Brauner <[email protected]>
commit
6b3ad6649a4c75504edeba242d3fd36b3096a57fupstream.Commit
69f594a38967("ptrace: do not audit capability check when outputing/proc/pid/stat") introduced the ability to opt out of audit messages for accesses to various proc files since they are not violations of policy. While doing so it somehow switched the check fromns_capable()to has_ns_capability{_noaudit}(). That means it switched from checking the subjective credentials of the task to using the objective credentials. This is wrong since.ptrace_has_cap()is currently only used inptrace_may_access()And is used to check whether the calling task (subject) has theCAP_SYS_PTRACEcapability in the provided user namespace to operate on the target task (object). According to thecred.hcomments this would mean the subjective credentials of the calling task need to be used.
This switchesptrace_has_cap()to usesecurity_capable(). Because we only callptrace_has_cap()inptrace_may_access()and in there we already have a stable reference to the calling task's creds underrcu_read_lock()there's no need to go through another series of dereferences and rcu locking done
in ns_capable{_noaudit}().As one example where this might be particularly problematic, Jann pointed out that in combination with the upcoming
IORING_OP_OPENATfeature, this bug might allow unprivileged users to bypass the capability checks while asynchronously opening files like/proc/*/mem, because the capability checks for this would be performed against kernel credentials.To illustrate on the former point about this being exploitable: When
io_uringcreates a new context it records the subjective credentials of the caller. Later on, when it starts to do work it creates a kernel thread and registers a callback. The callback runs with kernel creds forktask->real_credandktask->cred. To prevent this from becoming a full-blown 0-dayio_uringwill calloverride_cred()and overridektask->credwith the subjective credentials of the creator of theio_uringinstance. Withptrace_has_cap()currently looking atktask->real_credthis override will be ineffective and the caller will be able to open arbitray proc files as mentioned above.
Luckily, this is currently not exploitable but will turn into a 0-day once IORING_OP_OPENAT{2} land in v5.6. Fix it now!Cc Oleg Nesterov <[email protected]>Cc Eric Paris <[email protected]>Reviewed-by Kees Cook <[email protected]>Reviewed-by Serge Hallyn <[email protected]>Reviewed-by Jann Horn <[email protected]>Fixes 69f594a38967 ("ptrace: do not audit capability check when outputing /proc/pid/stat")Signed-off-by Christian Brauner <[email protected]>Signed-off-by Greg Kroah-Hartman <[email protected]>--- kernel/ptrace.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-)kernel/ptrace.c +2
-1@@ -258,12 +258,17 @@ static int ptrace_check_attach(struct tareturn ret; } -static int ptrace_has_cap (struct user_namespace *ns,unsigned int mode) +static bool ptrace_has_cap (const struct cred *cred,struct user_namespace *ns, +unsigned int mode) {
kernel/ptrace.c static int ptrace_check_attach(struct ta · line 271
Quoted 10 lines
kernel/ptrace.c +6
-2+int ret; +if (mode &PTRACE_MODE_NOAUDIT ) -return has_ns_capability_noaudit (current, ns,CAP_SYS_PTRACE ); + ret =security_capable (cred, ns,CAP_SYS_PTRACE );else -return has_ns_capability (current, ns,CAP_SYS_PTRACE ); + ret =security_capable (cred, ns,CAP_SYS_PTRACE ); + +return ret ==0 ;
This results in
if (condition) do_something; else do_the_same;
Is that really correct ? The upstream patch calls security_capable() with additional CAP_OPT_NOAUDIT vs. CAP_OPT_NONE parameter, which does make sense. But I don't really see the benefit of the change above.
Guenter
Greg Kroah-Hartman
maintainerRe: [PATCH 4.14 20/65] ptrace: reintroduce usage of subjective credentials in ptrace_has_cap()
Quoted 77 lines · Guenter Roeck
Quoted 64 lines · Greg Kroah-Hartman
From: Christian Brauner <[email protected]>
commit
6b3ad6649a4c75504edeba242d3fd36b3096a57fupstream.Commit
69f594a38967("ptrace: do not audit capability check when outputing/proc/pid/stat") introduced the ability to opt out of audit messages for accesses to various proc files since they are not violations of policy. While doing so it somehow switched the check fromns_capable()to has_ns_capability{_noaudit}(). That means it switched from checking the subjective credentials of the task to using the objective credentials. This is wrong since.ptrace_has_cap()is currently only used inptrace_may_access()And is used to check whether the calling task (subject) has theCAP_SYS_PTRACEcapability in the provided user namespace to operate on the target task (object). According to thecred.hcomments this would mean the subjective credentials of the calling task need to be used.
This switchesptrace_has_cap()to usesecurity_capable(). Because we only callptrace_has_cap()inptrace_may_access()and in there we already have a stable reference to the calling task's creds underrcu_read_lock()there's no need to go through another series of dereferences and rcu locking done
in ns_capable{_noaudit}().As one example where this might be particularly problematic, Jann pointed out that in combination with the upcoming
IORING_OP_OPENATfeature, this bug might allow unprivileged users to bypass the capability checks while asynchronously opening files like/proc/*/mem, because the capability checks for this would be performed against kernel credentials.To illustrate on the former point about this being exploitable: When
io_uringcreates a new context it records the subjective credentials of the caller. Later on, when it starts to do work it creates a kernel thread and registers a callback. The callback runs with kernel creds forktask->real_credandktask->cred. To prevent this from becoming a full-blown 0-dayio_uringwill calloverride_cred()and overridektask->credwith the subjective credentials of the creator of theio_uringinstance. Withptrace_has_cap()currently looking atktask->real_credthis override will be ineffective and the caller will be able to open arbitray proc files as mentioned above.
Luckily, this is currently not exploitable but will turn into a 0-day once IORING_OP_OPENAT{2} land in v5.6. Fix it now!Cc Oleg Nesterov <[email protected]>Cc Eric Paris <[email protected]>Reviewed-by Kees Cook <[email protected]>Reviewed-by Serge Hallyn <[email protected]>Reviewed-by Jann Horn <[email protected]>Fixes 69f594a38967 ("ptrace: do not audit capability check when outputing /proc/pid/stat")Signed-off-by Christian Brauner <[email protected]>Signed-off-by Greg Kroah-Hartman <[email protected]>--- kernel/ptrace.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-)kernel/ptrace.c +2
-1@@ -258,12 +258,17 @@ static int ptrace_check_attach(struct tareturn ret; } -static int ptrace_has_cap (struct user_namespace *ns,unsigned int mode) +static bool ptrace_has_cap (const struct cred *cred,struct user_namespace *ns, +unsigned int mode) {kernel/ptrace.c static int ptrace_check_attach(struct ta · line 271
Quoted 10 lines
kernel/ptrace.c +6
-2+int ret; +if (mode &PTRACE_MODE_NOAUDIT ) -return has_ns_capability_noaudit (current, ns,CAP_SYS_PTRACE ); + ret =security_capable (cred, ns,CAP_SYS_PTRACE );else -return has_ns_capability (current, ns,CAP_SYS_PTRACE ); + ret =security_capable (cred, ns,CAP_SYS_PTRACE ); + +return ret ==0 ;This results in
Quoted 8 lines
if (condition) do_something; else do_the_same;Is that really correct ? The upstream patch calls
security_capable()with additionalCAP_OPT_NOAUDITvs.CAP_OPT_NONEparameter, which does make sense. But I don't really see the benefit of the change above.
Yeah, this is odd, and differs from the original version I applied to the staging queue.
Sasha, you made this change to the patch, I'm guessing to make it build properly in 4.14? Should I just have dropped it from there instead?
thanks,
greg k-h
Ben Hutchings
Reviewed-by Kees CookRe: [PATCH 4.14 20/65] ptrace: reintroduce usage of subjective credentials in ptrace_has_cap()
Quoted 5 lines · Greg Kroah-Hartman
Quoted 4 lines · Guenter Roeck
Quoted 3 lines · Greg Kroah-Hartman
From: Christian Brauner <[email protected]>
commit
6b3ad6649a4c75504edeba242d3fd36b3096a57fupstream.
[...]
Quoted 31 lines
Quoted 22 lines
Quoted 10 lines
kernel/ptrace.c +2
-1@@ -258,12 +258,17 @@ static int ptrace_check_attach(struct tareturn ret; } -static int ptrace_has_cap (struct user_namespace *ns,unsigned int mode) +static bool ptrace_has_cap (const struct cred *cred,struct user_namespace *ns, +unsigned int mode) {kernel/ptrace.c static int ptrace_check_attach(struct ta · line 271
Quoted 10 lines
kernel/ptrace.c +6
-2+int ret; +if (mode &PTRACE_MODE_NOAUDIT ) -return has_ns_capability_noaudit (current, ns,CAP_SYS_PTRACE ); + ret =security_capable (cred, ns,CAP_SYS_PTRACE );else -return has_ns_capability (current, ns,CAP_SYS_PTRACE ); + ret =security_capable (cred, ns,CAP_SYS_PTRACE ); + +return ret ==0 ;This results in
Quoted 8 lines
if (condition) do_something; else do_the_same;Is that really correct ? The upstream patch calls
security_capable()with additionalCAP_OPT_NOAUDITvs.CAP_OPT_NONEparameter, which does make sense. But I don't really see the benefit of the change above.
Quoted 5 lines
Yeah, this is odd, and differs from the original version I applied to the staging queue.
Sasha, you made this change to the patch, I'm guessing to make it build properly in 4.14? Should I just have dropped it from there instead?
To make this work properly, you would need to pick these for 4.14 as well:
11c92f144bf3 apparmor: fix mediation of prlimit
(to avoid a conflict, but it's an important fix in its own right)
c1a85a00ea66 LSM: generalize flag passing to security_capable
I'm attaching a backport of the second commit.
Ben.
Signature · 3 lines
Ben Hutchings
Klipstein's 4th Law of Prototyping and Production:
A fail-safe circuit will destroy others.From 7f3ab5da5b288244374b8ac53165a278b2399963 Mon Sep 17 00:00:00 2001
From: Micah Morton <[email protected]>
Date: Mon, 7 Jan 2019 16:10:53 -0800
Subject: [PATCH] LSM: generalize flag passing to security_capable
This patch provides a general mechanism for passing flags to the security_capable LSM hook. It replaces the specific 'audit' flag that is used to tell security_capable whether it should log an audit message for the given capability check. The reason for generalizing this flag passing is so we can add an additional flag that signifies whether security_capable is being called by a setid syscall (which is needed by the proposed SafeSetID LSM).
[bwh: Backported to 4.14:
- Add the extra argument to security_capable() in ptrace_has_cap()
- Adjust context]
--- include/linux/lsm_hooks.h | 8 +++++--- include/linux/security.h | 28 +++++++++++++------------- kernel/capability.c | 22 +++++++++++--------- kernel/seccomp.c | 4 ++-- security/apparmor/capability.c | 14 ++++++------- security/apparmor/include/capability.h | 2 +- security/apparmor/ipc.c | 3 ++- security/apparmor/lsm.c | 4 ++-- security/apparmor/resource.c | 2 +- security/commoncap.c | 17 ++++++++-------- security/security.c | 14 +++++-------- security/selinux/hooks.c | 18 ++++++++--------- security/smack/smack_access.c | 2 +- 13 files changed, 71 insertions(+), 67 deletions(-)
include/linux/lsm_hooks.h +5 -3
@@ -1229,7 +1229,7 @@* @cred contains the credentials to use. * @ns contains the user namespace we want the capability in * @cap contains the capability <include/linux/capability.h>. -* @audit contains whether to write an audit message or not +* @opts contains options for the capable check <include/linux/security.h> * Return 0 if the capability is granted for @tsk. * @syslog: * Check permission before accessing the kernel message ring or changing
@@ -1371,8 +1371,10 @@ union security_list_options {const kernel_cap_t *effective, const kernel_cap_t *inheritable, const kernel_cap_t *permitted); -int (*capable)(const struct cred *cred,struct user_namespace *ns, -int cap,int audit); +int (*capable)(const struct cred *cred, +struct user_namespace *ns, +int cap, +unsigned int opts);int (*quotactl)(int cmds,int type,int id,struct super_block *sb);int (*quota_on)(struct dentry *dentry);int (*syslog)(int type);
include/linux/security.h +14 -14
@@ -57,9 +57,12 @@ struct xattr;struct xfrm_sec_ctx ;struct mm_struct ; +/* Default (no) options for the capable function */ +#define CAP_OPT_NONE 0x0/* If capable should audit the security request */ -#define SECURITY_CAP_NOAUDIT 0 -#define SECURITY_CAP_AUDIT 1 +#define CAP_OPT_NOAUDIT BIT(1) +/* If capable is being called by a setid function */ +#define CAP_OPT_INSETID BIT(2)/* LSM Agnostic defines for sb_set_mnt_opts */ #define SECURITY_LSM_NATIVE_LABELS 1
@@ -75,7 +78,7 @@ enum lsm_event {/* These functions are in security/commoncap.c */ extern int cap_capable (const struct cred *cred,struct user_namespace *ns, -int cap,int audit); +int cap,unsigned int opts);extern int cap_settime (const struct timespec64 *ts,const struct timezone *tz);extern int cap_ptrace_access_check (struct task_struct *child,unsigned int mode);extern int cap_ptrace_traceme (struct task_struct *parent);
@@ -214,10 +217,10 @@ int security_capset(struct cred *new, const struct cred *old,const kernel_cap_t *effective, const kernel_cap_t *inheritable, const kernel_cap_t *permitted); -int security_capable (const struct cred *cred,struct user_namespace *ns, -int cap); -int security_capable_noaudit (const struct cred *cred,struct user_namespace *ns, -int cap); +int security_capable (const struct cred *cred, +struct user_namespace *ns, +int cap, +unsigned int opts);int security_quotactl (int cmds,int type,int id,struct super_block *sb);int security_quota_on (struct dentry *dentry);int security_syslog (int type);
@@ -477,14 +480,11 @@ static inline int security_capset(struct cred *new, }static inline int security_capable (const struct cred *cred, -struct user_namespace *ns,int cap) +struct user_namespace *ns, +int cap, +unsigned int opts) { -return cap_capable (cred, ns, cap,SECURITY_CAP_AUDIT ); -} - -static inline int security_capable_noaudit (const struct cred *cred, -struct user_namespace *ns,int cap) { -return cap_capable (cred, ns, cap,SECURITY_CAP_NOAUDIT ); +return cap_capable (cred, ns, cap, opts); } static inline int security_quotactl(int cmds, int type, int id,
kernel/capability.c +13 -9
@@ -299,7 +299,7 @@ bool has_ns_capability(struct task_struct *t,int ret;rcu_read_lock (); - ret =security_capable (__task_cred (t), ns, cap); + ret =security_capable (__task_cred (t), ns, cap,CAP_OPT_NONE );rcu_read_unlock ();return (ret ==0 );
@@ -340,7 +340,7 @@ bool has_ns_capability_noaudit(struct task_struct *t,int ret;rcu_read_lock (); - ret =security_capable_noaudit (__task_cred (t), ns, cap); + ret =security_capable (__task_cred (t), ns, cap,CAP_OPT_NOAUDIT );rcu_read_unlock ();return (ret ==0 );
@@ -363,7 +363,9 @@ bool has_capability_noaudit(struct task_struct *t, int cap)return has_ns_capability_noaudit (t, &init_user_ns, cap); } -static bool ns_capable_common (struct user_namespace *ns,int cap,bool audit) +static bool ns_capable_common (struct user_namespace *ns, +int cap, +unsigned int opts) {int capable;
@@ -372,8 +374,7 @@ static bool ns_capable_common(struct user_namespace *ns, int cap, bool audit)BUG (); } - capable = audit ?security_capable (current_cred (), ns, cap) : -security_capable_noaudit (current_cred (), ns, cap); + capable =security_capable (current_cred (), ns, cap, opts);if (capable ==0 ) { current->flags |=PF_SUPERPRIV ;return true;
@@ -394,7 +395,7 @@ static bool ns_capable_common(struct user_namespace *ns, int cap, bool audit)*/ bool ns_capable (struct user_namespace *ns,int cap) { -return ns_capable_common (ns, cap, true); +return ns_capable_common (ns, cap,CAP_OPT_NONE ); }EXPORT_SYMBOL (ns_capable);
@@ -412,7 +413,7 @@ EXPORT_SYMBOL(ns_capable);*/ bool ns_capable_noaudit (struct user_namespace *ns,int cap) { -return ns_capable_common (ns, cap, false); +return ns_capable_common (ns, cap,CAP_OPT_NOAUDIT ); }EXPORT_SYMBOL (ns_capable_noaudit);
@@ -448,10 +449,11 @@ EXPORT_SYMBOL(capable);bool file_ns_capable (const struct file *file,struct user_namespace *ns,int cap) { +if (WARN_ON_ONCE (!cap_valid (cap)))return false; -if (security_capable (file->f_cred, ns, cap) ==0 ) +if (security_capable (file->f_cred, ns, cap,CAP_OPT_NONE ) ==0 )return true;return false;
@@ -500,10 +502,12 @@ bool ptracer_capable(struct task_struct *tsk, struct user_namespace *ns) {int ret =0 ;/* An absent tracer adds no restrictions */ const struct cred *cred; +rcu_read_lock (); cred =rcu_dereference (tsk->ptracer_cred);if (cred) - ret =security_capable_noaudit (cred, ns,CAP_SYS_PTRACE ); + ret =security_capable (cred, ns,CAP_SYS_PTRACE , +CAP_OPT_NOAUDIT );rcu_read_unlock ();return (ret ==0 ); }
kernel/seccomp.c +2 -2
@@ -383,8 +383,8 @@ static struct seccomp_filter *seccomp_prepare_filter(struct sock_fprog *fprog)* behavior of privileged children. */ if (!task_no_new_privs (current) && -security_capable_noaudit (current_cred (),current_user_ns (), -CAP_SYS_ADMIN ) !=0 ) +security_capable (current_cred (),current_user_ns (), +CAP_SYS_ADMIN ,CAP_OPT_NOAUDIT ) !=0 )return ERR_PTR (-EACCES );/* Allocate a new seccomp_filter */
security/apparmor/capability.c +7 -7
@@ -110,13 +110,13 @@ static int audit_caps(struct common_audit_data *sa, struct aa_profile *profile,* profile_capable - test if profile allows use of capability @cap * @profile: profile being enforced (NOT NULL, NOT unconfined) * @cap: capability to test if allowed -* @audit: whether an audit record should be generated +* @opts: CAP_OPT_NOAUDIT bit determines whether audit record is generated * @sa: audit data (MAY BE NULL indicating no auditing) * * Returns: 0 if allowed else -EPERM */ -static int profile_capable (struct aa_profile *profile,int cap,int audit, -struct common_audit_data *sa) +static int profile_capable (struct aa_profile *profile,int cap, +unsigned int opts,struct common_audit_data *sa) {int error;
@@ -126,7 +126,7 @@ static int profile_capable(struct aa_profile *profile, int cap, int audit,else error = -EPERM ; -if (audit ==SECURITY_CAP_NOAUDIT ) { +if (opts &CAP_OPT_NOAUDIT ) {if (!COMPLAIN_MODE (profile))return error;/* audit the cap request in complain mode but note that it
@@ -142,13 +142,13 @@ static int profile_capable(struct aa_profile *profile, int cap, int audit,* aa_capable - test permission to use capability * @label: label being tested for capability (NOT NULL) * @cap: capability to be tested -* @audit: whether an audit record should be generated +* @opts: CAP_OPT_NOAUDIT bit determines whether audit record is generated * * Look up capability in profile capability set. * * Returns: 0 on success, or else an error code. */ -int aa_capable (struct aa_label *label,int cap,int audit) +int aa_capable (struct aa_label *label,int cap,unsigned int opts) {struct aa_profile *profile;int error =0 ;
@@ -156,7 +156,7 @@ int aa_capable(struct aa_label *label, int cap, int audit) sa.u.cap = cap; error =fn_for_each_confined (label, profile, -profile_capable (profile, cap, audit, &sa)); +profile_capable (profile, cap, opts, &sa));return error; }
security/apparmor/include/capability.h +1 -1
@@ -40,7 +40,7 @@ struct aa_caps {extern struct aa_sfs_entry aa_sfs_entry_caps[]; -int aa_capable (struct aa_label *label,int cap,int audit); +int aa_capable (struct aa_label *label,int cap,unsigned int opts);static inline void aa_free_cap_rules (struct aa_caps *caps) {
security/apparmor/ipc.c +2 -1
@@ -107,7 +107,8 @@ static int profile_tracer_perm(struct aa_profile *tracer,aad (sa)->label = &tracer->label;aad (sa)->peer = tracee;aad (sa)->request =0 ; -aad (sa)->error =aa_capable (&tracer->label,CAP_SYS_PTRACE ,1 ); +aad (sa)->error =aa_capable (&tracer->label,CAP_SYS_PTRACE , +CAP_OPT_NONE );return aa_audit (AUDIT_APPARMOR_AUTO , tracer, sa, audit_ptrace_cb); }
security/apparmor/lsm.c +2 -2
@@ -167,14 +167,14 @@ static int apparmor_capget(struct task_struct *target, kernel_cap_t *effective, }static int apparmor_capable (const struct cred *cred,struct user_namespace *ns, -int cap,int audit) +int cap,unsigned int opts) {struct aa_label *label;int error =0 ; label =aa_get_newest_cred_label (cred);if (!unconfined (label)) - error =aa_capable (label, cap, audit); + error =aa_capable (label, cap, opts);aa_put_label (label);return error;
security/apparmor/resource.c +1 -1
@@ -124,7 +124,7 @@ int aa_task_setrlimit(struct aa_label *label, struct task_struct *task,*/ if (label != peer && -aa_capable (label,CAP_SYS_RESOURCE ,SECURITY_CAP_NOAUDIT ) !=0 ) +aa_capable (label,CAP_SYS_RESOURCE ,CAP_OPT_NOAUDIT ) !=0 ) error = fn_for_each(label, profile, audit_resource(profile, resource, new_rlim->rlim_max, peer,
security/commoncap.c +9 -8
@@ -69,7 +69,7 @@ static void warn_setuid_and_fcaps_mixed(const char *fname)* kernel's capable() and has_capability() returns 1 for this case. */ int cap_capable (const struct cred *cred,struct user_namespace *targ_ns, -int cap,int audit) +int cap,unsigned int opts) {struct user_namespace *ns = targ_ns;
@@ -223,12 +223,11 @@ int cap_capget(struct task_struct *target, kernel_cap_t *effective,*/ static inline int cap_inh_is_capped (void ) { -/* they are so limited unless the current task has the CAP_SETPCAP * capability */ if (cap_capable (current_cred (),current_cred ()->user_ns, -CAP_SETPCAP ,SECURITY_CAP_AUDIT ) ==0 ) +CAP_SETPCAP ,CAP_OPT_NONE ) ==0 )return 0 ;return 1 ; }
@@ -1145,8 +1144,9 @@ int cap_task_prctl(int option, unsigned long arg2, unsigned long arg3, || ((old->securebits & SECURE_ALL_LOCKS & ~arg2)) /*[2]*/ || (arg2 & ~(SECURE_ALL_LOCKS |SECURE_ALL_BITS ))/*[3]*/ || (cap_capable (current_cred (), -current_cred ()->user_ns,CAP_SETPCAP , -SECURITY_CAP_AUDIT ) !=0 )/*[4]*/ +current_cred ()->user_ns, +CAP_SETPCAP , +CAP_OPT_NONE ) !=0 )/*[4]*/ /* * [1] no changing of bits that are locked * [2] no unlocking of locks
@@ -1241,9 +1241,10 @@ int cap_vm_enough_memory(struct mm_struct *mm, long pages) {int cap_sys_admin =0 ; -if (cap_capable (current_cred (), &init_user_ns,CAP_SYS_ADMIN , -SECURITY_CAP_NOAUDIT ) ==0 ) +if (cap_capable (current_cred (), &init_user_ns, +CAP_SYS_ADMIN ,CAP_OPT_NOAUDIT ) ==0 ) cap_sys_admin =1 ; +return cap_sys_admin; }
@@ -1262,7 +1263,7 @@ int cap_mmap_addr(unsigned long addr)if (addr < dac_mmap_min_addr) { ret =cap_capable (current_cred (), &init_user_ns,CAP_SYS_RAWIO , -SECURITY_CAP_AUDIT ); +CAP_OPT_NONE );/* set PF_SUPERPRIV if it turns out we allow the low mmap */ if (ret ==0 ) current->flags |=PF_SUPERPRIV ;
security/security.c +5 -9
@@ -273,16 +273,12 @@ int security_capset(struct cred *new, const struct cred *old, effective, inheritable, permitted); } -int security_capable (const struct cred *cred,struct user_namespace *ns, -int cap) +int security_capable (const struct cred *cred, +struct user_namespace *ns, +int cap, +unsigned int opts) { -return call_int_hook (capable,0 , cred, ns, cap,SECURITY_CAP_AUDIT ); -} - -int security_capable_noaudit (const struct cred *cred,struct user_namespace *ns, -int cap) -{ -return call_int_hook (capable,0 , cred, ns, cap,SECURITY_CAP_NOAUDIT ); +return call_int_hook (capable,0 , cred, ns, cap, opts); }int security_quotactl (int cmds,int type,int id,struct super_block *sb)
security/selinux/hooks.c +9 -9
@@ -1738,7 +1738,7 @@ static inline u32 signal_to_av(int sig)/* Check whether a task is allowed to use a capability. */ static int cred_has_capability (const struct cred *cred, -int cap,int audit,bool initns) +int cap,unsigned int opts,bool initns) {struct common_audit_data ad;struct av_decision avd;
@@ -1765,7 +1765,7 @@ static int cred_has_capability(const struct cred *cred, } rc =avc_has_perm_noaudit (sid, sid, sclass, av,0 , &avd); -if (audit ==SECURITY_CAP_AUDIT ) { +if (!(opts &CAP_OPT_NOAUDIT )) {int rc2 =avc_audit (sid, sid, sclass, av, &avd, rc, &ad,0 );if (rc2)return rc2;
@@ -2242,9 +2242,9 @@ static int selinux_capset(struct cred *new, const struct cred *old,*/ static int selinux_capable (const struct cred *cred,struct user_namespace *ns, -int cap,int audit) +int cap,unsigned int opts) { -return cred_has_capability (cred, cap, audit, ns == &init_user_ns); +return cred_has_capability (cred, cap, opts, ns == &init_user_ns); }static int selinux_quotactl (int cmds,int type,int id,struct super_block *sb)
@@ -2315,7 +2315,7 @@ static int selinux_vm_enough_memory(struct mm_struct *mm, long pages)int rc, cap_sys_admin =0 ; rc =cred_has_capability (current_cred (),CAP_SYS_ADMIN , -SECURITY_CAP_NOAUDIT , true); +CAP_OPT_NOAUDIT , true);if (rc ==0 ) cap_sys_admin =1 ;
@@ -3173,11 +3173,11 @@ static int selinux_inode_setotherxattr(struct dentry *dentry, const char *name)static bool has_cap_mac_admin (bool audit) {const struct cred *cred =current_cred (); -int cap_audit = audit ?SECURITY_CAP_AUDIT :SECURITY_CAP_NOAUDIT ; +unsigned int opts = audit ?CAP_OPT_NONE :CAP_OPT_NOAUDIT ; -if (cap_capable (cred, &init_user_ns,CAP_MAC_ADMIN , cap_audit)) +if (cap_capable (cred, &init_user_ns,CAP_MAC_ADMIN , opts))return false; -if (cred_has_capability (cred,CAP_MAC_ADMIN , cap_audit, true)) +if (cred_has_capability (cred,CAP_MAC_ADMIN , opts, true))return false;return true; }
@@ -3556,7 +3556,7 @@ static int selinux_file_ioctl(struct file *file, unsigned int cmd,case KDSKBENT :case KDSKBSENT : error =cred_has_capability (cred,CAP_SYS_TTY_CONFIG , -SECURITY_CAP_AUDIT , true); +CAP_OPT_NONE , true);break ;/* default case assumes that the command will go
security/smack/smack_access.c +1 -1
@@ -642,7 +642,7 @@ bool smack_privileged(int cap)return true; rc =cap_capable (current_cred (), &init_user_ns, cap, -SECURITY_CAP_AUDIT ); +CAP_OPT_NONE );if (rc)return false;
Greg Kroah-Hartman
maintainerPATCH 21/65 usb: core: hub: Improved device recognition on remote wakeup
In reply to Greg Kroah-HartmanFrom: Keiya Nobuta <[email protected]>
commit 9c06ac4c83df6d6fbdbf7488fbad822b4002ba19 upstream.
If hub_activate() is called before D+ has stabilized after remote wakeup, the following situation might occur:
__ ___________________
/ \ /D+ __/ \__/
Hub _______________________________
| ^ ^ ^
| | | |
Host _____v__|___|___________|______
| | | |
| | | \-- Interrupt Transfer (*3)
| | \-- ClearPortFeature (*2) | \-- GetPortStatus (*1)
\-- Host detects remote wakeup
- D+ goes high, Host starts running by remote wakeup
- D+ is not stable, goes low
- Host requests GetPortStatus at (*1) and gets the following hub status:
- Current Connect Status bit is 0
- Connect Status Change bit is 1
- D+ stabilizes, goes high
- Host requests ClearPortFeature and thus Connect Status Change bit is cleared at (*2)
- After waiting 100 ms, Host starts the Interrupt Transfer at (*3)
- Since the Connect Status Change bit is 0, Hub returns NAK.
In this case, port_event() is not called in hub_event() and Host cannot recognize device. To solve this issue, flag change_bits even if only Connect Status Change bit is 1 when got in the first GetPortStatus.
This issue occurs rarely because it only if D+ changes during a very short time between GetPortStatus and ClearPortFeature. However, it is fatal if it occurs in embedded system.
--- drivers/usb/core/hub.c | 1 + 1 file changed, 1 insertion(+)
drivers/usb/core/hub.c +1 -0
@@ -1164,6 +1164,7 @@ static void hub_activate(struct usb_hub* PORT_OVER_CURRENT is not. So check for any of them. */ if (udev || (portstatus &USB_PORT_STAT_CONNECTION ) || + (portchange &USB_PORT_STAT_C_CONNECTION ) || (portstatus &USB_PORT_STAT_OVERCURRENT ) || (portchange &USB_PORT_STAT_C_OVERCURRENT ))set_bit (port1, hub->change_bits);
Greg Kroah-Hartman
maintainerPATCH 22/65 x86/resctrl: Fix an imbalance in domain_remove_cpu()
In reply to Greg Kroah-HartmanFrom: Qian Cai <[email protected]>
commit e278af89f1ba0a9ef20947db6afc2c9afa37e85b upstream.
A system that supports resource monitoring may have multiple resources while not all of these resources are capable of monitoring. Monitoring related state is initialized only for resources that are capable of monitoring and correspondingly this state should subsequently only be removed from these resources that are capable of monitoring.
domain_add_cpu() calls domain_setup_mon_state() only when r->mon_capable is true where it will initialize d->mbm_over. However, domain_remove_cpu() calls cancel_delayed_work(&d->mbm_over) without checking r->mon_capable resulting in an attempt to cancel d->mbm_over on all resources, even those that never initialized d->mbm_over because they are not capable of monitoring. Hence, it triggers a debugobjects warning when offlining CPUs because those timer debugobjects are never initialized:
ODEBUG: assert_init not available (active state 0) object type:
timer_list hint: 0x0
WARNING: CPU: 143 PID: 789 at lib/debugobjects.c:484 debug_print_object Hardware name: HP Synergy 680 Gen9/Synergy 680 Gen9 Compute Module, BIOS I40 05/23/2018 RIP: 0010:debug_print_object Call Trace: debug_object_assert_init del_timer try_to_grab_pending cancel_delayed_work resctrl_offline_cpu cpuhp_invoke_callback cpuhp_thread_fun smpboot_thread_fn kthread ret_from_fork
--- arch/x86/kernel/cpu/intel_rdt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/kernel/cpu/intel_rdt.c +1 -1
@@ -526,7 +526,7 @@ static void domain_remove_cpu(int cpu, sif (static_branch_unlikely (&rdt_mon_enable_key))rmdir_mondata_subdir_allrdtgrp (r, d->id);list_del (&d->list); -if (is_mbm_enabled ()) +if (r->mon_capable &&is_mbm_enabled ())cancel_delayed_work (&d->mbm_over);if (is_llc_occupancy_enabled () &&has_busy_rmid (r, d)) {/*
Greg Kroah-Hartman
maintainerPATCH 23/65 x86/efistub: Disable paging at mixed mode entry
In reply to Greg Kroah-HartmanFrom: Ard Biesheuvel <[email protected]>
commit 4911ee401b7ceff8f38e0ac597cbf503d71e690c upstream.
The EFI mixed mode entry code goes through the ordinary startup_32() routine before jumping into the kernel's EFI boot code in 64-bit mode. The 32-bit startup code must be entered with paging disabled, but this is not documented as a requirement for the EFI handover protocol, and so we should disable paging explicitly when entering the kernel from 32-bit EFI firmware.
--- arch/x86/boot/compressed/head_64.S | 5 +++++ 1 file changed, 5 insertions(+)
arch/x86/boot/compressed/head_64.S +5 -0
@@ -227,6 +227,11 @@ ENTRY(efi32_stub_entry) leal efi32_config(%ebp), %eax movl %eax, efi_config(%ebp) + /* Disable paging */ + movl %cr0, %eax + btrl $X86_CR0_PG_BIT, %eax + movl %eax, %cr0 + jmp startup_32 ENDPROC(efi32_stub_entry) #endif
Greg Kroah-Hartman
maintainerPATCH 24/65 perf hists: Fix variable names inconsistency in hists__for_each() macro
In reply to Greg Kroah-HartmanFrom: Yuya Fujita <[email protected]>
commit 55347ec340af401437680fd0e88df6739a967f9f upstream.
Variable names are inconsistent in hists__for_each macro().
Due to this inconsistency, the macro replaces its second argument with "fmt" regardless of its original name.
So far it works because only "fmt" is passed to the second argument. However, this behavior is not expected and should be fixed.
--- tools/perf/util/hist.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
tools/perf/util/hist.h +2 -2
@@ -317,10 +317,10 @@ static inline void perf_hpp__prepend_sor list_for_each_entry_safe(format, tmp, &(_list)->sorts, sort_list)#define hists__for_each_format (hists, format) \ - perf_hpp_list__for_each_format((hists)->hpp_list, fmt) + perf_hpp_list__for_each_format((hists)->hpp_list, format)#define hists__for_each_sort_list (hists, format) \ - perf_hpp_list__for_each_sort_list((hists)->hpp_list, fmt) + perf_hpp_list__for_each_sort_list((hists)->hpp_list, format)extern struct perf_hpp_fmt perf_hpp__format[];
Greg Kroah-Hartman
maintainerPATCH 25/65 perf report: Fix incorrectly added dimensions as switch perf data file
In reply to Greg Kroah-HartmanFrom: Jin Yao <[email protected]>
commit 0feba17bd7ee3b7e03d141f119049dcc23efa94e upstream.
We observed an issue that was some extra columns displayed after switching perf data file in browser. The steps to reproduce:
1. perf record -a -e cycles,instructions -- sleep 3
2. perf report --group
3. In browser, we use hotkey 's' to switch to another perf.data
4. Now in browser, the extra columns 'Self' and 'Children' are displayed.
The issue is setup_sorting() executed again after repeat path, so dimensions are added again.
This patch checks the last key returned from __cmd_report(). If it's K_SWITCH_INPUT_DATA, skips the setup_sorting().
--- tools/perf/builtin-report.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
tools/perf/builtin-report.c +4 -1
@@ -742,6 +742,7 @@ int cmd_report(int argc, const char **arstruct stat st;bool has_br_stack = false;int branch_mode =-1 ; +int last_key =0 ;bool branch_call_mode = false;char callchain_default_opt[] =CALLCHAIN_DEFAULT_OPT ;const char *const report_usage[] = {
@@ -1048,7 +1049,8 @@ repeat:else use_browser =0 ; -if (setup_sorting (session->evlist) <0 ) { +if ((last_key !=K_SWITCH_INPUT_DATA ) && + (setup_sorting (session->evlist) <0 )) {if (sort_order)parse_options_usage (report_usage, options,"s" ,1 );if (field_order)
@@ -1108,6 +1110,7 @@ repeat: ret =__cmd_report (&report);if (ret ==K_SWITCH_INPUT_DATA ) {perf_session__delete (session); + last_key =K_SWITCH_INPUT_DATA ; goto repeat; }else ret =0 ;
Greg Kroah-Hartman
maintainerPATCH 26/65 mm/shmem.c: thp, shmem: fix conflict of above-47bit hint address and PMD alignment
In reply to Greg Kroah-HartmanFrom: Kirill A. Shutemov <[email protected]>
commit 991589974d9c9ecb24ee3799ec8c415c730598a2 upstream.
Shmem/tmpfs tries to provide THP-friendly mappings if huge pages are enabled. But it doesn't work well with above-47bit hint address.
Normally, the kernel doesn't create userspace mappings above 47-bit, even if the machine allows this (such as with 5-level paging on x86-64). Not all user space is ready to handle wide addresses. It's known that at least some JIT compilers use higher bits in pointers to encode their information.
Userspace can ask for allocation from full address space by specifying hint address (with or without MAP_FIXED) above 47-bits. If the application doesn't need a particular address, but wants to allocate from whole address space it can specify -1 as a hint address.
Unfortunately, this trick breaks THP alignment in shmem/tmp:shmem_get_unmapped_area() would not try to allocate PMD-aligned area if *any* hint address specified.
This can be fixed by requesting the aligned area if the we failed to allocated at user-specified hint address. The request with inflated length will also take the user-specified hint address. This way we will not lose an allocation request from the full address space.
--- mm/shmem.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
mm/shmem.c +4 -3
@@ -2052,9 +2052,10 @@ unsigned long shmem_get_unmapped_area(st/* * Our priority is to support MAP_SHARED mapped hugely; * and support MAP_PRIVATE mapped hugely too, until it is COWed. -* But if caller specified an address hint, respect that as before. +* But if caller specified an address hint and we allocated area there +* successfully, respect that as before. */ -if (uaddr) +if (uaddr == addr)return addr;if (shmem_huge !=SHMEM_HUGE_FORCE ) {
@@ -2088,7 +2089,7 @@ unsigned long shmem_get_unmapped_area(stif (inflated_len < len)return addr; - inflated_addr =get_area (NULL ,0 , inflated_len,0 , flags); + inflated_addr =get_area (NULL , uaddr, inflated_len,0 , flags);if (IS_ERR_VALUE (inflated_addr))return addr;if (inflated_addr & ~PAGE_MASK )
Greg Kroah-Hartman
maintainerPATCH 27/65 btrfs: fix memory leak in qgroup accounting
In reply to Greg Kroah-HartmanFrom: Johannes Thumshirn <[email protected]>
commit 26ef8493e1ab771cb01d27defca2fa1315dc3980 upstream.
When running xfstests on the current btrfs I get the following splat from kmemleak:
unreferenced object 0xffff88821b2404e0 (size 32):
comm "kworker/u4:7", pid 26663, jiffies 4295283698 (age 8.776s) hex dump (first 32 bytes):
01 00 00 00 00 00 00 00 10 ff fd 26 82 88 ff ff ...........&....
10 ff fd 26 82 88 ff ff 20 ff fd 26 82 88 ff ff ...&.... ..&....
backtrace:
[<00000000f94fd43f>] ulist_alloc+0x25/0x60 [btrfs]
[<00000000fd023d99>] btrfs_find_all_roots_safe+0x41/0x100 [btrfs]
[<000000008f17bd32>] btrfs_find_all_roots+0x52/0x70 [btrfs]
[<00000000b7660afb>] btrfs_qgroup_rescan_worker+0x343/0x680 [btrfs]
[<0000000058e66778>] btrfs_work_helper+0xac/0x1e0 [btrfs]
[<00000000f0188930>] process_one_work+0x1cf/0x350
[<00000000af5f2f8e>] worker_thread+0x28/0x3c0
[<00000000b55a1add>] kthread+0x109/0x120
[<00000000f88cbd17>] ret_from_fork+0x35/0x40This corresponds to:
(gdb) l *(btrfs_find_all_roots_safe+0x41)
0x8d7e1 is in btrfs_find_all_roots_safe (fs/btrfs/backref.c:1413).
1408
1409 tmp = ulist_alloc(GFP_NOFS);
1410 if (!tmp)
1411 return -ENOMEM;
1412 *roots = ulist_alloc(GFP_NOFS);
1413 if (!*roots) {
1414 ulist_free(tmp);
1415 return -ENOMEM;
1416 }
1417Following the lifetime of the allocated 'roots' ulist, it gets freed again in btrfs_qgroup_account_extent().
But this does not happen if the function is called with the 'BTRFS_FS_QUOTA_ENABLED' flag cleared, then btrfs_qgroup_account_extent() does a short leave and directly returns.
Instead of directly returning we should jump to the 'out_free' in order to free all resources as expected.
--- fs/btrfs/qgroup.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
fs/btrfs/qgroup.c +5 -1
@@ -1928,8 +1928,12 @@ btrfs_qgroup_account_extent(struct btrfsu64 nr_old_roots =0 ;int ret =0 ; +/* +* If quotas get disabled meanwhile, the resouces need to be freed and +* we can't just exit here. +*/ if (!test_bit (BTRFS_FS_QUOTA_ENABLED , &fs_info->flags)) -return 0 ; + goto out_free;if (new_roots) {if (!maybe_fs_roots (new_roots))
Greg Kroah-Hartman
maintainerPATCH 28/65 mm/page-writeback.c: avoid potential division by zero in wb_min_max_ratio()
In reply to Greg Kroah-HartmanFrom: Wen Yang <[email protected]>
commit 6d9e8c651dd979aa666bee15f086745f3ea9c4b3 upstream.
Patch series "use div64_ul() instead of div_u64() if the divisor is unsigned long".
We were first inspired by commit b0ab99e7736a ("sched: Fix possible divide by zero in avg_atom () calculation"), then refer to the recently analyzed mm code, we found this suspicious place.
201 if (min) {
202 min *= this_bw;
203 do_div(min, tot_bw);
204 }
And we also disassembled and confirmed it:
/usr/src/debug/kernel-4.9.168-016.ali3000/linux-4.9.168-016.ali3000.alios7.x86_64/mm/page-writeback.c: 201
0xffffffff811c37da <__wb_calc_thresh+234>: xor %r10d,%r10d 0xffffffff811c37dd <__wb_calc_thresh+237>: test %rax,%rax 0xffffffff811c37e0 <__wb_calc_thresh+240>: je 0xffffffff811c3800 <__wb_calc_thresh+272> /usr/src/debug/kernel-4.9.168-016.ali3000/linux-4.9.168-016.ali3000.alios7.x86_64/mm/page-writeback.c: 202 0xffffffff811c37e2 <__wb_calc_thresh+242>: imul %r8,%rax /usr/src/debug/kernel-4.9.168-016.ali3000/linux-4.9.168-016.ali3000.alios7.x86_64/mm/page-writeback.c: 203 0xffffffff811c37e6 <__wb_calc_thresh+246>: mov %r9d,%r10d ---> truncates it to 32 bits here 0xffffffff811c37e9 <__wb_calc_thresh+249>: xor %edx,%edx 0xffffffff811c37eb <__wb_calc_thresh+251>: div %r10 0xffffffff811c37ee <__wb_calc_thresh+254>: imul %rbx,%rax 0xffffffff811c37f2 <__wb_calc_thresh+258>: shr $0x2,%rax 0xffffffff811c37f6 <__wb_calc_thresh+262>: mul %rcx 0xffffffff811c37f9 <__wb_calc_thresh+265>: shr $0x2,%rdx 0xffffffff811c37fd <__wb_calc_thresh+269>: mov %rdx,%r10
This series uses div64_ul() instead of div_u64() if the divisor is unsigned long, to avoid truncation to 32-bit on 64-bit platforms.
This patch (of 3):
The variables 'min' and 'max' are unsigned long and do_div truncates them to 32 bits, which means it can test non-zero and be truncated to zero for division. Fix this issue by using div64_ul() instead.
--- mm/page-writeback.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
mm/page-writeback.c +2 -2
@@ -201,11 +201,11 @@ static void wb_min_max_ratio(struct bdi_if (this_bw < tot_bw) {if (min) { min *= this_bw; -do_div (min, tot_bw); + min =div64_ul (min, tot_bw); }if (max <100 ) { max *= this_bw; -do_div (max, tot_bw); + max =div64_ul (max, tot_bw); } }
Greg Kroah-Hartman
maintainerPATCH 29/65 net: stmmac: 16KB buffer must be 16 byte aligned
In reply to Greg Kroah-HartmanFrom: Jose Abreu <[email protected]>
commit 8605131747e7e1fd8f6c9f97a00287aae2b2c640 upstream.
The 16KB RX Buffer must also be 16 byte aligned. Fix it.
--- drivers/net/ethernet/stmicro/stmmac/common.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
drivers/net/ethernet/stmicro/stmmac/common.h +2 -3
@@ -338,9 +338,8 @@ struct dma_features {unsigned int rx_fifo_size; }; -/* GMAC TX FIFO is 8K, Rx FIFO is 16K */ -#define BUF_SIZE_16KiB 16384 -/* RX Buffer size must be < 8191 and multiple of 4/8/16 bytes */ +/* RX Buffer size must be multiple of 4/8/16 bytes */ +#define BUF_SIZE_16KiB 16368#define BUF_SIZE_8KiB 8188#define BUF_SIZE_4KiB 4096#define BUF_SIZE_2KiB 2048
Greg Kroah-Hartman
maintainerPATCH 30/65 net: stmmac: Enable 16KB buffer size
In reply to Greg Kroah-HartmanFrom: Jose Abreu <[email protected]>
commit b2f3a481c4cd62f78391b836b64c0a6e72b503d2 upstream.
XGMAC supports maximum MTU that can go to 16KB. Lets add this check in the calculation of RX buffer size.
--- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +3 -1
@@ -1043,7 +1043,9 @@ static int stmmac_set_bfsize(int mtu, in {int ret = bufsize; -if (mtu >= BUF_SIZE_4KiB) +if (mtu >= BUF_SIZE_8KiB) + ret = BUF_SIZE_16KiB; +else if (mtu >= BUF_SIZE_4KiB) ret = BUF_SIZE_8KiB;else if (mtu >= BUF_SIZE_2KiB) ret = BUF_SIZE_4KiB;
Greg Kroah-Hartman
maintainerPATCH 31/65 USB: serial: io_edgeport: use irqsave() in USBs complete callback
In reply to Greg Kroah-HartmanFrom: John Ogness <[email protected]>
[ Upstream commit dd1fae527612543e560e84f2eba4f6ef2006ac55 ]
The USB completion callback does not disable interrupts while acquiring the lock. We want to remove the local_irq_disable() invocation from __usb_hcd_giveback_urb() and therefore it is required for the callback handler to disable the interrupts while acquiring the lock. The callback may be invoked either in IRQ or BH context depending on the USB host controller.
Use the _irqsave() variant of the locking primitives.
--- drivers/usb/serial/io_edgeport.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-)
drivers/usb/serial/io_edgeport.c +11 -6
@@ -652,6 +652,7 @@ static void edge_interrupt_callback(struct urb *urb)struct usb_serial_port *port;unsigned char *data = urb->transfer_buffer;int length = urb->actual_length; +unsigned long flags;int bytes_avail;int position;int txCredits;
@@ -683,7 +684,7 @@ static void edge_interrupt_callback(struct urb *urb)if (length >1 ) { bytes_avail = data[0 ] | (data[1 ] <<8 );if (bytes_avail) { -spin_lock (&edge_serial->es_lock); +spin_lock_irqsave (&edge_serial->es_lock, flags); edge_serial->rxBytesAvail += bytes_avail; dev_dbg(dev, "%s - bytes_avail=%d, rxBytesAvail=%d, read_in_progress=%d\n",
@@ -706,7 +707,8 @@ static void edge_interrupt_callback(struct urb *urb) edge_serial->read_in_progress = false; } } -spin_unlock (&edge_serial->es_lock); +spin_unlock_irqrestore (&edge_serial->es_lock, + flags); } }/* grab the txcredits for the ports if available */
@@ -719,9 +721,11 @@ static void edge_interrupt_callback(struct urb *urb) port = edge_serial->serial->port[portNumber]; edge_port =usb_get_serial_port_data (port);if (edge_port->open) { -spin_lock (&edge_port->ep_lock); +spin_lock_irqsave (&edge_port->ep_lock, + flags); edge_port->txCredits += txCredits; -spin_unlock (&edge_port->ep_lock); +spin_unlock_irqrestore (&edge_port->ep_lock, + flags);dev_dbg (dev,"%s - txcredits for port%d = %d\n" , __func__, portNumber, edge_port->txCredits);
@@ -762,6 +766,7 @@ static void edge_bulk_in_callback(struct urb *urb)int retval;__u16 raw_data_length;int status = urb->status; +unsigned long flags;if (status) { dev_dbg(&urb->dev->dev, "%s - nonzero read bulk status received: %d\n",
@@ -781,7 +786,7 @@ static void edge_bulk_in_callback(struct urb *urb)usb_serial_debug_data (dev, __func__, raw_data_length, data); -spin_lock (&edge_serial->es_lock); +spin_lock_irqsave (&edge_serial->es_lock, flags);/* decrement our rxBytes available by the number that we just got */ edge_serial->rxBytesAvail -= raw_data_length;
@@ -805,7 +810,7 @@ static void edge_bulk_in_callback(struct urb *urb) edge_serial->read_in_progress = false; } -spin_unlock (&edge_serial->es_lock); +spin_unlock_irqrestore (&edge_serial->es_lock, flags); }
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 32/65 USB: serial: io_edgeport: handle unbound ports on URB completion
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
[ Upstream commit e37d1aeda737a20b1846a91a3da3f8b0f00cf690 ]
Check for NULL port data in the shared interrupt and bulk completion callbacks to avoid dereferencing a NULL pointer in case a device sends data for a port device which isn't bound to a driver (e.g. due to a malicious device having unexpected endpoints or after an allocation failure on port probe).
--- drivers/usb/serial/io_edgeport.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/usb/serial/io_edgeport.c +2 -2
@@ -720,7 +720,7 @@ static void edge_interrupt_callback(struct urb *urb)if (txCredits) { port = edge_serial->serial->port[portNumber]; edge_port =usb_get_serial_port_data (port); -if (edge_port->open) { +if (edge_port && edge_port->open) {spin_lock_irqsave (&edge_port->ep_lock, flags); edge_port->txCredits += txCredits;
@@ -1847,7 +1847,7 @@ static void process_rcvd_data(struct edgeport_serial *edge_serial,if (rxLen && edge_serial->rxPort < serial->num_ports) { port = serial->port[edge_serial->rxPort]; edge_port =usb_get_serial_port_data (port); -if (edge_port->open) { +if (edge_port && edge_port->open) {dev_dbg (dev,"%s - Sending %d bytes to TTY for port %d\n" , __func__, rxLen, edge_serial->rxPort);
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 33/65 mm/huge_memory.c: make __thp_get_unmapped_area static
In reply to Greg Kroah-HartmanFrom: Bharath Vedartham <[email protected]>
[ Upstream commit b3b07077b01ecbbd98efede778c195567de25b71 ]
__thp_get_unmapped_area is only used in mm/huge_memory.c. Make it static. Tested by building and booting the kernel.
--- mm/huge_memory.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
mm/huge_memory.c +1 -1
@@ -502,7 +502,7 @@ void prep_transhuge_page(struct page *page)set_compound_page_dtor (page,TRANSHUGE_PAGE_DTOR ); } -unsigned long __thp_get_unmapped_area (struct file *filp,unsigned long len, +static unsigned long __thp_get_unmapped_area (struct file *filp,unsigned long len,loff_t off,unsigned long flags,unsigned long size) {unsigned long addr;
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 34/65 mm/huge_memory.c: thp: fix conflict of above-47bit hint address and PMD alignment
In reply to Greg Kroah-HartmanFrom: Kirill A. Shutemov <[email protected]>
[ Upstream commit 97d3d0f9a1cf132c63c0b8b8bd497b8a56283dd9 ]
Patch series "Fix two above-47bit hint address vs. THP bugs".
The two get_unmapped_area() implementations have to be fixed to provide THP-friendly mappings if above-47bit hint address is specified.
This patch (of 2):
Filesystems use thp_get_unmapped_area() to provide THP-friendly mappings. For DAX in particular.
Normally, the kernel doesn't create userspace mappings above 47-bit, even if the machine allows this (such as with 5-level paging on x86-64). Not all user space is ready to handle wide addresses. It's known that at least some JIT compilers use higher bits in pointers to encode their information.
Userspace can ask for allocation from full address space by specifying hint address (with or without MAP_FIXED) above 47-bits. If the application doesn't need a particular address, but wants to allocate from whole address space it can specify -1 as a hint address.
Unfortunately, this trick breaks thp_get_unmapped_area(): the function would not try to allocate PMD-aligned area if *any* hint address specified.
Modify the routine to handle it correctly:
- Try to allocate the space at the specified hint address with length padding required for PMD alignment.
- If failed, retry without length padding (but with the same hint address);
- If the returned address matches the hint address return it.
- Otherwise, align the address as required for THP and return.
The user specified hint address is passed down to get_unmapped_area() so above-47bit hint address will be taken into account without breaking alignment requirements.
--- mm/huge_memory.c | 38 ++++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 14 deletions(-)
mm/huge_memory.c +24 -14
@@ -502,13 +502,13 @@ void prep_transhuge_page(struct page *page)set_compound_page_dtor (page,TRANSHUGE_PAGE_DTOR ); } -static unsigned long __thp_get_unmapped_area (struct file *filp,unsigned long len, +static unsigned long __thp_get_unmapped_area (struct file *filp, +unsigned long addr,unsigned long len,loff_t off,unsigned long flags,unsigned long size) { -unsigned long addr;loff_t off_end = off + len;loff_t off_align =round_up (off, size); -unsigned long len_pad; +unsigned long len_pad, ret;if (off_end <= off_align || (off_end - off_align) < size)return 0 ;
@@ -517,30 +517,40 @@ static unsigned long __thp_get_unmapped_area(struct file *filp, unsigned long leif (len_pad < len || (off + len_pad) < off)return 0 ; - addr = current->mm->get_unmapped_area (filp,0 , len_pad, + ret = current->mm->get_unmapped_area (filp, addr, len_pad, off >>PAGE_SHIFT , flags); -if (IS_ERR_VALUE (addr)) + +/* +* The failure might be due to length padding. The caller will retry +* without the padding. +*/ +if (IS_ERR_VALUE (ret))return 0 ; - addr += (off - addr) & (size -1 ); -return addr; +/* +* Do not try to align to THP boundary if allocation at the address +* hint succeeds. +*/ +if (ret == addr) +return addr; + + ret += (off - ret) & (size -1 ); +return ret; }unsigned long thp_get_unmapped_area (struct file *filp,unsigned long addr,unsigned long len,unsigned long pgoff,unsigned long flags) { +unsigned long ret;loff_t off = (loff_t )pgoff <<PAGE_SHIFT ; -if (addr) - goto out;if (!IS_DAX (filp->f_mapping->host) || !IS_ENABLED (CONFIG_FS_DAX_PMD )) goto out; - addr =__thp_get_unmapped_area (filp, len, off, flags,PMD_SIZE ); -if (addr) -return addr; - - out: + ret =__thp_get_unmapped_area (filp, addr, len, off, flags,PMD_SIZE ); +if (ret) +return ret; +out:return current->mm->get_unmapped_area (filp, addr, len, pgoff, flags); }EXPORT_SYMBOL_GPL (thp_get_unmapped_area);
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 35/65 arm64: dts: agilex/stratix10: fix pmu interrupt numbers
In reply to Greg Kroah-HartmanFrom: Dinh Nguyen <[email protected]>
[ Upstream commit 210de0e996aee8e360ccc9e173fe7f0a7ed2f695 ]
Fix up the correct interrupt numbers for the PMU unit on Agilex and Stratix10.
--- arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi +4 -4
@@ -56,10 +56,10 @@ pmu { compatible = "arm,armv8-pmuv3"; - interrupts = <0 120 8>, - <0 121 8>, - <0 122 8>, - <0 123 8>; + interrupts = <0 170 4>, + <0 171 4>, + <0 172 4>, + <0 173 4>; interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>,
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 36/65 cfg80211: fix page refcount issue in A-MSDU decap
In reply to Greg Kroah-HartmanFrom: Felix Fietkau <[email protected]>
commit 81c044fc3bdc5b7be967cd3682528ea94b58c06a upstream.
The fragments attached to a skb can be part of a compound page. In that case, page_ref_inc will increment the refcount for the wrong page. Fix this by using get_page instead, which calls page_ref_inc on the compound head and also checks for overflow.
--- net/wireless/util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/wireless/util.c +1 -1
@@ -652,7 +652,7 @@ __frame_add_frag(struct sk_buff *skb, ststruct skb_shared_info *sh =skb_shinfo (skb);int page_offset; -page_ref_inc (page); +get_page (page); page_offset = ptr -page_address (page);skb_add_rx_frag (skb, sh->nr_frags, page, page_offset, len, size); }
Greg Kroah-Hartman
maintainerPATCH 37/65 netfilter: fix a use-after-free in mtype_destroy()
In reply to Greg Kroah-HartmanFrom: Cong Wang <[email protected]>
commit c120959387efa51479056fd01dc90adfba7a590c upstream.
map->members is freed by ip_set_free() right before using it in mtype_ext_cleanup() again. So we just have to move it down.
--- net/netfilter/ipset/ip_set_bitmap_gen.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/netfilter/ipset/ip_set_bitmap_gen.h +1 -1
@@ -64,9 +64,9 @@ mtype_destroy(struct ip_set *set)if (SET_WITH_TIMEOUT (set))del_timer_sync (&map->gc); -ip_set_free (map->members);if (set->dsize && set->extensions &IPSET_EXT_DESTROY )mtype_ext_cleanup (set); +ip_set_free (map->members);ip_set_free (map); set->data =NULL ;
Greg Kroah-Hartman
maintainerPATCH 38/65 netfilter: arp_tables: init netns pointer in xt_tgdtor_param struct
In reply to Greg Kroah-HartmanFrom: Florian Westphal <[email protected]>
commit 212e7f56605ef9688d0846db60c6c6ec06544095 upstream.
An earlier commit (1b789577f655060d98d20e,
"netfilter: arp_tables: init netns pointer in xt_tgchk_param struct") fixed missing net initialization for arptables, but turns out it was incomplete. We can get a very similar struct net NULL deref during error unwinding:
general protection fault: 0000 [#1] PREEMPT SMP KASAN RIP: 0010:xt_rateest_put+0xa1/0x440 net/netfilter/xt_RATEEST.c:77 xt_rateest_tg_destroy+0x72/0xa0 net/netfilter/xt_RATEEST.c:175 cleanup_entry net/ipv4/netfilter/arp_tables.c:509 [inline] translate_table+0x11f4/0x1d80 net/ipv4/netfilter/arp_tables.c:587 do_replace net/ipv4/netfilter/arp_tables.c:981 [inline] do_arpt_set_ctl+0x317/0x650 net/ipv4/netfilter/arp_tables.c:1461
Also init the netns pointer in xt_tgdtor_param struct.
--- net/ipv4/netfilter/arp_tables.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-)
net/ipv4/netfilter/arp_tables.c +10 -9
@@ -506,12 +506,13 @@ static inline int check_entry_size_and_hreturn 0 ; } -static inline void cleanup_entry (struct arpt_entry *e) +static void cleanup_entry (struct arpt_entry *e,struct net *net) {struct xt_tgdtor_param par;struct xt_entry_target *t; t =arpt_get_target (e); + par.net = net; par.target = t->u.kernel.target; par.targinfo = t->data; par.family =NFPROTO_ARP ;
@@ -601,7 +602,7 @@ static int translate_table(struct net *n xt_entry_foreach(iter, entry0, newinfo->size) {if (i-- ==0 )break ; -cleanup_entry (iter); +cleanup_entry (iter, net); }return ret; }
@@ -926,7 +927,7 @@ static int __do_replace(struct net *net,/* Decrease module usage counts and free resource */ loc_cpu_old_entry = oldinfo->entries; xt_entry_foreach(iter, loc_cpu_old_entry, oldinfo->size) -cleanup_entry (iter); +cleanup_entry (iter, net);xt_free_table_info (oldinfo); if (copy_to_user(counters_ptr, counters,
@@ -990,7 +991,7 @@ static int do_replace(struct net *net, c free_newinfo_untrans: xt_entry_foreach(iter, loc_cpu_entry, newinfo->size) -cleanup_entry (iter); +cleanup_entry (iter, net); free_newinfo:xt_free_table_info (newinfo);return ret;
@@ -1287,7 +1288,7 @@ static int compat_do_replace(struct net free_newinfo_untrans: xt_entry_foreach(iter, loc_cpu_entry, newinfo->size) -cleanup_entry (iter); +cleanup_entry (iter, net); free_newinfo:xt_free_table_info (newinfo);return ret;
@@ -1514,7 +1515,7 @@ static int do_arpt_get_ctl(struct sock *return ret; } -static void __arpt_unregister_table (struct xt_table *table) +static void __arpt_unregister_table (struct net *net,struct xt_table *table) {struct xt_table_info *private;void *loc_cpu_entry;
@@ -1526,7 +1527,7 @@ static void __arpt_unregister_table(stru/* Decrease module usage counts and free resources */ loc_cpu_entry = private->entries; xt_entry_foreach(iter, loc_cpu_entry, private->size) -cleanup_entry (iter); +cleanup_entry (iter, net);if (private->number > private->initial_entries)module_put (table_owner);xt_free_table_info (private);
@@ -1566,7 +1567,7 @@ int arpt_register_table(struct net *net, ret =nf_register_net_hooks (net, ops,hweight32 (table->valid_hooks));if (ret !=0 ) { -__arpt_unregister_table (new_table); +__arpt_unregister_table (net, new_table); *res =NULL ; }
@@ -1581,7 +1582,7 @@ void arpt_unregister_table(struct net *n const struct nf_hook_ops *ops) {nf_unregister_net_hooks (net, ops,hweight32 (table->valid_hooks)); -__arpt_unregister_table (table); +__arpt_unregister_table (net, table); }/* The built-in targets: standard (NULL) and error. */
Greg Kroah-Hartman
maintainerPATCH 39/65 NFC: pn533: fix bulk-message timeout
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
commit a112adafcb47760feff959ee1ecd10b74d2c5467 upstream.
The driver was doing a synchronous uninterruptible bulk-transfer without using a timeout. This could lead to the driver hanging on probe due to a malfunctioning (or malicious) device until the device is physically disconnected. While sleeping in probe the driver prevents other devices connected to the same hub from being added to (or removed from) the bus.
An arbitrary limit of five seconds should be more than enough.
--- drivers/nfc/pn533/usb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/nfc/pn533/usb.c +1 -1
@@ -403,7 +403,7 @@ static int pn533_acr122_poweron_rdr(stru cmd, sizeof(cmd), false); rc =usb_bulk_msg (phy->udev, phy->out_urb->pipe, buffer,sizeof (cmd), - &transferred,0 ); + &transferred,5000 );kfree (buffer);if (rc || (transferred !=sizeof (cmd))) { nfc_err(&phy->udev->dev,
Greg Kroah-Hartman
maintainerPATCH 40/65 batman-adv: Fix DAT candidate selection on little endian systems
In reply to Greg Kroah-HartmanFrom: Sven Eckelmann <[email protected]>
commit 4cc4a1708903f404d2ca0dfde30e71e052c6cbc9 upstream.
The distributed arp table is using a DHT to store and retrieve MAC address information for an IP address. This is done using unicast messages to selected peers. The potential peers are looked up using the IP address and the VID.
While the IP address is always stored in big endian byte order, this is not the case of the VID. It can (depending on the host system) either be big endian or little endian. The host must therefore always convert it to big endian to ensure that all devices calculate the same peers for the same lookup data.
--- net/batman-adv/distributed-arp-table.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
net/batman-adv/distributed-arp-table.c +3 -1
@@ -243,6 +243,7 @@ static u32 batadv_hash_dat(const void *du32 hash =0 ;const struct batadv_dat_entry *dat = data;const unsigned char *key; +__be16 vid;u32 i; key = (const unsigned char *)&dat->ip;
@@ -252,7 +253,8 @@ static u32 batadv_hash_dat(const void *d hash ^= (hash >>6 ); } - key = (const unsigned char *)&dat->vid; + vid =htons (dat->vid); + key = (__force const unsigned char *)&vid;for (i =0 ; i <sizeof (dat->vid); i++) { hash += key[i]; hash += (hash <<10 );
Greg Kroah-Hartman
maintainerPATCH 41/65 macvlan: use skb_reset_mac_header() in macvlan_queue_xmit()
In reply to Greg Kroah-HartmanFrom: Eric Dumazet <[email protected]>
[ Upstream commit 1712b2fff8c682d145c7889d2290696647d82dab ]
I missed the fact that macvlan_broadcast() can be used both in RX and TX.
skb_eth_hdr() makes only sense in TX paths, so we can not use it blindly in macvlan_broadcast()
--- drivers/net/macvlan.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/net/macvlan.c +3 -2
@@ -263,7 +263,7 @@ static void macvlan_broadcast(struct sk_ struct net_device *src, enum macvlan_mode mode) { -const struct ethhdr *eth =skb_eth_hdr (skb); +const struct ethhdr *eth =eth_hdr (skb);const struct macvlan_dev *vlan;struct sk_buff *nskb;unsigned int i;
@@ -515,10 +515,11 @@ static int macvlan_queue_xmit(struct sk_const struct macvlan_dev *dest;if (vlan->mode ==MACVLAN_MODE_BRIDGE ) { -const struct ethhdr *eth = (void *)skb->data; +const struct ethhdr *eth =skb_eth_hdr (skb);/* send to other bridge ports directly */ if (is_multicast_ether_addr (eth->h_dest)) { +skb_reset_mac_header (skb);macvlan_broadcast (skb, port, dev,MACVLAN_MODE_BRIDGE ); goto xmit_world; }
Greg Kroah-Hartman
maintainerPATCH 42/65 hv_netvsc: Fix memory leak when removing rndis device
In reply to Greg Kroah-HartmanFrom: Mohammed Gamal <[email protected]>
[ Upstream commit 536dc5df2808efbefc5acee334d3c4f701790ec0 ]
kmemleak detects the following memory leak when hot removing a network device:
unreferenced object 0xffff888083f63600 (size 256):
comm "kworker/0:1", pid 12, jiffies 4294831717 (age 1113.676s) hex dump (first 32 bytes):
00 40 c7 33 80 88 ff ff 00 00 00 00 10 00 00 00 [email protected]............ 00 00 00 00 ad 4e ad de ff ff ff ff 00 00 00 00 .....N.......... backtrace: [<00000000d4a8f5be>] rndis_filter_device_add+0x117/0x11c0 [hv_netvsc] [<000000009c02d75b>] netvsc_probe+0x5e7/0xbf0 [hv_netvsc] [<00000000ddafce23>] vmbus_probe+0x74/0x170 [hv_vmbus] [<00000000046e64f1>] really_probe+0x22f/0xb50 [<000000005cc35eb7>] driver_probe_device+0x25e/0x370 [<0000000043c642b2>] bus_for_each_drv+0x11f/0x1b0 [<000000005e3d09f0>] __device_attach+0x1c6/0x2f0 [<00000000a72c362f>] bus_probe_device+0x1a6/0x260 [<0000000008478399>] device_add+0x10a3/0x18e0 [<00000000cf07b48c>] vmbus_device_register+0xe7/0x1e0 [hv_vmbus] [<00000000d46cf032>] vmbus_add_channel_work+0x8ab/0x1770 [hv_vmbus] [<000000002c94bb64>] process_one_work+0x919/0x17d0 [<0000000096de6781>] worker_thread+0x87/0xb40 [<00000000fbe7397e>] kthread+0x333/0x3f0 [<000000004f844269>] ret_from_fork+0x3a/0x50
rndis_filter_device_add() allocates an instance of struct rndis_device which never gets deallocated as rndis_filter_device_remove() sets net_device->extension which points to the rndis_device struct to NULL, leaving the rndis_device dangling.
Since net_device->extension is eventually freed in free_netvsc_device(), we refrain from setting it to NULL inside rndis_filter_device_remove()
--- drivers/net/hyperv/rndis_filter.c | 2 -- 1 file changed, 2 deletions(-)
drivers/net/hyperv/rndis_filter.c +0 -2
@@ -1331,8 +1331,6 @@ void rndis_filter_device_remove(struct h/* Halt and release the rndis device */ rndis_filter_halt_device (rndis_dev); - net_dev->extension =NULL ; -netvsc_device_remove (dev); }
Greg Kroah-Hartman
maintainerPATCH 43/65 net: dsa: tag_qca: fix doubled Tx statistics
In reply to Greg Kroah-HartmanFrom: Alexander Lobakin <[email protected]>
[ Upstream commit bd5874da57edd001b35cf28ae737779498c16a56 ]
DSA subsystem takes care of netdev statistics since commit 4ed70ce9f01c ("net: dsa: Refactor transmit path to eliminate duplication"), so any accounting inside tagger callbacks is redundant and can lead to messing up the stats.
This bug is present in Qualcomm tagger since day 0.
--- net/dsa/tag_qca.c | 3 --- 1 file changed, 3 deletions(-)
net/dsa/tag_qca.c +0 -3
@@ -41,9 +41,6 @@ static struct sk_buff *qca_tag_xmit(strustruct dsa_slave_priv *p =netdev_priv (dev);u16 *phdr, hdr; - dev->stats.tx_packets++; - dev->stats.tx_bytes += skb->len; -if (skb_cow_head (skb,0 ) <0 )return NULL ;
Greg Kroah-Hartman
maintainerPATCH 44/65 net: hns: fix soft lockup when there is not enough memory
In reply to Greg Kroah-HartmanFrom: Yonglong Liu <[email protected]>
[ Upstream commit 49edd6a2c456150870ddcef5b7ed11b21d849e13 ]
When there is not enough memory and napi_alloc_skb() return NULL, the HNS driver will print error message, and than try again, if the memory is not enough for a while, huge error message and the retry operation will cause soft lockup.
When napi_alloc_skb() return NULL because of no memory, we can get a warn_alloc() call trace, so this patch deletes the error message. We already use polling mode to handle irq, but the retry operation will render the polling weight inactive, this patch just return budget when the rx is not completed to avoid dead loop.
--- drivers/net/ethernet/hisilicon/hns/hns_enet.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
drivers/net/ethernet/hisilicon/hns/hns_enet.c +1 -3
@@ -669,7 +669,6 @@ static int hns_nic_poll_rx_skb(struct hn skb = *out_skb =napi_alloc_skb (&ring_data->napi,HNS_RX_HEAD_SIZE );if (unlikely (!skb)) { -netdev_err (ndev,"alloc rx skb fail\n" ); ring->stats.sw_err_cnt++;return -ENOMEM ; }
@@ -1180,7 +1179,6 @@ static int hns_nic_common_poll(struct na container_of(napi, struct hns_nic_ring_data, napi);struct hnae_ring *ring = ring_data->ring; -try_again: clean_complete += ring_data->poll_one ( ring_data, budget - clean_complete, ring_data->ex_process);
@@ -1190,7 +1188,7 @@ try_again:napi_complete (napi); ring->q->handle->dev->ops->toggle_ring_irq (ring,0 ); }else { - goto try_again; +return budget; } }
Greg Kroah-Hartman
maintainerPATCH 45/65 net: usb: lan78xx: limit size of local TSO packets
In reply to Greg Kroah-HartmanFrom: Eric Dumazet <[email protected]>
[ Upstream commit f8d7408a4d7f60f8b2df0f81decdc882dd9c20dc ]
lan78xx_tx_bh() makes sure to not exceed MAX_SINGLE_PACKET_SIZE bytes in the aggregated packets it builds, but does nothing to prevent large GSO packets being submitted.
Pierre-Francois reported various hangs when/if TSO is enabled.
For localy generated packets, we can use netif_set_gso_max_size() to limit the size of TSO packets.
Note that forwarded packets could still hit the issue, so a complete fix might require implementing .ndo_features_check for this driver, forcing a software segmentation if the size of the TSO packet exceeds MAX_SINGLE_PACKET_SIZE.
--- drivers/net/usb/lan78xx.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/usb/lan78xx.c +1 -0
@@ -3612,6 +3612,7 @@ static int lan78xx_probe(struct usb_inte/* MTU range: 68 - 9000 */ netdev->max_mtu =MAX_SINGLE_PACKET_SIZE ; +netif_set_gso_max_size (netdev,MAX_SINGLE_PACKET_SIZE -MAX_HEADER ); dev->ep_blkin = (intf->cur_altsetting)->endpoint +0 ; dev->ep_blkout = (intf->cur_altsetting)->endpoint +1 ;
Greg Kroah-Hartman
maintainerPATCH 46/65 net/wan/fsl_ucc_hdlc: fix out of bounds write on array utdm_info
In reply to Greg Kroah-HartmanFrom: Colin Ian King <[email protected]>
[ Upstream commit ddf420390526ede3b9ff559ac89f58cb59d9db2f ]
Array utdm_info is declared as an array of MAX_HDLC_NUM (4) elements however up to UCC_MAX_NUM (8) elements are potentially being written to it. Currently we have an array out-of-bounds write error on the last 4 elements. Fix this by making utdm_info UCC_MAX_NUM elements in size.
Addresses-Coverity: ("Out-of-bounds write")
--- drivers/net/wan/fsl_ucc_hdlc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/wan/fsl_ucc_hdlc.c +1 -1
@@ -76,7 +76,7 @@ static struct ucc_tdm_info utdm_primary_ }, }; -static struct ucc_tdm_info utdm_info[MAX_HDLC_NUM ]; +static struct ucc_tdm_info utdm_info[UCC_MAX_NUM ];static int uhdlc_init (struct ucc_hdlc_private *priv) {
Greg Kroah-Hartman
maintainerPATCH 47/65 ptp: free ptp device pin descriptors properly
In reply to Greg Kroah-HartmanFrom: Vladis Dronov <[email protected]>
[ Upstream commit 75718584cb3c64e6269109d4d54f888ac5a5fd15 ]
There is a bug in ptp_clock_unregister(), where ptp_cleanup_pin_groups() first frees ptp->pin_{,dev_}attr, but then posix_clock_unregister() needs them to destroy a related sysfs device.
These functions can not be just swapped, as posix_clock_unregister() frees ptp which is needed in the ptp_cleanup_pin_groups(). Fix this by calling ptp_cleanup_pin_groups() in ptp_clock_release(), right before ptp is freed.
This makes this patch fix an UAF bug in a patch which fixes an UAF bug.
--- drivers/ptp/ptp_clock.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/ptp/ptp_clock.c +2 -2
@@ -179,6 +179,7 @@ static void ptp_clock_release(struct dev { struct ptp_clock *ptp = container_of(dev, struct ptp_clock, dev); +ptp_cleanup_pin_groups (ptp);mutex_destroy (&ptp->tsevq_mux);mutex_destroy (&ptp->pincfg_mux);ida_simple_remove (&ptp_clocks_map, ptp->index);
@@ -315,9 +316,8 @@ int ptp_clock_unregister(struct ptp_clocif (ptp->pps_source)pps_unregister_source (ptp->pps_source); -ptp_cleanup_pin_groups (ptp); -posix_clock_unregister (&ptp->clock); +return 0 ; }EXPORT_SYMBOL (ptp_clock_unregister);
Greg Kroah-Hartman
maintainerPATCH 48/65 r8152: add missing endpoint sanity check
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
[ Upstream commit 86f3f4cd53707ceeec079b83205c8d3c756eca93 ]
Add missing endpoint sanity check to probe in order to prevent a NULL-pointer dereference (or slab out-of-bounds access) when retrieving the interrupt-endpoint bInterval on ndo_open() in case a device lacks the expected endpoints.
--- drivers/net/usb/r8152.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/net/usb/r8152.c +3 -0
@@ -5158,6 +5158,9 @@ static int rtl8152_probe(struct usb_intereturn -ENODEV ; } +if (intf->cur_altsetting->desc.bNumEndpoints <3 ) +return -ENODEV ; +usb_reset_device (udev); netdev =alloc_etherdev (sizeof (struct r8152 ));if (!netdev) {
Greg Kroah-Hartman
maintainerPATCH 49/65 tcp: fix marked lost packets not being retransmitted
In reply to Greg Kroah-HartmanFrom: Pengcheng Yang <[email protected]>
[ Upstream commit e176b1ba476cf36f723cfcc7a9e57f3cb47dec70 ]
When the packet pointed to by retransmit_skb_hint is unlinked by ACK, retransmit_skb_hint will be set to NULL in tcp_clean_rtx_queue(). If packet loss is detected at this time, retransmit_skb_hint will be set to point to the current packet loss in tcp_verify_retransmit_hint(), then the packets that were previously marked lost but not retransmitted due to the restriction of cwnd will be skipped and cannot be retransmitted.
To fix this, when retransmit_skb_hint is NULL, retransmit_skb_hint can be reset only after all marked lost packets are retransmitted (retrans_out >= lost_out), otherwise we need to traverse from tcp_rtx_queue_head in tcp_xmit_retransmit_queue().
Packetdrill to demonstrate:
// Disable RACK and set max_reordering to keep things simple
0 `sysctl -q net.ipv4.tcp_recovery=0`
+0 sysctl -q net.ipv4.tcp_max_reordering=3
// Establish a connection
+0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 +0 bind(3, ..., ...) = 0
+0 listen(3, 1) = 0
+.1 < S 0:0(0) win 32792 <mss 1000,sackOK,nop,nop,nop,wscale 7>
+0 > S. 0:0(0) ack 1 <...>
+.01 < . 1:1(0) ack 1 win 257
+0 accept(3, ..., ...) = 4
// Send 8 data segments
+0 write(4, ..., 8000) = 8000
+0 > P. 1:8001(8000) ack 1
// Enter recovery and 1:3001 is marked lost
+.01 < . 1:1(0) ack 1 win 257 <sack 3001:4001,nop,nop>
+0 < . 1:1(0) ack 1 win 257 <sack 5001:6001 3001:4001,nop,nop> +0 < . 1:1(0) ack 1 win 257 <sack 5001:7001 3001:4001,nop,nop>
// Retransmit 1:1001, now retransmit_skb_hint points to 1001:2001
+0 > . 1:1001(1000) ack 1
// 1001:2001 was ACKed causing retransmit_skb_hint to be set to NULL
+.01 < . 1:1(0) ack 2001 win 257 <sack 5001:8001 3001:4001,nop,nop>
// Now retransmit_skb_hint points to 4001:5001 which is now marked lost
// BUG: 2001:3001 was not retransmitted
+0 > . 2001:3001(1000) ack 1
--- net/ipv4/tcp_input.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
net/ipv4/tcp_input.c +4 -3
@@ -932,9 +932,10 @@ static void tcp_update_reordering(struct/* This must be called before lost_out is incremented */ static void tcp_verify_retransmit_hint (struct tcp_sock *tp,struct sk_buff *skb) { -if (!tp->retransmit_skb_hint || -before (TCP_SKB_CB (skb)->seq, -TCP_SKB_CB (tp->retransmit_skb_hint)->seq)) +if ((!tp->retransmit_skb_hint && tp->retrans_out >= tp->lost_out) || + (tp->retransmit_skb_hint && +before (TCP_SKB_CB (skb)->seq, +TCP_SKB_CB (tp->retransmit_skb_hint)->seq))) tp->retransmit_skb_hint = skb; }
Greg Kroah-Hartman
maintainerPATCH 50/65 xen/blkfront: Adjust indentation in xlvbd_alloc_gendisk
In reply to Greg Kroah-HartmanFrom: Nathan Chancellor <[email protected]>
commit 589b72894f53124a39d1bb3c0cecaf9dcabac417 upstream.
Clang warns:
../drivers/block/xen-blkfront.c:1117:4: warning: misleading indentation; statement is not part of the previous 'if' [-Wmisleading-indentation]
nr_parts = PARTS_PER_DISK;
^
../drivers/block/xen-blkfront.c:1115:3: note: previous statement is here
if (err)
^This is because there is a space at the beginning of this line; remove it so that the indentation is consistent according to the Linux kernel coding style and clang no longer warns.
While we are here, the previous line has some trailing whitespace; clean that up as well.
--- drivers/block/xen-blkfront.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/block/xen-blkfront.c +2 -2
@@ -1115,8 +1115,8 @@ static int xlvbd_alloc_gendisk(blkif_secif (!VDEV_IS_EXTENDED (info->vdevice)) { err =xen_translate_vdev (info->vdevice, &minor, &offset);if (err) -return err; - nr_parts =PARTS_PER_DISK ; +return err; + nr_parts =PARTS_PER_DISK ; }else { minor =BLKIF_MINOR_EXT (info->vdevice); nr_parts =PARTS_PER_EXT_DISK ;
Greg Kroah-Hartman
maintainerPATCH 51/65 cw1200: Fix a signedness bug in cw1200_load_firmware()
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
commit 4a50d454502f1401171ff061a5424583f91266db upstream.
The "priv->hw_type" is an enum and in this context GCC will treat it as an unsigned int so the error handling will never trigger.
--- drivers/net/wireless/st/cw1200/fwio.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/net/wireless/st/cw1200/fwio.c +3 -3
@@ -323,12 +323,12 @@ int cw1200_load_firmware(struct cw1200_c goto out; } - priv->hw_type =cw1200_get_hw_type (val32, &major_revision); -if (priv->hw_type <0 ) { + ret =cw1200_get_hw_type (val32, &major_revision); +if (ret <0 ) {pr_err ("Can't deduce hardware type.\n" ); - ret = -ENOTSUPP ; goto out; } + priv->hw_type = ret;/* Set DPLL Reg value, and read back to confirm writes work */ ret = cw1200_reg_write_32(priv, ST90TDS_TSET_GEN_R_W_REG_ID,
Greg Kroah-Hartman
maintainerPATCH 52/65 arm64: dts: meson-gxl-s905x-khadas-vim: fix gpio-keys-polled node
In reply to Greg Kroah-HartmanFrom: Christian Hewitt <[email protected]>
commit d5f6fa904ecbadbb8e9fa6302b0fc165bec0559a upstream.
Fix DTC warnings:
arch/arm/dts/meson-gxl-s905x-khadas-vim.dtb: Warning (avoid_unnecessary_addr_size):
/gpio-keys-polled: unnecessary #address-cells/#size-cells
without "ranges" or child "reg" property
--- arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts +1 -3
@@ -33,11 +33,9 @@ gpio-keys-polled { compatible = "gpio-keys-polled"; - #address-cells = <1>; - #size-cells = <0>; poll-interval = <100>; - button@0 { + power-button { label = "power"; linux,code = <KEY_POWER>; gpios = <&gpio_ao GPIOAO_2 GPIO_ACTIVE_LOW>;
Greg Kroah-Hartman
maintainerPATCH 53/65 cfg80211: check for set_wiphy_params
In reply to Greg Kroah-HartmanFrom: Johannes Berg <[email protected]>
commit 24953de0a5e31dcca7e82c8a3c79abc2dfe8fb6e upstream.
Check if set_wiphy_params is assigned and return an error if not, some drivers (e.g. virt_wifi where syzbot reported it) don't have it.
--- net/wireless/rdev-ops.h | 4 ++++ 1 file changed, 4 insertions(+)
net/wireless/rdev-ops.h +4 -0
@@ -537,6 +537,10 @@ static inline int rdev_set_wiphy_params(struct cfg80211_registered_device *rdev, u32 changed) { int ret; + +if (!rdev->ops->set_wiphy_params) +return -EOPNOTSUPP ; +trace_rdev_set_wiphy_params (&rdev->wiphy, changed); ret = rdev->ops->set_wiphy_params (&rdev->wiphy, changed);trace_rdev_return_int (&rdev->wiphy, ret);
Greg Kroah-Hartman
maintainerPATCH 54/65 tick/sched: Annotate lockless access to last_jiffies_update
In reply to Greg Kroah-HartmanFrom: Eric Dumazet <[email protected]>
commit de95a991bb72e009f47e0c4bbc90fc5f594588d5 upstream.
syzbot (KCSAN) reported a data-race in tick_do_update_jiffies64():
BUG: KCSAN: data-race in tick_do_update_jiffies64 / tick_do_update_jiffies64
write to 0xffffffff8603d008 of 8 bytes by interrupt on cpu 1:
tick_do_update_jiffies64+0x100/0x250 kernel/time/tick-sched.c:73 tick_sched_do_timer+0xd4/0xe0 kernel/time/tick-sched.c:138 tick_sched_timer+0x43/0xe0 kernel/time/tick-sched.c:1292 __run_hrtimer kernel/time/hrtimer.c:1514 [inline] __hrtimer_run_queues+0x274/0x5f0 kernel/time/hrtimer.c:1576 hrtimer_interrupt+0x22a/0x480 kernel/time/hrtimer.c:1638 local_apic_timer_interrupt arch/x86/kernel/apic/apic.c:1110 [inline] smp_apic_timer_interrupt+0xdc/0x280 arch/x86/kernel/apic/apic.c:1135 apic_timer_interrupt+0xf/0x20 arch/x86/entry/entry_64.S:830 arch_local_irq_restore arch/x86/include/asm/paravirt.h:756 [inline] kcsan_setup_watchpoint+0x1d4/0x460 kernel/kcsan/core.c:436 check_access kernel/kcsan/core.c:466 [inline] __tsan_read1 kernel/kcsan/core.c:593 [inline] __tsan_read1+0xc2/0x100 kernel/kcsan/core.c:593 kallsyms_expand_symbol.constprop.0+0x70/0x160 kernel/kallsyms.c:79 kallsyms_lookup_name+0x7f/0x120 kernel/kallsyms.c:170 insert_report_filterlist kernel/kcsan/debugfs.c:155 [inline] debugfs_write+0x14b/0x2d0 kernel/kcsan/debugfs.c:256 full_proxy_write+0xbd/0x100 fs/debugfs/file.c:225 __vfs_write+0x67/0xc0 fs/read_write.c:494 vfs_write fs/read_write.c:558 [inline] vfs_write+0x18a/0x390 fs/read_write.c:542 ksys_write+0xd5/0x1b0 fs/read_write.c:611 __do_sys_write fs/read_write.c:623 [inline] __se_sys_write fs/read_write.c:620 [inline] __x64_sys_write+0x4c/0x60 fs/read_write.c:620 do_syscall_64+0xcc/0x370 arch/x86/entry/common.c:290 entry_SYSCALL_64_after_hwframe+0x44/0xa9
read to 0xffffffff8603d008 of 8 bytes by task 0 on cpu 0:
tick_do_update_jiffies64+0x2b/0x250 kernel/time/tick-sched.c:62 tick_nohz_update_jiffies kernel/time/tick-sched.c:505 [inline] tick_nohz_irq_enter kernel/time/tick-sched.c:1257 [inline] tick_irq_enter+0x139/0x1c0 kernel/time/tick-sched.c:1274 irq_enter+0x4f/0x60 kernel/softirq.c:354 entering_irq arch/x86/include/asm/apic.h:517 [inline] entering_ack_irq arch/x86/include/asm/apic.h:523 [inline] smp_apic_timer_interrupt+0x55/0x280 arch/x86/kernel/apic/apic.c:1133 apic_timer_interrupt+0xf/0x20 arch/x86/entry/entry_64.S:830 native_safe_halt+0xe/0x10 arch/x86/include/asm/irqflags.h:60 arch_cpu_idle+0xa/0x10 arch/x86/kernel/process.c:571 default_idle_call+0x1e/0x40 kernel/sched/idle.c:94 cpuidle_idle_call kernel/sched/idle.c:154 [inline] do_idle+0x1af/0x280 kernel/sched/idle.c:263 cpu_startup_entry+0x1b/0x20 kernel/sched/idle.c:355 rest_init+0xec/0xf6 init/main.c:452 arch_call_rest_init+0x17/0x37 start_kernel+0x838/0x85e init/main.c:786 x86_64_start_reservations+0x29/0x2b arch/x86/kernel/head64.c:490 x86_64_start_kernel+0x72/0x76 arch/x86/kernel/head64.c:471 secondary_startup_64+0xa4/0xb0 arch/x86/kernel/head_64.S:241
Reported by Kernel Concurrency Sanitizer on:
CPU: 0 PID: 0 Comm: swapper/0 Not tainted 5.4.0-rc7+ #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
Use READ_ONCE() and WRITE_ONCE() to annotate this expected race.
--- kernel/time/tick-sched.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-)
kernel/time/tick-sched.c +9 -5
@@ -60,8 +60,9 @@ static void tick_do_update_jiffies64(kti/* * Do a quick check without holding jiffies_lock: +* The READ_ONCE() pairs with two updates done later in this function. */ - delta =ktime_sub (now, last_jiffies_update); + delta =ktime_sub (now,READ_ONCE (last_jiffies_update));if (delta < tick_period)return ;
@@ -72,8 +73,9 @@ static void tick_do_update_jiffies64(ktiif (delta >= tick_period) { delta =ktime_sub (delta, tick_period); - last_jiffies_update =ktime_add (last_jiffies_update, - tick_period); +/* Pairs with the lockless read in this function. */ +WRITE_ONCE (last_jiffies_update, +ktime_add (last_jiffies_update, tick_period));/* Slow path for long timeouts */ if (unlikely (delta >= tick_period)) {
@@ -81,8 +83,10 @@ static void tick_do_update_jiffies64(kti ticks =ktime_divns (delta, incr); - last_jiffies_update =ktime_add_ns (last_jiffies_update, - incr * ticks); +/* Pairs with the lockless read in this function. */ +WRITE_ONCE (last_jiffies_update, +ktime_add_ns (last_jiffies_update, + incr * ticks)); }do_timer (++ticks);
Greg Kroah-Hartman
maintainerPATCH 55/65 Revert "arm64: dts: juno: add dma-ranges property"
In reply to Greg Kroah-HartmanFrom: Sudeep Holla <[email protected]>
commit 54fb3fe0f211d4729a2551cf9497bd612189af9d upstream.
This reverts commit 193d00a2b35ee3353813b4006a18131122087205.
Commit 951d48855d86 ("of: Make of_dma_get_range() work on bus nodes") reworked the logic such that of_dma_get_range() works correctly starting from a bus node containing "dma-ranges".
Since on Juno we don't have a SoC level bus node and "dma-ranges" is present only in the root node, we get the following error:
OF: translation of DMA address(0) to CPU address failed node(/sram@2e000000)
OF: translation of DMA address(0) to CPU address failed node(/uart@7ff80000)
...
OF: translation of DMA address(0) to CPU address failed node(/mhu@2b1f0000)
OF: translation of DMA address(0) to CPU address failed node(/iommu@2b600000)
OF: translation of DMA address(0) to CPU address failed node(/iommu@2b600000)
OF: translation of DMA address(0) to CPU address failed node(/iommu@2b600000)
So let's fix it by dropping the "dma-ranges" property for now. This should be fine since it doesn't represent any kind of device-visible restriction; it was only there for completeness, and we've since given in to the assumption that missing "dma-ranges" implies a 1:1 mapping anyway.
We can add it later with a proper SoC bus node and moving all the devices that belong there along with the "dma-ranges" if required.
--- arch/arm64/boot/dts/arm/juno-base.dtsi | 1 - 1 file changed, 1 deletion(-)
arch/arm64/boot/dts/arm/juno-base.dtsi +0 -1
@@ -5,7 +5,6 @@ /* * Devices shared by all Juno boards */ - dma-ranges = <0 0 0 0 0x100 0>; memtimer: timer@2a810000 { compatible = "arm,armv7-timer-mem";
Greg Kroah-Hartman
maintainerPATCH 56/65 reiserfs: fix handling of -EOPNOTSUPP in reiserfs_for_each_xattr
In reply to Greg Kroah-HartmanFrom: Jeff Mahoney <[email protected]>
commit 394440d469413fa9b74f88a11f144d76017221f2 upstream.
Commit 60e4cf67a58 (reiserfs: fix extended attributes on the root directory) introduced a regression open_xa_root started returning -EOPNOTSUPP but it was not handled properly in reiserfs_for_each_xattr.
When the reiserfs module is built without CONFIG_REISERFS_FS_XATTR, deleting an inode would result in a warning and chowning an inode would also result in a warning and then fail to complete.
With CONFIG_REISERFS_FS_XATTR enabled, the xattr root would always be present for read-write operations.
This commit handles -EOPNOSUPP in the same way -ENODATA is handled.
--- fs/reiserfs/xattr.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
fs/reiserfs/xattr.c +6 -2
@@ -319,8 +319,12 @@ static int reiserfs_for_each_xattr(struc out_dir:dput (dir); out: -/* -ENODATA isn't an error */ -if (err == -ENODATA ) +/* +* -ENODATA: this object doesn't have any xattrs +* -EOPNOTSUPP: this file system doesn't have xattrs enabled on disk. +* Neither are errors +*/ +if (err == -ENODATA || err == -EOPNOTSUPP ) err =0 ;return err; }
Greg Kroah-Hartman
maintainerPATCH 57/65 scsi: esas2r: unlock on error in esas2r_nvram_read_direct()
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
commit 906ca6353ac09696c1bf0892513c8edffff5e0a6 upstream.
This error path is missing an unlock.
--- drivers/scsi/esas2r/esas2r_flash.c | 1 + 1 file changed, 1 insertion(+)
drivers/scsi/esas2r/esas2r_flash.c +1 -0
@@ -1197,6 +1197,7 @@ bool esas2r_nvram_read_direct(struct esaif (!esas2r_read_flash_block (a, a->nvram,FLS_OFFSET_NVR ,sizeof (struct esas2r_sas_nvram ))) {esas2r_hdebug ("NVRAM read failed, using defaults" ); +up (&a->nvram_semaphore);return false; }
Greg Kroah-Hartman
maintainerPATCH 58/65 scsi: qla4xxx: fix double free bug
In reply to Greg Kroah-HartmanFrom: Pan Bian <[email protected]>
commit 3fe3d2428b62822b7b030577cd612790bdd8c941 upstream.
The variable init_fw_cb is released twice, resulting in a double free bug. The call to the function dma_free_coherent() before goto is removed to get rid of potential double free.
--- drivers/scsi/qla4xxx/ql4_mbx.c | 3 --- 1 file changed, 3 deletions(-)
drivers/scsi/qla4xxx/ql4_mbx.c +0 -3
@@ -641,9 +641,6 @@ int qla4xxx_initialize_fw_cb(struct scsiif (qla4xxx_get_ifcb (ha, &mbox_cmd[0 ], &mbox_sts[0 ], init_fw_cb_dma) !=QLA_SUCCESS ) { -dma_free_coherent (&ha->pdev->dev, -sizeof (struct addr_ctrl_blk ), - init_fw_cb, init_fw_cb_dma); goto exit_init_fw_cb; }
Greg Kroah-Hartman
maintainerPATCH 59/65 scsi: bnx2i: fix potential use after free
In reply to Greg Kroah-HartmanFrom: Pan Bian <[email protected]>
commit 29d28f2b8d3736ac61c28ef7e20fda63795b74d9 upstream.
The member hba->pcidev may be used after its reference is dropped. Move the put function to where it is never used to avoid potential use after free issues.
--- drivers/scsi/bnx2i/bnx2i_iscsi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/scsi/bnx2i/bnx2i_iscsi.c +1 -1
@@ -915,12 +915,12 @@ void bnx2i_free_hba(struct bnx2i_hba *hbINIT_LIST_HEAD (&hba->ep_ofld_list);INIT_LIST_HEAD (&hba->ep_active_list);INIT_LIST_HEAD (&hba->ep_destroy_list); -pci_dev_put (hba->pcidev);if (hba->regview) {pci_iounmap (hba->pcidev, hba->regview); hba->regview =NULL ; } +pci_dev_put (hba->pcidev);bnx2i_free_mp_bdt (hba);bnx2i_release_free_cid_que (hba);iscsi_host_free (shost);
Greg Kroah-Hartman
maintainerPATCH 60/65 scsi: target: core: Fix a pr_debug() argument
In reply to Greg Kroah-HartmanFrom: Bart Van Assche <[email protected]>
commit c941e0d172605731de9b4628bd4146d35cf2e7d6 upstream.
Print the string for which conversion failed instead of printing the function name twice.
--- drivers/target/target_core_fabric_lib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/target/target_core_fabric_lib.c +1 -1
@@ -131,7 +131,7 @@ static int srp_get_pr_transport_id(memset (buf +8 ,0 , leading_zero_bytes); rc =hex2bin (buf +8 + leading_zero_bytes, p, count);if (rc <0 ) { -pr_debug ("hex2bin failed for %s: %d\n" , __func__, rc); +pr_debug ("hex2bin failed for %s: %d\n" , p, rc);return rc; }
Greg Kroah-Hartman
maintainerPATCH 61/65 scsi: qla2xxx: Fix qla2x00_request_irqs() for MSI
In reply to Greg Kroah-HartmanFrom: Huacai Chen <[email protected]>
commit 45dc8f2d9c94ed74a5e31e63e9136a19a7e16081 upstream.
Commit 4fa183455988 ("scsi: qla2xxx: Utilize pci_alloc_irq_vectors/ pci_free_irq_vectors calls.") use pci_alloc_irq_vectors() to replace pci_enable_msi() but it didn't handle the return value correctly. This bug make qla2x00 always fail to setup MSI if MSI-X fail, so fix it.
BTW, improve the log message of return value in qla2x00_request_irqs() to avoid confusion.
--- drivers/scsi/qla2xxx/qla_isr.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/scsi/qla2xxx/qla_isr.c +3 -3
@@ -3519,7 +3519,7 @@ qla2x00_request_irqs(struct qla_hw_data skip_msix:ql_log (ql_log_info, vha,0x0037 , -"Falling back-to MSI mode -%d.\n" , ret); +"Falling back-to MSI mode -- ret=%d.\n" , ret); if (!IS_QLA24XX(ha) && !IS_QLA2532(ha) && !IS_QLA8432(ha) && !IS_QLA8001(ha) && !IS_P3P_TYPE(ha) && !IS_QLAFX00(ha) &&
@@ -3527,13 +3527,13 @@ skip_msix: goto skip_msi; ret =pci_alloc_irq_vectors (ha->pdev,1 ,1 ,PCI_IRQ_MSI ); -if (!ret) { +if (ret >0 ) {ql_dbg (ql_dbg_init, vha,0x0038 ,"MSI: Enabled.\n" ); ha->flags.msi_enabled =1 ; }else ql_log (ql_log_warn, vha,0x0039 , -"Falling back-to INTa mode -- %d.\n" , ret); +"Falling back-to INTa mode -- ret=%d.\n" , ret); skip_msi:/* Skip INTx on ISP82xx. */
Greg Kroah-Hartman
maintainerPATCH 62/65 scsi: qla2xxx: fix rports not being mark as lost in sync fabric scan
In reply to Greg Kroah-HartmanFrom: Martin Wilck <[email protected]>
commit d341e9a8f2cffe4000c610225c629f62c7489c74 upstream.
In qla2x00_find_all_fabric_devs(), fcport->flags & FCF_LOGIN_NEEDED is a necessary condition for logging into new rports, but not for dropping lost ones.
--- drivers/scsi/qla2xxx/qla_init.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/scsi/qla2xxx/qla_init.c +3 -3
@@ -5145,8 +5145,7 @@ qla2x00_find_all_fabric_devs(scsi_qla_hoif (test_bit (LOOP_RESYNC_NEEDED , &vha->dpc_flags))break ; -if ((fcport->flags &FCF_FABRIC_DEVICE ) ==0 || - (fcport->flags &FCF_LOGIN_NEEDED ) ==0 ) +if ((fcport->flags &FCF_FABRIC_DEVICE ) ==0 )continue ;if (fcport->scan_state ==QLA_FCPORT_SCAN ) {
@@ -5171,7 +5170,8 @@ qla2x00_find_all_fabric_devs(scsi_qla_ho } } -if (fcport->scan_state ==QLA_FCPORT_FOUND ) +if (fcport->scan_state ==QLA_FCPORT_FOUND && + (fcport->flags &FCF_LOGIN_NEEDED ) !=0 )qla24xx_fcport_handle_login (vha, fcport); }return (rval);
Greg Kroah-Hartman
maintainerPATCH 63/65 scsi: core: scsi_trace: Use get_unaligned_be*()
In reply to Greg Kroah-HartmanFrom: Bart Van Assche <[email protected]>
commit b1335f5b0486f61fb66b123b40f8e7a98e49605d upstream.
This patch fixes an unintended sign extension on left shifts. From Colin
King: "Shifting a u8 left will cause the value to be promoted to an integer. If the top bit of the u8 is set then the following conversion to an u64 will sign extend the value causing the upper 32 bits to be set in the result."
Fix this by using get_unaligned_be*() instead.
--- drivers/scsi/scsi_trace.c | 103 ++++++++++++---------------------------------- 1 file changed, 28 insertions(+), 75 deletions(-)
drivers/scsi/scsi_trace.c +28 -75
@@ -21,7 +21,7 @@#include <trace/events/scsi.h> #define SERVICE_ACTION16 (cdb) (cdb[1] & 0x1f) -#define SERVICE_ACTION32 (cdb) ((cdb[8] << 8) | cdb[9]) +#define SERVICE_ACTION32 (cdb) (get_unaligned_be16(&cdb[8]))static const char *scsi_trace_misc (struct trace_seq *,unsigned char *,int );
@@ -51,17 +51,12 @@ static const char * scsi_trace_rw10(struct trace_seq *p, unsigned char *cdb, int len) { const char *ret = trace_seq_buffer_ptr(p); -sector_t lba =0 , txlen =0 ; +u32 lba, txlen; - lba |= (cdb[2 ] <<24 ); - lba |= (cdb[3 ] <<16 ); - lba |= (cdb[4 ] <<8 ); - lba |= cdb[5 ]; - txlen |= (cdb[7 ] <<8 ); - txlen |= cdb[8 ]; + lba =get_unaligned_be32 (&cdb[2 ]); + txlen =get_unaligned_be16 (&cdb[7 ]); -trace_seq_printf (p,"lba=%llu txlen=%llu protect=%u" , - (unsigned long long )lba, (unsigned long long )txlen, +trace_seq_printf (p,"lba=%u txlen=%u protect=%u" , lba, txlen, cdb[1 ] >>5 );if (cdb[0 ] ==WRITE_SAME )
@@ -76,19 +71,12 @@ static const char * scsi_trace_rw12(struct trace_seq *p, unsigned char *cdb, int len) { const char *ret = trace_seq_buffer_ptr(p); -sector_t lba =0 , txlen =0 ; +u32 lba, txlen; - lba |= (cdb[2 ] <<24 ); - lba |= (cdb[3 ] <<16 ); - lba |= (cdb[4 ] <<8 ); - lba |= cdb[5 ]; - txlen |= (cdb[6 ] <<24 ); - txlen |= (cdb[7 ] <<16 ); - txlen |= (cdb[8 ] <<8 ); - txlen |= cdb[9 ]; + lba =get_unaligned_be32 (&cdb[2 ]); + txlen =get_unaligned_be32 (&cdb[6 ]); -trace_seq_printf (p,"lba=%llu txlen=%llu protect=%u" , - (unsigned long long )lba, (unsigned long long )txlen, +trace_seq_printf (p,"lba=%u txlen=%u protect=%u" , lba, txlen, cdb[1 ] >>5 );trace_seq_putc (p,0 );
@@ -99,23 +87,13 @@ static const char * scsi_trace_rw16(struct trace_seq *p, unsigned char *cdb, int len) { const char *ret = trace_seq_buffer_ptr(p); -sector_t lba =0 , txlen =0 ; +u64 lba; +u32 txlen; - lba |= ((u64 )cdb[2 ] <<56 ); - lba |= ((u64 )cdb[3 ] <<48 ); - lba |= ((u64 )cdb[4 ] <<40 ); - lba |= ((u64 )cdb[5 ] <<32 ); - lba |= (cdb[6 ] <<24 ); - lba |= (cdb[7 ] <<16 ); - lba |= (cdb[8 ] <<8 ); - lba |= cdb[9 ]; - txlen |= (cdb[10 ] <<24 ); - txlen |= (cdb[11 ] <<16 ); - txlen |= (cdb[12 ] <<8 ); - txlen |= cdb[13 ]; + lba =get_unaligned_be64 (&cdb[2 ]); + txlen =get_unaligned_be32 (&cdb[10 ]); -trace_seq_printf (p,"lba=%llu txlen=%llu protect=%u" , - (unsigned long long )lba, (unsigned long long )txlen, +trace_seq_printf (p,"lba=%llu txlen=%u protect=%u" , lba, txlen, cdb[1 ] >>5 );if (cdb[0 ] ==WRITE_SAME_16 )
@@ -130,8 +108,8 @@ static const char * scsi_trace_rw32(struct trace_seq *p, unsigned char *cdb, int len) { const char *ret = trace_seq_buffer_ptr(p), *cmd; -sector_t lba =0 , txlen =0 ; -u32 ei_lbrt =0 ; +u64 lba; +u32 ei_lbrt, txlen;switch (SERVICE_ACTION32 (cdb)) {case READ_32 :
@@ -151,26 +129,12 @@ scsi_trace_rw32(struct trace_seq *p, uns goto out; } - lba |= ((u64 )cdb[12 ] <<56 ); - lba |= ((u64 )cdb[13 ] <<48 ); - lba |= ((u64 )cdb[14 ] <<40 ); - lba |= ((u64 )cdb[15 ] <<32 ); - lba |= (cdb[16 ] <<24 ); - lba |= (cdb[17 ] <<16 ); - lba |= (cdb[18 ] <<8 ); - lba |= cdb[19 ]; - ei_lbrt |= (cdb[20 ] <<24 ); - ei_lbrt |= (cdb[21 ] <<16 ); - ei_lbrt |= (cdb[22 ] <<8 ); - ei_lbrt |= cdb[23 ]; - txlen |= (cdb[28 ] <<24 ); - txlen |= (cdb[29 ] <<16 ); - txlen |= (cdb[30 ] <<8 ); - txlen |= cdb[31 ]; - -trace_seq_printf (p,"%s_32 lba=%llu txlen=%llu protect=%u ei_lbrt=%u" , - cmd, (unsigned long long )lba, - (unsigned long long )txlen, cdb[10 ] >>5 , ei_lbrt); + lba =get_unaligned_be64 (&cdb[12 ]); + ei_lbrt =get_unaligned_be32 (&cdb[20 ]); + txlen =get_unaligned_be32 (&cdb[28 ]); + +trace_seq_printf (p,"%s_32 lba=%llu txlen=%u protect=%u ei_lbrt=%u" , + cmd, lba, txlen, cdb[10 ] >>5 , ei_lbrt);if (SERVICE_ACTION32 (cdb) ==WRITE_SAME_32 )trace_seq_printf (p," unmap=%u" , cdb[10 ] >>3 &1 );
@@ -185,7 +149,7 @@ static const char * scsi_trace_unmap(struct trace_seq *p, unsigned char *cdb, int len) { const char *ret = trace_seq_buffer_ptr(p); -unsigned int regions = cdb[7 ] <<8 | cdb[8 ]; +unsigned int regions =get_unaligned_be16 (&cdb[7 ]);trace_seq_printf (p,"regions=%u" , (regions -8 ) /16 );trace_seq_putc (p,0 );
@@ -197,8 +161,8 @@ static const char * scsi_trace_service_action_in(struct trace_seq *p, unsigned char *cdb, int len) { const char *ret = trace_seq_buffer_ptr(p), *cmd; -sector_t lba =0 ; -u32 alloc_len =0 ; +u64 lba; +u32 alloc_len;switch (SERVICE_ACTION16 (cdb)) {case SAI_READ_CAPACITY_16 :
@@ -212,21 +176,10 @@ scsi_trace_service_action_in(struct trac goto out; } - lba |= ((u64 )cdb[2 ] <<56 ); - lba |= ((u64 )cdb[3 ] <<48 ); - lba |= ((u64 )cdb[4 ] <<40 ); - lba |= ((u64 )cdb[5 ] <<32 ); - lba |= (cdb[6 ] <<24 ); - lba |= (cdb[7 ] <<16 ); - lba |= (cdb[8 ] <<8 ); - lba |= cdb[9 ]; - alloc_len |= (cdb[10 ] <<24 ); - alloc_len |= (cdb[11 ] <<16 ); - alloc_len |= (cdb[12 ] <<8 ); - alloc_len |= cdb[13 ]; + lba =get_unaligned_be64 (&cdb[2 ]); + alloc_len =get_unaligned_be32 (&cdb[10 ]); -trace_seq_printf (p,"%s lba=%llu alloc_len=%u" , cmd, - (unsigned long long )lba, alloc_len); +trace_seq_printf (p,"%s lba=%llu alloc_len=%u" , cmd, lba, alloc_len); out:trace_seq_putc (p,0 );
Greg Kroah-Hartman
maintainerPATCH 64/65 perf probe: Fix wrong address verification
In reply to Greg Kroah-HartmanFrom: Masami Hiramatsu <[email protected]>
commit 07d369857808b7e8e471bbbbb0074a6718f89b31 upstream.
Since there are some DIE which has only ranges instead of the combination of entrypc/highpc, address verification must use dwarf_haspc() instead of dwarf_entrypc/dwarf_highpc.
Also, the ranges only DIE will have a partial code in different section (e.g. unlikely code will be in text.unlikely as "FUNC.cold" symbol). In that case, we can not use dwarf_entrypc() or die_entrypc(), because the offset from original DIE can be a minus value.
Instead, this simply gets the symbol and offset from symtab.
Without this patch;
# perf probe -D clear_tasks_mm_cpumask:1
Failed to get entry address of clear_tasks_mm_cpumask
Error: Failed to add events.And with this patch:
# perf probe -D clear_tasks_mm_cpumask:1 p:probe/clear_tasks_mm_cpumask clear_tasks_mm_cpumask+0 p:probe/clear_tasks_mm_cpumask_1 clear_tasks_mm_cpumask+5 p:probe/clear_tasks_mm_cpumask_2 clear_tasks_mm_cpumask+8 p:probe/clear_tasks_mm_cpumask_3 clear_tasks_mm_cpumask+16 p:probe/clear_tasks_mm_cpumask_4 clear_tasks_mm_cpumask+82
Committer testing:
I managed to reproduce the above:
[root@quaco ~]# perf probe -D clear_tasks_mm_cpumask:1 p:probe/clear_tasks_mm_cpumask _text+919968 p:probe/clear_tasks_mm_cpumask_1 _text+919973 p:probe/clear_tasks_mm_cpumask_2 _text+919976 [root@quaco ~]#
But then when trying to actually put the probe in place, it fails if I use :0 as the offset:
[root@quaco ~]# perf probe -L clear_tasks_mm_cpumask | head -5
<clear_tasks_mm_cpumask@/usr/src/debug/kernel-5.2.fc30/linux-5.2.18-200.fc30.x86_64/kernel/cpu.c:0>
0 void clear_tasks_mm_cpumask(int cpu)
1 {
2 struct task_struct *p; [root@quaco ~]# perf probe clear_tasks_mm_cpumask:0 Probe point 'clear_tasks_mm_cpumask' not found.
Error: Failed to add events.
[root@quaco
The next patch is needed to fix this case.
--- tools/perf/util/probe-finder.c | 32 ++++++++++---------------------- 1 file changed, 10 insertions(+), 22 deletions(-)
tools/perf/util/probe-finder.c +10 -22
@@ -615,38 +615,26 @@ static int convert_to_trace_point(Dwarf_const char *function, struct probe_trace_point *tp) { - Dwarf_Addr eaddr, highaddr; + Dwarf_Addr eaddr;GElf_Sym sym;const char *symbol;/* Verify the address is correct */ -if (dwarf_entrypc (sp_die, &eaddr) !=0 ) { -pr_warning ("Failed to get entry address of %s\n" , -dwarf_diename (sp_die)); -return -ENOENT ; - } -if (dwarf_highpc (sp_die, &highaddr) !=0 ) { -pr_warning ("Failed to get end address of %s\n" , -dwarf_diename (sp_die)); -return -ENOENT ; - } -if (paddr > highaddr) { -pr_warning ("Offset specified is greater than size of %s\n" , +if (!dwarf_haspc (sp_die, paddr)) { +pr_warning ("Specified offset is out of %s\n" ,dwarf_diename (sp_die));return -EINVAL ; } - symbol =dwarf_diename (sp_die); +/* Try to get actual symbol name from symtab */ + symbol =dwfl_module_addrsym (mod, paddr, &sym,NULL );if (!symbol) { -/* Try to get the symbol name from symtab */ - symbol =dwfl_module_addrsym (mod, paddr, &sym,NULL ); -if (!symbol) { -pr_warning ("Failed to find symbol at 0x%lx\n" , - (unsigned long )paddr); -return -ENOENT ; - } - eaddr = sym.st_value; +pr_warning ("Failed to find symbol at 0x%lx\n" , + (unsigned long )paddr); +return -ENOENT ; } + eaddr = sym.st_value; + tp->offset = (unsigned long )(paddr - eaddr); tp->address = (unsigned long )paddr; tp->symbol =strdup (symbol);
Greg Kroah-Hartman
maintainerPATCH 65/65 regulator: ab8500: Remove SYSCLKREQ from enum ab8505_regulator_id
In reply to Greg Kroah-HartmanFrom: Stephan Gerhold <[email protected]>
commit 458ea3ad033fc86e291712ce50cbe60c3428cf30 upstream.
Those regulators are not actually supported by the AB8500 regulator driver. There is no ab8500_regulator_info for them and no entry in ab8505_regulator_match.
As such, they cannot be registered successfully, and looking them up in ab8505_regulator_match causes an out-of-bounds array read.
--- include/linux/regulator/ab8500.h | 2 -- 1 file changed, 2 deletions(-)
include/linux/regulator/ab8500.h +0 -2
@@ -43,8 +43,6 @@ enum ab8505_regulator_id {AB8505_LDO_ANAMIC2 ,AB8505_LDO_AUX8 ,AB8505_LDO_ANA , -AB8505_SYSCLKREQ_2 , -AB8505_SYSCLKREQ_4 , AB8505_NUM_REGULATORS, };
Quoted 10 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 4.14.167 release. There are 65 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Fri, 24 Jan 2020 09:25:24 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.14.167-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-4.14.y
and the diffstat can be found below.thanks,
greg k-h
Results from Linaro’s test farm.
No regressions on arm64, arm, x86_64, and i386.
Summary
------------------------------------------------------------------------
kernel: 4.14.167-rc1
git repo: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git
git branch: linux-4.14.y
git commit: bb5af942ee10d2c10d2fef949267311a54bae868
git describe: v4.14.166-66-gbb5af942ee10
Test details: https://qa-reports.linaro.org/lkft/linux-stable-rc-4.14-oe/build/v4.14.166-66-gbb5af942ee10
No regressions (compared to build v4.14.166)
No fixes (compared to build v4.14.166)
Ran 19891 total tests in the following environments and test suites.
Environments
--------------
- dragonboard-410c - arm64
- hi6220-hikey - arm64
- i386
- juno-r2 - arm64
- qemu_arm
- qemu_arm64
- qemu_i386
- qemu_x86_64
- x15 - arm
- x86_64
Test Suites
-----------
* build
* install-android-platform-tools-r2600
* kselftest
* linux-log-parser
* ltp-containers-tests
* libhugetlbfs
* ltp-cap_bounds-tests
* ltp-commands-tests
* ltp-cpuhotplug-tests
* ltp-cve-tests
* ltp-dio-tests
* ltp-fcntl-locktests-tests
* ltp-filecaps-tests
* ltp-fs-tests
* ltp-fs_bind-tests
* ltp-fs_perms_simple-tests
* ltp-fsx-tests
* ltp-hugetlb-tests
* ltp-io-tests
* ltp-ipc-tests
* ltp-math-tests
* ltp-mm-tests
* ltp-open-posix-tests
* ltp-pty-tests
* ltp-sched-tests
* ltp-securebits-tests
* ltp-syscalls-tests
* network-basic-tests
* perf
* spectre-meltdown-checker-test
* v4l2-compliance
* kvm-unit-tests
* ltp-nptl-tests
* kselftest-vsyscall-mode-native
* kselftest-vsyscall-mode-none
Signature · 2 lines
Linaro LKFT https://lkft.linaro.org
Jon Hunter
maintainerQuoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 4.14.167 release. There are 65 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Fri, 24 Jan 2020 09:25:24 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.14.167-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-4.14.y
and the diffstat can be found below.thanks,
greg k-h
All tests are passing for Tegra ...
Test results for stable-v4.14:
8 builds: 8 pass, 0 fail
16 boots: 16 pass, 0 fail
24 tests: 24 pass, 0 failLinux version: 4.14.167-rc1-gbb5af942ee10
Boards tested: tegra124-jetson-tk1, tegra20-ventana,
tegra210-p2371-2180, tegra30-cardhu-a04
Cheers
Jon
Signature · 1 line
nvpublic
Quoted 8 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 4.14.167 release. There are 65 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Fri, 24 Jan 2020 09:25:24 +0000. Anything received after that time might be too late.
Build results:
total: 172 pass: 172 fail: 0 Qemu test results: total: 375 pass: 375 fail: 0
Guenter
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 4.14.167 release. There are 65 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Fri, 24 Jan 2020 09:25:24 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 9 lines
https://www.kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.14.167-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-4.14.y
and the diffstat can be found below.thanks,
greg k-h
Compiled and booted on my test system. No dmesg regressions.
thanks,
-- Shuah