summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@google.com>2021-10-27 09:43:12 +0200
committerGreg Kroah-Hartman <gregkh@google.com>2021-10-27 09:43:12 +0200
commitf9d6c5b38776d05c5c99ae84b68caf7639c22d2f (patch)
tree764a1ced941994d582b6648f92e9316ac89b6ae5 /kernel
parentbf687da3fdbe378ae33b7d4c6cbaa2dfa3993628 (diff)
parent7e1cc0d92c7deb0994154b3b6e9eea8e3aa4af0c (diff)
Merge 4.4.290 into android-4.4-p
Changes in 4.4.290 ALSA: seq: Fix a potential UAF by wrong private_free call order s390: fix strrchr() implementation xhci: Enable trust tx length quirk for Fresco FL11 USB controller cb710: avoid NULL pointer subtraction efi/cper: use stack buffer for error record decoding Input: xpad - add support for another USB ID of Nacon GC-100 USB: serial: qcserial: add EM9191 QDL support USB: serial: option: add Telit LE910Cx composition 0x1204 nvmem: Fix shift-out-of-bound (UBSAN) with byte size cells iio: adc128s052: Fix the error handling path of 'adc128_probe()' iio: ssp_sensors: add more range checking in ssp_parse_dataframe() iio: ssp_sensors: fix error code in ssp_print_mcu_debug() net: arc: select CRC32 net: korina: select CRC32 net: encx24j600: check error in devm_regmap_init_encx24j600 ethernet: s2io: fix setting mac address during resume nfc: fix error handling of nfc_proto_register() NFC: digital: fix possible memory leak in digital_tg_listen_mdaa() NFC: digital: fix possible memory leak in digital_in_send_sdd_req() pata_legacy: fix a couple uninitialized variable bugs drm/msm: Fix null pointer dereference on pointer edp r8152: select CRC32 and CRYPTO/CRYPTO_HASH/CRYPTO_SHA256 NFSD: Keep existing listeners on portlist error netfilter: ipvs: make global sysctl readonly in non-init netns NIOS2: irqflags: rename a redefined register name can: rcar_can: fix suspend/resume can: peak_usb: pcan_usb_fd_decode_status(): fix back to ERROR_ACTIVE state notification can: peak_pci: peak_pci_remove(): fix UAF ocfs2: mount fails with buffer overflow in strlen elfcore: correct reference to CONFIG_UML ALSA: usb-audio: Provide quirk for Sennheiser GSP670 Headset ASoC: DAPM: Fix missing kctl change notifications ovl: fix missing negative dentry check in ovl_rename() nfc: nci: fix the UAF of rf_conn_info object isdn: cpai: check ctr->cnr to avoid array index out of bound netfilter: Kconfig: use 'default y' instead of 'm' for bool config option ARM: dts: spear3xx: Fix gmac node isdn: mISDN: Fix sleeping function called from invalid context platform/x86: intel_scu_ipc: Update timeout value in comment ALSA: hda: avoid write to STATESTS if controller is in reset net: mdiobus: Fix memory leak in __mdiobus_register tracing: Have all levels of checks prevent recursion ARM: 9122/1: select HAVE_FUTEX_CMPXCHG Linux 4.4.290 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com> Change-Id: I97fdd4fb10f590df04407cb87713af101af36f67
Diffstat (limited to 'kernel')
-rw-r--r--kernel/trace/ftrace.c4
-rw-r--r--kernel/trace/trace.h64
-rw-r--r--kernel/trace/trace_functions.c2
3 files changed, 23 insertions, 47 deletions
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index e591da4449f0..c5484723abda 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -5185,7 +5185,7 @@ __ftrace_ops_list_func(unsigned long ip, unsigned long parent_ip,
struct ftrace_ops *op;
int bit;
- bit = trace_test_and_set_recursion(TRACE_LIST_START, TRACE_LIST_MAX);
+ bit = trace_test_and_set_recursion(TRACE_LIST_START);
if (bit < 0)
return;
@@ -5246,7 +5246,7 @@ static void ftrace_ops_recurs_func(unsigned long ip, unsigned long parent_ip,
{
int bit;
- bit = trace_test_and_set_recursion(TRACE_LIST_START, TRACE_LIST_MAX);
+ bit = trace_test_and_set_recursion(TRACE_LIST_START);
if (bit < 0)
return;
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
index c5c6daef8cdf..53e8ccbae818 100644
--- a/kernel/trace/trace.h
+++ b/kernel/trace/trace.h
@@ -431,23 +431,8 @@ struct tracer {
* When function tracing occurs, the following steps are made:
* If arch does not support a ftrace feature:
* call internal function (uses INTERNAL bits) which calls...
- * If callback is registered to the "global" list, the list
- * function is called and recursion checks the GLOBAL bits.
- * then this function calls...
* The function callback, which can use the FTRACE bits to
* check for recursion.
- *
- * Now if the arch does not suppport a feature, and it calls
- * the global list function which calls the ftrace callback
- * all three of these steps will do a recursion protection.
- * There's no reason to do one if the previous caller already
- * did. The recursion that we are protecting against will
- * go through the same steps again.
- *
- * To prevent the multiple recursion checks, if a recursion
- * bit is set that is higher than the MAX bit of the current
- * check, then we know that the check was made by the previous
- * caller, and we can skip the current check.
*/
enum {
TRACE_BUFFER_BIT,
@@ -460,12 +445,14 @@ enum {
TRACE_FTRACE_NMI_BIT,
TRACE_FTRACE_IRQ_BIT,
TRACE_FTRACE_SIRQ_BIT,
+ TRACE_FTRACE_TRANSITION_BIT,
- /* INTERNAL_BITs must be greater than FTRACE_BITs */
+ /* Internal use recursion bits */
TRACE_INTERNAL_BIT,
TRACE_INTERNAL_NMI_BIT,
TRACE_INTERNAL_IRQ_BIT,
TRACE_INTERNAL_SIRQ_BIT,
+ TRACE_INTERNAL_TRANSITION_BIT,
TRACE_CONTROL_BIT,
@@ -478,12 +465,6 @@ enum {
* can only be modified by current, we can reuse trace_recursion.
*/
TRACE_IRQ_BIT,
-
- /*
- * When transitioning between context, the preempt_count() may
- * not be correct. Allow for a single recursion to cover this case.
- */
- TRACE_TRANSITION_BIT,
};
#define trace_recursion_set(bit) do { (current)->trace_recursion |= (1<<(bit)); } while (0)
@@ -493,12 +474,18 @@ enum {
#define TRACE_CONTEXT_BITS 4
#define TRACE_FTRACE_START TRACE_FTRACE_BIT
-#define TRACE_FTRACE_MAX ((1 << (TRACE_FTRACE_START + TRACE_CONTEXT_BITS)) - 1)
#define TRACE_LIST_START TRACE_INTERNAL_BIT
-#define TRACE_LIST_MAX ((1 << (TRACE_LIST_START + TRACE_CONTEXT_BITS)) - 1)
-#define TRACE_CONTEXT_MASK TRACE_LIST_MAX
+#define TRACE_CONTEXT_MASK ((1 << (TRACE_LIST_START + TRACE_CONTEXT_BITS)) - 1)
+
+enum {
+ TRACE_CTX_NMI,
+ TRACE_CTX_IRQ,
+ TRACE_CTX_SOFTIRQ,
+ TRACE_CTX_NORMAL,
+ TRACE_CTX_TRANSITION,
+};
static __always_inline int trace_get_context_bit(void)
{
@@ -506,59 +493,48 @@ static __always_inline int trace_get_context_bit(void)
if (in_interrupt()) {
if (in_nmi())
- bit = 0;
+ bit = TRACE_CTX_NMI;
else if (in_irq())
- bit = 1;
+ bit = TRACE_CTX_IRQ;
else
- bit = 2;
+ bit = TRACE_CTX_SOFTIRQ;
} else
- bit = 3;
+ bit = TRACE_CTX_NORMAL;
return bit;
}
-static __always_inline int trace_test_and_set_recursion(int start, int max)
+static __always_inline int trace_test_and_set_recursion(int start)
{
unsigned int val = current->trace_recursion;
int bit;
- /* A previous recursion check was made */
- if ((val & TRACE_CONTEXT_MASK) > max)
- return 0;
-
bit = trace_get_context_bit() + start;
if (unlikely(val & (1 << bit))) {
/*
* It could be that preempt_count has not been updated during
* a switch between contexts. Allow for a single recursion.
*/
- bit = TRACE_TRANSITION_BIT;
+ bit = start + TRACE_CTX_TRANSITION;
if (trace_recursion_test(bit))
return -1;
trace_recursion_set(bit);
barrier();
- return bit + 1;
+ return bit;
}
- /* Normal check passed, clear the transition to allow it again */
- trace_recursion_clear(TRACE_TRANSITION_BIT);
-
val |= 1 << bit;
current->trace_recursion = val;
barrier();
- return bit + 1;
+ return bit;
}
static __always_inline void trace_clear_recursion(int bit)
{
unsigned int val = current->trace_recursion;
- if (!bit)
- return;
-
- bit--;
bit = 1 << bit;
val &= ~bit;
diff --git a/kernel/trace/trace_functions.c b/kernel/trace/trace_functions.c
index fcd41a166405..7adbfcf555fd 100644
--- a/kernel/trace/trace_functions.c
+++ b/kernel/trace/trace_functions.c
@@ -137,7 +137,7 @@ function_trace_call(unsigned long ip, unsigned long parent_ip,
pc = preempt_count();
preempt_disable_notrace();
- bit = trace_test_and_set_recursion(TRACE_FTRACE_START, TRACE_FTRACE_MAX);
+ bit = trace_test_and_set_recursion(TRACE_FTRACE_START);
if (bit < 0)
goto out;