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 for Android: free password hash cracker in your pocket
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Date:   Tue, 7 Aug 2018 16:39:48 +0200
From:   Jiri Olsa <jolsa@...hat.com>
To:     Oleg Nesterov <oleg@...hat.com>
Cc:     Jiri Olsa <jolsa@...nel.org>,
        Arnaldo Carvalho de Melo <acme@...nel.org>,
        Milind Chabbi <chabbi.milind@...il.com>,
        lkml <linux-kernel@...r.kernel.org>,
        Ingo Molnar <mingo@...nel.org>,
        Namhyung Kim <namhyung@...nel.org>,
        David Ahern <dsahern@...il.com>,
        Alexander Shishkin <alexander.shishkin@...ux.intel.com>,
        Peter Zijlstra <a.p.zijlstra@...llo.nl>,
        Frederic Weisbecker <frederic@...nel.org>
Subject: Re: [PATCH 3/2] perf/hw_breakpoint: Remove superfluous
 bp->attr.disabled = 0 new attr has disabled set

On Tue, Aug 07, 2018 at 11:10:08AM +0200, Oleg Nesterov wrote:
> On 08/07, Jiri Olsa wrote:
> >
> > On Mon, Aug 06, 2018 at 06:34:36PM +0200, Oleg Nesterov wrote:
> > > > --- a/kernel/events/hw_breakpoint.c
> > > > +++ b/kernel/events/hw_breakpoint.c
> > > > @@ -526,10 +526,9 @@ int modify_user_hw_breakpoint(struct perf_event *bp, struct perf_event_attr *att
> > > >  	if (err)
> > > >  		return err;
> > > >
> > > > -	if (!attr->disabled) {
> > > > +	if (!attr->disabled)
> > > >  		perf_event_enable(bp);
> > > > -		bp->attr.disabled = 0;
> > > > -	}
> > > > +
> > >
> > > Yes, but again, this still looks confusing.
> > >
> > > IMO, we should either remove "bp->attr.disabled = attr->disabled" in
> > > modify_user_hw_breakpoint_check() because bp->attr.disabled  is not really
> > > used, or we should set bp->attr.disabled = 1 on failure just for consistency.
> > >
> > >
> > > Hmm... actually ptrace_get_dr7() checks ->attr.disabled, so we can hit
> > > WARN_ON(second_pass) in ptrace_write_dr7() in case when attr.disabled is
> > > falsely 0 because modify_user_hw_breakpoint_check() failed before?
> >
> > hum, I can't see how modify_user_hw_breakpoint_check could falsely set disabled
> > new attr stuff is copied once all checks passed
> 
> Hmm. So modify_user_hw_breakpoint() does perf_event_disable(bp) first and afaics
> this doesn't set bp->attr.disabled = 1.
> 
> If modify_user_hw_breakpoint_check() fails after that we do not update bp->attr,
> so bp->attr.disabled is still zero while this bp is actually disabled.

this seems to be cared of the 2nd pass restore logic, where the
old dr7 value will make the breakpoint to be enabled again:

bp0.attr.disabled = 0 (enabled)

ptrace_write_dr7(newdr7)
   dr7 = newdr7
   ptrace_modify_breakpoint(bp0)
     perf_event_disable                        -> bp0 disabled, but bp0.attr.disabled = 0
     modify_user_hw_breakpoint_check fails
       return -1                               -> leaving with bp0 disabled, bp0.attr.disabled = 0

   dr7 = olddr7                                -> bp0 bit enabled
   second_pass = true
   ptrace_modify_breakpoint                    -> attr->disabled = 0
     perf_event_disable
     modify_user_hw_breakpoint_check
       hw_breakpoint_copy_attr
     perf_event_enable                         -> bp0 enabled, bp0.attr.disabled = 0



but this could be problem for ptrace_set_breakpoint_addr, because
the new address modification in modify_user_hw_breakpoint_check,
can fail and leave enabled breakpoint with disabled = 0

might be enough to manualy disable it in case of error like below
(squashed with my previou change) need to test this..

jirka


---
diff --git a/kernel/events/hw_breakpoint.c b/kernel/events/hw_breakpoint.c
index fb229d9c7f3c..eff7ab716139 100644
--- a/kernel/events/hw_breakpoint.c
+++ b/kernel/events/hw_breakpoint.c
@@ -523,13 +523,14 @@ int modify_user_hw_breakpoint(struct perf_event *bp, struct perf_event_attr *att
 		perf_event_disable(bp);
 
 	err = modify_user_hw_breakpoint_check(bp, attr, false);
-	if (err)
+	if (err) {
+		bp->attr.disabled = 1;
 		return err;
+	}
 
-	if (!attr->disabled) {
+	if (!attr->disabled)
 		perf_event_enable(bp);
-		bp->attr.disabled = 0;
-	}
+
 	return 0;
 }
 EXPORT_SYMBOL_GPL(modify_user_hw_breakpoint);
-- 
2.17.1

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ