linux/drivers
Vladimir Oltean bcf2c1dc53 net: enetc: avoid buffer leaks on xdp_do_redirect() failure
[ Upstream commit 628050ec95 ]

Before enetc_clean_rx_ring_xdp() calls xdp_do_redirect(), each software
BD in the RX ring between index orig_i and i can have one of 2 refcount
values on its page.

We are the owner of the current buffer that is being processed, so the
refcount will be at least 1.

If the current owner of the buffer at the diametrically opposed index
in the RX ring (i.o.w, the other half of this page) has not yet called
kfree(), this page's refcount could even be 2.

enetc_page_reusable() in enetc_flip_rx_buff() tests for the page
refcount against 1, and [ if it's 2 ] does not attempt to reuse it.

But if enetc_flip_rx_buff() is put after the xdp_do_redirect() call,
the page refcount can have one of 3 values. It can also be 0, if there
is no owner of the other page half, and xdp_do_redirect() for this
buffer ran so far that it triggered a flush of the devmap/cpumap bulk
queue, and the consumers of those bulk queues also freed the buffer,
all by the time xdp_do_redirect() returns the execution back to enetc.

This is the reason why enetc_flip_rx_buff() is called before
xdp_do_redirect(), but there is a big flaw with that reasoning:
enetc_flip_rx_buff() will set rx_swbd->page = NULL on both sides of the
enetc_page_reusable() branch, and if xdp_do_redirect() returns an error,
we call enetc_xdp_free(), which does not deal gracefully with that.

In fact, what happens is quite special. The page refcounts start as 1.
enetc_flip_rx_buff() figures they're reusable, transfers these
rx_swbd->page pointers to a different rx_swbd in enetc_reuse_page(), and
bumps the refcount to 2. When xdp_do_redirect() later returns an error,
we call the no-op enetc_xdp_free(), but we still haven't lost the
reference to that page. A copy of it is still at rx_ring->next_to_alloc,
but that has refcount 2 (and there are no concurrent owners of it in
flight, to drop the refcount). What really kills the system is when
we'll flip the rx_swbd->page the second time around. With an updated
refcount of 2, the page will not be reusable and we'll really leak it.
Then enetc_new_page() will have to allocate more pages, which will then
eventually leak again on further errors from xdp_do_redirect().

The problem, summarized, is that we zeroize rx_swbd->page before we're
completely done with it, and this makes it impossible for the error path
to do something with it.

Since the packet is potentially multi-buffer and therefore the
rx_swbd->page is potentially an array, manual passing of the old
pointers between enetc_flip_rx_buff() and enetc_xdp_free() is a bit
difficult.

For the sake of going with a simple solution, we accept the possibility
of racing with xdp_do_redirect(), and we move the flip procedure to
execute only on the redirect success path. By racing, I mean that the
page may be deemed as not reusable by enetc (having a refcount of 0),
but there will be no leak in that case, either.

Once we accept that, we have something better to do with buffers on
XDP_REDIRECT failure. Since we haven't performed half-page flipping yet,
we won't, either (and this way, we can avoid enetc_xdp_free()
completely, which gives the entire page to the slab allocator).
Instead, we'll call enetc_xdp_drop(), which will recycle this half of
the buffer back to the RX ring.

Fixes: 9d2b68cc10 ("net: enetc: add support for XDP_REDIRECT")
Suggested-by: Lorenzo Bianconi <lorenzo.bianconi@redhat.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Link: https://lore.kernel.org/r/20221213001908.2347046-1-vladimir.oltean@nxp.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
2022-12-31 13:14:37 +01:00
..
accessibility speakup: fix a segfault caused by switching consoles 2022-11-26 09:24:44 +01:00
acpi ACPICA: Fix use-after-free in acpi_ut_copy_ipackage_to_ipackage() 2022-12-31 13:14:04 +01:00
amba
android binder: validate alloc->mm in ->mmap() handler 2022-12-02 17:41:00 +01:00
ata ata: libata: fix NCQ autosense logic 2022-12-31 13:14:06 +01:00
atm atm: idt77252: fix use-after-free bugs caused by tst_timer 2022-08-25 11:40:15 +02:00
auxdisplay
base class: fix possible memory leak in __class_register() 2022-12-31 13:14:27 +01:00
bcma
block drbd: destroy workqueue when drbd device was freed 2022-12-31 13:14:12 +01:00
bluetooth Bluetooth: hci_bcsp: don't call kfree_skb() under spin_lock_irqsave() 2022-12-31 13:14:20 +01:00
bus bus: ixp4xx: Don't touch bit 7 on IXP42x 2022-12-02 17:41:08 +01:00
cdrom
char hwrng: geode - Fix PCI device refcount leak 2022-12-31 13:14:26 +01:00
clk clk: socfpga: Fix memory leak in socfpga_gate_init() 2022-12-31 13:14:18 +01:00
clocksource clocksource/drivers/timer-ti-dm: Fix missing clk_disable_unprepare in dmtimer_systimer_init_clock() 2022-12-31 13:14:04 +01:00
comedi
connector
counter counter: stm32-lptimer-cnt: fix the check on arr and cmp registers update 2022-12-31 13:14:30 +01:00
cpufreq cpufreq: amd_freq_sensitivity: Add missing pci_dev_put() 2022-12-31 13:14:03 +01:00
cpuidle cpuidle: dt: Return the correct numbers of parsed idle states 2022-12-31 13:14:01 +01:00
crypto crypto: img-hash - Fix variable dereferenced before check 'hdev->req' 2022-12-31 13:14:26 +01:00
cxl
dax devdax: Fix soft-reservation memory description 2022-09-28 11:11:57 +02:00
dca
devfreq
dio drivers: dio: fix possible memory leak in dio_init() 2022-12-31 13:14:27 +01:00
dma dmaengine: at_hdmac: Check return code of dma_async_device_register 2022-11-16 09:58:30 +01:00
dma-buf dma-buf: fix racing conflict of dma_heap_add() 2022-12-02 17:41:06 +01:00
edac EDAC/i10nm: fix refcount leak in pci_get_dev_wrapper() 2022-12-31 13:14:03 +01:00
eisa
extcon extcon: usbc-tusb320: Update state on probe even if no IRQ pending 2022-12-31 13:14:28 +01:00
firewire
firmware firmware: raspberrypi: fix possible memory leak in rpi_firmware_probe() 2022-12-31 13:14:29 +01:00
fpga fpga: prevent integer overflow in dfl_feature_ioctl_set_irq() 2022-10-26 12:35:07 +02:00
fsi fsi: core: Check error number after calling ida_simple_get 2022-10-26 12:35:17 +02:00
gnss
gpio gpiolib: protect the GPIO device against being dropped while in use by user-space 2022-12-31 13:14:31 +01:00
gpu drm/amdkfd: Fix memory leakage 2022-12-31 13:14:14 +01:00
greybus
hid HID: hid-sensor-custom: set fixed size for custom attributes 2022-12-31 13:14:11 +01:00
hsi HSI: omap_ssi_core: Fix error handling in ssi_init() 2022-12-31 13:14:32 +01:00
hv Drivers: hv: vmbus: fix possible memory leak in vmbus_device_register() 2022-12-02 17:41:05 +01:00
hwmon hwmon: (jc42) Restore the min/max/critical temperatures on resume 2022-12-31 13:14:15 +01:00
hwspinlock hwspinlock: qcom: correct MMIO max register for newer SoCs 2022-11-16 09:58:13 +01:00
hwtracing coresight: trbe: remove cpuhp instance node before remove cpuhp state 2022-12-31 13:14:30 +01:00
i2c i2c: ismt: Fix an out-of-bounds bug in ismt_access() 2022-12-31 13:14:31 +01:00
i3c
idle
iio iio: adis: add '__adis_enable_irq()' implementation 2022-12-31 13:14:29 +01:00
infiniband RDMA/siw: Fix pointer cast warning 2022-12-31 13:14:33 +01:00
input Input: wistron_btns - disable on UML 2022-12-31 13:14:14 +01:00
interconnect interconnect: imx: fix max_node_id 2022-08-17 14:23:53 +02:00
iommu iommu/sun50i: Remove IOMMU_DOMAIN_IDENTITY 2022-12-31 13:14:35 +01:00
ipack
irqchip irqchip/wpcm450: Fix memory leak in wpcm450_aic_of_init() 2022-12-31 13:14:03 +01:00
isdn mISDN: hfcmulti: don't call dev_kfree_skb/kfree_skb() under spin_lock_irqsave() 2022-12-31 13:14:37 +01:00
leds leds: lm3601x: Don't use mutex after it was destroyed 2022-10-26 12:34:39 +02:00
macintosh macintosh/macio-adb: check the return value of ioremap() 2022-12-31 13:14:35 +01:00
mailbox mailbox: bcm-ferxrm-mailbox: Fix error check for dma_map_sg 2022-10-26 12:35:21 +02:00
mcb mcb: mcb-parse: fix error handing in chameleon_parse_gdd() 2022-12-31 13:14:30 +01:00
md dm integrity: clear the journal on suspend 2022-12-02 17:41:11 +01:00
media media: coda: Add check for kmalloc 2022-12-31 13:14:18 +01:00
memory memory: of: Fix refcount leak bug in of_lpddr3_get_ddr_timings() 2022-10-26 12:34:58 +02:00
memstick memstick/ms_block: Add check for alloc_ordered_workqueue 2022-12-31 13:14:17 +01:00
message
mfd mfd: pm8008: Fix return value check in pm8008_probe() 2022-12-31 13:14:36 +01:00
misc cxl: Fix refcount leak in cxl_calc_capp_routing 2022-12-31 13:14:35 +01:00
mmc mmc: core: Normalize the error handling branch in sd_read_ext_regs() 2022-12-31 13:14:17 +01:00
most
mtd mtd: maps: pxa2xx-flash: fix memory leak in probe 2022-12-31 13:14:12 +01:00
mux
net net: enetc: avoid buffer leaks on xdp_do_redirect() failure 2022-12-31 13:14:37 +01:00
nfc nfc: st-nci: fix incorrect sizing calculations in EVT_TRANSACTION 2022-12-02 17:41:07 +01:00
ntb NTB: ntb_tool: uninitialized heap data in tool_fn_write() 2022-08-25 11:40:14 +02:00
nubus
nvdimm
nvme nvme: return err on nvme_init_non_mdts_limits fail 2022-12-31 13:14:10 +01:00
nvmem nvmem: rmem: Fix return value check in rmem_read() 2022-12-08 11:28:39 +01:00
of of: overlay: fix null pointer dereferencing in find_dup_cset_node_entry() and find_dup_cset_prop() 2022-12-31 13:14:19 +01:00
opp opp: Fix error check in dev_pm_opp_attach_genpd() 2022-08-17 14:24:01 +02:00
parisc parisc: Export iosapic_serial_irq() symbol for serial port driver 2022-11-10 18:15:40 +01:00
parport parport_pc: Avoid FIFO port location truncation 2022-11-26 09:24:36 +01:00
pci PCI: Check for alloc failure in pci_request_irq() 2022-12-31 13:14:24 +01:00
pcmcia
perf perf/smmuv3: Fix hotplug callback leak in arm_smmu_pmu_init() 2022-12-31 13:13:58 +01:00
phy phy: usb: s2 WoL wakeup_count not incremented for USB->Eth devices 2022-12-31 13:14:33 +01:00
pinctrl pinctrl: pinconf-generic: add missing of_node_put() 2022-12-31 13:14:12 +01:00
platform platform/mellanox: mlxbf-pmc: Fix event typo 2022-12-31 13:14:05 +01:00
pnp PNP: fix name memory leak in pnp_alloc_dev() 2022-12-31 13:14:02 +01:00
power power: supply: fix null pointer dereferencing in power_supply_get_battery_info 2022-12-31 13:14:33 +01:00
powercap powercap: intel_rapl: fix UBSAN shift-out-of-bounds issue 2022-10-26 12:35:30 +02:00
pps
ps3
ptp
pwm pwm: mediatek: always use bus clock for PWM on MT7622 2022-12-31 13:14:36 +01:00
rapidio rapidio: devices: fix missing put_device in mport_cdev_open 2022-12-31 13:14:05 +01:00
ras
regulator regulator: qcom-labibb: Fix missing of_node_put() in qcom_labibb_regulator_probe() 2022-12-31 13:14:17 +01:00
remoteproc remoteproc: qcom: q6v5: Fix missing clk_disable_unprepare() in q6v5_wcss_qcs404_power_on() 2022-12-31 13:14:36 +01:00
reset reset: imx7: Fix the iMX8MP PCIe PHY PERST support 2022-10-05 10:39:40 +02:00
rpmsg rpmsg: qcom: glink: replace strncpy() with strscpy_pad() 2022-10-12 09:53:28 +02:00
rtc rtc: pcf85063: fix pcf85063_clkout_control 2022-12-31 13:14:37 +01:00
s390 s390/qeth: fix use-after-free in hsci 2022-12-14 11:37:30 +01:00
sbus
scsi scsi: snic: Fix possible UAF in snic_tgt_create() 2022-12-31 13:14:25 +01:00
sh
siox siox: fix possible memory leak in siox_device_add() 2022-11-26 09:24:36 +01:00
slimbus slimbus: stream: correct presence rate frequencies 2022-11-26 09:24:44 +01:00
soc soc: ti: smartreflex: Fix PM disable depth imbalance in omap_sr_probe 2022-12-31 13:13:58 +01:00
soundwire soundwire: intel: Initialize clock stop timeout 2022-12-14 11:37:19 +01:00
spi spi: spi-gpio: Don't set MOSI as an input if not 3WIRE mode 2022-12-31 13:14:18 +01:00
spmi spmi: pmic-arb: correct duplicate APID to PPID mapping logic 2022-10-26 12:35:19 +02:00
ssb
staging staging: rtl8192e: Fix potential use-after-free in rtllib_rx_Monitor() 2022-12-31 13:14:30 +01:00
target scsi: target: tcm_loop: Fix possible name leak in tcm_loop_setup_hba_bus() 2022-11-26 09:24:49 +01:00
tc
tee tee: optee: fix possible memory leak in optee_register_device() 2022-12-02 17:41:03 +01:00
thermal thermal/drivers/qcom/lmh: Fix irq handler return value 2022-12-31 13:14:31 +01:00
thunderbolt thunderbolt: Add DP OUT resource when DP tunnel is discovered 2022-11-16 09:58:13 +01:00
tty serial: sunsab: Fix error handling in sunsab_init() 2022-12-31 13:14:28 +01:00
uio uio: uio_dmem_genirq: Fix deadlock between irq config and handling 2022-12-31 13:14:27 +01:00
usb usb: storage: Add check for kcalloc 2022-12-31 13:14:31 +01:00
vdpa vdpa/ifcvf: fix the calculation of queuepair 2022-10-05 10:39:43 +02:00
vfio vfio: platform: Do not pass return buffer to ACPI _RST method 2022-12-31 13:14:27 +01:00
vhost vhost/vsock: Use kvmalloc/kvfree for larger packets. 2022-10-26 12:34:47 +02:00
video fbdev: uvesafb: Fixes an error handling path in uvesafb_probe() 2022-12-31 13:14:32 +01:00
virt vboxguest: Do not use devm for irq 2022-08-25 11:40:33 +02:00
virtio
visorbus
vlynq
vme vme: Fix error not catched in fake_init() 2022-12-31 13:14:30 +01:00
w1
watchdog watchdog: armada_37xx_wdt: check the return value of devm_ioremap() in armada_37xx_wdt_probe() 2022-08-17 14:24:11 +02:00
xen xen/privcmd: Fix a possible warning in privcmd_ioctl_mmap_resource() 2022-12-31 13:14:04 +01:00
zorro
Kconfig
Makefile