Skip to content

Implement chcon #1041

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

Closed
muzikmoe opened this issue May 20, 2017 · 8 comments · Fixed by #2075
Closed

Implement chcon #1041

muzikmoe opened this issue May 20, 2017 · 8 comments · Fixed by #2075

Comments

@muzikmoe
Copy link

I'll be working on chcon.

@koutheir
Copy link
Contributor

@muzikmoe: it's been a long time. Have you got any results that you can share?

@koutheir
Copy link
Contributor

koutheir commented Apr 4, 2021

I've been working on implementing chcon, and I'm at the phase of implementing integration tests.

I'm trying to use the helper macros/crates provided by this project, but I'm stuck with a problem: chcon requires root privileges in order to succeed. This means that running the following chcon integration test fails with an Operation not permitted error when run as a normal user:

    let file = tempfile::NamedTempFile::new().unwrap();

    new_ucmd!()
        .args(&[
            OsStr::new("--user=user1"),
            OsStr::new("--type=type1"),
            OsStr::new("--role=role1"),
            OsStr::new("--range=range1"),
            file.path().as_ref(),
        ])
        .succeeds();

This would only succeed if run with root privileges, due to the requirements of libselinux.

Is there a way to run some integration tests as root, while still implementing them within the testing framework of this project?

@sylvestre
Copy link
Contributor

I think chown is doing stuff which requires root
https://github.com/uutils/coreutils/blob/4873c8a24b7e00283572f05da18e3b74a6819562/tests/by-util/test_chown.rs
but maybe not on all builds nodes?!

@koutheir
Copy link
Contributor

koutheir commented Apr 8, 2021

@sylvestre: I couldn't find anything in test_chown.rs which requires running as root. Did I miss something?

@koutheir
Copy link
Contributor

koutheir commented Apr 8, 2021

I'm done implementing basic integration tests, but they only succeed when the test binary is run as root. This might be unacceptable for this project, but that's the best I could achieve for the moment without attempting to over-engineer.

Example of running as a normal user:

$ target/debug/deps/tests-d097b5ae9f0f2f6f
running 10 tests
/sbin/setfilecon:  setfilecon(/tmp/.tmpRJ9LVp/a.tmp,user0:role0:type0:range0) failed
/sbin/setfilecon:  setfilecon(/tmp/.tmpvUZcLj/a.tmp,user0:role0:type0:range0) failed
/sbin/setfilecon:  setfilecon(/tmp/.tmpYPDv0h/a.tmp,user0:role0:type0:range0) failed
/sbin/setfilecon:  setfilecon(/tmp/.tmpK3WlX9/a.tmp,user0:role0:type0:range0) failed
test test_chcon::user_change ... FAILED
test test_chcon::role_change ... FAILED
test test_chcon::range_change ... FAILED
test test_chcon::type_change ... FAILED
/sbin/setfilecon:  setfilecon(/tmp/.tmpdPKOqi/a.tmp,user0:role0:type0:range0) failed
/sbin/setfilecon:  setfilecon(/tmp/.tmptfN1k5/a.tmp,user0:role0:type0:range0) failed
test test_chcon::valid_context ... FAILED
test test_chcon::user_role_range_type ... FAILED
/sbin/setfilecon:  setfilecon(/tmp/.tmpvuP2Sx/a.tmp,user0:role0:type0:range0) failed
test test_chcon::valid_reference ... FAILED
test test_chcon::version ... ok
test test_chcon::help ... ok
test test_chcon::reference_errors ... ok

failures:

---- test_chcon::user_change stdout ----
current_directory_resolved: 
touch: /tmp/.tmpvUZcLj/a.tmp
thread 'test_chcon::user_change' panicked at 'assertion failed: status.success()', /home/koutheir/Desktop/coreutils/tests/by-util/test_chcon.rs:155:5

---- test_chcon::role_change stdout ----
current_directory_resolved: 
touch: /tmp/.tmpK3WlX9/a.tmp
thread 'test_chcon::role_change' panicked at 'assertion failed: status.success()', /home/koutheir/Desktop/coreutils/tests/by-util/test_chcon.rs:155:5

---- test_chcon::range_change stdout ----
current_directory_resolved: 
touch: /tmp/.tmpRJ9LVp/a.tmp
thread 'test_chcon::range_change' panicked at 'assertion failed: status.success()', /home/koutheir/Desktop/coreutils/tests/by-util/test_chcon.rs:155:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

---- test_chcon::type_change stdout ----
current_directory_resolved: 
touch: /tmp/.tmpYPDv0h/a.tmp
thread 'test_chcon::type_change' panicked at 'assertion failed: status.success()', /home/koutheir/Desktop/coreutils/tests/by-util/test_chcon.rs:155:5

---- test_chcon::valid_context stdout ----
current_directory_resolved: 
touch: /tmp/.tmpdPKOqi/a.tmp
thread 'test_chcon::valid_context' panicked at 'assertion failed: status.success()', /home/koutheir/Desktop/coreutils/tests/by-util/test_chcon.rs:155:5

---- test_chcon::user_role_range_type stdout ----
current_directory_resolved: 
touch: /tmp/.tmptfN1k5/a.tmp
thread 'test_chcon::user_role_range_type' panicked at 'assertion failed: status.success()', /home/koutheir/Desktop/coreutils/tests/by-util/test_chcon.rs:155:5

---- test_chcon::valid_reference stdout ----
current_directory_resolved: 
touch: /tmp/.tmpvuP2Sx/a.tmp
thread 'test_chcon::valid_reference' panicked at 'assertion failed: status.success()', /home/koutheir/Desktop/coreutils/tests/by-util/test_chcon.rs:155:5


failures:
    test_chcon::range_change
    test_chcon::role_change
    test_chcon::type_change
    test_chcon::user_change
    test_chcon::user_role_range_type
    test_chcon::valid_context
    test_chcon::valid_reference

test result: FAILED. 3 passed; 7 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s

Example of running as root:

$ sudo target/debug/deps/tests-d097b5ae9f0f2f6f
running 10 tests
test test_chcon::role_change ... ok
test test_chcon::user_change ... ok
test test_chcon::range_change ... ok
test test_chcon::type_change ... ok
test test_chcon::reference_errors ... ok
test test_chcon::help ... ok
test test_chcon::version ... ok
test test_chcon::user_role_range_type ... ok
test test_chcon::valid_context ... ok
test test_chcon::valid_reference ... ok

test result: ok. 10 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.03s

Please advise me on how to proceed. Should I solve this issue somehow before I contribute to the project? Or do I make a pull request with the integration tests failing, unless run as root?

@sylvestre
Copy link
Contributor

yeah, do like:

if get_effective_uid() == 0 {

if get_effective_uid() == 0 {

@koutheir
Copy link
Contributor

koutheir commented Apr 8, 2021

This approach would only solve the issue of test failures when run as a normal user, but it will make the tests basically useless, as they are not going to be executed to help avoid regressions.

@sylvestre: Do the CI servers ever run tests as root?

@koutheir
Copy link
Contributor

Given that I didn't receive any answers about this issue, I marked all tests that need to be run as root as ignored. This means that they will not be executed by default, and that fact will be explicitly indicated in the test results. For example:

$ target/debug/deps/tests-a36c810d3fd0c415

running 34 tests
test common::util::tests::test_code_is ... ok
test common::util::tests::test_failure ... ok
test common::util::tests::test_no_std_errout ... ok
test common::util::tests::test_code_is_fail ... ok
test common::util::tests::test_failure_fail ... ok
test common::util::tests::test_no_stderr_fail ... ok
test common::util::tests::test_no_stdout_fail ... ok
test common::util::tests::test_std_does_not_contain ... ok
test common::util::tests::test_stderr_does_not_contain_fail ... ok
test common::util::tests::test_stdout_does_not_contain_fail ... ok
test common::util::tests::test_success ... ok
test test_chcon::range_change ... ignored
test test_chcon::role_change ... ignored
test test_chcon::type_change ... ignored
test test_chcon::user_change ... ignored
test common::util::tests::test_success_fail ... ok
test test_chcon::user_role_range_type_with_prior_xattributes ... ignored
test test_chcon::valid_context ... ignored
test test_chcon::valid_context_directory ... ignored
test test_chcon::valid_context_directory_recursive ... ignored
test test_chcon::valid_context_directory_recursive_follow_all_symlinks ... ignored
test test_chcon::valid_context_directory_recursive_follow_args_dir_symlinks ... ignored
test test_chcon::valid_context_on_broken_symlink ... ignored
test test_chcon::valid_context_on_valid_symlink ... ignored
test test_chcon::valid_context_with_prior_xattributes ... ignored
test test_chcon::valid_reference ... ignored
test common::util::tests::test_stdout_matches_fail ... ok
test common::util::tests::test_stdout_matches ... ok
test common::util::tests::test_stdout_not_matches_fail ... ok
test test_chcon::user_role_range_type ... ok
test test_chcon::version ... ok
test test_chcon::help ... ok
test test_chcon::reference_errors ... ok
test test_chcon::recursive_errors ... ok

test result: ok. 20 passed; 0 failed; 14 ignored; 0 measured; 0 filtered out; finished in 0.03s

Executing those tests requires running as root while specifying the flag --include-ignored. For example:

$ sudo target/debug/deps/tests-a36c810d3fd0c415 --include-ignored

running 34 tests
test common::util::tests::test_code_is ... ok
test common::util::tests::test_failure ... ok
test common::util::tests::test_no_std_errout ... ok
test common::util::tests::test_code_is_fail ... ok
test common::util::tests::test_failure_fail ... ok
test common::util::tests::test_no_stdout_fail ... ok
test common::util::tests::test_no_stderr_fail ... ok
test common::util::tests::test_std_does_not_contain ... ok
test common::util::tests::test_stderr_does_not_contain_fail ... ok
test common::util::tests::test_stdout_does_not_contain_fail ... ok
test common::util::tests::test_success ... ok
test common::util::tests::test_success_fail ... ok
test common::util::tests::test_stdout_matches_fail ... ok
test common::util::tests::test_stdout_not_matches_fail ... ok
test test_chcon::range_change ... ok
test common::util::tests::test_stdout_matches ... ok
test test_chcon::role_change ... ok
test test_chcon::type_change ... ok
test test_chcon::user_change ... ok
test test_chcon::user_role_range_type ... ok
test test_chcon::valid_context ... ok
test test_chcon::valid_context_directory ... ok
test test_chcon::user_role_range_type_with_prior_xattributes ... ok
test test_chcon::help ... ok
test test_chcon::valid_context_directory_recursive ... ok
test test_chcon::valid_context_directory_recursive_follow_all_symlinks ... ok
test test_chcon::valid_context_directory_recursive_follow_args_dir_symlinks ... ok
test test_chcon::valid_context_on_broken_symlink ... ok
test test_chcon::valid_context_on_valid_symlink ... ok
test test_chcon::reference_errors ... ok
test test_chcon::version ... ok
test test_chcon::recursive_errors ... ok
test test_chcon::valid_context_with_prior_xattributes ... ok
test test_chcon::valid_reference ... ok

test result: ok. 34 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.03s

The source code documents the reason behind the ignore attribute:

#[test]
#[ignore = "test must be run as root"]
fn valid_context_directory_recursive_follow_all_symlinks() {
    /* ... */
}

With this change, I'm ready to send a pull request.

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

Successfully merging a pull request may close this issue.

3 participants