55//! C header: [`include/linux/sched.h`](srctree/include/linux/sched.h).
66
77use crate :: { bindings, types:: Opaque } ;
8- use core:: { marker:: PhantomData , ops:: Deref , ptr} ;
8+ use core:: {
9+ cmp:: { Eq , PartialEq } ,
10+ marker:: PhantomData ,
11+ ops:: Deref ,
12+ ptr,
13+ } ;
914
1015/// Returns the currently running task.
1116#[ macro_export]
@@ -78,6 +83,12 @@ unsafe impl Sync for Task {}
7883/// The type of process identifiers (PIDs).
7984type Pid = bindings:: pid_t ;
8085
86+ /// The type of user identifiers (UIDs).
87+ #[ derive( Copy , Clone ) ]
88+ pub struct Kuid {
89+ kuid : bindings:: kuid_t ,
90+ }
91+
8192impl Task {
8293 /// Returns a task reference for the currently executing task/thread.
8394 ///
@@ -132,12 +143,32 @@ impl Task {
132143 unsafe { * ptr:: addr_of!( ( * self . 0 . get( ) ) . pid) }
133144 }
134145
146+ /// Returns the UID of the given task.
147+ pub fn uid ( & self ) -> Kuid {
148+ // SAFETY: By the type invariant, we know that `self.0` is valid.
149+ Kuid :: from_raw ( unsafe { bindings:: task_uid ( self . 0 . get ( ) ) } )
150+ }
151+
152+ /// Returns the effective UID of the given task.
153+ pub fn euid ( & self ) -> Kuid {
154+ // SAFETY: By the type invariant, we know that `self.0` is valid.
155+ Kuid :: from_raw ( unsafe { bindings:: task_euid ( self . 0 . get ( ) ) } )
156+ }
157+
135158 /// Determines whether the given task has pending signals.
136159 pub fn signal_pending ( & self ) -> bool {
137160 // SAFETY: By the type invariant, we know that `self.0` is valid.
138161 unsafe { bindings:: signal_pending ( self . 0 . get ( ) ) != 0 }
139162 }
140163
164+ /// Returns the given task's pid in the current pid namespace.
165+ pub fn pid_in_current_ns ( & self ) -> Pid {
166+ // SAFETY: Calling `task_active_pid_ns` with the current task is always safe.
167+ let namespace = unsafe { bindings:: task_active_pid_ns ( bindings:: get_current ( ) ) } ;
168+ // SAFETY: We know that `self.0.get()` is valid by the type invariant.
169+ unsafe { bindings:: task_tgid_nr_ns ( self . 0 . get ( ) , namespace) }
170+ }
171+
141172 /// Wakes up the task.
142173 pub fn wake_up ( & self ) {
143174 // SAFETY: By the type invariant, we know that `self.0.get()` is non-null and valid.
@@ -147,6 +178,41 @@ impl Task {
147178 }
148179}
149180
181+ impl Kuid {
182+ /// Get the current euid.
183+ pub fn current_euid ( ) -> Kuid {
184+ // SAFETY: Just an FFI call.
185+ Self :: from_raw ( unsafe { bindings:: current_euid ( ) } )
186+ }
187+
188+ /// Create a `Kuid` given the raw C type.
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+ pub fn into_raw ( self ) -> bindings:: kuid_t {
195+ self . kuid
196+ }
197+
198+ /// Converts this kernel UID into a userspace UID.
199+ ///
200+ /// Uses the namespace of the current task.
201+ pub fn into_uid_in_current_ns ( self ) -> bindings:: uid_t {
202+ // SAFETY: Just an FFI call.
203+ unsafe { bindings:: from_kuid ( bindings:: current_user_ns ( ) , self . kuid ) }
204+ }
205+ }
206+
207+ impl PartialEq for Kuid {
208+ fn eq ( & self , other : & Kuid ) -> bool {
209+ // SAFETY: Just an FFI call.
210+ unsafe { bindings:: uid_eq ( self . kuid , other. kuid ) }
211+ }
212+ }
213+
214+ impl Eq for Kuid { }
215+
150216// SAFETY: The type invariants guarantee that `Task` is always ref-counted.
151217unsafe impl crate :: types:: AlwaysRefCounted for Task {
152218 fn inc_ref ( & self ) {
0 commit comments