diff options
| author | Srinivasarao P <spathi@codeaurora.org> | 2018-09-28 12:18:04 +0530 |
|---|---|---|
| committer | Srinivasarao P <spathi@codeaurora.org> | 2018-09-28 12:18:14 +0530 |
| commit | d9a879450e01a53b297876072dfc1e541181862b (patch) | |
| tree | 5932887f7b824627944dd940980fcc9329c7d8f8 /lib/list_debug.c | |
| parent | 9637304250063317d1907386a0f76b24b5aed872 (diff) | |
| parent | f9e413438f6a3d2a636018eace071fd4b28f95e5 (diff) | |
Merge android-4.4.158 (f9e4134) into msm-4.4
* refs/heads/tmp-f9e4134
Linux 4.4.158
MIPS: VDSO: Match data page cache colouring when D$ aliases
drivers: net: cpsw: fix segfault in case of bad phy-handle
mei: bus: type promotion bug in mei_nfc_if_version()
USB: serial: ti_usb_3410_5052: fix array underflow in completion handler
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
gpiolib: Mark gpio_suffixes array with __maybe_unused
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
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
MIPS: loongson64: cs5536: Fix PCI_OHCI_INT_REG reads
mtdchar: fix overflows in adjustment of `count`
audit: fix use-after-free in audit_add_watch
binfmt_elf: Respect error return from `regset->active'
CIFS: fix wrapping bugs in num_entries()
cifs: prevent integer overflow in nxt_dir_entry()
usb: cdc-wdm: Fix a sleep-in-atomic-context bug in service_outstanding_interrupt()
USB: yurex: Fix buffer over-read in yurex_write()
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: 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: Add quirk to support DJI CineSSD
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
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
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
arm64: dts: qcom: db410c: Fix Bluetooth LED trigger
xen-netfront: fix queue name setting
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
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()
mtd/maps: fix solutionengine.c printk format warnings
media: videobuf2-core: check for q->error in vb2_core_qbuf()
MIPS: ath79: fix system restart
dmaengine: pl330: fix irq race with terminate_all
kbuild: add .DELETE_ON_ERROR special target
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
BACKPORT: arm/syscalls: Optimize address limit check
UPSTREAM: syscalls: Use CHECK_DATA_CORRUPTION for addr_limit_user_check
BACKPORT: 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
BACKPORT: 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()
BACKPORT: list: Split list_add() debug checking into separate function
FROMLIST: ANDROID: binder: Add BINDER_GET_NODE_INFO_FOR_REF ioctl.
Conflicts:
include/linux/bug.h
lib/Kconfig.debug
lib/list_debug.c
Change-Id: I9d87b6b133cac5b642e5e0c928e0bcd0eda6fbdb
Signed-off-by: Srinivasarao P <spathi@codeaurora.org>
Diffstat (limited to 'lib/list_debug.c')
| -rw-r--r-- | lib/list_debug.c | 116 |
1 files changed, 36 insertions, 80 deletions
diff --git a/lib/list_debug.c b/lib/list_debug.c index 8cf180bfaabe..18b872cc4242 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,51 @@ #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); - - next->prev = new; - new->next = next; - new->prev = prev; - prev->next = new; + 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; + + return true; } -EXPORT_SYMBOL(__list_add); +EXPORT_SYMBOL(__list_add_valid); -void __list_del_entry(struct list_head *entry) +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; - } - - __list_del(prev, next); -} -EXPORT_SYMBOL(__list_del_entry); - -/** - * 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); + 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; + + return true; -/* - * 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); |
