Nothing to see here, move along
at main 136 lines 4.1 kB view raw
1use crate::cap::cnode; 2use crate::cap::object::ObjectTag; 3use crate::cap::ops; 4use crate::cap::pool::POOL; 5use crate::cap::table::Rights; 6use crate::error::KernelError; 7use crate::proc::PROCESSES; 8use crate::proc::context::CpuContext; 9use crate::syscall::{SyscallResult, try_syscall}; 10 11pub fn sys_cap_derive(ctx: &mut CpuContext) { 12 let src_addr = ctx.rdi; 13 let dest_addr = ctx.rsi; 14 let rights_raw = try_syscall!(ctx, super::u16_from_reg(ctx.rdx)); 15 let rights_mask = Rights::from_bits(rights_raw); 16 let pid = crate::arch::syscall::current_pid(); 17 18 let ptable = PROCESSES.lock(); 19 let (cnode_id, cnode_gen, depth, gv, gb) = try_syscall!(ctx, cnode::cnode_coords(pid, &ptable)); 20 21 let mut pool = POOL.lock_after(&ptable); 22 23 ctx.rax = match ops::derive_via_cnode( 24 &mut pool, 25 cnode_id, 26 cnode_gen, 27 src_addr, 28 dest_addr, 29 depth, 30 gv, 31 gb, 32 rights_mask, 33 ) { 34 Ok(()) => SyscallResult::ok().raw(), 35 Err(e) => SyscallResult::error(e).raw(), 36 }; 37} 38 39pub fn sys_cap_revoke(ctx: &mut CpuContext) { 40 let address = ctx.rdi; 41 let pid = crate::arch::syscall::current_pid(); 42 43 let mut ptable = PROCESSES.lock(); 44 if ptable.get(pid).is_none() { 45 ctx.rax = SyscallResult::error(KernelError::InvalidObject).raw(); 46 return; 47 } 48 49 ctx.rax = match ops::revoke_via_cnode(pid, address, &mut ptable) { 50 Ok(()) => SyscallResult::ok().raw(), 51 Err(e) => SyscallResult::error(e).raw(), 52 }; 53} 54 55pub fn sys_cap_identify(ctx: &mut CpuContext) { 56 let address = ctx.rdi; 57 let pid = crate::arch::syscall::current_pid(); 58 59 let ptable = PROCESSES.lock(); 60 let (cnode_id, cnode_gen, depth, gv, gb) = try_syscall!(ctx, cnode::cnode_coords(pid, &ptable)); 61 let pool = POOL.lock_after(&ptable); 62 63 match ops::identify_via_cnode(&pool, cnode_id, cnode_gen, address, depth, gv, gb) { 64 Ok((tag, rights)) => { 65 ctx.rdx = rights.bits() as u64; 66 ctx.rax = tag as u8 as u64; 67 } 68 Err(e) => ctx.rax = SyscallResult::error(e).raw(), 69 } 70} 71 72pub fn sys_cap_grant(ctx: &mut CpuContext) { 73 let src_addr = ctx.rdi; 74 let proc_cap_addr = ctx.rsi; 75 let dest_addr = ctx.rdx; 76 let rights_mask = match super::u16_from_reg(ctx.r10) { 77 Ok(v) => Rights::from_bits(v), 78 Err(e) => { 79 ctx.rax = SyscallResult::error(e).raw(); 80 return; 81 } 82 }; 83 let pid = crate::arch::syscall::current_pid(); 84 85 let ptable = PROCESSES.lock(); 86 87 let (child_pid, cap_to_grant) = { 88 let pool = POOL.lock_after(&ptable); 89 90 let proc_cap = try_syscall!( 91 ctx, 92 cnode::resolve_caller_validate( 93 pid, 94 proc_cap_addr, 95 ObjectTag::Process, 96 Rights::WRITE, 97 &ptable, 98 &pool, 99 ) 100 ); 101 102 let child_pid = try_syscall!(ctx, ops::resolve_process_cap(&proc_cap, &pool)); 103 104 let src_cap = try_syscall!( 105 ctx, 106 cnode::resolve_caller_read(pid, src_addr, &ptable, &pool) 107 ); 108 109 if !src_cap.rights().contains(Rights::GRANT) { 110 ctx.rax = SyscallResult::error(KernelError::InsufficientRights).raw(); 111 return; 112 } 113 let granted = src_cap.with_rights(src_cap.rights() & rights_mask); 114 (child_pid, granted) 115 }; 116 117 if ptable.get(child_pid).is_none() { 118 ctx.rax = SyscallResult::error(KernelError::InvalidObject).raw(); 119 return; 120 } 121 122 let mut pool = POOL.lock_after(&ptable); 123 if let Err(e) = pool.inc_ref(cap_to_grant.phys(), cap_to_grant.generation()) { 124 ctx.rax = SyscallResult::error(e).raw(); 125 return; 126 } 127 128 ctx.rax = match cnode::resolve_caller_insert(child_pid, dest_addr, cap_to_grant, &ptable, &pool) 129 { 130 Ok(()) => SyscallResult::ok().raw(), 131 Err(e) => { 132 pool.dec_ref_phys(cap_to_grant.phys(), cap_to_grant.generation()); 133 SyscallResult::error(e).raw() 134 } 135 }; 136}