From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757994AbcHCPLP (ORCPT ); Wed, 3 Aug 2016 11:11:15 -0400 Received: from userp1050.oracle.com ([156.151.31.82]:51452 "EHLO userp1050.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756413AbcHCPKI (ORCPT ); Wed, 3 Aug 2016 11:10:08 -0400 From: Vegard Nossum To: Akinobu Mita , Peter Zijlstra , Ingo Molnar Cc: linux-kernel@vger.kernel.org, Vegard Nossum Subject: [PATCH 04/10] fault injection: prevent recursive fault injection Date: Wed, 3 Aug 2016 17:05:49 +0200 Message-Id: <1470236755-29844-4-git-send-email-vegard.nossum@oracle.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1470236755-29844-1-git-send-email-vegard.nossum@oracle.com> References: <1470236755-29844-1-git-send-email-vegard.nossum@oracle.com> X-Source-IP: userp1040.oracle.com [156.151.31.81] Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org If something we call in the fail_dump() code path tries to acquire a resource that might fail (due to fault injection), then we should not try to recurse back into the fault injection code. I've seen this happen with the console semaphore in the upcoming semaphore trylock fault injection code. Signed-off-by: Vegard Nossum --- lib/fault-inject.c | 34 ++++++++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/lib/fault-inject.c b/lib/fault-inject.c index 6a823a5..adba7c9 100644 --- a/lib/fault-inject.c +++ b/lib/fault-inject.c @@ -100,6 +100,33 @@ static inline bool fail_stacktrace(struct fault_attr *attr) #endif /* CONFIG_FAULT_INJECTION_STACKTRACE_FILTER */ +static DEFINE_PER_CPU(int, fault_active); + +static bool __fail(struct fault_attr *attr) +{ + bool ret = false; + + /* + * Prevent recursive fault injection (this could happen if for + * example printing the fault would itself run some code that + * could fail) + */ + preempt_disable(); + if (unlikely(__this_cpu_inc_return(fault_active) != 1)) + goto out; + + ret = true; + fail_dump(attr); + + if (atomic_read(&attr->times) != -1) + atomic_dec_not_zero(&attr->times); + +out: + __this_cpu_dec(fault_active); + preempt_enable(); + return ret; +} + /* * This code is stolen from failmalloc-1.0 * http://www.nongnu.org/failmalloc/ @@ -134,12 +161,7 @@ bool should_fail(struct fault_attr *attr, ssize_t size) if (!fail_stacktrace(attr)) return false; - fail_dump(attr); - - if (atomic_read(&attr->times) != -1) - atomic_dec_not_zero(&attr->times); - - return true; + return __fail(attr); } EXPORT_SYMBOL_GPL(should_fail); -- 1.9.1