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]
Date:	Wed, 7 Sep 2011 06:44:35 +0200
From:	Denys Vlasenko <vda.linux@...glemail.com>
To:	Oleg Nesterov <oleg@...hat.com>
Cc:	Denys Vlasenko <dvlasenk@...hat.com>, Tejun Heo <tj@...nel.org>,
	linux-kernel@...r.kernel.org
Subject: Re: [PATCH v2] Fix clearing of task->ptrace if PTRACE_SETOPTIONS fails

On Tuesday 06 September 2011 20:43, Oleg Nesterov wrote:
> > +#define PT_OPT_FLAG_SHIFT	3
> > +/* must be directly before PT_TRACE_event bits */
> > +#define PT_TRACESYSGOOD	0x00000008
> 
> This probably means PT_TRACESYSGOOD should be also defined as PT_EVENT_FLAG(0)

Good idea.

> >  /* PT_TRACE_* event enable flags */
> > -#define PT_EVENT_FLAG_SHIFT	4
> > -#define PT_EVENT_FLAG(event)	(1 << (PT_EVENT_FLAG_SHIFT + (event) - 1))
> > -
> > +#define PT_EVENT_FLAG(event)	(1 << (PT_OPT_FLAG_SHIFT + (event)))
> 
> And ptrace_setoptions() does
> 
> 	child->ptrace |= (data << PT_OPT_FLAG_SHIFT);
> 
> Now we should verify that
> 
> 	PTRACE_O_XXX == 1 << PTRACE_EVENT_XXX;
> 
> for every XXX... Looks correct. But perhaps it makes sense to do this
> explicitely and redefine PTRACE_O_* via PTRACE_EVENT_*.

Also good idea.
 
> > -	if (seize && !(flags & PTRACE_SEIZE_DEVEL))
> > -		goto out;
> > +	if (seize) {
> > +		if ((flags & ~(long)PTRACE_O_MASK) != PTRACE_SEIZE_DEVEL)
> > +			goto out;
> > +		flags &= ~PTRACE_SEIZE_DEVEL;
> > +	} else
> > +		flags = 0;
> >  
> >  	audit_ptrace(task);
> 
> This chunk looks completely off-topic, why it is needed in this patch?

It isn't, it wasn't supposed to be there :(


> >  static int ptrace_setoptions(struct task_struct *child, unsigned long data)
> >  {
> > -	child->ptrace &= ~PT_TRACE_MASK;
> > -
> > -	if (data & PTRACE_O_TRACESYSGOOD)
> > -		child->ptrace |= PT_TRACESYSGOOD;
> > -
> > -	if (data & PTRACE_O_TRACEFORK)
> > -		child->ptrace |= PT_TRACE_FORK;
> > -
> > -	if (data & PTRACE_O_TRACEVFORK)
> > -		child->ptrace |= PT_TRACE_VFORK;
> > -
> > -	if (data & PTRACE_O_TRACECLONE)
> > -		child->ptrace |= PT_TRACE_CLONE;
> > -
> > -	if (data & PTRACE_O_TRACEEXEC)
> > -		child->ptrace |= PT_TRACE_EXEC;
> > -
> > -	if (data & PTRACE_O_TRACEVFORKDONE)
> > -		child->ptrace |= PT_TRACE_VFORK_DONE;
> > +	if (data & ~(long)PTRACE_O_MASK)
> > +		return -EINVAL;
> 
> Oh, yes, I always hated this logic. We change ->ptrace first, then
> return -EINVAL if data is wrong.
> 
> But. Denys, I think this needs a separate patch. And of course, of
> course this can break things. Say, a poor application passes the
> unsupported bit along with the valid bits, and doesn't check the result.
> This works before this patch.

This is really a gross bug, I think we should just bite the bullet
and fix it.

I have hard time imagining how application managed to *inadvertently*
invent a non-existing PTRACE_O_BOGUSFLAG and pass it
to PTRACE_SETOPTIONS call. In what header did they fing PTRACE_O_BOGUSFLAG?

I think this can only happen if they do this on purpose,
but *what* purpose? To get options cleared? Can't imagine anyone doing that,
option clearing can be done without resort to undocumented kernel bugs -
ptrace(PTRACE_SETOPTIONS, pid, 0, 0) does it, rigth?

Sending patch v3 in separate mail.

-- 
vda
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ