Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BUG: ensure normal processing of syscall -1 on x86_64/x32 #80

Closed
hallyn opened this issue Feb 10, 2017 · 12 comments
Closed

BUG: ensure normal processing of syscall -1 on x86_64/x32 #80

hallyn opened this issue Feb 10, 2017 · 12 comments

Comments

@hallyn
Copy link
Contributor

hallyn commented Feb 10, 2017

When libseccomp generates bpf, it adds a check to make sure that X86_SYSCALL_BIT is not set, bypassing compat checks. It does this by simply checking whether nr >= X86_SYSCALL_BIT. Unfortunately, this catches nr = (u32)-1. -1 is a nop, and as far as I know cannot be abused.

As the seccomp manpage points out, after seeing a SECCOMP_RET_TRACE, a tracer can set nr to -1 to skip the syscall. Similarly, one task could be debugging another seccomp'd task, simply doing PTRACE_SYSCALL without using SECCOMP_PTRACE, and want to make the tracee skip a syscall by setting nr to -1.

Since libseccomp is used by default by all lxc and lxd containers, any such tracing application do not work in containers right now.

Please update the bpf generator to allow syscall_nr == -1.

@pcmoore pcmoore changed the title Allow nr==-1 BUG: ensure normal processing of syscall value -1 on x86_64/x32 Feb 10, 2017
@pcmoore pcmoore self-assigned this Feb 10, 2017
@pcmoore
Copy link
Member

pcmoore commented Feb 10, 2017

The relevant portion of the seccomp(2) man-page:

   SECCOMP_RET_TRACE
          When returned, this value will cause the kernel to attempt to
          notify a ptrace(2)-based tracer prior to executing the system
          call.  If there is no tracer present, the system call is not
          executed and returns a failure status with errno set to
          ENOSYS.

          A tracer will be notified if it requests PTRACE_O_TRACESECCOMP
          using ptrace(PTRACE_SETOPTIONS).  The tracer will be notified
          of a PTRACE_EVENT_SECCOMP and the SECCOMP_RET_DATA portion of
          the filter's return value will be available to the tracer via
          PTRACE_GETEVENTMSG.

          The tracer can skip the system call by changing the system
          call number to -1.  Alternatively, the tracer can change the
          system call requested by changing the system call to a valid
          system call number.  If the tracer asks to skip the system
          call, then the system call will appear to return the value
          that the tracer puts in the return value register.

          Before kernel 4.8, the seccomp check will not be run again
          after the tracer is notified.  (This means that, on older
          kernels, seccomp-based sandboxes must not allow use of
          ptrace(2)—even of other sandboxed processes—without extreme
          care; ptracers can use this mechanism to escape from the
          seccomp sandbox.)

@pcmoore pcmoore changed the title BUG: ensure normal processing of syscall value -1 on x86_64/x32 BUG: ensure normal processing of syscall -1 on x86_64/x32 Feb 10, 2017
@pcmoore pcmoore modified the milestone: v2.3.2 Feb 14, 2017
@pcmoore
Copy link
Member

pcmoore commented Feb 15, 2017

It turns out that libseccomp will not let you create a filter rule using a syscall value of -1 at the moment so the risk of someone accidentally running into this problem should be zero. However, the greater problem of not handling syscall -1 correctly still stands.

@pcmoore
Copy link
Member

pcmoore commented Feb 16, 2017

The more time I spend with this, the messier it gets. Perhaps the largest problem is that __NR_SCMP_ERROR has a value of -1 in the libseccomp v2.x series which means that we need to allow a syscall value that has always been used as an error sentinel. Allowing rules with a -1 syscall value is likely going to require some additional work (think attribute setting) on the caller's end so we don't break the API for everyone.

pcmoore added a commit to pcmoore/misc-libseccomp that referenced this issue Feb 16, 2017
Process tracers use a -1 syscall value to indicate that a syscall
should be skipped.  This turns out to be quite an undertaking as
we need to workaround __NR_SCMP_ERROR (which also has a value of
-1).  Pay special attention to the new attribute,
SCMP_FLTATR_CTL_TSKIP, and the documentation additions.

More information in the GitHub issue:
* seccomp#80

Signed-off-by: Paul Moore <paul@paul-moore.com>
@pcmoore
Copy link
Member

pcmoore commented Feb 16, 2017

@hallyn Any chance you can take a look at the master branch of https://github.com/pcmoore/misc-libseccomp and see if it is acceptable?

pcmoore added a commit to pcmoore/misc-libseccomp that referenced this issue Feb 17, 2017
Process tracers use a -1 syscall value to indicate that a syscall
should be skipped.  This turns out to be quite an undertaking as
we need to workaround __NR_SCMP_ERROR (which also has a value of
-1).  Pay special attention to the new attribute,
SCMP_FLTATR_CTL_TSKIP, and the documentation additions.

More information in the GitHub issue:
* seccomp#80

Signed-off-by: Paul Moore <paul@paul-moore.com>
pcmoore added a commit to pcmoore/misc-libseccomp that referenced this issue Feb 17, 2017
Process tracers use a -1 syscall value to indicate that a syscall
should be skipped.  This turns out to be quite an undertaking as
we need to workaround __NR_SCMP_ERROR (which also has a value of
-1).  Pay special attention to the new attribute,
SCMP_FLTATR_CTL_TSKIP, and the documentation additions.

More information in the GitHub issue:
* seccomp#80

Signed-off-by: Paul Moore <paul@paul-moore.com>
@hallyn
Copy link
Contributor Author

hallyn commented Feb 17, 2017 via email

@pcmoore
Copy link
Member

pcmoore commented Feb 17, 2017

@hallyn I'm mainly looking for feedback on the API, specifically the SCMP_FLTATR_CTL_TSKIP attribute requirement. You can ignore the guts of the change if you want, although any review is always welcome ;)

@hallyn
Copy link
Contributor Author

hallyn commented Feb 19, 2017

Tried out the patch and it did work for me, thanks.

My imagination is failing me - what does SCMP_FLTATR_CTL_TSKIP stand for? :-)

What is the threat against which you are defending by making this off by default? (again, failing imagination)

@pcmoore
Copy link
Member

pcmoore commented Feb 20, 2017

Tried out the patch and it did work for me, thanks.

Thanks.

My imagination is failing me - what does SCMP_FLTATR_CTL_TSKIP stand for? :-)

The thinking was that TSKIP was a shortened version of "Tracer SKIP"; I also thought about "Negative ONE" but that didn't work for obvious reasons. If you've got a suggestion, I'd love to hear it. I'm definitely not loving TSKIP, but I'm failing to think of anything better.

What is the threat against which you are defending by making this off by default? (again, failing imagination)

The problem is that historically -1 has been a protected value due to __NR_SCMP_ERROR and seccomp_rule_add(...) specifically checks for this value (see the "RETURN VALUE" section in the seccomp_syscall_resolve_name(3) man-page). If I changed seccomp_rule_add(...) to allow -1 as a syscall value I would potentially break a number of applications which make use of this functionality.

pcmoore added a commit to pcmoore/misc-libseccomp that referenced this issue Feb 20, 2017
Process tracers use a -1 syscall value to indicate that a syscall
should be skipped.  This turns out to be quite an undertaking as
we need to workaround __NR_SCMP_ERROR (which also has a value of
-1).  Pay special attention to the new attribute,
SCMP_FLTATR_CTL_TSKIP, and the documentation additions.

More information in the GitHub issue:
* seccomp#80

Signed-off-by: Paul Moore <paul@paul-moore.com>
@hallyn
Copy link
Contributor Author

hallyn commented Feb 21, 2017 via email

@pcmoore
Copy link
Member

pcmoore commented Feb 21, 2017

But the -1 is ambiguous only for passing to rules right? If it is deemed "always ok" to allow syscall -1, then we can unambiguously state that a. -1 at seccomp_rule_add() means __NR_SCMP_ERROR b. -1 as a syscall is ignored (allowed) Basically my possibly false assertion is that syscall -1 can never put the system at risk and can safely be always allowed, so admins would never try to say "don't allow syscall -1" in a policy.

My concern is that we have never implicitly added a rule (other than the ABI checks) to the libseccomp filters and I'm not sure this is something I want to start doing at this moment. While small, I don't think the risk is close enough to zero to warrant adding a default -1 rule, and there is always the chance that some application will want to do something clever with a seccomp filter and the -1 syscall and I don't want to prevent that.

However, this did get me thinking about changing the name of the CTL_TSKIP attribute to API_TSKIP to leave the door open for a potential future attribute which would create an implicit -1 allow rule. I think I'll do that now, just in case (arguably it makes more sense anyway).

Thoughts @hallyn ?

pcmoore added a commit to pcmoore/misc-libseccomp that referenced this issue Feb 21, 2017
Process tracers use a -1 syscall value to indicate that a syscall
should be skipped.  This turns out to be quite an undertaking as
we need to workaround __NR_SCMP_ERROR (which also has a value of
-1).  Pay special attention to the new attribute,
SCMP_FLTATR_CTL_TSKIP, and the documentation additions.

More information in the GitHub issue:
* seccomp#80

Signed-off-by: Paul Moore <paul@paul-moore.com>
pcmoore added a commit that referenced this issue Feb 23, 2017
Process tracers use a -1 syscall value to indicate that a syscall
should be skipped.  This turns out to be quite an undertaking as
we need to workaround __NR_SCMP_ERROR (which also has a value of
-1).  Pay special attention to the new attribute,
SCMP_FLTATR_API_TSKIP, and the documentation additions.

More information in the GitHub issue:
* #80

Signed-off-by: Paul Moore <paul@paul-moore.com>
@pcmoore
Copy link
Member

pcmoore commented Feb 23, 2017

I just committed the fixes in dc87999 11e2109 ba73ee4 and I'm going to mark this as resolved for now.

@pcmoore pcmoore closed this as completed Feb 23, 2017
pcmoore added a commit that referenced this issue Feb 23, 2017
Process tracers use a -1 syscall value to indicate that a syscall
should be skipped.  This turns out to be quite an undertaking as
we need to workaround __NR_SCMP_ERROR (which also has a value of
-1).  Pay special attention to the new attribute,
SCMP_FLTATR_API_TSKIP, and the documentation additions.

More information in the GitHub issue:
* #80

Signed-off-by: Paul Moore <paul@paul-moore.com>
(imported from commit dc87999)
@hallyn
Copy link
Contributor Author

hallyn commented Feb 23, 2017

Great, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants