Skip to content

Commit

Permalink
restrict resource: improve
Browse files Browse the repository at this point in the history
  • Loading branch information
bradjc committed Jan 23, 2024
1 parent 636ab50 commit 6af9e89
Showing 1 changed file with 44 additions and 19 deletions.
63 changes: 44 additions & 19 deletions capsules/extra/src/restrict_resource.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,31 +8,45 @@ use kernel::syscall::{CommandReturn, SyscallDriver};
use kernel::ErrorCode;
use kernel::ProcessId;

pub struct AppPermittedData {
/// Represents the permissions an app has to use the underlying resource.
///
/// The app is represented by its `ShortID` and this identifies the ranges of
/// the first argument to every command that is permitted for the identified
/// app.
pub struct AppPermissions {
/// The identified app that these permissions are for.
app_id: kernel::process::ShortID,
range_start: usize,
range_end: usize,
/// The range of allowed arguments to argument 1 of the command syscall.
permitted_arg1: core::ops::Range<usize>,
/// The range of allowed arguments to argument 2 of the command syscall.
permitted_arg2: core::ops::Range<usize>,
}

/// Holds the array of LEDs and implements a `Driver` interface to
/// control them.
pub struct RestrictResource<'a, D: kernel::syscall::SyscallDriver> {
/// Capsule that restricts applications to only accessing commands with a subset
/// of arguments.
pub struct CommandRestrictions<'a, D: kernel::syscall::SyscallDriver> {
/// Underlying `SyscallDriver` resource that is being restricted.
driver: &'a D,
/// Command num for the command that returns the count of the underlying
/// resource. So for example, if `command_num==5` means return the number of
/// GPIO pins, then this capsule should be configured with
/// `command_num_num==5`.
command_num_num: usize,
permitted: &'a [AppPermittedData],
/// Array of permissions granted to specific apps.
permissions: &'a [AppPermissions],
}

impl<'a, D: kernel::syscall::SyscallDriver> RestrictResource<'a, D> {
pub fn new(driver: &'a D, permitted: &'a [AppPermittedData], command_num_num: usize) -> Self {
impl<'a, D: kernel::syscall::SyscallDriver> CommandRestrictions<'a, D> {
pub fn new(driver: &'a D, permissions: &'a [AppPermissions], command_num_num: usize) -> Self {
Self {
driver,
command_num_num,
permitted,
permissions,
}
}

fn get_app_permitted(&self, processid: ProcessId) -> Option<&AppPermittedData> {
for perm in self.permitted {
fn get_app_permitted(&self, processid: ProcessId) -> Option<&AppPermissions> {
for perm in self.permissions {
if processid.short_app_id() == perm.app_id {
return Some(&perm);
}
Expand All @@ -41,26 +55,37 @@ impl<'a, D: kernel::syscall::SyscallDriver> RestrictResource<'a, D> {
}
}

impl<'a, D: kernel::syscall::SyscallDriver> SyscallDriver for RestrictResource<'a, D> {
impl<'a, D: kernel::syscall::SyscallDriver> SyscallDriver for CommandRestrictions<'a, D> {
fn command(
&self,
command_num: usize,
data: usize,
arg1: usize,
arg2: usize,
processid: ProcessId,
) -> CommandReturn {
match command_num {
0 => self.driver.command(0, data, arg2, processid),
0 => self.driver.command(0, arg1, arg2, processid),

_ => match self.get_app_permitted(processid) {
Some(perm) => {
if command_num == self.command_num_num {
CommandReturn::success_u32((perm.range_end - perm.range_start) as u32)
CommandReturn::success_u32(perm.permitted_arg1.len() as u32)
} else {
let new_data = perm.range_start;
if new_data < perm.range_end {
self.driver.command(0, new_data, arg2, processid)
// For all other commands, we convert the arguments from
// the range used by the app to the full range used by
// the underlying resource and then call into the
// underlying resource.
let new_arg1 = perm.permitted_arg1.start + arg1;
let new_arg2 = perm.permitted_arg2.start + arg2;

// If that is within the approved range, call the
// command in the underlying resource.
if perm.permitted_arg1.contains(&new_arg1)
&& perm.permitted_arg2.contains(&new_arg2)
{
self.driver.command(0, new_arg1, new_arg2, processid)
} else {
// Otherwise return a failure.
CommandReturn::failure(ErrorCode::NOSUPPORT)
}
}
Expand Down

0 comments on commit 6af9e89

Please sign in to comment.