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