lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <70455B9B-0952-4E03-B2CE-EEAE1E110C5B@amacapital.net>
Date:   Thu, 18 Jun 2020 07:57:35 -0700
From:   Andy Lutomirski <luto@...capital.net>
To:     Peter Zijlstra <peterz@...radead.org>
Cc:     Josh Poimboeuf <jpoimboe@...hat.com>, linux-kernel@...r.kernel.org,
        x86@...nel.org, dvyukov@...gle.com, elver@...gle.com,
        andreyknvl@...gle.com, Mark.Rutland@....com, mhelsley@...are.com,
        rostedt@...dmis.org, jthierry@...hat.com, mbenes@...e.cz
Subject: Re: [PATCH 1/7] x86/entry: Fix #UD vs WARN more



> On Jun 18, 2020, at 7:50 AM, Peter Zijlstra <peterz@...radead.org> wrote:
> 
> vmlinux.o: warning: objtool: exc_invalid_op()+0x47: call to probe_kernel_read() leaves .noinstr.text section
> 
> Since we use UD2 as a short-cut for 'CALL __WARN', treat it as such.
> Have the bare exception handler do the report_bug() thing.

I think you should consider inlining or noinstr-ifying report_bug() too if you want to make this more bulletproof. I admit the scenario where someone instruments it and it goes wrong is farfetched.

> 
> Fixes: 15a416e8aaa7 ("x86/entry: Treat BUG/WARN as NMI-like entries")
> Signed-off-by: Peter Zijlstra (Intel) <peterz@...radead.org>
> ---
> ---
> arch/x86/kernel/traps.c |   50 +++++++++++++++++++++---------------------------
> 1 file changed, 22 insertions(+), 28 deletions(-)
> 
> --- a/arch/x86/kernel/traps.c
> +++ b/arch/x86/kernel/traps.c
> @@ -216,40 +216,34 @@ static inline void handle_invalid_op(str
>              ILL_ILLOPN, error_get_trap_addr(regs));
> }
> 
> +static noinstr bool handle_bug(struct pt_regs *regs)
> +{
> +    bool handled = false;
> +
> +    /*
> +     * All lies, just get the WARN/BUG out.
> +     */
> +    instrumentation_begin();
> +    if (report_bug(regs->ip, regs) == BUG_TRAP_TYPE_WARN) {
> +        regs->ip += LEN_UD2;
> +        handled = true;
> +    }
> +    instrumentation_end();
> +
> +    return handled;
> +}
> +
> DEFINE_IDTENTRY_RAW(exc_invalid_op)
> {
>    bool rcu_exit;
> 
>    /*
> -     * Handle BUG/WARN like NMIs instead of like normal idtentries:
> -     * if we bugged/warned in a bad RCU context, for example, the last
> -     * thing we want is to BUG/WARN again in the idtentry code, ad
> -     * infinitum.
> +     * We use UD2 as a short encoding for 'CALL __WARN', as such
> +     * handle it before exception entry to avoid recursive WARN
> +     * in case exception entry is the one triggering WARNs.
>     */
> -    if (!user_mode(regs) && is_valid_bugaddr(regs->ip)) {
> -        enum bug_trap_type type;
> -
> -        nmi_enter();
> -        instrumentation_begin();
> -        trace_hardirqs_off_finish();
> -        type = report_bug(regs->ip, regs);
> -        if (regs->flags & X86_EFLAGS_IF)
> -            trace_hardirqs_on_prepare();
> -        instrumentation_end();
> -        nmi_exit();
> -
> -        if (type == BUG_TRAP_TYPE_WARN) {
> -            /* Skip the ud2. */
> -            regs->ip += LEN_UD2;
> -            return;
> -        }
> -
> -        /*
> -         * Else, if this was a BUG and report_bug returns or if this
> -         * was just a normal #UD, we want to continue onward and
> -         * crash.
> -         */
> -    }
> +    if (!user_mode(regs) && handle_bug(regs))
> +        return;
> 
>    rcu_exit = idtentry_enter_cond_rcu(regs);
>    instrumentation_begin();
> 
> 

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ