Giter Club home page Giter Club logo

caps-rs's People

Contributors

asomers avatar bkchr avatar dependabot-preview[bot] avatar ferrell-code avatar glaubitz avatar hvdijk avatar infinity0 avatar luben avatar lucab avatar msizanoen1 avatar thesecretmaster avatar zhaixiaojuan avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

caps-rs's Issues

caps-rs on armv7 CAP[S|G]ET not found in `nr`

I'm entirely unfamiliar with Rust but, attempting to compile railcar (https://github.com/oracle/railcar) on an armv7 device, throws errors in caps-rs that I suspect are due to the absence of armv7 target references in nr.rs

error[E0425]: cannot find value `CAPGET` in module `nr`
  --> /root/.cargo/registry/src/github.com-1ecc6299db9ec823/caps-0.0.1/src/base.rs:10:40
   |
10 |     let r = unsafe { libc::syscall(nr::CAPGET, hdr, data) };
   |                                        ^^^^^^ not found in `nr`

error[E0425]: cannot find value `CAPSET` in module `nr`
  --> /root/.cargo/registry/src/github.com-1ecc6299db9ec823/caps-0.0.1/src/base.rs:18:40
   |
18 |     let r = unsafe { libc::syscall(nr::CAPSET, hdr, data) };
   |                                        ^^^^^^ not found in `nr`

I tried (!) with:

#[cfg(target_arch = "arm")]
pub const CAPGET: i32 = 184;
#[cfg(target_arch = "arm")]
pub const CAPSET: i32 = 185;

and this appears (!) to resolve the error; at least it permits the compilation to proceed further.

I'm uncertain:

  • why target_arch must be arm for and not armv7 (as I'm using armv7-unknown-linux-gnueabihf)
  • I guessed (!) that CAPGET==184 and CAPSET==185 but was unable to find a syscall list

Unhelpful error message when attempting to un`set` Permitted capabilities

If you attempt to set capabilities in the Permitted capabilities set to a strict subset of the current capabilities without first dropping them in the Effective set, then this library returns an unhelpful error message CapsError("capset failure: Operation not permitted (os error 1)").

Under the hood, this library sets exactly what you tell it to and otherwise preserves the current state. This causes issues when using set to drop a lot of capabilities at once (for my application, I only need a few capabilities, so it's easier to set what I need than to clear what I don't). If I immediately set the Permitted capabilities, then the syscall it produces tries to preserve the current Effective capabilities and set the Permitted capabilities, which produces an Effective set that is no longer a subset of the Permitted set (which isn't allowed, hence the error return).

I'd prefer if calling set on the Permitted capabilities could also intersect the provided capabilities with the current Effective set and only set those Effective capabilities, so you can just make one call to set to drop the capabilities. However, that would be changing the API in ways that I'm not sure if you'd want, so if that's not allowed, then I'd prefer for this failure mode to get a more descriptive error message (likely has to be manually inserted as a check before we syscall into the kernel) and for documentation of this limitation could be put into set (and other methods if they also have this behavior).

Support PR_SET_KEEPCAPS

hey! I've noticed that the crate is currently not able to retain capabilities across a uid transition. It might be useful to have a function that corresponds to:

prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0);

Build failure on powerpc64 and mips64

Thanks for the crate! I'm trying to use it for Nix's CI tests. However, the build fails for powerpc64-unknown-linux-gnu, powerpc64le-unknown-linux-gnu, mips64-unknown-linux-gnu, and mips64el-unknown-linux-gnu.

   Compiling caps v0.3.0
error[E0425]: cannot find value `CAPGET` in module `nr`
  --> /cargo/registry/src/github.com-1ecc6299db9ec823/caps-0.3.0/src/base.rs:12:40
   |
12 |     let r = unsafe { libc::syscall(nr::CAPGET, hdr, data) };
   |                                        ^^^^^^ not found in `nr`
error[E0425]: cannot find value `CAPSET` in module `nr`
  --> /cargo/registry/src/github.com-1ecc6299db9ec823/caps-0.3.0/src/base.rs:20:40
   |
20 |     let r = unsafe { libc::syscall(nr::CAPSET, hdr, data) };
   |                                        ^^^^^^ not found in `nr`
error: aborting due to 2 previous errors
error: Could not compile `caps`.

Permitted set can be cleared but not set

While testing the keepcaps code I noticed I'm not able to drop capabilities from the permitted set:

 [%]> id
uid=0 euid=0 suid=0 gid=0 egid=0 sgid=0 groups=[0]
 [%]> caps
{CAP_SYS_RAWIO, CAP_LINUX_IMMUTABLE, CAP_MAC_OVERRIDE, CAP_SETUID, CAP_DAC_OVERRIDE, CAP_NET_ADMIN, CAP_IPC_LOCK, CAP_CHOWN, CAP_SETFCAP, CAP_AUDIT_READ, CAP_SYS_TIME, CAP_FOWNER, CAP_SYS_CHROOT, CAP_WAKE_ALARM, CAP_BLOCK_SUSPEND, CAP_MKNOD, CAP_AUDIT_CONTROL, CAP_MAC_ADMIN, CAP_SYSLOG, CAP_NET_RAW, CAP_SYS_RESOURCE, CAP_NET_BIND_SERVICE, CAP_SYS_TTY_CONFIG, CAP_LEASE, CAP_SYS_BOOT, CAP_KILL, CAP_SYS_NICE, CAP_FSETID, CAP_SYS_MODULE, CAP_NET_BROADCAST, CAP_SYS_PTRACE, CAP_SETPCAP, CAP_SYS_PACCT, CAP_DAC_READ_SEARCH, CAP_SYS_ADMIN, CAP_SETGID, CAP_IPC_OWNER, CAP_AUDIT_WRITE}
 [%]> caps -d CAP_SYS_NICE
error: Error(Caps(Error(Msg("capset error"), State { next_error: Some(Error(Sys(Errno { code: 1, description: Some("Operation not permitted") }), State { next_error: None, backtrace: InternalBacktrace { backtrace: None } })), backtrace: InternalBacktrace { backtrace: None } })), State { next_error: None, backtrace: InternalBacktrace { backtrace: None } })
 [%]> 

This translates to this call in rust:

caps::drop(None, CapSet::Permitted, cap)?;

I have the same issue with caps::set (which is used by drop under the hood). Dropping/Setting other capability sets is working correctly and I can also clear the permitted set using caps::clear(None, CapSet::Permitted).

Consider switching to bitflags

At some point in the future I will re-evaluate how we define Capability and CapsHashSet and possibly switch to use https://docs.rs/bitflags/latest/bitflags/index.html for those.

Unfortunately, we I started writing this library, the types generated by bitflags were not very ergonomic so it was better to go with a plain enum plus HashSet.

On the positive side, this will make the library a bit more lean, as flags manipulation will be done through integer arithmetic without allocating containers. However this is not really a pressing point, as capabilities introspection/manipulation is basically never done in any kind of hot-loop or sensitive spot.

On the negative side, this will require re-arranging most of the public interfaces and breaking the API. The latter cascades into all consumers of the library.

For these reasons I'm not currently going after this in the short term, but I'm leaving this open as a future working item.

Upgrading to macro_attr 0.2

custom-derive 0.1.7 was superseded by macro-attr 0.2. I tried updating it with this diff (using macro-attr 0.2.1 from git, because enum-derive 0.2 was not yet uploaded to crates.io):

diff --git a/Cargo.toml b/Cargo.toml
index 7dd5afc..481792f 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -15,8 +15,8 @@ exclude = [
 [dependencies]
 libc = "0.2"
 error-chain = {version = "0.9", default-features = false}
-enum_derive = "0.1"
-custom_derive ="0.1"
+enum_derive = {path = "../rust-custom-derive/enum_derive"}
+macro-attr = {path = "../rust-custom-derive"}
 
 [package.metadata.release]
 sign-commit = true
diff --git a/src/lib.rs b/src/lib.rs
index 7fa8772..db1df2e 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -23,7 +23,7 @@ extern crate libc;
 #[macro_use]
 extern crate error_chain;
 #[macro_use]
-extern crate custom_derive;
+extern crate macro_attr;
 #[macro_use]
 extern crate enum_derive;
 
@@ -61,7 +61,7 @@ pub enum CapSet {
     Permitted,
 }
 
-custom_derive! {
+macro_attr! {
     /// Linux capabilities.
     ///
     /// All capabilities supported by Linux, including standard

However cargo / rustc 1.19 gives me this error:

error: no rules expected the token `split_derive_attrs`
   --> src/lib.rs:64:1
    |
64  | / macro_attr! {
65  | |     /// Linux capabilities.
66  | |     ///
67  | |     /// All capabilities supported by Linux, including standard
...   |
138 | |     }
139 | | }
    | |_^
    |
    = note: this error originates in a macro outside of the current crate

error: Could not compile `caps`.

To learn more, run the command again with --verbose.
exit code 101

it's possible this is a bug in macro-attr (@split_derive_attrs is from there) but I'm not sure.

Expose errno on failure

It would be nice if the error code in errno would be accessible if an error happens. The error currently looks like this:

Error(Msg("capset error -1"), State { next_error: None, backtrace: None })

This could be improved with the error code why it failed, like permission denied. errno is useful for this.

Using strum to denoise `Capability` enum

The idea is to use the strum crate to be able to make the Capability enum more compact and Rusty. This means that we could reduce this:

caps-rs/src/lib.rs

Lines 75 to 77 in cb54844

pub enum Capability {
/// `CAP_CHOWN` (from POSIX)
CAP_CHOWN = nr::CAP_CHOWN,

to

#[strum(serialize_all = "shouty_snake_case")]
/// All available capabilities.
pub enum Capability {
    #[strum(serialize = "CHOWN", serialize = "CAP_CHOWN")]
    // In a system with the [_POSIX_CHOWN_RESTRICTED] option defined, this
    // overrides the restriction of changing file ownership and group ownership.
    Chown,

We already use this method in containrs, which is a WIP project: https://github.com/cri-o/containrs/blob/master/src/capability.rs

Do you think this makes sense?

Type error on x86_32

When trying to compile this crate on a x86_32 linux machine I get a type error because nr::{CapSet, CapGet} are i64 but libc::syscall expects an i32.

Elaborate on error handling

Currently, the error type is just a wrapper around String and the functions do not have descriptions on how they might fail either. It would be nice to have some information on error handling.

securebits: add support for all flags

Release 0.3.0 introduced support for a single flag in securebits, namely SECBIT_KEEP_CAPS.

There are three more flags missing, with their corresponding "locked" twins. All of those should be implemented via PR_SET_SECUREBITS and PR_GET_SECUREBITS.

This is a followup to #26.

ambient: add ambient_set_supported()

This is an enhancement ticket to add run-time detection of ambient set support, which is only available on kernels >= 4.3.

The proposed signature is as follow:

pub fn ambient_set_supported() -> Result<(), Err(i32)>

(or maybe only a bool which just swallows all errno into false?)

This can be implement via PR_CAP_AMBIENT+PR_CAP_AMBIENT_IS_SET+CAP_CHOWN which should always return >=0 when the set is supported.

/cc @vishvananda and @aep for feedback on the ergonomic/signature. This is intended to provide a simple way for consumers to opt out ambient-set manipulation on kernels where it is unsupported: a conditional on caps::ambient_set_supported().is_ok().

Release 0.5.3

Is there any pending changes for 0.5.3? I think the serde support is big enough feature.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.