-
Notifications
You must be signed in to change notification settings - Fork 167
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: Tor sandbox issue with libseccomp v2.4.0 #148
Comments
Hi @toralf, unfortunately I'm not very familiar with the Tor sandboxing code. Is there anyway for you to capture the libseccomp PFC output from the Tor libseccomp filter so we can compare it with the desired Tor filter? See the |
@drakenclimber you wouldn't happen to have any experience with Tor, would you? |
|
Thanks for keeping us updated @toralf, if you need any help/advice on writing libseccomp filters for Tor (or any other application) please let us know, we're happy to help. Good luck! |
I do wonder about your opinion about https://trac.torproject.org/projects/tor/ticket/29819#comment:10 ? |
Hello again. As I said previously, I'm really not very familiar with the Tor libseccomp filters and there isn't much information in the linked ticket. I think it might be helpful if you could capture the libseccomp PFC output from the Tor libseccomp filters so we can compare it to the desired filter. |
I got the PFC output (pfc.txt). rt_sigaction(1 (=SIGHUP), …) is what causes the crash but I'm not sure if the PFC is trying to tell me that that's allowed or not:
|
I get the same rt_sigaction filter for the case that fails. For the versions of libseccomp that succeed, I get:
The order is difference, but the permitted signals seem to be the same. |
@pgerber can you share the full PFC output for the older/success case? |
Full PFC output: |
Hmm, nothing is immediately jumping out at me. Would you mind capturing the BPF output? I only need the libseccomp v2.4.0 BPF output. |
BPF output for v2.4.0: |
Thanks @pgerber, for reference, here is the disassembled BPF: https://gist.github.com/pcmoore/ec93299cf460683464fdc3847b4cdf13 |
Okay, yes, it looks like the BPF is incorrect. Take the case of First the normal x86_64 preamble:
... eventually we get to
... and we don't see 1/SIGHUP listed to we need to take the false branch at the end which jumps down to line 355:
... which we can see is definitely not correct. The PFC looks correct, so this is likely a problem with the BPF code generator. Thanks for bringing this to our attention, and providing the filter output so we could identify that the problem was with libseccomp. We'll look into this and keep this issue updated as we make progress. |
@drakenclimber fixing this is obviously a priority for libseccomp, any help you can provide would be good. |
That definitely made a positive difference:
|
For reference, this is my current libseccomp patch:
|
Let me try and explain what is happening and why I think you don't want to leave those two While you had multiple Does that make sense? |
@drakenclimber First off, does that patch above look reasonable to you? If so, can I add your Acked-by to the patch? Regardless of anything else, I think that is a fix we should make. On the issue of reverting some changes to preserve the ordering of the argument checks from v2.3.x, I'd like to leave things the way they are in v2.4.0 simply because now there is an explicit ordering. Prior to the v2.4.0 release, the order of argument checks was dependent on what order the rules were added to the filter, but starting with v2.4.0 we explicitly order the argument checks. While it does differ from v2.3.x, it shouldn't cause any filters to break unless there are other issues (as we've seen here). |
@pgerber I wasn't familiar with the intricacies of I wrote a small test to verify this behavior. Here are the critical parts of it:
I'm still not certain how libseccomp v2.3.3 and Tor is not encountering this problem. The BPF for v2.3.3 and v2.4 (with the hash fix) look very similar. I'll keep researching this. |
Sorry, I forgot to respond to that last night. Yes, you are both correct, for safety reasons the kernel's seccomp code doesn't look into user provided pointers. However, as I mentioned above, the |
Thanks, @pcmoore. I agree. I waded through their code quite a bit and they are using different string pointers throughout the codebase. That will prove problematic for seccomp and the I did get a chance to look through the Tor's v2.3.3 @pgerber and others - once we get the hash collision fix into libseccomp, let me know if want another set of eyes on the seccomp changes you need to make on your end. |
Thanks for you responses, both of you. I left a comment on Tor's bug tracker in the hope of getting some feedback from some actual Tor developers. It would appear that there is some logic in place to statically allocate all the strings used as paths prot_strings() in sandbox.c:1239) and reuse them later (sandbox_intern_string() in sandbox:1169). I guess what @pcmoore mentioned in an earrlier comment about there being some filters just looking at the flags of |
Filters with complex argument chains could potentially experience mishandled hash collisions. In this instance, the BPF code generated for rt_sigaction() was inadvertently chained to socket() due to improper hash collision management. This addresses GitHub issue seccomp#148. Reported-by: Toralf Förster <toralf.foerster@gmx.de> Suggested-by: Paul Moore <paul@paul-moore.com> Signed-off-by: Tom Hromatka <tom.hromatka@oracle.com>
I was able to create a test case that reproduces the hash collision reported by Tor. I added it (and the |
This addresses a problem where dissimilar instruction blocks were improperly hashed to the same value because we were not taking into account the accumulator state. See the GitHub issue below for more information: * seccomp#148 Reported-by: Toralf Förster <toralf.foerster@gmx.de> Signed-off-by: Paul Moore <paul@paul-moore.com> Signed-off-by: Tom Hromatka <tom.hromatka@oracle.com>
libseccomp utilizes a hash table to manage BPF blocks. It currently employs MurmurHash3 where the key is the hashed values of the BPF instruction blocks, the accumulator start, and the accumulator end. This test was added because of a mishandled hash collision reported by Tor in GitHub issue seccomp#148. * seccomp#148 Signed-off-by: Tom Hromatka <tom.hromatka@oracle.com>
I'm not sure I understand this fully. Tor uses this logic currently:
In order to achieve this, Tor assumes that the order rules are added is the order in which they are later applied. If I understood you, @pcmoore, correctly, the order in which rules are added has no longer an impact on the order rules are applied. Did I understand this correctly? If this is indeed the case, is there still a way to restore the old logic? Also, I'd expect this to be a common pattern and I'd also expect that sooner or later others run into the same issue as Tor when upgrading to v2.4.0. Intuitively, I'd expect the rule to be applied in the user-given order. |
At Gentoo these packages were at least candidates:
|
First off I think a bit of clarification is in order. The "ordering" that @drakenclimber and I were talking about is the ordering related to checking syscall argument values for the same syscall argument. Imagine a syscall named "foo" which takes a single numerical argument, e.g. The ordering you are talking about, general ordering between rules depending on the order in which they are created, is somewhat related but it is quite different in practice and not something libseccomp has ever guaranteed. Even the syscall priority functions are just "hints" to the filter optimization engine and do not guarantee a strict ordering.
Unfortunately that is not the way libseccomp has ever worked. Thinking quickly, I'm not sure how difficult it would be, but we may be able to allow callers to request a specific rule ordering in the future, but doing so would severely handicap the rule/BPF optimizations to the point that I don't believe we could do anything meaningful. The only guarantees that libseccomp provides regarding rule execution is that argument comparisons within a single rule are applied using a boolean "AND" when determining if a particular syscall invocation is a match, and that the individual rules are combined using a boolean "OR". I apologize if that was not clear from the beginning. If you are having trouble adapting the Tor filter, please let us know and we can try to help. |
This addresses a problem where dissimilar instruction blocks were improperly hashed to the same value because we were not taking into account the accumulator state. See the GitHub issue below for more information: * seccomp#148 Reported-by: Toralf Förster <toralf.foerster@gmx.de> Signed-off-by: Paul Moore <paul@paul-moore.com> Signed-off-by: Tom Hromatka <tom.hromatka@oracle.com>
libseccomp utilizes a hash table to manage BPF blocks. It currently employs MurmurHash3 where the key is the hashed values of the BPF instruction blocks, the accumulator start, and the accumulator end. This test was added because of a mishandled hash collision reported by Tor in GitHub issue seccomp#148. * seccomp#148 Signed-off-by: Tom Hromatka <tom.hromatka@oracle.com>
This addresses a problem where dissimilar instruction blocks were improperly hashed to the same value because we were not taking into account the accumulator state. See the GitHub issue below for more information: * #148 Reported-by: Toralf Förster <toralf.foerster@gmx.de> Signed-off-by: Paul Moore <paul@paul-moore.com> Signed-off-by: Tom Hromatka <tom.hromatka@oracle.com>
libseccomp utilizes a hash table to manage BPF blocks. It currently employs MurmurHash3 where the key is the hashed values of the BPF instruction blocks, the accumulator start, and the accumulator end. This test was added because of a mishandled hash collision reported by Tor in GitHub issue #148. * #148 Signed-off-by: Tom Hromatka <tom.hromatka@oracle.com> Signed-off-by: Paul Moore <paul@paul-moore.com>
This addresses a problem where dissimilar instruction blocks were improperly hashed to the same value because we were not taking into account the accumulator state. See the GitHub issue below for more information: * #148 Reported-by: Toralf Förster <toralf.foerster@gmx.de> Signed-off-by: Paul Moore <paul@paul-moore.com> Signed-off-by: Tom Hromatka <tom.hromatka@oracle.com>
libseccomp utilizes a hash table to manage BPF blocks. It currently employs MurmurHash3 where the key is the hashed values of the BPF instruction blocks, the accumulator start, and the accumulator end. This test was added because of a mishandled hash collision reported by Tor in GitHub issue #148. * #148 Signed-off-by: Tom Hromatka <tom.hromatka@oracle.com> Signed-off-by: Paul Moore <paul@paul-moore.com>
I believe we should now have this fixed in the master and release-2.4 branches. @drakenclimber I'm thinking we should do a v2.4.1 release soon (e.g. this week) to address this problem, what do you think? Have you seen any other bugs in the v2.4.0 release? |
Yes, I think this bug is serious enough to merit another release. Let me know how I can help.
Nope. In fact this fixed an issue that had been bothering me with the binary tree work. I think it's looking pretty solid. |
Okay, since we're in agreement I'll start working through the release process for v2.4.1. As for help ... I thought we would have a bit more time before the next release to get all our co-maintainer processes in place, but that didn't quite work to plan :) In the interest of getting this out the door quickly I'll just take care of it (it should be relatively easy given the single fix). However, I did just add issue #146 as a blocker for v2.4.2 so we're on the hook to getting you fully plugged-in for v2.4.2 ;) You've probably already seen it, but if you haven't, I've documented the release process in https://github.com/seccomp/libseccomp/blob/master/RELEASE_PROCESS.md .
Fingers crossed. |
@toralf @pgerber since it appears we've resolved this issue in the libseccomp upstream, I'm going to close this bug now and start the libseccomp v2.4.1 with the fix we've discussed here. If you have any additional questions or concerns, please do let us know. Thanks again for bringing this to our attention and helping us out while we arrived at a solution. |
For reference, libseccomp v2.4.1 is out with the fix for this bug. |
There's a small regression with 2.40 and Tor:
https://trac.torproject.org/projects/tor/ticket/29819#comment:5
and I do wonder if this is a shortcoming of the Tor code?
The text was updated successfully, but these errors were encountered: