@@ -11,7 +11,7 @@ use syscall_logger::log_syscall;
1111
1212use crate :: host:: descriptor:: descriptor_table:: DescriptorTable ;
1313use crate :: host:: process:: ProcessId ;
14- use crate :: host:: syscall_types:: SyscallError ;
14+ use crate :: host:: syscall_types:: { SyscallError , SyscallResult } ;
1515use crate :: host:: thread:: Thread ;
1616
1717use super :: { SyscallContext , SyscallHandler } ;
@@ -271,12 +271,12 @@ impl SyscallHandler {
271271 // Note that the syscall args are different than the libc wrapper.
272272 // See "C library/kernel differences" in clone(2).
273273 #[ log_syscall(
274- /* rv */ kernel_pid_t,
275- /* flags */ i32 ,
276- /* child_stack */ * const std:: ffi:: c_void,
277- /* ptid */ * const kernel_pid_t,
278- /* ctid */ * const kernel_pid_t,
279- /* newtls */ * const std:: ffi:: c_void) ]
274+ /* rv */ kernel_pid_t,
275+ /* flags */ i32 ,
276+ /* child_stack */ * const std:: ffi:: c_void,
277+ /* ptid */ * const kernel_pid_t,
278+ /* ctid */ * const kernel_pid_t,
279+ /* newtls */ * const std:: ffi:: c_void) ]
280280 pub fn clone (
281281 ctx : & mut SyscallContext ,
282282 flags_and_exit_signal : i32 ,
@@ -307,9 +307,9 @@ impl SyscallHandler {
307307 }
308308
309309 #[ log_syscall(
310- /* rv */ kernel_pid_t,
311- /* args*/ * const std:: ffi:: c_void,
312- /* args_size*/ usize ) ]
310+ /* rv */ kernel_pid_t,
311+ /* args*/ * const std:: ffi:: c_void,
312+ /* args_size*/ usize ) ]
313313 pub fn clone3 (
314314 ctx : & mut SyscallContext ,
315315 args : ForeignPtr < linux_api:: sched:: clone_args > ,
@@ -346,7 +346,7 @@ impl SyscallHandler {
346346 )
347347 }
348348
349- #[ log_syscall( /* rv */ kernel_pid_t) ]
349+ #[ log_syscall( /* rv */ kernel_pid_t) ]
350350 pub fn fork ( ctx : & mut SyscallContext ) -> Result < kernel_pid_t , SyscallError > {
351351 // This should be the correct call to `clone_internal`, but `clone_internal`
352352 // will currently return an error.
@@ -361,7 +361,7 @@ impl SyscallHandler {
361361 )
362362 }
363363
364- #[ log_syscall( /* rv */ kernel_pid_t) ]
364+ #[ log_syscall( /* rv */ kernel_pid_t) ]
365365 pub fn vfork ( ctx : & mut SyscallContext ) -> Result < kernel_pid_t , SyscallError > {
366366 // This should be the correct call to `clone_internal`, but `clone_internal`
367367 // will currently return an error.
@@ -376,8 +376,74 @@ impl SyscallHandler {
376376 )
377377 }
378378
379- #[ log_syscall( /* rv */ kernel_pid_t) ]
379+ #[ log_syscall( /* rv */ kernel_pid_t) ]
380380 pub fn gettid ( ctx : & mut SyscallContext ) -> Result < kernel_pid_t , SyscallError > {
381381 Ok ( kernel_pid_t:: from ( ctx. objs . thread . id ( ) ) )
382382 }
383+
384+ #[ log_syscall( /* rv */ std:: ffi:: c_int,
385+ /* hdrp */ * const std:: ffi:: c_void,
386+ /* datap */ * const std:: ffi:: c_void) ]
387+ pub fn capget (
388+ ctx : & mut SyscallContext ,
389+ hdrp : ForeignPtr < linux_raw_sys:: general:: __user_cap_header_struct > ,
390+ datap : ForeignPtr < [ linux_raw_sys:: general:: __user_cap_data_struct ; 2 ] > ,
391+ ) -> SyscallResult {
392+ // If the version is not 3, we return the error
393+ let hdrp = ctx. objs . process . memory_borrow ( ) . read ( hdrp) ?;
394+ if hdrp. version != linux_raw_sys:: general:: _LINUX_CAPABILITY_VERSION_3 {
395+ warn ! (
396+ "The version of Linux capabilities is not supported ({})" ,
397+ hdrp. version
398+ ) ;
399+ return Err ( Errno :: EINVAL . into ( ) ) ;
400+ }
401+
402+ if !datap. is_null ( ) {
403+ // Since we don't provide any capability to the managed plugin, we return zeroes to both
404+ // datap[0] and datap[1]
405+ let empty = linux_raw_sys:: general:: __user_cap_data_struct {
406+ effective : 0 ,
407+ permitted : 0 ,
408+ inheritable : 0 ,
409+ } ;
410+ ctx. objs
411+ . process
412+ . memory_borrow_mut ( )
413+ . write ( datap, & [ empty, empty] ) ?;
414+ }
415+ Ok ( 0 . into ( ) )
416+ }
417+
418+ #[ log_syscall( /* rv */ std:: ffi:: c_int,
419+ /* hdrp */ * const std:: ffi:: c_void,
420+ /* datap */ * const std:: ffi:: c_void) ]
421+ pub fn capset (
422+ ctx : & mut SyscallContext ,
423+ hdrp : ForeignPtr < linux_raw_sys:: general:: __user_cap_header_struct > ,
424+ datap : ForeignPtr < [ linux_raw_sys:: general:: __user_cap_data_struct ; 2 ] > ,
425+ ) -> SyscallResult {
426+ // If the version is not 3, we return the error
427+ let hdrp = ctx. objs . process . memory_borrow ( ) . read ( hdrp) ?;
428+ if hdrp. version != linux_raw_sys:: general:: _LINUX_CAPABILITY_VERSION_3 {
429+ warn ! (
430+ "The version of Linux capabilities is not supported ({})" ,
431+ hdrp. version
432+ ) ;
433+ return Err ( Errno :: EINVAL . into ( ) ) ;
434+ }
435+
436+ let datap: [ _ ; 2 ] = ctx. objs . process . memory_borrow ( ) . read ( datap) ?;
437+ for data in & datap {
438+ // We don't allow the plugin to set any capability
439+ if data. effective != 0 || data. permitted != 0 || data. inheritable != 0 {
440+ warn ! (
441+ "The version of Linux capabilities is not supported ({})" ,
442+ hdrp. version
443+ ) ;
444+ return Err ( Errno :: EINVAL . into ( ) ) ;
445+ }
446+ }
447+ Ok ( 0 . into ( ) )
448+ }
383449}
0 commit comments