Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'vfs-6.13.rust.file' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs

Pull vfs rust file abstractions from Christian Brauner:
"This contains the file abstractions needed by the Rust implementation
of the Binder driver and other parts of the kernel.

Let's treat this as a first attempt at getting something working but I
do expect the actual interfaces to change significantly over time.
Simply because we are still figuring out what actually works. But
there's no point in further theorizing. Let's see how it holds up with
actual users"

* tag 'vfs-6.13.rust.file' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs:
rust: task: adjust safety comments in Task methods
rust: add seqfile abstraction
rust: file: add abstraction for `poll_table`
rust: file: add `Kuid` wrapper
rust: file: add `FileDescriptorReservation`
rust: security: add abstraction for secctx
rust: cred: add Rust abstraction for `struct cred`
rust: file: add Rust abstraction for `struct file`
rust: task: add `Task::current_raw`
rust: types: add `NotThreadSafe`

+1035 -24
+7
fs/file.c
··· 1096 1096 * 1097 1097 * The fput_needed flag returned by fget_light should be passed to the 1098 1098 * corresponding fput_light. 1099 + * 1100 + * (As an exception to rule 2, you can call filp_close between fget_light and 1101 + * fput_light provided that you capture a real refcount with get_file before 1102 + * the call to filp_close, and ensure that this real refcount is fput *after* 1103 + * the fput_light call.) 1104 + * 1105 + * See also the documentation in rust/kernel/file.rs. 1099 1106 */ 1100 1107 static inline struct fd __fget_light(unsigned int fd, fmode_t mask) 1101 1108 {
+6
rust/bindings/bindings_helper.h
··· 10 10 #include <linux/blk-mq.h> 11 11 #include <linux/blk_types.h> 12 12 #include <linux/blkdev.h> 13 + #include <linux/cred.h> 13 14 #include <linux/errname.h> 14 15 #include <linux/ethtool.h> 16 + #include <linux/file.h> 15 17 #include <linux/firmware.h> 18 + #include <linux/fs.h> 16 19 #include <linux/jiffies.h> 17 20 #include <linux/mdio.h> 18 21 #include <linux/phy.h> 22 + #include <linux/pid_namespace.h> 23 + #include <linux/poll.h> 19 24 #include <linux/refcount.h> 20 25 #include <linux/sched.h> 26 + #include <linux/security.h> 21 27 #include <linux/slab.h> 22 28 #include <linux/wait.h> 23 29 #include <linux/workqueue.h>
+13
rust/helpers/cred.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + 3 + #include <linux/cred.h> 4 + 5 + const struct cred *rust_helper_get_cred(const struct cred *cred) 6 + { 7 + return get_cred(cred); 8 + } 9 + 10 + void rust_helper_put_cred(const struct cred *cred) 11 + { 12 + put_cred(cred); 13 + }
+12
rust/helpers/fs.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + 3 + /* 4 + * Copyright (C) 2024 Google LLC. 5 + */ 6 + 7 + #include <linux/fs.h> 8 + 9 + struct file *rust_helper_get_file(struct file *f) 10 + { 11 + return get_file(f); 12 + }
+3
rust/helpers/helpers.c
··· 11 11 #include "bug.c" 12 12 #include "build_assert.c" 13 13 #include "build_bug.c" 14 + #include "cred.c" 14 15 #include "err.c" 16 + #include "fs.c" 15 17 #include "kunit.c" 16 18 #include "mutex.c" 17 19 #include "page.c" 18 20 #include "rbtree.c" 19 21 #include "refcount.c" 22 + #include "security.c" 20 23 #include "signal.c" 21 24 #include "slab.c" 22 25 #include "spinlock.c"
+20
rust/helpers/security.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + 3 + #include <linux/security.h> 4 + 5 + #ifndef CONFIG_SECURITY 6 + void rust_helper_security_cred_getsecid(const struct cred *c, u32 *secid) 7 + { 8 + security_cred_getsecid(c, secid); 9 + } 10 + 11 + int rust_helper_security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen) 12 + { 13 + return security_secid_to_secctx(secid, secdata, seclen); 14 + } 15 + 16 + void rust_helper_security_release_secctx(char *secdata, u32 seclen) 17 + { 18 + security_release_secctx(secdata, seclen); 19 + } 20 + #endif
+38
rust/helpers/task.c
··· 17 17 { 18 18 put_task_struct(t); 19 19 } 20 + 21 + kuid_t rust_helper_task_uid(struct task_struct *task) 22 + { 23 + return task_uid(task); 24 + } 25 + 26 + kuid_t rust_helper_task_euid(struct task_struct *task) 27 + { 28 + return task_euid(task); 29 + } 30 + 31 + #ifndef CONFIG_USER_NS 32 + uid_t rust_helper_from_kuid(struct user_namespace *to, kuid_t uid) 33 + { 34 + return from_kuid(to, uid); 35 + } 36 + #endif /* CONFIG_USER_NS */ 37 + 38 + bool rust_helper_uid_eq(kuid_t left, kuid_t right) 39 + { 40 + return uid_eq(left, right); 41 + } 42 + 43 + kuid_t rust_helper_current_euid(void) 44 + { 45 + return current_euid(); 46 + } 47 + 48 + struct user_namespace *rust_helper_current_user_ns(void) 49 + { 50 + return current_user_ns(); 51 + } 52 + 53 + pid_t rust_helper_task_tgid_nr_ns(struct task_struct *tsk, 54 + struct pid_namespace *ns) 55 + { 56 + return task_tgid_nr_ns(tsk, ns); 57 + }
+85
rust/kernel/cred.rs
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + 3 + // Copyright (C) 2024 Google LLC. 4 + 5 + //! Credentials management. 6 + //! 7 + //! C header: [`include/linux/cred.h`](srctree/include/linux/cred.h). 8 + //! 9 + //! Reference: <https://www.kernel.org/doc/html/latest/security/credentials.html> 10 + 11 + use crate::{ 12 + bindings, 13 + task::Kuid, 14 + types::{AlwaysRefCounted, Opaque}, 15 + }; 16 + 17 + /// Wraps the kernel's `struct cred`. 18 + /// 19 + /// Credentials are used for various security checks in the kernel. 20 + /// 21 + /// Most fields of credentials are immutable. When things have their credentials changed, that 22 + /// happens by replacing the credential instead of changing an existing credential. See the [kernel 23 + /// documentation][ref] for more info on this. 24 + /// 25 + /// # Invariants 26 + /// 27 + /// Instances of this type are always ref-counted, that is, a call to `get_cred` ensures that the 28 + /// allocation remains valid at least until the matching call to `put_cred`. 29 + /// 30 + /// [ref]: https://www.kernel.org/doc/html/latest/security/credentials.html 31 + #[repr(transparent)] 32 + pub struct Credential(Opaque<bindings::cred>); 33 + 34 + // SAFETY: 35 + // - `Credential::dec_ref` can be called from any thread. 36 + // - It is okay to send ownership of `Credential` across thread boundaries. 37 + unsafe impl Send for Credential {} 38 + 39 + // SAFETY: It's OK to access `Credential` through shared references from other threads because 40 + // we're either accessing properties that don't change or that are properly synchronised by C code. 41 + unsafe impl Sync for Credential {} 42 + 43 + impl Credential { 44 + /// Creates a reference to a [`Credential`] from a valid pointer. 45 + /// 46 + /// # Safety 47 + /// 48 + /// The caller must ensure that `ptr` is valid and remains valid for the lifetime of the 49 + /// returned [`Credential`] reference. 50 + pub unsafe fn from_ptr<'a>(ptr: *const bindings::cred) -> &'a Credential { 51 + // SAFETY: The safety requirements guarantee the validity of the dereference, while the 52 + // `Credential` type being transparent makes the cast ok. 53 + unsafe { &*ptr.cast() } 54 + } 55 + 56 + /// Get the id for this security context. 57 + pub fn get_secid(&self) -> u32 { 58 + let mut secid = 0; 59 + // SAFETY: The invariants of this type ensures that the pointer is valid. 60 + unsafe { bindings::security_cred_getsecid(self.0.get(), &mut secid) }; 61 + secid 62 + } 63 + 64 + /// Returns the effective UID of the given credential. 65 + pub fn euid(&self) -> Kuid { 66 + // SAFETY: By the type invariant, we know that `self.0` is valid. Furthermore, the `euid` 67 + // field of a credential is never changed after initialization, so there is no potential 68 + // for data races. 69 + Kuid::from_raw(unsafe { (*self.0.get()).euid }) 70 + } 71 + } 72 + 73 + // SAFETY: The type invariants guarantee that `Credential` is always ref-counted. 74 + unsafe impl AlwaysRefCounted for Credential { 75 + fn inc_ref(&self) { 76 + // SAFETY: The existence of a shared reference means that the refcount is nonzero. 77 + unsafe { bindings::get_cred(self.0.get()) }; 78 + } 79 + 80 + unsafe fn dec_ref(obj: core::ptr::NonNull<Credential>) { 81 + // SAFETY: The safety requirements guarantee that the refcount is nonzero. The cast is okay 82 + // because `Credential` has the same representation as `struct cred`. 83 + unsafe { bindings::put_cred(obj.cast().as_ptr()) }; 84 + } 85 + }
+8
rust/kernel/fs.rs
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + 3 + //! Kernel file systems. 4 + //! 5 + //! C headers: [`include/linux/fs.h`](srctree/include/linux/fs.h) 6 + 7 + pub mod file; 8 + pub use self::file::{File, LocalFile};
+461
rust/kernel/fs/file.rs
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + 3 + // Copyright (C) 2024 Google LLC. 4 + 5 + //! Files and file descriptors. 6 + //! 7 + //! C headers: [`include/linux/fs.h`](srctree/include/linux/fs.h) and 8 + //! [`include/linux/file.h`](srctree/include/linux/file.h) 9 + 10 + use crate::{ 11 + bindings, 12 + cred::Credential, 13 + error::{code::*, Error, Result}, 14 + types::{ARef, AlwaysRefCounted, NotThreadSafe, Opaque}, 15 + }; 16 + use core::ptr; 17 + 18 + /// Flags associated with a [`File`]. 19 + pub mod flags { 20 + /// File is opened in append mode. 21 + pub const O_APPEND: u32 = bindings::O_APPEND; 22 + 23 + /// Signal-driven I/O is enabled. 24 + pub const O_ASYNC: u32 = bindings::FASYNC; 25 + 26 + /// Close-on-exec flag is set. 27 + pub const O_CLOEXEC: u32 = bindings::O_CLOEXEC; 28 + 29 + /// File was created if it didn't already exist. 30 + pub const O_CREAT: u32 = bindings::O_CREAT; 31 + 32 + /// Direct I/O is enabled for this file. 33 + pub const O_DIRECT: u32 = bindings::O_DIRECT; 34 + 35 + /// File must be a directory. 36 + pub const O_DIRECTORY: u32 = bindings::O_DIRECTORY; 37 + 38 + /// Like [`O_SYNC`] except metadata is not synced. 39 + pub const O_DSYNC: u32 = bindings::O_DSYNC; 40 + 41 + /// Ensure that this file is created with the `open(2)` call. 42 + pub const O_EXCL: u32 = bindings::O_EXCL; 43 + 44 + /// Large file size enabled (`off64_t` over `off_t`). 45 + pub const O_LARGEFILE: u32 = bindings::O_LARGEFILE; 46 + 47 + /// Do not update the file last access time. 48 + pub const O_NOATIME: u32 = bindings::O_NOATIME; 49 + 50 + /// File should not be used as process's controlling terminal. 51 + pub const O_NOCTTY: u32 = bindings::O_NOCTTY; 52 + 53 + /// If basename of path is a symbolic link, fail open. 54 + pub const O_NOFOLLOW: u32 = bindings::O_NOFOLLOW; 55 + 56 + /// File is using nonblocking I/O. 57 + pub const O_NONBLOCK: u32 = bindings::O_NONBLOCK; 58 + 59 + /// File is using nonblocking I/O. 60 + /// 61 + /// This is effectively the same flag as [`O_NONBLOCK`] on all architectures 62 + /// except SPARC64. 63 + pub const O_NDELAY: u32 = bindings::O_NDELAY; 64 + 65 + /// Used to obtain a path file descriptor. 66 + pub const O_PATH: u32 = bindings::O_PATH; 67 + 68 + /// Write operations on this file will flush data and metadata. 69 + pub const O_SYNC: u32 = bindings::O_SYNC; 70 + 71 + /// This file is an unnamed temporary regular file. 72 + pub const O_TMPFILE: u32 = bindings::O_TMPFILE; 73 + 74 + /// File should be truncated to length 0. 75 + pub const O_TRUNC: u32 = bindings::O_TRUNC; 76 + 77 + /// Bitmask for access mode flags. 78 + /// 79 + /// # Examples 80 + /// 81 + /// ``` 82 + /// use kernel::fs::file; 83 + /// # fn do_something() {} 84 + /// # let flags = 0; 85 + /// if (flags & file::flags::O_ACCMODE) == file::flags::O_RDONLY { 86 + /// do_something(); 87 + /// } 88 + /// ``` 89 + pub const O_ACCMODE: u32 = bindings::O_ACCMODE; 90 + 91 + /// File is read only. 92 + pub const O_RDONLY: u32 = bindings::O_RDONLY; 93 + 94 + /// File is write only. 95 + pub const O_WRONLY: u32 = bindings::O_WRONLY; 96 + 97 + /// File can be both read and written. 98 + pub const O_RDWR: u32 = bindings::O_RDWR; 99 + } 100 + 101 + /// Wraps the kernel's `struct file`. Thread safe. 102 + /// 103 + /// This represents an open file rather than a file on a filesystem. Processes generally reference 104 + /// open files using file descriptors. However, file descriptors are not the same as files. A file 105 + /// descriptor is just an integer that corresponds to a file, and a single file may be referenced 106 + /// by multiple file descriptors. 107 + /// 108 + /// # Refcounting 109 + /// 110 + /// Instances of this type are reference-counted. The reference count is incremented by the 111 + /// `fget`/`get_file` functions and decremented by `fput`. The Rust type `ARef<File>` represents a 112 + /// pointer that owns a reference count on the file. 113 + /// 114 + /// Whenever a process opens a file descriptor (fd), it stores a pointer to the file in its fd 115 + /// table (`struct files_struct`). This pointer owns a reference count to the file, ensuring the 116 + /// file isn't prematurely deleted while the file descriptor is open. In Rust terminology, the 117 + /// pointers in `struct files_struct` are `ARef<File>` pointers. 118 + /// 119 + /// ## Light refcounts 120 + /// 121 + /// Whenever a process has an fd to a file, it may use something called a "light refcount" as a 122 + /// performance optimization. Light refcounts are acquired by calling `fdget` and released with 123 + /// `fdput`. The idea behind light refcounts is that if the fd is not closed between the calls to 124 + /// `fdget` and `fdput`, then the refcount cannot hit zero during that time, as the `struct 125 + /// files_struct` holds a reference until the fd is closed. This means that it's safe to access the 126 + /// file even if `fdget` does not increment the refcount. 127 + /// 128 + /// The requirement that the fd is not closed during a light refcount applies globally across all 129 + /// threads - not just on the thread using the light refcount. For this reason, light refcounts are 130 + /// only used when the `struct files_struct` is not shared with other threads, since this ensures 131 + /// that other unrelated threads cannot suddenly start using the fd and close it. Therefore, 132 + /// calling `fdget` on a shared `struct files_struct` creates a normal refcount instead of a light 133 + /// refcount. 134 + /// 135 + /// Light reference counts must be released with `fdput` before the system call returns to 136 + /// userspace. This means that if you wait until the current system call returns to userspace, then 137 + /// all light refcounts that existed at the time have gone away. 138 + /// 139 + /// ### The file position 140 + /// 141 + /// Each `struct file` has a position integer, which is protected by the `f_pos_lock` mutex. 142 + /// However, if the `struct file` is not shared, then the kernel may avoid taking the lock as a 143 + /// performance optimization. 144 + /// 145 + /// The condition for avoiding the `f_pos_lock` mutex is different from the condition for using 146 + /// `fdget`. With `fdget`, you may avoid incrementing the refcount as long as the current fd table 147 + /// is not shared; it is okay if there are other fd tables that also reference the same `struct 148 + /// file`. However, `fdget_pos` can only avoid taking the `f_pos_lock` if the entire `struct file` 149 + /// is not shared, as different processes with an fd to the same `struct file` share the same 150 + /// position. 151 + /// 152 + /// To represent files that are not thread safe due to this optimization, the [`LocalFile`] type is 153 + /// used. 154 + /// 155 + /// ## Rust references 156 + /// 157 + /// The reference type `&File` is similar to light refcounts: 158 + /// 159 + /// * `&File` references don't own a reference count. They can only exist as long as the reference 160 + /// count stays positive, and can only be created when there is some mechanism in place to ensure 161 + /// this. 162 + /// 163 + /// * The Rust borrow-checker normally ensures this by enforcing that the `ARef<File>` from which 164 + /// a `&File` is created outlives the `&File`. 165 + /// 166 + /// * Using the unsafe [`File::from_raw_file`] means that it is up to the caller to ensure that the 167 + /// `&File` only exists while the reference count is positive. 168 + /// 169 + /// * You can think of `fdget` as using an fd to look up an `ARef<File>` in the `struct 170 + /// files_struct` and create an `&File` from it. The "fd cannot be closed" rule is like the Rust 171 + /// rule "the `ARef<File>` must outlive the `&File`". 172 + /// 173 + /// # Invariants 174 + /// 175 + /// * All instances of this type are refcounted using the `f_count` field. 176 + /// * There must not be any active calls to `fdget_pos` on this file that did not take the 177 + /// `f_pos_lock` mutex. 178 + #[repr(transparent)] 179 + pub struct File { 180 + inner: Opaque<bindings::file>, 181 + } 182 + 183 + // SAFETY: This file is known to not have any active `fdget_pos` calls that did not take the 184 + // `f_pos_lock` mutex, so it is safe to transfer it between threads. 185 + unsafe impl Send for File {} 186 + 187 + // SAFETY: This file is known to not have any active `fdget_pos` calls that did not take the 188 + // `f_pos_lock` mutex, so it is safe to access its methods from several threads in parallel. 189 + unsafe impl Sync for File {} 190 + 191 + // SAFETY: The type invariants guarantee that `File` is always ref-counted. This implementation 192 + // makes `ARef<File>` own a normal refcount. 193 + unsafe impl AlwaysRefCounted for File { 194 + #[inline] 195 + fn inc_ref(&self) { 196 + // SAFETY: The existence of a shared reference means that the refcount is nonzero. 197 + unsafe { bindings::get_file(self.as_ptr()) }; 198 + } 199 + 200 + #[inline] 201 + unsafe fn dec_ref(obj: ptr::NonNull<File>) { 202 + // SAFETY: To call this method, the caller passes us ownership of a normal refcount, so we 203 + // may drop it. The cast is okay since `File` has the same representation as `struct file`. 204 + unsafe { bindings::fput(obj.cast().as_ptr()) } 205 + } 206 + } 207 + 208 + /// Wraps the kernel's `struct file`. Not thread safe. 209 + /// 210 + /// This type represents a file that is not known to be safe to transfer across thread boundaries. 211 + /// To obtain a thread-safe [`File`], use the [`assume_no_fdget_pos`] conversion. 212 + /// 213 + /// See the documentation for [`File`] for more information. 214 + /// 215 + /// # Invariants 216 + /// 217 + /// * All instances of this type are refcounted using the `f_count` field. 218 + /// * If there is an active call to `fdget_pos` that did not take the `f_pos_lock` mutex, then it 219 + /// must be on the same thread as this file. 220 + /// 221 + /// [`assume_no_fdget_pos`]: LocalFile::assume_no_fdget_pos 222 + pub struct LocalFile { 223 + inner: Opaque<bindings::file>, 224 + } 225 + 226 + // SAFETY: The type invariants guarantee that `LocalFile` is always ref-counted. This implementation 227 + // makes `ARef<File>` own a normal refcount. 228 + unsafe impl AlwaysRefCounted for LocalFile { 229 + #[inline] 230 + fn inc_ref(&self) { 231 + // SAFETY: The existence of a shared reference means that the refcount is nonzero. 232 + unsafe { bindings::get_file(self.as_ptr()) }; 233 + } 234 + 235 + #[inline] 236 + unsafe fn dec_ref(obj: ptr::NonNull<LocalFile>) { 237 + // SAFETY: To call this method, the caller passes us ownership of a normal refcount, so we 238 + // may drop it. The cast is okay since `File` has the same representation as `struct file`. 239 + unsafe { bindings::fput(obj.cast().as_ptr()) } 240 + } 241 + } 242 + 243 + impl LocalFile { 244 + /// Constructs a new `struct file` wrapper from a file descriptor. 245 + /// 246 + /// The file descriptor belongs to the current process, and there might be active local calls 247 + /// to `fdget_pos` on the same file. 248 + /// 249 + /// To obtain an `ARef<File>`, use the [`assume_no_fdget_pos`] function to convert. 250 + /// 251 + /// [`assume_no_fdget_pos`]: LocalFile::assume_no_fdget_pos 252 + #[inline] 253 + pub fn fget(fd: u32) -> Result<ARef<LocalFile>, BadFdError> { 254 + // SAFETY: FFI call, there are no requirements on `fd`. 255 + let ptr = ptr::NonNull::new(unsafe { bindings::fget(fd) }).ok_or(BadFdError)?; 256 + 257 + // SAFETY: `bindings::fget` created a refcount, and we pass ownership of it to the `ARef`. 258 + // 259 + // INVARIANT: This file is in the fd table on this thread, so either all `fdget_pos` calls 260 + // are on this thread, or the file is shared, in which case `fdget_pos` calls took the 261 + // `f_pos_lock` mutex. 262 + Ok(unsafe { ARef::from_raw(ptr.cast()) }) 263 + } 264 + 265 + /// Creates a reference to a [`LocalFile`] from a valid pointer. 266 + /// 267 + /// # Safety 268 + /// 269 + /// * The caller must ensure that `ptr` points at a valid file and that the file's refcount is 270 + /// positive for the duration of 'a. 271 + /// * The caller must ensure that if there is an active call to `fdget_pos` that did not take 272 + /// the `f_pos_lock` mutex, then that call is on the current thread. 273 + #[inline] 274 + pub unsafe fn from_raw_file<'a>(ptr: *const bindings::file) -> &'a LocalFile { 275 + // SAFETY: The caller guarantees that the pointer is not dangling and stays valid for the 276 + // duration of 'a. The cast is okay because `File` is `repr(transparent)`. 277 + // 278 + // INVARIANT: The caller guarantees that there are no problematic `fdget_pos` calls. 279 + unsafe { &*ptr.cast() } 280 + } 281 + 282 + /// Assume that there are no active `fdget_pos` calls that prevent us from sharing this file. 283 + /// 284 + /// This makes it safe to transfer this file to other threads. No checks are performed, and 285 + /// using it incorrectly may lead to a data race on the file position if the file is shared 286 + /// with another thread. 287 + /// 288 + /// This method is intended to be used together with [`LocalFile::fget`] when the caller knows 289 + /// statically that there are no `fdget_pos` calls on the current thread. For example, you 290 + /// might use it when calling `fget` from an ioctl, since ioctls usually do not touch the file 291 + /// position. 292 + /// 293 + /// # Safety 294 + /// 295 + /// There must not be any active `fdget_pos` calls on the current thread. 296 + #[inline] 297 + pub unsafe fn assume_no_fdget_pos(me: ARef<LocalFile>) -> ARef<File> { 298 + // INVARIANT: There are no `fdget_pos` calls on the current thread, and by the type 299 + // invariants, if there is a `fdget_pos` call on another thread, then it took the 300 + // `f_pos_lock` mutex. 301 + // 302 + // SAFETY: `LocalFile` and `File` have the same layout. 303 + unsafe { ARef::from_raw(ARef::into_raw(me).cast()) } 304 + } 305 + 306 + /// Returns a raw pointer to the inner C struct. 307 + #[inline] 308 + pub fn as_ptr(&self) -> *mut bindings::file { 309 + self.inner.get() 310 + } 311 + 312 + /// Returns the credentials of the task that originally opened the file. 313 + pub fn cred(&self) -> &Credential { 314 + // SAFETY: It's okay to read the `f_cred` field without synchronization because `f_cred` is 315 + // never changed after initialization of the file. 316 + let ptr = unsafe { (*self.as_ptr()).f_cred }; 317 + 318 + // SAFETY: The signature of this function ensures that the caller will only access the 319 + // returned credential while the file is still valid, and the C side ensures that the 320 + // credential stays valid at least as long as the file. 321 + unsafe { Credential::from_ptr(ptr) } 322 + } 323 + 324 + /// Returns the flags associated with the file. 325 + /// 326 + /// The flags are a combination of the constants in [`flags`]. 327 + #[inline] 328 + pub fn flags(&self) -> u32 { 329 + // This `read_volatile` is intended to correspond to a READ_ONCE call. 330 + // 331 + // SAFETY: The file is valid because the shared reference guarantees a nonzero refcount. 332 + // 333 + // FIXME(read_once): Replace with `read_once` when available on the Rust side. 334 + unsafe { core::ptr::addr_of!((*self.as_ptr()).f_flags).read_volatile() } 335 + } 336 + } 337 + 338 + impl File { 339 + /// Creates a reference to a [`File`] from a valid pointer. 340 + /// 341 + /// # Safety 342 + /// 343 + /// * The caller must ensure that `ptr` points at a valid file and that the file's refcount is 344 + /// positive for the duration of 'a. 345 + /// * The caller must ensure that if there are active `fdget_pos` calls on this file, then they 346 + /// took the `f_pos_lock` mutex. 347 + #[inline] 348 + pub unsafe fn from_raw_file<'a>(ptr: *const bindings::file) -> &'a File { 349 + // SAFETY: The caller guarantees that the pointer is not dangling and stays valid for the 350 + // duration of 'a. The cast is okay because `File` is `repr(transparent)`. 351 + // 352 + // INVARIANT: The caller guarantees that there are no problematic `fdget_pos` calls. 353 + unsafe { &*ptr.cast() } 354 + } 355 + } 356 + 357 + // Make LocalFile methods available on File. 358 + impl core::ops::Deref for File { 359 + type Target = LocalFile; 360 + #[inline] 361 + fn deref(&self) -> &LocalFile { 362 + // SAFETY: The caller provides a `&File`, and since it is a reference, it must point at a 363 + // valid file for the desired duration. 364 + // 365 + // By the type invariants, there are no `fdget_pos` calls that did not take the 366 + // `f_pos_lock` mutex. 367 + unsafe { LocalFile::from_raw_file(self as *const File as *const bindings::file) } 368 + } 369 + } 370 + 371 + /// A file descriptor reservation. 372 + /// 373 + /// This allows the creation of a file descriptor in two steps: first, we reserve a slot for it, 374 + /// then we commit or drop the reservation. The first step may fail (e.g., the current process ran 375 + /// out of available slots), but commit and drop never fail (and are mutually exclusive). 376 + /// 377 + /// Dropping the reservation happens in the destructor of this type. 378 + /// 379 + /// # Invariants 380 + /// 381 + /// The fd stored in this struct must correspond to a reserved file descriptor of the current task. 382 + pub struct FileDescriptorReservation { 383 + fd: u32, 384 + /// Prevent values of this type from being moved to a different task. 385 + /// 386 + /// The `fd_install` and `put_unused_fd` functions assume that the value of `current` is 387 + /// unchanged since the call to `get_unused_fd_flags`. By adding this marker to this type, we 388 + /// prevent it from being moved across task boundaries, which ensures that `current` does not 389 + /// change while this value exists. 390 + _not_send: NotThreadSafe, 391 + } 392 + 393 + impl FileDescriptorReservation { 394 + /// Creates a new file descriptor reservation. 395 + pub fn get_unused_fd_flags(flags: u32) -> Result<Self> { 396 + // SAFETY: FFI call, there are no safety requirements on `flags`. 397 + let fd: i32 = unsafe { bindings::get_unused_fd_flags(flags) }; 398 + if fd < 0 { 399 + return Err(Error::from_errno(fd)); 400 + } 401 + Ok(Self { 402 + fd: fd as u32, 403 + _not_send: NotThreadSafe, 404 + }) 405 + } 406 + 407 + /// Returns the file descriptor number that was reserved. 408 + pub fn reserved_fd(&self) -> u32 { 409 + self.fd 410 + } 411 + 412 + /// Commits the reservation. 413 + /// 414 + /// The previously reserved file descriptor is bound to `file`. This method consumes the 415 + /// [`FileDescriptorReservation`], so it will not be usable after this call. 416 + pub fn fd_install(self, file: ARef<File>) { 417 + // SAFETY: `self.fd` was previously returned by `get_unused_fd_flags`. We have not yet used 418 + // the fd, so it is still valid, and `current` still refers to the same task, as this type 419 + // cannot be moved across task boundaries. 420 + // 421 + // Furthermore, the file pointer is guaranteed to own a refcount by its type invariants, 422 + // and we take ownership of that refcount by not running the destructor below. 423 + // Additionally, the file is known to not have any non-shared `fdget_pos` calls, so even if 424 + // this process starts using the file position, this will not result in a data race on the 425 + // file position. 426 + unsafe { bindings::fd_install(self.fd, file.as_ptr()) }; 427 + 428 + // `fd_install` consumes both the file descriptor and the file reference, so we cannot run 429 + // the destructors. 430 + core::mem::forget(self); 431 + core::mem::forget(file); 432 + } 433 + } 434 + 435 + impl Drop for FileDescriptorReservation { 436 + fn drop(&mut self) { 437 + // SAFETY: By the type invariants of this type, `self.fd` was previously returned by 438 + // `get_unused_fd_flags`. We have not yet used the fd, so it is still valid, and `current` 439 + // still refers to the same task, as this type cannot be moved across task boundaries. 440 + unsafe { bindings::put_unused_fd(self.fd) }; 441 + } 442 + } 443 + 444 + /// Represents the `EBADF` error code. 445 + /// 446 + /// Used for methods that can only fail with `EBADF`. 447 + #[derive(Copy, Clone, Eq, PartialEq)] 448 + pub struct BadFdError; 449 + 450 + impl From<BadFdError> for Error { 451 + #[inline] 452 + fn from(_: BadFdError) -> Error { 453 + EBADF 454 + } 455 + } 456 + 457 + impl core::fmt::Debug for BadFdError { 458 + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { 459 + f.pad("EBADF") 460 + } 461 + }
+4
rust/kernel/lib.rs
··· 30 30 #[cfg(CONFIG_BLOCK)] 31 31 pub mod block; 32 32 mod build_assert; 33 + pub mod cred; 33 34 pub mod device; 34 35 pub mod error; 35 36 #[cfg(CONFIG_RUST_FW_LOADER_ABSTRACTIONS)] 36 37 pub mod firmware; 38 + pub mod fs; 37 39 pub mod init; 38 40 pub mod ioctl; 39 41 #[cfg(CONFIG_KUNIT)] ··· 47 45 pub mod prelude; 48 46 pub mod print; 49 47 pub mod rbtree; 48 + pub mod security; 49 + pub mod seq_file; 50 50 pub mod sizes; 51 51 mod static_assert; 52 52 #[doc(hidden)]
+74
rust/kernel/security.rs
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + 3 + // Copyright (C) 2024 Google LLC. 4 + 5 + //! Linux Security Modules (LSM). 6 + //! 7 + //! C header: [`include/linux/security.h`](srctree/include/linux/security.h). 8 + 9 + use crate::{ 10 + bindings, 11 + error::{to_result, Result}, 12 + }; 13 + 14 + /// A security context string. 15 + /// 16 + /// # Invariants 17 + /// 18 + /// The `secdata` and `seclen` fields correspond to a valid security context as returned by a 19 + /// successful call to `security_secid_to_secctx`, that has not yet been destroyed by calling 20 + /// `security_release_secctx`. 21 + pub struct SecurityCtx { 22 + secdata: *mut core::ffi::c_char, 23 + seclen: usize, 24 + } 25 + 26 + impl SecurityCtx { 27 + /// Get the security context given its id. 28 + pub fn from_secid(secid: u32) -> Result<Self> { 29 + let mut secdata = core::ptr::null_mut(); 30 + let mut seclen = 0u32; 31 + // SAFETY: Just a C FFI call. The pointers are valid for writes. 32 + to_result(unsafe { bindings::security_secid_to_secctx(secid, &mut secdata, &mut seclen) })?; 33 + 34 + // INVARIANT: If the above call did not fail, then we have a valid security context. 35 + Ok(Self { 36 + secdata, 37 + seclen: seclen as usize, 38 + }) 39 + } 40 + 41 + /// Returns whether the security context is empty. 42 + pub fn is_empty(&self) -> bool { 43 + self.seclen == 0 44 + } 45 + 46 + /// Returns the length of this security context. 47 + pub fn len(&self) -> usize { 48 + self.seclen 49 + } 50 + 51 + /// Returns the bytes for this security context. 52 + pub fn as_bytes(&self) -> &[u8] { 53 + let ptr = self.secdata; 54 + if ptr.is_null() { 55 + debug_assert_eq!(self.seclen, 0); 56 + // We can't pass a null pointer to `slice::from_raw_parts` even if the length is zero. 57 + return &[]; 58 + } 59 + 60 + // SAFETY: The call to `security_secid_to_secctx` guarantees that the pointer is valid for 61 + // `seclen` bytes. Furthermore, if the length is zero, then we have ensured that the 62 + // pointer is not null. 63 + unsafe { core::slice::from_raw_parts(ptr.cast(), self.seclen) } 64 + } 65 + } 66 + 67 + impl Drop for SecurityCtx { 68 + fn drop(&mut self) { 69 + // SAFETY: By the invariant of `Self`, this frees a pointer that came from a successful 70 + // call to `security_secid_to_secctx` and has not yet been destroyed by 71 + // `security_release_secctx`. 72 + unsafe { bindings::security_release_secctx(self.secdata, self.seclen as u32) }; 73 + } 74 + }
+52
rust/kernel/seq_file.rs
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + 3 + //! Seq file bindings. 4 + //! 5 + //! C header: [`include/linux/seq_file.h`](srctree/include/linux/seq_file.h) 6 + 7 + use crate::{bindings, c_str, types::NotThreadSafe, types::Opaque}; 8 + 9 + /// A utility for generating the contents of a seq file. 10 + #[repr(transparent)] 11 + pub struct SeqFile { 12 + inner: Opaque<bindings::seq_file>, 13 + _not_send: NotThreadSafe, 14 + } 15 + 16 + impl SeqFile { 17 + /// Creates a new [`SeqFile`] from a raw pointer. 18 + /// 19 + /// # Safety 20 + /// 21 + /// The caller must ensure that for the duration of 'a the following is satisfied: 22 + /// * The pointer points at a valid `struct seq_file`. 23 + /// * The `struct seq_file` is not accessed from any other thread. 24 + pub unsafe fn from_raw<'a>(ptr: *mut bindings::seq_file) -> &'a SeqFile { 25 + // SAFETY: The caller ensures that the reference is valid for 'a. There's no way to trigger 26 + // a data race by using the `&SeqFile` since this is the only thread accessing the seq_file. 27 + // 28 + // CAST: The layout of `struct seq_file` and `SeqFile` is compatible. 29 + unsafe { &*ptr.cast() } 30 + } 31 + 32 + /// Used by the [`seq_print`] macro. 33 + pub fn call_printf(&self, args: core::fmt::Arguments<'_>) { 34 + // SAFETY: Passing a void pointer to `Arguments` is valid for `%pA`. 35 + unsafe { 36 + bindings::seq_printf( 37 + self.inner.get(), 38 + c_str!("%pA").as_char_ptr(), 39 + &args as *const _ as *const core::ffi::c_void, 40 + ); 41 + } 42 + } 43 + } 44 + 45 + /// Write to a [`SeqFile`] with the ordinary Rust formatting syntax. 46 + #[macro_export] 47 + macro_rules! seq_print { 48 + ($m:expr, $($arg:tt)+) => ( 49 + $m.call_printf(format_args!($($arg)+)) 50 + ); 51 + } 52 + pub use seq_print;
+1
rust/kernel/sync.rs
··· 11 11 mod condvar; 12 12 pub mod lock; 13 13 mod locked_by; 14 + pub mod poll; 14 15 15 16 pub use arc::{Arc, ArcBorrow, UniqueArc}; 16 17 pub use condvar::{new_condvar, CondVar, CondVarTimeoutResult};
+9 -4
rust/kernel/sync/lock.rs
··· 6 6 //! spinlocks, raw spinlocks) to be provided with minimal effort. 7 7 8 8 use super::LockClassKey; 9 - use crate::{init::PinInit, pin_init, str::CStr, types::Opaque, types::ScopeGuard}; 10 - use core::{cell::UnsafeCell, marker::PhantomData, marker::PhantomPinned}; 9 + use crate::{ 10 + init::PinInit, 11 + pin_init, 12 + str::CStr, 13 + types::{NotThreadSafe, Opaque, ScopeGuard}, 14 + }; 15 + use core::{cell::UnsafeCell, marker::PhantomPinned}; 11 16 use macros::pin_data; 12 17 13 18 pub mod mutex; ··· 144 139 pub struct Guard<'a, T: ?Sized, B: Backend> { 145 140 pub(crate) lock: &'a Lock<T, B>, 146 141 pub(crate) state: B::GuardState, 147 - _not_send: PhantomData<*mut ()>, 142 + _not_send: NotThreadSafe, 148 143 } 149 144 150 145 // SAFETY: `Guard` is sync when the data protected by the lock is also sync. ··· 196 191 Self { 197 192 lock, 198 193 state, 199 - _not_send: PhantomData, 194 + _not_send: NotThreadSafe, 200 195 } 201 196 } 202 197 }
+121
rust/kernel/sync/poll.rs
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + 3 + // Copyright (C) 2024 Google LLC. 4 + 5 + //! Utilities for working with `struct poll_table`. 6 + 7 + use crate::{ 8 + bindings, 9 + fs::File, 10 + prelude::*, 11 + sync::{CondVar, LockClassKey}, 12 + types::Opaque, 13 + }; 14 + use core::ops::Deref; 15 + 16 + /// Creates a [`PollCondVar`] initialiser with the given name and a newly-created lock class. 17 + #[macro_export] 18 + macro_rules! new_poll_condvar { 19 + ($($name:literal)?) => { 20 + $crate::sync::poll::PollCondVar::new( 21 + $crate::optional_name!($($name)?), $crate::static_lock_class!() 22 + ) 23 + }; 24 + } 25 + 26 + /// Wraps the kernel's `struct poll_table`. 27 + /// 28 + /// # Invariants 29 + /// 30 + /// This struct contains a valid `struct poll_table`. 31 + /// 32 + /// For a `struct poll_table` to be valid, its `_qproc` function must follow the safety 33 + /// requirements of `_qproc` functions: 34 + /// 35 + /// * The `_qproc` function is given permission to enqueue a waiter to the provided `poll_table` 36 + /// during the call. Once the waiter is removed and an rcu grace period has passed, it must no 37 + /// longer access the `wait_queue_head`. 38 + #[repr(transparent)] 39 + pub struct PollTable(Opaque<bindings::poll_table>); 40 + 41 + impl PollTable { 42 + /// Creates a reference to a [`PollTable`] from a valid pointer. 43 + /// 44 + /// # Safety 45 + /// 46 + /// The caller must ensure that for the duration of 'a, the pointer will point at a valid poll 47 + /// table (as defined in the type invariants). 48 + /// 49 + /// The caller must also ensure that the `poll_table` is only accessed via the returned 50 + /// reference for the duration of 'a. 51 + pub unsafe fn from_ptr<'a>(ptr: *mut bindings::poll_table) -> &'a mut PollTable { 52 + // SAFETY: The safety requirements guarantee the validity of the dereference, while the 53 + // `PollTable` type being transparent makes the cast ok. 54 + unsafe { &mut *ptr.cast() } 55 + } 56 + 57 + fn get_qproc(&self) -> bindings::poll_queue_proc { 58 + let ptr = self.0.get(); 59 + // SAFETY: The `ptr` is valid because it originates from a reference, and the `_qproc` 60 + // field is not modified concurrently with this call since we have an immutable reference. 61 + unsafe { (*ptr)._qproc } 62 + } 63 + 64 + /// Register this [`PollTable`] with the provided [`PollCondVar`], so that it can be notified 65 + /// using the condition variable. 66 + pub fn register_wait(&mut self, file: &File, cv: &PollCondVar) { 67 + if let Some(qproc) = self.get_qproc() { 68 + // SAFETY: The pointers to `file` and `self` need to be valid for the duration of this 69 + // call to `qproc`, which they are because they are references. 70 + // 71 + // The `cv.wait_queue_head` pointer must be valid until an rcu grace period after the 72 + // waiter is removed. The `PollCondVar` is pinned, so before `cv.wait_queue_head` can 73 + // be destroyed, the destructor must run. That destructor first removes all waiters, 74 + // and then waits for an rcu grace period. Therefore, `cv.wait_queue_head` is valid for 75 + // long enough. 76 + unsafe { qproc(file.as_ptr() as _, cv.wait_queue_head.get(), self.0.get()) }; 77 + } 78 + } 79 + } 80 + 81 + /// A wrapper around [`CondVar`] that makes it usable with [`PollTable`]. 82 + /// 83 + /// [`CondVar`]: crate::sync::CondVar 84 + #[pin_data(PinnedDrop)] 85 + pub struct PollCondVar { 86 + #[pin] 87 + inner: CondVar, 88 + } 89 + 90 + impl PollCondVar { 91 + /// Constructs a new condvar initialiser. 92 + pub fn new(name: &'static CStr, key: &'static LockClassKey) -> impl PinInit<Self> { 93 + pin_init!(Self { 94 + inner <- CondVar::new(name, key), 95 + }) 96 + } 97 + } 98 + 99 + // Make the `CondVar` methods callable on `PollCondVar`. 100 + impl Deref for PollCondVar { 101 + type Target = CondVar; 102 + 103 + fn deref(&self) -> &CondVar { 104 + &self.inner 105 + } 106 + } 107 + 108 + #[pinned_drop] 109 + impl PinnedDrop for PollCondVar { 110 + fn drop(self: Pin<&mut Self>) { 111 + // Clear anything registered using `register_wait`. 112 + // 113 + // SAFETY: The pointer points at a valid `wait_queue_head`. 114 + unsafe { bindings::__wake_up_pollfree(self.inner.wait_queue_head.get()) }; 115 + 116 + // Wait for epoll items to be properly removed. 117 + // 118 + // SAFETY: Just an FFI call. 119 + unsafe { bindings::synchronize_rcu() }; 120 + } 121 + }
+100 -20
rust/kernel/task.rs
··· 4 4 //! 5 5 //! C header: [`include/linux/sched.h`](srctree/include/linux/sched.h). 6 6 7 - use crate::types::Opaque; 7 + use crate::{ 8 + bindings, 9 + types::{NotThreadSafe, Opaque}, 10 + }; 8 11 use core::{ 12 + cmp::{Eq, PartialEq}, 9 13 ffi::{c_int, c_long, c_uint}, 10 - marker::PhantomData, 11 14 ops::Deref, 12 15 ptr, 13 16 }; ··· 97 94 /// The type of process identifiers (PIDs). 98 95 type Pid = bindings::pid_t; 99 96 97 + /// The type of user identifiers (UIDs). 98 + #[derive(Copy, Clone)] 99 + pub struct Kuid { 100 + kuid: bindings::kuid_t, 101 + } 102 + 100 103 impl Task { 104 + /// Returns a raw pointer to the current task. 105 + /// 106 + /// It is up to the user to use the pointer correctly. 107 + #[inline] 108 + pub fn current_raw() -> *mut bindings::task_struct { 109 + // SAFETY: Getting the current pointer is always safe. 110 + unsafe { bindings::get_current() } 111 + } 112 + 101 113 /// Returns a task reference for the currently executing task/thread. 102 114 /// 103 115 /// The recommended way to get the current task/thread is to use the ··· 124 106 pub unsafe fn current() -> impl Deref<Target = Task> { 125 107 struct TaskRef<'a> { 126 108 task: &'a Task, 127 - _not_send: PhantomData<*mut ()>, 109 + _not_send: NotThreadSafe, 128 110 } 129 111 130 112 impl Deref for TaskRef<'_> { ··· 135 117 } 136 118 } 137 119 138 - // SAFETY: Just an FFI call with no additional safety requirements. 139 - let ptr = unsafe { bindings::get_current() }; 140 - 120 + let current = Task::current_raw(); 141 121 TaskRef { 142 122 // SAFETY: If the current thread is still running, the current task is valid. Given 143 123 // that `TaskRef` is not `Send`, we know it cannot be transferred to another thread 144 124 // (where it could potentially outlive the caller). 145 - task: unsafe { &*ptr.cast() }, 146 - _not_send: PhantomData, 125 + task: unsafe { &*current.cast() }, 126 + _not_send: NotThreadSafe, 147 127 } 128 + } 129 + 130 + /// Returns a raw pointer to the task. 131 + #[inline] 132 + pub fn as_ptr(&self) -> *mut bindings::task_struct { 133 + self.0.get() 148 134 } 149 135 150 136 /// Returns the group leader of the given task. 151 137 pub fn group_leader(&self) -> &Task { 152 - // SAFETY: By the type invariant, we know that `self.0` is a valid task. Valid tasks always 153 - // have a valid `group_leader`. 154 - let ptr = unsafe { *ptr::addr_of!((*self.0.get()).group_leader) }; 138 + // SAFETY: The group leader of a task never changes after initialization, so reading this 139 + // field is not a data race. 140 + let ptr = unsafe { *ptr::addr_of!((*self.as_ptr()).group_leader) }; 155 141 156 142 // SAFETY: The lifetime of the returned task reference is tied to the lifetime of `self`, 157 143 // and given that a task has a reference to its group leader, we know it must be valid for ··· 165 143 166 144 /// Returns the PID of the given task. 167 145 pub fn pid(&self) -> Pid { 168 - // SAFETY: By the type invariant, we know that `self.0` is a valid task. Valid tasks always 169 - // have a valid pid. 170 - unsafe { *ptr::addr_of!((*self.0.get()).pid) } 146 + // SAFETY: The pid of a task never changes after initialization, so reading this field is 147 + // not a data race. 148 + unsafe { *ptr::addr_of!((*self.as_ptr()).pid) } 149 + } 150 + 151 + /// Returns the UID of the given task. 152 + pub fn uid(&self) -> Kuid { 153 + // SAFETY: It's always safe to call `task_uid` on a valid task. 154 + Kuid::from_raw(unsafe { bindings::task_uid(self.as_ptr()) }) 155 + } 156 + 157 + /// Returns the effective UID of the given task. 158 + pub fn euid(&self) -> Kuid { 159 + // SAFETY: It's always safe to call `task_euid` on a valid task. 160 + Kuid::from_raw(unsafe { bindings::task_euid(self.as_ptr()) }) 171 161 } 172 162 173 163 /// Determines whether the given task has pending signals. 174 164 pub fn signal_pending(&self) -> bool { 175 - // SAFETY: By the type invariant, we know that `self.0` is valid. 176 - unsafe { bindings::signal_pending(self.0.get()) != 0 } 165 + // SAFETY: It's always safe to call `signal_pending` on a valid task. 166 + unsafe { bindings::signal_pending(self.as_ptr()) != 0 } 167 + } 168 + 169 + /// Returns the given task's pid in the current pid namespace. 170 + pub fn pid_in_current_ns(&self) -> Pid { 171 + // SAFETY: It's valid to pass a null pointer as the namespace (defaults to current 172 + // namespace). The task pointer is also valid. 173 + unsafe { bindings::task_tgid_nr_ns(self.as_ptr(), ptr::null_mut()) } 177 174 } 178 175 179 176 /// Wakes up the task. 180 177 pub fn wake_up(&self) { 181 - // SAFETY: By the type invariant, we know that `self.0.get()` is non-null and valid. 182 - // And `wake_up_process` is safe to be called for any valid task, even if the task is 178 + // SAFETY: It's always safe to call `signal_pending` on a valid task, even if the task 183 179 // running. 184 - unsafe { bindings::wake_up_process(self.0.get()) }; 180 + unsafe { bindings::wake_up_process(self.as_ptr()) }; 185 181 } 186 182 } 187 183 ··· 207 167 unsafe impl crate::types::AlwaysRefCounted for Task { 208 168 fn inc_ref(&self) { 209 169 // SAFETY: The existence of a shared reference means that the refcount is nonzero. 210 - unsafe { bindings::get_task_struct(self.0.get()) }; 170 + unsafe { bindings::get_task_struct(self.as_ptr()) }; 211 171 } 212 172 213 173 unsafe fn dec_ref(obj: ptr::NonNull<Self>) { ··· 215 175 unsafe { bindings::put_task_struct(obj.cast().as_ptr()) } 216 176 } 217 177 } 178 + 179 + impl Kuid { 180 + /// Get the current euid. 181 + #[inline] 182 + pub fn current_euid() -> Kuid { 183 + // SAFETY: Just an FFI call. 184 + Self::from_raw(unsafe { bindings::current_euid() }) 185 + } 186 + 187 + /// Create a `Kuid` given the raw C type. 188 + #[inline] 189 + pub fn from_raw(kuid: bindings::kuid_t) -> Self { 190 + Self { kuid } 191 + } 192 + 193 + /// Turn this kuid into the raw C type. 194 + #[inline] 195 + pub fn into_raw(self) -> bindings::kuid_t { 196 + self.kuid 197 + } 198 + 199 + /// Converts this kernel UID into a userspace UID. 200 + /// 201 + /// Uses the namespace of the current task. 202 + #[inline] 203 + pub fn into_uid_in_current_ns(self) -> bindings::uid_t { 204 + // SAFETY: Just an FFI call. 205 + unsafe { bindings::from_kuid(bindings::current_user_ns(), self.kuid) } 206 + } 207 + } 208 + 209 + impl PartialEq for Kuid { 210 + #[inline] 211 + fn eq(&self, other: &Kuid) -> bool { 212 + // SAFETY: Just an FFI call. 213 + unsafe { bindings::uid_eq(self.kuid, other.kuid) } 214 + } 215 + } 216 + 217 + impl Eq for Kuid {}
+21
rust/kernel/types.rs
··· 532 532 // does not have any uninitialized portions either. 533 533 unsafe impl<T: AsBytes> AsBytes for [T] {} 534 534 unsafe impl<T: AsBytes, const N: usize> AsBytes for [T; N] {} 535 + 536 + /// Zero-sized type to mark types not [`Send`]. 537 + /// 538 + /// Add this type as a field to your struct if your type should not be sent to a different task. 539 + /// Since [`Send`] is an auto trait, adding a single field that is `!Send` will ensure that the 540 + /// whole type is `!Send`. 541 + /// 542 + /// If a type is `!Send` it is impossible to give control over an instance of the type to another 543 + /// task. This is useful to include in types that store or reference task-local information. A file 544 + /// descriptor is an example of such task-local information. 545 + /// 546 + /// This type also makes the type `!Sync`, which prevents immutable access to the value from 547 + /// several threads in parallel. 548 + pub type NotThreadSafe = PhantomData<*mut ()>; 549 + 550 + /// Used to construct instances of type [`NotThreadSafe`] similar to how `PhantomData` is 551 + /// constructed. 552 + /// 553 + /// [`NotThreadSafe`]: type@NotThreadSafe 554 + #[allow(non_upper_case_globals)] 555 + pub const NotThreadSafe: NotThreadSafe = PhantomData;