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: <20150603144303.GC3160@smitten>
Date:	Wed, 3 Jun 2015 08:43:03 -0600
From:	Tycho Andersen <tycho.andersen@...onical.com>
To:	Oleg Nesterov <oleg@...hat.com>
Cc:	linux-kernel@...r.kernel.org, linux-api@...r.kernel.org,
	Kees Cook <keescook@...omium.org>,
	Andy Lutomirski <luto@...capital.net>,
	Will Drewry <wad@...omium.org>,
	Roland McGrath <roland@...k.frob.com>,
	Pavel Emelyanov <xemul@...allels.com>,
	"Serge E. Hallyn" <serge.hallyn@...ntu.com>
Subject: Re: [PATCH] seccomp: add ptrace commands for suspend/resume

On Tue, Jun 02, 2015 at 08:28:29PM +0200, Oleg Nesterov wrote:
> On 06/01, Tycho Andersen wrote:
> >
> > --- a/include/linux/seccomp.h
> > +++ b/include/linux/seccomp.h
> > @@ -25,6 +25,9 @@ struct seccomp_filter;
> >  struct seccomp {
> >  	int mode;
> >  	struct seccomp_filter *filter;
> > +#ifdef CONFIG_CHECKPOINT_RESTORE
> > +	bool suspended;
> > +#endif
> 
> Then afaics you need to change copy_seccomp() to clear ->suspended.
> At least if the child is not traced.

Yes, thank you.

> > @@ -691,6 +697,11 @@ u32 seccomp_phase1(struct seccomp_data *sd)
> >  	int this_syscall = sd ? sd->nr :
> >  		syscall_get_nr(current, task_pt_regs(current));
> >  
> > +#ifdef CONFIG_CHECKPOINT_RESTORE
> > +	if (unlikely(current->seccomp.suspended))
> > +		return SECCOMP_PHASE1_OK;
> > +#endif
> > +
> 
> I am wondering if PTRACE_SUSPEND_SECCOMP can just clear/set TIF_SECCOMP.
> Of course, it is not that resume_seccomp() can simply do set_tsk_thread_flag,
> it should be more careful. And prctl_set_seccomp() paths will need some
> changes. Probably not, this would be more complex.
> 
> So perhaps it would be better to add PTRACE_O_SUSPEND_SECCOMP? This also
> solves the problem with the killed tracer. Except TIF_NOTSC...
> 
> But why do we bother to play with TIF_NOTSC, could you explain?

The procedure for restoring is to call seccomp suspend, restore the
seccomp filters (and potentially other stuff), and then resume them at
the end. If the other stuff happens to use RDTSC, the process gets
killed because TIF_NOTSC has been set. It seems to me that since
seccomp is the one setting TIF_NOTSC, suspending seccomp should unset
it.

We can work around this in criu by doing the seccomp restore as the
very last thing before the final sigreturn, but that seems like the
seccomp suspend API is incomplete, IMO. However, since both you and
Andy complained, perhaps I should remove it :)

> > +int suspend_seccomp(struct task_struct *task)
> > +{
> > +	int ret = -EACCES;
> > +
> > +	spin_lock_irq(&task->sighand->siglock);
> > +
> > +	if (!capable(CAP_SYS_ADMIN))
> > +		goto out;
> 
> I am puzzled ;) Why do we need ->siglock? And even if we need it, why
> we can't check CAP_SYS_ADMIN lockless?

I'm not sure, other pieces of the seccomp code
(seccomp_set_mode_strict() and friends) take the lock when
manipulating the seccomp mode, so I just followed suit here. You're
right that we can do the capability check lockless, I'll make that
change.

> And I am not sure I understand why do we need the additional security
> check, but I leave this to you and Andy.

Yes, it is required to prevent the case Pavel mentions (although there
are other ways to get around seccomp with ptrace, the goal here is to
not depend on that behavior so that when it is eventually fixed this
doesn't break).

> If you have the rights to trace this task, then you can do anything
> the tracee could do without the filtering.
>
> > +
> > +	task->seccomp.suspended = true;
> > +
> > +#ifdef TIF_NOTSC
> > +	if (task->seccomp.mode == SECCOMP_MODE_STRICT)
> > +		clear_tsk_thread_flag(task, TIF_NOTSC);
> > +#endif
> > +
> > +	ret = 0;
> > +out:
> > +	spin_unlock_irq(&task->sighand->siglock);
> > +
> > +	return ret;
> > +}
> > +
> > +int resume_seccomp(struct task_struct *task)
> > +{
> > +	int ret = -EACCES;
> > +
> > +	spin_lock_irq(&task->sighand->siglock);
> > +
> > +	if (!capable(CAP_SYS_ADMIN))
> > +		goto out;
> > +
> > +	task->seccomp.suspended = false;
> > +
> > +#ifdef TIF_NOTSC
> > +	if (task->seccomp.mode == SECCOMP_MODE_STRICT)
> > +		set_tsk_thread_flag(task, TIF_NOTSC);
> > +#endif
> > +
> > +	ret = 0;
> > +out:
> > +	spin_unlock_irq(&task->sighand->siglock);
> > +
> > +	return ret;
> > +}
> > +#endif /* CONFIG_CHECKPOINT_RESTORE */
> 
> Well, I do not think we need 2 helpers, just one which takes a boolean
> will look better, imo.

Ok, this has changed slightly with the "always resume on
detach/unlink" change Pavel suggested, but I'll see if I can find a
nice way to merge them.

Thanks for taking a look.

Tycho

> Oleg.
> 
--
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