Bug 1777831
Summary: | chcon fails with "invalid context: ‘<context>’: No such file or directory" | |||
---|---|---|---|---|
Product: | Red Hat Enterprise Linux 8 | Reporter: | Renaud Métrich <rmetrich> | |
Component: | coreutils | Assignee: | Kamil Dudka <kdudka> | |
Status: | CLOSED ERRATA | QA Contact: | Radka Brychtova <rskvaril> | |
Severity: | medium | Docs Contact: | ||
Priority: | urgent | |||
Version: | 8.1 | CC: | dperpeet, dwalsh, fkrska, kdudka, lnykryn, lvrabec, mmalik, plautrba, ssekidde, vmojzis | |
Target Milestone: | rc | Keywords: | Patch, ZStream | |
Target Release: | 8.0 | |||
Hardware: | All | |||
OS: | Linux | |||
Whiteboard: | ||||
Fixed In Version: | coreutils-8.30-7.el8 | Doc Type: | Bug Fix | |
Doc Text: |
Cause:
chcon validated the CONTEXT argument using API that does not work when SELinux is disabled.
Consequence:
If SELinux was disabled, chcon unnecessarily failed.
Fix:
chcon has been changed to only validate the CONTEXT argument if SELinux is enabled.
Result:
chcon now works even if SELinux is disabled.
|
Story Points: | --- | |
Clone Of: | ||||
: | 1796060 1822393 (view as bug list) | Environment: | ||
Last Closed: | 2020-11-04 01:37:10 UTC | Type: | Bug | |
Regression: | --- | Mount Type: | --- | |
Documentation: | --- | CRM: | ||
Verified Versions: | Category: | --- | ||
oVirt Team: | --- | RHEL 7.3 requirements from Atomic Host: | ||
Cloudforms Team: | --- | Target Upstream Version: | ||
Embargoed: | ||||
Bug Depends On: | 1681018 | |||
Bug Blocks: | 1796060, 1822393 |
Description
Renaud Métrich
2019-11-28 12:12:16 UTC
The issue is within libselinux: -------- 8< ---------------- 8< ---------------- 8< ---------------- 8< -------- 12 int security_check_context_raw(const char * con) 13 { : 22 if (!selinux_mnt) { 23 errno = ENOENT; 24 return -1; 25 } -------- 8< ---------------- 8< ---------------- 8< ---------------- 8< -------- we have selinux_mnt == NULL Does is work if you add "s0" to the context? # chcon unconfined_u:object_r:usr_t:s0 <file> I believe that chcon needs a complete context if all options are omitted. Nope, doesn't work either. Honestly I don't know if it's a libselinux issue or coreutils issue. I see a difference in chcon.c RHEL7/RHEL8: RHEL7: -------- 8< ---------------- 8< ---------------- 8< ---------------- 8< -------- 557 { 558 context_t context; 559 specified_context = argv[optind++]; 560 context = context_new (specified_context); 561 if (!context) 562 error (EXIT_FAILURE, 0, _("invalid context: %s"), 563 quotearg_colon (specified_context)); 564 context_free (context); 565 } -------- 8< ---------------- 8< ---------------- 8< ---------------- 8< -------- Line 561 always succeeds, even with SELinux disabled. RHEL8: -------- 8< ---------------- 8< ---------------- 8< ---------------- 8< -------- 558 { 559 specified_context = argv[optind++]; 560 if (security_check_context (se_const (specified_context)) < 0) 561 die (EXIT_FAILURE, errno, _("invalid context: %s"), 562 quote (specified_context)); 563 } -------- 8< ---------------- 8< ---------------- 8< ---------------- 8< -------- Line 560 fails with SELinux disabled. I would tend to see back to coreutils ... Note anyway that this is some oddity: with SELinux disabled, you can set whatever label you want, even if it doesn't exist (assuming the file already exists of course) Enabled: # chcon -t boulet_t /tmp/foo chcon: failed to change context of ‘/tmp/foo’ to ‘unconfined_u:object_r:boulet_t:s0’: Invalid argument Disabled: # chcon -t boulet_t /tmp/foo --> no error The code in coreutils was changed here: -------- 8< ---------------- 8< ---------------- 8< ---------------- 8< -------- commit e4081e44e0dcc4bfe11d0da0ae47518df087349d Author: Namhyung Kim <namhyung> Date: Tue Jul 1 00:12:41 2014 +0900 chcon: use security_check_context() for context validation context_new() and _free() are used for checking validity of a specified context. libselinux provides security_check_context for this purpose so use it. Note that context_new() can fail for a valid context - e.g. ENOMEM. * src/chcon.c (main): Use security_check_context(). --- src/chcon.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/chcon.c b/src/chcon.c index 32d4b0f..8c18167 100644 --- a/src/chcon.c +++ b/src/chcon.c @@ -555,13 +555,10 @@ main (int argc, char **argv) } else { - context_t context; specified_context = argv[optind++]; - context = context_new (specified_context); - if (!context) - error (EXIT_FAILURE, 0, _("invalid context: %s"), + if (security_check_context (specified_context) < 0) + error (EXIT_FAILURE, errno, _("invalid context: %s"), quotearg_colon (specified_context)); - context_free (context); } if (reference_file && component_specified) -------- 8< ---------------- 8< ---------------- 8< ---------------- 8< -------- I'm tempted to say that it's not possible to chcon when SELinux is disabled, since it doesn't know which contexts are available (may depend on the policy used ...), hence I would consider "context_new()" not failing when SELinux is disabled is a bug. context_new() and other context_* routines are used for manipulating security context so that caller doesn't need to know internal implementation. It doesn't do any check. E.g. on SELinux enabled system, you can call context_new() on invalid context it will pass: ^&^ python3 Python 3.7.5 (default, Oct 17 2019, 12:16:48) [GCC 9.2.1 20190827 (Red Hat 9.2.1-1)] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import selinux >>> c = selinux.context_new("a:b:c:d") >>> selinux.context_type_get(c) 'c' >>> selinux.context_user_get(c) 'a' >>> selinux.context_role_get(c) 'b' So it's not a bug in context_new() that it's not failing when SELinux is disabled. But security_check_context() can't work with disabled SELinux. In this case, I'd say that chcon should not try to valide the context if SELinux is disabled. It should be enough add another check before context validation: if (is_selinux_enabled && security_check_context (specified_context) < 0) if (is_selinux_enabled() && security_check_context (specified_context) < 0) And it looks like the same check is not applied when -u/-r/-t used. It just computes a new context based on given values and applies it. I believe that the original behavior when you can set any context in SELinux disabled mode is correct. Thank you for finding the cause and proposing a solution! I have submitted it upstream for review: https://lists.gnu.org/archive/html/coreutils/2019-12/msg00002.html Credits to Petr :-) upstream commit: https://git.savannah.gnu.org/gitweb/?p=coreutils.git;a=commitdiff;h=v8.31-64-g5118a2e39 Since the problem described in this bug report should be resolved in a recent advisory, it has been closed with a resolution of ERRATA. For information on the advisory (coreutils bug fix and enhancement update), and where to find the updated files, follow the link below. If the solution does not work for you, open a new bug report. https://access.redhat.com/errata/RHBA-2020:4454 |