Merge android-4.9.129 (b727d1c) into msm-4.9
* refs/heads/tmp-b727d1c:
Linux 4.9.129
e1000e: Fix link check race condition
Revert "e1000e: Separate signaling for link check/link up"
e1000e: Avoid missed interrupts following ICR read
e1000e: Fix queue interrupt re-raising in Other interrupt
Partial revert "e1000e: Avoid receiver overrun interrupt bursts"
e1000e: Remove Other from EIAC
MIPS: VDSO: Match data page cache colouring when D$ aliases
mei: bus: type promotion bug in mei_nfc_if_version()
pinctrl: qcom: spmi-gpio: Fix pmic_gpio_config_get() to be compliant
drm/panel: type promotion bug in s6e8aa0_read_mtp_id()
selftest: timers: Tweak raw_skew to SKIP when ADJ_OFFSET/other clock adjustments are in progress
ALSA: pcm: Fix snd_interval_refine first/last with open min/max
rtc: bq4802: add error handling for devm_ioremap
drm/amdkfd: Fix error codes in kfd_get_process
input: rohm_bu21023: switch to i2c_lock_bus(..., I2C_LOCK_SEGMENT)
mfd: 88pm860x-i2c: switch to i2c_lock_bus(..., I2C_LOCK_SEGMENT)
gpiolib: Mark gpio_suffixes array with __maybe_unused
gpio: pxa: Fix potential NULL dereference
coresight: tpiu: Fix disabling timeouts
coresight: Handle errors in finding input/output ports
parport: sunbpp: fix error return code
drm/nouveau: tegra: Detach from ARM DMA/IOMMU mapping
mmc: sdhci: do not try to use 3.3V signaling if not supported
mmc: tegra: prevent HS200 on Tegra 3
gpu: ipu-v3: csi: pass back mbus_code_to_bus_cfg error codes
ARM: hisi: check of_iomap and fix missing of_node_put
ARM: hisi: fix error handling and missing of_node_put
ARM: hisi: handle of_iomap and fix missing of_node_put
efi/esrt: Only call efi_mem_reserve() for boot services memory
configfs: fix registered group removal
MIPS: loongson64: cs5536: Fix PCI_OHCI_INT_REG reads
evm: Don't deadlock if a crypto algorithm is unavailable
mtdchar: fix overflows in adjustment of `count`
audit: fix use-after-free in audit_add_watch
binfmt_elf: Respect error return from `regset->active'
NFSv4.1 fix infinite loop on I/O.
perf/core: Force USER_DS when recording user stack data
CIFS: fix wrapping bugs in num_entries()
cifs: prevent integer overflow in nxt_dir_entry()
Revert "cdc-acm: implement put_char() and flush_chars()"
usb: cdc-wdm: Fix a sleep-in-atomic-context bug in service_outstanding_interrupt()
USB: yurex: Fix buffer over-read in yurex_write()
USB: serial: ti_usb_3410_5052: fix array underflow in completion handler
usb: misc: uss720: Fix two sleep-in-atomic-context bugs
USB: serial: io_ti: fix array underflow in completion handler
USB: net2280: Fix erroneous synchronization change
usb: gadget: udc: renesas_usb3: fix maxpacket size of ep0
USB: add quirk for WORLDE Controller KS49 or Prodipe MIDI 49C USB controller
usb: host: u132-hcd: Fix a sleep-in-atomic-context bug in u132_get_frame()
usb: Avoid use-after-free by flushing endpoints early in usb_set_interface()
usb: uas: add support for more quirk flags
USB: Add quirk to support DJI CineSSD
mei: ignore not found client in the enumeration
usb: Don't die twice if PCI xhci host is not responding in resume
misc: hmc6352: fix potential Spectre v1
Tools: hv: Fix a bug in the key delete code
mmc: omap_hsmmc: fix wakeirq handling on removal
IB/ipoib: Avoid a race condition between start_xmit and cm_rep_handler
xen/netfront: fix waiting for xenbus state change
pstore: Fix incorrect persistent ram buffer mapping
RDMA/cma: Protect cma dev list with lock
xen-netfront: fix warn message as irq device name has '/'
crypto: sharah - Unregister correct algorithms for SAHARA 3
dmaengine: mv_xor_v2: kill the tasklets upon exit
drivers/base: stop new probing during shutdown
KVM: arm/arm64: Fix vgic init race
platform/x86: toshiba_acpi: Fix defined but not used build warnings
s390/qeth: reset layer2 attribute on layer switch
s390/qeth: fix race in used-buffer accounting
ARM: dts: qcom: msm8974-hammerhead: increase load on l20 for sdhci
arm64: dts: qcom: db410c: Fix Bluetooth LED trigger
xen-netfront: fix queue name setting
nfp: avoid buffer leak when FW communication fails
efi/arm: preserve early mapping of UEFI memory map longer for BGRT
wan/fsl_ucc_hdlc: use IS_ERR_VALUE() to check return value of qe_muram_alloc
Smack: Fix handling of IPv4 traffic received by PF_INET6 sockets
mac80211: restrict delayed tailroom needed decrement
MIPS: jz4740: Bump zload address
powerpc/powernv: opal_put_chars partial write fix
perf powerpc: Fix callchain ip filtering
ARM: exynos: Clear global variable on init error path
fbdev: Distinguish between interlaced and progressive modes
video: fbdev: pxafb: clear allocated memory for video modes
perf powerpc: Fix callchain ip filtering when return address is in a register
fbdev/via: fix defined but not used warning
video: goldfishfb: fix memory leak on driver remove
fbdev: omapfb: off by one in omapfb_register_client()
gfs2: Don't reject a supposedly full bitmap if we have blocks reserved
perf test: Fix subtest number when showing results
mtd/maps: fix solutionengine.c printk format warnings
IB/rxe: Drop QP0 silently
media: videobuf2-core: check for q->error in vb2_core_qbuf()
MIPS: ath79: fix system restart
dmaengine: pl330: fix irq race with terminate_all
media: tw686x: Fix oops on buffer alloc failure
kbuild: add .DELETE_ON_ERROR special target
clk: clk-fixed-factor: Clear OF_POPULATED flag in case of failure
clk: imx6ul: fix missing of_node_put()
gfs2: Special-case rindex for gfs2_grow
xfrm: fix 'passing zero to ERR_PTR()' warning
ALSA: usb-audio: Fix multiple definitions in AU0828_DEVICE() macro
ALSA: msnd: Fix the default sample sizes
iommu/arm-smmu-v3: sync the OVACKFLG to PRIQ consumer register
net/mlx5: Fix debugfs cleanup in the device init/remove flow
net/mlx5: Fix use-after-free in self-healing flow
rds: fix two RCU related problems
be2net: Fix memory leak in be_cmd_get_profile_config()
UPSTREAM: arm64/syscalls: Move address limit check in loop
BACKPORT: arm/syscalls: Optimize address limit check
UPSTREAM: syscalls: Use CHECK_DATA_CORRUPTION for addr_limit_user_check
UPSTREAM: arm64/syscalls: Check address limit on user-mode return
BACKPORT: x86/syscalls: Check address limit on user-mode return
BACKPORT: lkdtm: add bad USER_DS test
UPSTREAM: bug: switch data corruption check to __must_check
UPSTREAM: lkdtm: Add tests for struct list corruption
UPSTREAM: bug: Provide toggle for BUG on data corruption
UPSTREAM: list: Split list_del() debug checking into separate function
UPSTREAM: rculist: Consolidate DEBUG_LIST for list_add_rcu()
UPSTREAM: list: Split list_add() debug checking into separate function
FROMLIST: ANDROID: binder: Add BINDER_GET_NODE_INFO_FOR_REF ioctl.
Conflicts:
drivers/misc/lkdtm.h
drivers/misc/lkdtm_bugs.c
drivers/misc/lkdtm_core.c
include/linux/bug.h
lib/Kconfig.debug
lib/list_debug.c
Change-Id: I599369f47c3695545470d1ae6069f58728cd61f3
Signed-off-by: Minming Qi <mqi@codeaurora.org>
diff --git a/lib/list_debug.c b/lib/list_debug.c
index 7a5c1c0..8dfe861 100644
--- a/lib/list_debug.c
+++ b/lib/list_debug.c
@@ -2,8 +2,7 @@
* Copyright 2006, Red Hat, Inc., Dave Jones
* Released under the General Public License (GPL).
*
- * This file contains the linked list implementations for
- * DEBUG_LIST.
+ * This file contains the linked list validation for DEBUG_LIST.
*/
#include <linux/export.h>
@@ -14,94 +13,57 @@
#include <linux/bug.h>
/*
- * Insert a new entry between two known consecutive entries.
- *
- * This is only for internal list manipulation where we know
- * the prev/next entries already!
+ * Check that the data structures for the list manipulations are reasonably
+ * valid. Failures here indicate memory corruption (and possibly an exploit
+ * attempt).
*/
-void __list_add(struct list_head *new,
- struct list_head *prev,
- struct list_head *next)
+bool __list_add_valid(struct list_head *new, struct list_head *prev,
+ struct list_head *next)
{
- WARN(next->prev != prev,
- "list_add corruption. next->prev should be "
- "prev (%p), but was %p. (next=%p).\n",
- prev, next->prev, next);
- WARN(prev->next != next,
- "list_add corruption. prev->next should be "
- "next (%p), but was %p. (prev=%p).\n",
- next, prev->next, prev);
- WARN(new == prev || new == next,
- "list_add double add: new=%p, prev=%p, next=%p.\n",
- new, prev, next);
- BUG_ON((prev->next != next || next->prev != prev ||
- new == prev || new == next) && PANIC_CORRUPTION);
+ if (CHECK_DATA_CORRUPTION(next->prev != prev,
+ "list_add corruption. next->prev should be prev (%p), but was %p. (next=%p).\n",
+ prev, next->prev, next) ||
+ CHECK_DATA_CORRUPTION(prev->next != next,
+ "list_add corruption. prev->next should be next (%p), but was %p. (prev=%p).\n",
+ next, prev->next, prev) ||
+ CHECK_DATA_CORRUPTION(new == prev || new == next,
+ "list_add double add: new=%p, prev=%p, next=%p.\n",
+ new, prev, next))
+ return false;
next->prev = new;
new->next = next;
new->prev = prev;
WRITE_ONCE(prev->next, new);
-}
-EXPORT_SYMBOL(__list_add);
-void __list_del_entry(struct list_head *entry)
+ return true;
+}
+EXPORT_SYMBOL(__list_add_valid);
+
+bool __list_del_entry_valid(struct list_head *entry)
{
struct list_head *prev, *next;
prev = entry->prev;
next = entry->next;
- if (WARN(next == LIST_POISON1,
- "list_del corruption, %p->next is LIST_POISON1 (%p)\n",
- entry, LIST_POISON1) ||
- WARN(prev == LIST_POISON2,
- "list_del corruption, %p->prev is LIST_POISON2 (%p)\n",
- entry, LIST_POISON2) ||
- WARN(prev->next != entry,
- "list_del corruption. prev->next should be %p, "
- "but was %p\n", entry, prev->next) ||
- WARN(next->prev != entry,
- "list_del corruption. next->prev should be %p, but was %p\n",
- entry, next->prev)) {
- BUG_ON(PANIC_CORRUPTION);
- return;
- }
+ if (CHECK_DATA_CORRUPTION(next == LIST_POISON1,
+ "list_del corruption, %p->next is LIST_POISON1 (%p)\n",
+ entry, LIST_POISON1) ||
+ CHECK_DATA_CORRUPTION(prev == LIST_POISON2,
+ "list_del corruption, %p->prev is LIST_POISON2 (%p)\n",
+ entry, LIST_POISON2) ||
+ CHECK_DATA_CORRUPTION(prev->next != entry,
+ "list_del corruption. prev->next should be %p, but was %p\n",
+ entry, prev->next) ||
+ CHECK_DATA_CORRUPTION(next->prev != entry,
+ "list_del corruption. next->prev should be %p, but was %p\n",
+ entry, next->prev))
+ return false;
- __list_del(prev, next);
-}
-EXPORT_SYMBOL(__list_del_entry);
+ return true;
-/**
- * list_del - deletes entry from list.
- * @entry: the element to delete from the list.
- * Note: list_empty on entry does not return true after this, the entry is
- * in an undefined state.
- */
-void list_del(struct list_head *entry)
-{
- __list_del_entry(entry);
- entry->next = LIST_POISON1;
- entry->prev = LIST_POISON2;
}
-EXPORT_SYMBOL(list_del);
-
-/*
- * RCU variants.
- */
-void __list_add_rcu(struct list_head *new,
- struct list_head *prev, struct list_head *next)
-{
- WARN(next->prev != prev,
- "list_add_rcu corruption. next->prev should be prev (%p), but was %p. (next=%p).\n",
- prev, next->prev, next);
- WARN(prev->next != next,
- "list_add_rcu corruption. prev->next should be next (%p), but was %p. (prev=%p).\n",
- next, prev->next, prev);
- new->next = next;
- new->prev = prev;
- rcu_assign_pointer(list_next_rcu(prev), new);
- next->prev = new;
-}
-EXPORT_SYMBOL(__list_add_rcu);
+EXPORT_SYMBOL(__list_del_entry_valid);