From 6a834cd6f17631f3e43528f3248e1d6eb5458a3e Mon Sep 17 00:00:00 2001 From: Ruihan Li Date: Wed, 4 Feb 2026 23:37:11 +0800 Subject: [PATCH] Rewrite `Credentials` comments --- .../src/process/credentials/capabilities.rs | 15 ++- .../src/process/credentials/credentials_.rs | 92 ++++++++------ kernel/src/process/credentials/mod.rs | 11 +- kernel/src/process/credentials/secure_bits.rs | 13 +- kernel/src/process/credentials/static_cap.rs | 112 ++++++++++-------- 5 files changed, 141 insertions(+), 102 deletions(-) diff --git a/kernel/src/process/credentials/capabilities.rs b/kernel/src/process/credentials/capabilities.rs index 553d588db..fa40b054b 100644 --- a/kernel/src/process/credentials/capabilities.rs +++ b/kernel/src/process/credentials/capabilities.rs @@ -61,24 +61,29 @@ impl CapSet { self.bits() as u32 } - /// Creates a new `CapSet` with a full capability set, typically for a root user. + /// Creates a new `CapSet` with full capabilities, typically for a root user. pub const fn new_root() -> Self { CapSet::all() } - /// The most significant bit in a 64-bit `CapSet` that may be set to represent a Linux capability. + /// Returns the most significant bit in a 64-bit `CapSet` that may be set to represent a Linux + /// capability. pub const fn most_significant_bit() -> u8 { - // CHECKPOINT_RESTORE is the Linux capability with the largest numerical value + // CHECKPOINT_RESTORE is the Linux capability with the largest numerical value. 40 } } +/// An error occurred when converting invalid bits to a [`CapSet`]. +#[derive(Debug)] +pub struct InvalidCapSetError; + impl TryFrom for CapSet { - type Error = &'static str; + type Error = InvalidCapSetError; fn try_from(value: u64) -> Result { if value & !CapSet::MASK != 0 { - Err("Invalid CapSet.") + Err(InvalidCapSetError) } else { Ok(CapSet { bits: value }) } diff --git a/kernel/src/process/credentials/credentials_.rs b/kernel/src/process/credentials/credentials_.rs index 69d360578..140fa9664 100644 --- a/kernel/src/process/credentials/credentials_.rs +++ b/kernel/src/process/credentials/credentials_.rs @@ -14,48 +14,68 @@ use crate::{ #[derive(Debug)] pub(super) struct Credentials_ { - /// Real user id. The user to which the process belongs. + /// The real user ID. + /// + /// This is the user to which the process belongs. ruid: AtomicUid, - /// Effective user id. Used to determine the permissions granted to a process when it tries to perform various operations (i.e., system calls) + /// The effective user ID. + /// + /// This is used to determine the permissions granted to a process when it tries to perform + /// various operations (e.g., system calls). euid: AtomicUid, - /// Saved-set uid. Used by set_uid elf, the saved_set_uid will be set if the elf has setuid bit + /// The saved-set user ID. + /// + /// This saves a copy of the effective user ID that were set when the program was executed. suid: AtomicUid, - /// User id used for filesystem checks. + /// The filesystem user ID. + /// + /// This is used to determine permissions for accessing files. fsuid: AtomicUid, - /// Real group id. The group to which the process belongs + /// The real group ID. + /// + /// This is the group to which the process belongs. rgid: AtomicGid, - /// Effective gid, + /// The effective group ID. + /// + /// This is used to determine the permissions granted to a process when it tries to perform + /// various operations (e.g., system calls). egid: AtomicGid, - /// Saved-set gid. Used by set_gid elf, the saved_set_gid will be set if the elf has setgid bit + /// The saved-set group ID. + /// + /// This saves a copy of the effective group ID that were set when the program was executed. sgid: AtomicGid, - /// Group id used for file system checks. + /// The filesystem group ID. + /// + /// This is used to determine permissions for accessing files. fsgid: AtomicGid, /// A set of additional groups to which a process belongs. supplementary_gids: RwLock>, - /// The Linux capabilities. - /// - /// This is not the capability (in static_cap.rs) enforced on rust objects. - /// Capability that child processes can inherit + // The Linux capabilities. They are not the capability (in `static_cap.rs`) that is enforced on + // Rust objects. + // + /// Capabilities that child processes can inherit. inheritable_capset: AtomicCapSet, - /// Capabilities that a process can potentially be granted. - /// It defines the maximum set of privileges that the process could possibly have. - /// Even if the process is not currently using these privileges, it has the potential ability to enable them. + /// + /// It defines the maximum set of privileges that the process could possibly have. Even if the + /// process is not currently using these privileges, it has the potential ability to enable + /// them. permitted_capset: AtomicCapSet, - - /// Capability that we can actually use + /// Capabilities that we can actually use. effective_capset: AtomicCapSet, - /// Secure bits flags + /// Secure bits. securebits: AtomicSecureBits, } impl Credentials_ { - /// Create a new credentials. ruid, euid, suid will be set as the same uid, and gid is the same. - pub fn new(uid: Uid, gid: Gid, capset: CapSet) -> Self { + /// Creates a new `Credentials_`. + /// + /// The real, effective, saved set, and filesystem IDs will be initialized to the same ID. + pub(super) fn new(uid: Uid, gid: Gid, capset: CapSet) -> Self { let mut supplementary_gids = BTreeSet::new(); supplementary_gids.insert(gid); @@ -76,7 +96,7 @@ impl Credentials_ { } } - // ******* Uid methods ******* + // ******* UID methods ******* pub(super) fn ruid(&self) -> Uid { self.ruid.load(Ordering::Relaxed) @@ -160,8 +180,8 @@ impl Credentials_ { self.set_resuid_unchecked(None, None, Some(suid)); } - // For `setreuid`, ruid can *NOT* be set to old suid, - // while for `setresuid`, ruid can be set to old suid. + // For `setreuid`, the real UID can *NOT* be set to the old saved-set user ID, + // For `setresuid`, the real UID can be set to the old saved-set user ID. fn check_uid_perm( &self, ruid: Option<&Uid>, @@ -180,7 +200,7 @@ impl Credentials_ { { return_errno_with_message!( Errno::EPERM, - "ruid can only be one of old ruid, old euid (and old suid)." + "the new real UID is not one of the associated UIDs" ); } @@ -191,7 +211,7 @@ impl Credentials_ { { return_errno_with_message!( Errno::EPERM, - "euid can only be one of old ruid, old euid and old suid." + "the new effective UID is not one of the associated UIDs" ) } @@ -202,7 +222,7 @@ impl Credentials_ { { return_errno_with_message!( Errno::EPERM, - "suid can only be one of old ruid, old euid and old suid." + "the new saved-set UID is not one of the associated UIDs" ) } @@ -285,7 +305,7 @@ impl Credentials_ { } } - // ******* Gid methods ******* + // ******* GID methods ******* pub(super) fn rgid(&self) -> Gid { self.rgid.load(Ordering::Relaxed) @@ -373,8 +393,8 @@ impl Credentials_ { self.set_resgid_unchecked(None, None, Some(sgid)); } - // For `setregid`, rgid can *NOT* be set to old sgid, - // while for `setresgid`, ruid can be set to old sgid. + // For `setregid`, the real GID can *NOT* be set to old saved-set GID, + // For `setresgid`, the real GID can be set to the old saved-set GID. fn check_gid_perm( &self, rgid: Option<&Gid>, @@ -393,7 +413,7 @@ impl Credentials_ { { return_errno_with_message!( Errno::EPERM, - "rgid can only be one of old rgid, old egid (and old sgid)." + "the new real GID is not one of the associated GIDs" ); } @@ -404,7 +424,7 @@ impl Credentials_ { { return_errno_with_message!( Errno::EPERM, - "egid can only be one of old rgid, old egid and old sgid." + "the new effective GID is not one of the associated GIDs" ) } @@ -415,7 +435,7 @@ impl Credentials_ { { return_errno_with_message!( Errno::EPERM, - "sgid can only be one of old rgid, old egid and old sgid." + "the new saved-set GID is not one of the associated GIDs" ) } @@ -442,7 +462,7 @@ impl Credentials_ { self.fsgid.store(fsuid, Ordering::Relaxed); } - // ******* Supplementary groups methods ******* + // ******* Supplementary Groups methods ******* pub(super) fn groups(&self) -> RwLockReadGuard<'_, BTreeSet, PreemptDisabled> { self.supplementary_gids.read() @@ -452,7 +472,7 @@ impl Credentials_ { self.supplementary_gids.write() } - // ******* Linux Capability methods ******* + // ******* Linux Capabilities methods ******* pub(super) fn inheritable_capset(&self) -> CapSet { self.inheritable_capset.load(Ordering::Relaxed) @@ -496,7 +516,7 @@ impl Credentials_ { self.securebits.try_store(stored_bits, Ordering::Relaxed) } - // ******* SecureBits methods ******* + // ******* Secure Bits methods ******* pub(super) fn securebits(&self) -> SecureBits { self.securebits.load(Ordering::Relaxed) @@ -506,7 +526,7 @@ impl Credentials_ { if !self.effective_capset().contains(CapSet::SETPCAP) { return_errno_with_message!( Errno::EPERM, - "only threads with CAP_SETPCAP can change securebits" + "only threads with CAP_SETPCAP can change secure bits" ); } diff --git a/kernel/src/process/credentials/mod.rs b/kernel/src/process/credentials/mod.rs index a7e8368f2..ae776725a 100644 --- a/kernel/src/process/credentials/mod.rs +++ b/kernel/src/process/credentials/mod.rs @@ -16,13 +16,14 @@ pub use user::Uid; use crate::prelude::*; -/// `Credentials` represents a set of associated numeric user ids (UIDs) and group identifiers (GIDs) -/// for a process. -/// These identifiers are as follows: +/// A set of associated numeric user IDs (UIDs) and group IDs (GIDs) for a process. +/// +/// This type contains: /// - real user ID and group ID; /// - effective user ID and group ID; /// - saved-set user ID and saved-set group ID; -/// - file system user ID and group ID (Linux-specific); +/// - filesystem user ID and group ID (Linux-specific); /// - supplementary group IDs; -/// - Linux capabilities. +/// - Linux capabilities; +/// - secure bits. pub struct Credentials(Arc, R); diff --git a/kernel/src/process/credentials/secure_bits.rs b/kernel/src/process/credentials/secure_bits.rs index 4d14abbc4..f4c46b373 100644 --- a/kernel/src/process/credentials/secure_bits.rs +++ b/kernel/src/process/credentials/secure_bits.rs @@ -8,36 +8,33 @@ use bitflags::bitflags; use crate::prelude::*; bitflags! { - /// Represents the secure bits flags for a POSIX thread. + /// Represents the secure bits for a POSIX thread. /// /// These flags control the behavior of capabilities when changing UIDs. + /// /// Reference: pub struct SecureBits: u16 { /// If set, the kernel does not grant capabilities when a set-user-ID-root program /// is executed, or when a process with an effective or real UID of 0 calls `execve`. const NOROOT = 1 << 0; - /// Make `NOROOT` bit immutable (irreversible). const NOROOT_LOCKED = 1 << 1; /// If set, the kernel does not adjust the process's permitted, effective, and /// ambient capability sets when the UIDs are switched between zero and nonzero values. const NO_SETUID_FIXUP = 1 << 2; - /// Make `NO_SETUID_FIXUP` bit immutable (irreversible). const NO_SETUID_FIXUP_LOCKED = 1 << 3; /// If set, the kernel preserves permitted capabilities across UID changes, /// specifically when all UIDs transition from root (0) to non-root values. const KEEP_CAPS = 1 << 4; - /// Make `KEEP_CAPS` bit immutable (irreversible). const KEEP_CAPS_LOCKED = 1 << 5; /// If set, the kernel will not permit raising ambient capabilities via the /// prctl PR_CAP_AMBIENT_RAISE operation. const NO_CAP_AMBIENT_RAISE = 1 << 6; - /// Make `NO_CAP_AMBIENT_RAISE` bit immutable (irreversible). const NO_CAP_AMBIENT_RAISE_LOCKED = 1 << 7; } @@ -72,7 +69,7 @@ impl TryFrom for SecureBits { fn try_from(value: u16) -> Result { if value & !SecureBits::ALL_VALID_BITS != 0 { - return_errno_with_message!(Errno::EINVAL, "invalid SecureBits value"); + return_errno_with_message!(Errno::EINVAL, "the bits are not valid secure bits"); } #[cfg(debug_assertions)] @@ -140,11 +137,11 @@ impl AtomicSecureBits { let locked_bits = current.locked_bits(); if locked_bits & current != locked_bits & bits { - return_errno_with_message!(Errno::EPERM, "one or more SecureBits are locked"); + return_errno_with_message!(Errno::EPERM, "one or more secure bits are locked"); } if SecureBits::LOCK_MASK & current.bits() & !bits.bits() != 0 { - return_errno_with_message!(Errno::EPERM, "cannot unlock the lock bits"); + return_errno_with_message!(Errno::EPERM, "locked secure bits cannot be unlocked"); } self.inner.store(bits, ordering); diff --git a/kernel/src/process/credentials/static_cap.rs b/kernel/src/process/credentials/static_cap.rs index 1b5d59fa6..dd87b53d6 100644 --- a/kernel/src/process/credentials/static_cap.rs +++ b/kernel/src/process/credentials/static_cap.rs @@ -8,7 +8,9 @@ use super::{Credentials, Gid, SecureBits, Uid, capabilities::CapSet, credentials use crate::prelude::*; impl Credentials { - /// Creates a root `Credentials`. This method can only be used when creating the first process + /// Creates a root `Credentials`. + /// + /// This method can only be used when creating the init process. pub fn new_root() -> Self { let uid = Uid::new_root(); let gid = Gid::new_root(); @@ -43,9 +45,9 @@ impl Credentials { Credentials(credentials_, R1::new()) } - // *********** Uid methods ********** + // *********** UID methods ********** - /// Gets real user id. + /// Gets the real user ID. /// /// This method requires the `Read` right. #[require(R > Read)] @@ -53,7 +55,7 @@ impl Credentials { self.0.ruid() } - /// Gets effective user id. + /// Gets the effective user ID. /// /// This method requires the `Read` right. #[require(R > Read)] @@ -61,7 +63,7 @@ impl Credentials { self.0.euid() } - /// Gets saved-set user id. + /// Gets the saved-set user ID. /// /// This method requires the `Read` right. #[require(R > Read)] @@ -69,7 +71,7 @@ impl Credentials { self.0.suid() } - /// Gets file system user id. + /// Gets the filesystem user ID. /// /// This method requires the `Read` right. #[require(R > Read)] @@ -77,8 +79,10 @@ impl Credentials { self.0.fsuid() } - /// Sets uid. If self is privileged, sets the effective, real, saved-set user ids as `uid`, - /// Otherwise, sets effective user id as `uid`. + /// Sets the user ID. + /// + /// If `self` is privileged, sets the real, effective, saved-set user IDs as `uid`, Otherwise, + /// sets the effective user ID as `uid`. /// /// This method requires the `Write` right. #[require(R > Write)] @@ -86,8 +90,9 @@ impl Credentials { self.0.set_uid(uid) } - /// Sets real, effective user ids as `ruid`, `euid` respectively. if `ruid` or `euid` - /// is `None`, the corresponding user id will leave unchanged. + /// Sets the real, effective user IDs as `ruid`, `euid` respectively. + /// + /// If `ruid` or `euid` is `None`, the corresponding user ID will leave unchanged. /// /// This method requires the `Write` right. #[require(R > Write)] @@ -95,8 +100,9 @@ impl Credentials { self.0.set_reuid(ruid, euid) } - /// Sets real, effective, saved-set user ids as `ruid`, `euid`, `suid` respectively. if - /// `ruid`, `euid` or `suid` is `None`, the corresponding user id will leave unchanged. + /// Sets the real, effective, saved-set user IDs as `ruid`, `euid`, `suid` respectively. + /// + /// If `ruid`, `euid`, or `suid` is `None`, the corresponding user ID will leave unchanged. /// /// This method requires the `Write` right. #[require(R > Write)] @@ -109,8 +115,9 @@ impl Credentials { self.0.set_resuid(ruid, euid, suid) } - /// Sets file system user id as `fsuid`. Returns the original file system user id. - /// If `fsuid` is None, leaves file system user id unchanged. + /// Sets the filesystem user ID as `fsuid` and returns the original filesystem user ID. + /// + /// If `fsuid` is `None`, leaves the filesystem user ID unchanged. /// /// This method requires the `Write` right. #[require(R > Write)] @@ -118,8 +125,9 @@ impl Credentials { self.0.set_fsuid(fsuid) } - /// Sets effective user id as `euid`. This method should only be used when executing a file - /// whose `setuid` bit is set. + /// Sets the effective user ID as `euid`. + /// + /// This method should only be used when executing a file whose `setuid` bit is set. /// /// This method requires the `Write` right. #[require(R > Write)] @@ -127,8 +135,9 @@ impl Credentials { self.0.set_euid(euid); } - /// Sets saved-set user id as the same of effective user id. This method should only be used when - /// executing a new executable file. + /// Sets the saved-set user ID as the same of the effective user ID. + /// + /// This method should only be used when executing a new executable file. /// /// This method requires the `Write` right. #[require(R > Write)] @@ -137,9 +146,9 @@ impl Credentials { self.0.set_suid(euid); } - // *********** Gid methods ********** + // *********** GID methods ********** - /// Gets real group id. + /// Gets the real group ID. /// /// This method requires the `Read` right. #[require(R > Read)] @@ -147,7 +156,7 @@ impl Credentials { self.0.rgid() } - /// Gets effective group id. + /// Gets the effective group ID. /// /// This method requires the `Read` right. #[require(R > Read)] @@ -155,7 +164,7 @@ impl Credentials { self.0.egid() } - /// Gets saved-set group id. + /// Gets the saved-set group ID. /// /// This method requires the `Read` right. #[require(R > Read)] @@ -163,7 +172,7 @@ impl Credentials { self.0.sgid() } - /// Gets file system group id. + /// Gets the filesystem group ID. /// /// This method requires the `Read` right. #[require(R > Read)] @@ -171,8 +180,10 @@ impl Credentials { self.0.fsgid() } - /// Sets gid. If self is privileged, sets the effective, real, saved-set group ids as `gid`, - /// Otherwise, sets effective group id as `gid`. + /// Sets the group ID. + /// + /// If `self` is privileged, sets the real, effective, saved-set group IDs as `gid`, Otherwise, + /// sets the effective group ID as `gid`. /// /// This method requires the `Write` right. #[require(R > Write)] @@ -180,8 +191,9 @@ impl Credentials { self.0.set_gid(gid) } - /// Sets real, effective group ids as `rgid`, `egid` respectively. if `rgid` or `egid` - /// is `None`, the corresponding group id will leave unchanged. + /// Sets the real, effective group IDs as `rgid`, `egid` respectively. + /// + /// If `rgid` or `egid` is `None`, the corresponding group ID will leave unchanged. /// /// This method requires the `Write` right. #[require(R > Write)] @@ -189,8 +201,9 @@ impl Credentials { self.0.set_regid(rgid, egid) } - /// Sets real, effective, saved-set group ids as `rgid`, `egid`, `sgid` respectively. if - /// `rgid`, `egid` or `sgid` is `None`, the corresponding group id will leave unchanged. + /// Sets the real, effective, saved-set group IDs as `rgid`, `egid`, `sgid` respectively. + /// + /// If `rgid`, `egid`, or `sgid` is `None`, the corresponding group ID will leave unchanged. /// /// This method requires the `Write` right. #[require(R > Write)] @@ -203,8 +216,9 @@ impl Credentials { self.0.set_resgid(rgid, egid, sgid) } - /// Sets file system group id as `fsgid`. Returns the original file system group id. - /// If `fsgid` is None, leaves file system group id unchanged. + /// Sets the filesystem group ID as `fsgid` and returns the original filesystem group ID. + /// + /// If `fsgid` is `None`, leaves the filesystem group ID unchanged. /// /// This method requires the `Write` right. #[require(R > Write)] @@ -212,8 +226,9 @@ impl Credentials { self.0.set_fsgid(fsgid) } - /// Sets effective group id as `egid`. This method should only be used when executing a file - /// whose `setgid` bit is set. + /// Sets the effective group ID as `egid`. + /// + /// This method should only be used when executing a file whose `setgid` bit is set. /// /// This method requires the `Write` right. #[require(R > Write)] @@ -221,8 +236,9 @@ impl Credentials { self.0.set_egid(egid); } - /// Sets saved-set group id as the same of effective group id. This method should only be used when - /// executing a new executable file. + /// Sets the saved-set group ID as the same of the effective group ID. + /// + /// This method should only be used when executing a new executable file. /// /// This method requires the `Write` right. #[require(R > Write)] @@ -231,9 +247,9 @@ impl Credentials { self.0.set_sgid(egid); } - // *********** Supplementary group methods ********** + // *********** Supplementary Groups methods ********** - /// Acquires the read lock of supplementary group ids. + /// Acquires the read lock of supplementary group IDs. /// /// This method requires the `Read` right. #[require(R > Read)] @@ -241,7 +257,7 @@ impl Credentials { self.0.groups() } - /// Acquires the write lock of supplementary group ids. + /// Acquires the write lock of supplementary group IDs. /// /// This method requires the `Write` right. #[require(R > Write)] @@ -249,9 +265,9 @@ impl Credentials { self.0.groups_mut() } - // *********** Linux Capability methods ********** + // *********** Linux Capabilities methods ********** - /// Gets the capabilities that child process can inherit. + /// Gets the capabilities that child processes can inherit. /// /// This method requires the `Read` right. #[require(R > Read)] @@ -259,7 +275,7 @@ impl Credentials { self.0.inheritable_capset() } - /// Gets the capabilities that are permitted. + /// Gets the capabilities that are a process can potentially be granted. /// /// This method requires the `Read` right. #[require(R > Read)] @@ -267,7 +283,7 @@ impl Credentials { self.0.permitted_capset() } - /// Gets the capabilities that actually use. + /// Gets the capabilities that we can actually use. /// /// This method requires the `Read` right. #[require(R > Read)] @@ -275,7 +291,7 @@ impl Credentials { self.0.effective_capset() } - /// Sets the capabilities that child process can inherit. + /// Sets the capabilities that child processes can inherit. /// /// This method requires the `Write` right. #[require(R > Write)] @@ -283,7 +299,7 @@ impl Credentials { self.0.set_inheritable_capset(inheritable_capset); } - /// Sets the capabilities that are permitted. + /// Sets the capabilities that are a process can potentially be granted. /// /// This method requires the `Write` right. #[require(R > Write)] @@ -291,7 +307,7 @@ impl Credentials { self.0.set_permitted_capset(permitted_capset); } - /// Sets the capabilities that actually use. + /// Sets the capabilities that we can actually use. /// /// This method requires the `Write` right. #[require(R > Write)] @@ -317,7 +333,7 @@ impl Credentials { self.0.set_keep_capabilities(keep_capabilities) } - // *********** SecureBits methods ********** + // *********** Secure Bits methods ********** /// Gets the secure bits. /// @@ -329,8 +345,8 @@ impl Credentials { /// Sets the secure bits. /// - /// If the caller does not have the `CAP_SETPCAP` capability, or if it tries to set - /// locked bits, this method will return an error. + /// If the caller does not have the `CAP_SETPCAP` capability, or if it tries to set locked + /// bits, this method will return an error. /// /// This method requires the `Write` right. #[require(R > Write)]