-
Notifications
You must be signed in to change notification settings - Fork 61
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: selinux-testsuite overlayfs failures on v4.19-rc1 #41
Comments
Observations:
|
Yes, I think this is related. So during dentry lookup we also check if metacopy xattr is present or not. So kernel makes a vfs_getxattr() call on underlying file. This test is not giving any access on the file, so getxattr fails. I think we should modify selinux policy for test and atleast give getattr access to underlying file and that should fix the issue. Another alternative is to not check for metacopy xattr if metacopy=on is not passed. But this will create problems if somebody mounted overlayfs with metacopy=on and later remounted without metacopy=on. In that case we don't want to create any new metacopy indoes but there are already existing metacopy inodes in the fs and we want to make sure that these are handled without any issues. Unfortunately we don't have any mechanism in overlayfs to determine that what options were used with overlayfs mount and what options are now incompatible for mounting. There are some proposals but nothing has made upstream yet. |
I dislike the requirement to change the SELinux policy for the simple reason that it implies a breaking change in kernel behavior. Changing the selinux-testsuite policy is easy enough, but what about all of the distribution, third-party, and custom SELinux policies? I think we need to find a way to make this work with the existing policy/tests. |
Should overlayfs be using __vfs_getxattr() to avoid permission checking on these kinds of internal operations? |
vfs_getxattr() vs __vfs_getxattr(): The former does permission checking and also transparently redirects requests for the security.* attributes to the security module for handling (to deal with filesystems that do not natively support security xattrs and to allow the security module to provide the canonical value). The latter just invokes the xattr handler to fetch the value from the filesystem. For non-security attributes, unless we want permission checking here, we should just use __vfs_getxattr(). |
Current overlayfs model is to switch to mounter's creds for operations on lower or upper files. so bypassing checks on getxattr() is just one operation and it does not fit into overlayfs's current security model. In our test we have noaccess file. I think we need to give atleast getattr() permission to mounter and then check would succeed. If mounter can't even do getattr, file unlink will be denied. Is this something critical from user's point of view? Also metacopy is just one xattr. There are other xattrs as well. May be it was by chance that we did not hit that path in the past. I remember having discussed this with dan walsh and he had agreed that noaccessfile should have atleast getattr permission. Or get rid of test. CC @rhatdan |
I was wondering why this test did not fail previously because we already have logic for checking XATTR_ORIGIN in ovl_lookup(). Looks like checking XATTR_ORIGIN kicks in only if there is upperdentry. Given there is no upper file in our test, I think that's why it succeeded. If we modify test to copy up file and then do unlink() it should fail same way. IOW, current lookup in overlayfs has dependency that atleast mounter should be able to check xattr of the file. |
As a quick test, I attempted a similar operation using an ext4 filesystem:
|
Based on the comments above I think the right answer is simply to expect the test to fail; basically we should replace the call to |
@pcmoore, If we replace test_72_ctx() with test_72(), then it will start failing on older kernels. So either we should not run test_72() at all during context mounts. Or if we want to run test with context mounts, then we need to give getattr permission on noaccess file. I just experimented with giving getattr permission to mounter and created a PR. SELinuxProject/selinux-testsuite#39 I am fine with whatever change you like. |
Or may be trying unlink on noaccess_file_t is not the right thing to test. We should it on a file which does not have unlink permission to overlay_client_t. So unlink will fail without context. But it will succeed with context mount. And mounter should have getattr on this file type. So may be we need to create a new type file_no_unlink_t? |
I am still unclear on why we are using vfs_getxattr() here rather than __vfs_getxattr(). In the case of fetching the metacopy xattr, we are not doing so in order to expose it to userspace, but rather to use it internally within the kernel code, right? At no point are we returning the xattr value to userspace in this code path? So omitting the permission check altogether when fetching overlayfs-internal xattrs does not risk allowing the mounter to gain access to unauthorized files through overlayfs context mounts, avoids needing to allow the mounter to directly perform getxattr(2) calls on it, and avoids the brittleness of making policy dependent on overlayfs internal implementation details. |
This btw would apply to all of the overlay xattrs (metacopy, origin, redirect, nlink) - as long as it is purely kernel-internal, why do we need to perform a check here? Not sure what happens in the NFS case though where the server might apply a check. |
My current opinion is that the selinux-testsuite should focus on testing for the correct behavior, even though this may cause test failures on older, unpatched kernels. The primary focus of the selinux-testsuite is to serve as a quick regression test for upstream development. Of course it can be used for other purposes as well, but those are secondary. @rhvgoyal it would also be good to address @stephensmalley's concern regarding the use of __vfs_getxattr(); while you made some comments about overlayfs' design, I don't think you really answered the question. |
I think using vfs_getxattr() in the context of mounter creds works well with the current security model. Any operation on underlying layer happens with the creds of mounter and if mounter is not allowed to do certain operation it fails. Bypassing checks during lookup for getxattr() seems like a band aid fix. There are other cases to consider. For example, what if mounter does not have permission to search in lower dir. In that case also path resolution will fail (IIUC) and then unlink will fail. And it makes sense because that's how security model was designed. Another case to consider is that unlink drops a whiteout if a file on upper directory is being removed. (So that lower file does not become visible). Now if mounter does not have permission to write to upper or create char device, this unlink operation will fail. What I am trying to say is that getxattr() is just one operation which is done in with the mounter's creds on underlying file system. There are many operations which are done with mounter's creds and if policy is not configured right, it will break in all those cases as well. While it is little difficult, I think we have to configure policy right and make sure mounter has right permissions. It might be little un-intuitive sometimes (as in this case. Why unlink is resulting in getxattr in lower filesystem), but that's overlayfs design. It tries to emulate certain things. Dropping whiteout on unlink is another example of operation which is not intuitive. |
Why are we trying to run these test cases on noaccess_t files. We are trying to first test no-context vs context. So a file which does not have "unlink" permission without context, gets permission to unlink with-context. But that should assume that mounter has all the access to the file. By creating a test where client does not have access as well as mounter can't do the operation on the underlying file is going to complicate things. I think mounter's tests should be decoupled from client's test. When client is being tested, it should be assumed that mounter can do all all the operations. And then there should probably be separate tests to make sure if mounter does not have certain access, client can't get those accesses as well and there is no privilege escalation. Right now we seem to be mixing two things and assuming unlink() does not result in any other operation in overlayfs while trying to emulate it. |
@pcmoore Assuming that mounter is going to need exactly same permission as client I think is a problem. And trying to change overlayfs design for that will just lead to more confusion. That is in what cases should we check mounter's creds and in what cases to bypass it. A rather simpler model is that give mounter's policy all basic access on underlying files and make client's access restrictive and run the tests. Assuming that because client does not require getattr permission to unlink a file and hence mounter will not require getattr as well on underlying file I think is going to be problematic. We will run into these kind of situations again and again as overlayfs design evolves. |
For example, android folks are proposing another security model where checks on underlying filesystem also happen with the creds of the caller/client. (And not mounter). There is a good chance that those patches will be merged as well and user gets to choose security model they want. In that case, IIUC, ovl_lookup() will happen with the creds of caller. And getattr() will be called in the context of caller as well. And unlink() will need getattr permission for it to succeed. (As opposed to current needs). Given overlayfs is stacked filesystem and does certain operations on lower to emulate top level operations, writing policy will be little un-intuitive. I gave another example of already, doing unlink of |
Ok, I accept your argument WRT to vfs_getxattr() and getattr permission. |
Ok, here is another PR to fix the issue. SELinuxProject/selinux-testsuite#40 I got rid of test_72() and test_72_ctx(). IMO, test_70() and test_70_ctx() are doing the job we want to do. That is make sure a file can't be unlinked without context mount but same file can be unlinked with context mount. And this should work with old kernel as well as new kernel. test_72() and test_72_ctxt() did not make much sense to me. It was not clear to me what are we testing which test_70() is not already doing. |
The test suite focus remains on making sure we are testing the proper behavior on current, upstream kernels. RHEL kernels are such an odd mix of backports and unusual behavior that the test suite often needs special patching to work on a given RHEL release. Upstream should focus on upstream and let the distros worry about the distros. |
Resolved in SELinuxProject/selinux-testsuite#40 |
…A memory with different size" The TI CPSW(s) driver produces warning with DMA API debug options enabled: WARNING: CPU: 0 PID: 1033 at kernel/dma/debug.c:1025 check_unmap+0x4a8/0x968 DMA-API: cpsw 48484000.ethernet: device driver frees DMA memory with different size [device address=0x00000000abc6aa02] [map size=64 bytes] [unmap size=42 bytes] CPU: 0 PID: 1033 Comm: ping Not tainted 5.3.0-dirty #41 Hardware name: Generic DRA72X (Flattened Device Tree) [<c0112c60>] (unwind_backtrace) from [<c010d270>] (show_stack+0x10/0x14) [<c010d270>] (show_stack) from [<c09bc564>] (dump_stack+0xd8/0x110) [<c09bc564>] (dump_stack) from [<c013b93c>] (__warn+0xe0/0x10c) [<c013b93c>] (__warn) from [<c013b9ac>] (warn_slowpath_fmt+0x44/0x6c) [<c013b9ac>] (warn_slowpath_fmt) from [<c01e0368>] (check_unmap+0x4a8/0x968) [<c01e0368>] (check_unmap) from [<c01e08a8>] (debug_dma_unmap_page+0x80/0x90) [<c01e08a8>] (debug_dma_unmap_page) from [<c0752414>] (__cpdma_chan_free+0x114/0x16c) [<c0752414>] (__cpdma_chan_free) from [<c07525c4>] (__cpdma_chan_process+0x158/0x17c) [<c07525c4>] (__cpdma_chan_process) from [<c0753690>] (cpdma_chan_process+0x3c/0x5c) [<c0753690>] (cpdma_chan_process) from [<c0758660>] (cpsw_tx_mq_poll+0x48/0x94) [<c0758660>] (cpsw_tx_mq_poll) from [<c0803018>] (net_rx_action+0x108/0x4e4) [<c0803018>] (net_rx_action) from [<c010230c>] (__do_softirq+0xec/0x598) [<c010230c>] (__do_softirq) from [<c0143914>] (do_softirq.part.4+0x68/0x74) [<c0143914>] (do_softirq.part.4) from [<c0143a44>] (__local_bh_enable_ip+0x124/0x17c) [<c0143a44>] (__local_bh_enable_ip) from [<c0871590>] (ip_finish_output2+0x294/0xb7c) [<c0871590>] (ip_finish_output2) from [<c0875440>] (ip_output+0x210/0x364) [<c0875440>] (ip_output) from [<c0875e2c>] (ip_send_skb+0x1c/0xf8) [<c0875e2c>] (ip_send_skb) from [<c08a7fd4>] (raw_sendmsg+0x9a8/0xc74) [<c08a7fd4>] (raw_sendmsg) from [<c07d6b90>] (sock_sendmsg+0x14/0x24) [<c07d6b90>] (sock_sendmsg) from [<c07d8260>] (__sys_sendto+0xbc/0x100) [<c07d8260>] (__sys_sendto) from [<c01011ac>] (__sys_trace_return+0x0/0x14) Exception stack(0xea9a7fa8 to 0xea9a7ff0) ... The reason is that cpdma_chan_submit_si() now stores original buffer length (sw_len) in CPDMA descriptor instead of adjusted buffer length (hw_len) used to map the buffer. Hence, fix an issue by passing correct buffer length in CPDMA descriptor. Cc: Ivan Khoronzhuk <ivan.khoronzhuk@linaro.org> Fixes: 6670aca ("net: ethernet: ti: davinci_cpdma: add dma mapped submit") Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com> Reviewed-by: Ivan Khoronzhuk <ivan.khoronzhuk@linaro.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Running the selinux-testsuite results in the following failure:
The text was updated successfully, but these errors were encountered: