Skip to content

Commit

Permalink
Merge pull request torvalds#411 from wedsonaf/lsms
Browse files Browse the repository at this point in the history
rust: add support for calling some security functions.
  • Loading branch information
ojeda authored Jul 2, 2021
2 parents e9190d8 + 99cedeb commit dcf2391
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 0 deletions.
29 changes: 29 additions & 0 deletions rust/helpers.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <linux/errname.h>
#include <linux/mutex.h>
#include <linux/platform_device.h>
#include <linux/security.h>

void rust_helper_BUG(void)
{
Expand Down Expand Up @@ -183,6 +184,34 @@ void rust_helper_put_task_struct(struct task_struct * t)
}
EXPORT_SYMBOL_GPL(rust_helper_put_task_struct);

int rust_helper_security_binder_set_context_mgr(struct task_struct *mgr)
{
return security_binder_set_context_mgr(mgr);
}
EXPORT_SYMBOL_GPL(rust_helper_security_binder_set_context_mgr);

int rust_helper_security_binder_transaction(struct task_struct *from,
struct task_struct *to)
{
return security_binder_transaction(from, to);
}
EXPORT_SYMBOL_GPL(rust_helper_security_binder_transaction);

int rust_helper_security_binder_transfer_binder(struct task_struct *from,
struct task_struct *to)
{
return security_binder_transfer_binder(from, to);
}
EXPORT_SYMBOL_GPL(rust_helper_security_binder_transfer_binder);

int rust_helper_security_binder_transfer_file(struct task_struct *from,
struct task_struct *to,
struct file *file)
{
return security_binder_transfer_file(from, to, file);
}
EXPORT_SYMBOL_GPL(rust_helper_security_binder_transfer_file);

/* We use bindgen's --size_t-is-usize option to bind the C size_t type
* as the Rust usize type, so we can use it in contexts where Rust
* expects a usize like slice (array) indices. usize is defined to be
Expand Down
1 change: 1 addition & 0 deletions rust/kernel/bindings_helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include <uapi/linux/android/binder.h>
#include <linux/platform_device.h>
#include <linux/of_platform.h>
#include <linux/security.h>

// `bindgen` gets confused at certain things
const gfp_t BINDINGS_GFP_KERNEL = GFP_KERNEL;
Expand Down
1 change: 1 addition & 0 deletions rust/kernel/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ pub mod file;
pub mod file_operations;
pub mod miscdev;
pub mod pages;
pub mod security;
pub mod str;
pub mod task;
pub mod traits;
Expand Down
79 changes: 79 additions & 0 deletions rust/kernel/security.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// SPDX-License-Identifier: GPL-2.0

//! Linux Security Modules (LSM).
//!
//! C header: [`include/linux/security.h`](../../../../include/linux/security.h).
use crate::{bindings, c_types, error::Error, file::File, task::Task, Result};

extern "C" {
#[allow(improper_ctypes)]
fn rust_helper_security_binder_set_context_mgr(
mgr: *mut bindings::task_struct,
) -> c_types::c_int;
#[allow(improper_ctypes)]
fn rust_helper_security_binder_transaction(
from: *mut bindings::task_struct,
to: *mut bindings::task_struct,
) -> c_types::c_int;
#[allow(improper_ctypes)]
fn rust_helper_security_binder_transfer_binder(
from: *mut bindings::task_struct,
to: *mut bindings::task_struct,
) -> c_types::c_int;
#[allow(improper_ctypes)]
fn rust_helper_security_binder_transfer_file(
from: *mut bindings::task_struct,
to: *mut bindings::task_struct,
file: *mut bindings::file,
) -> c_types::c_int;
}

/// Calls the security modules to determine if the given task can become the manager of a binder
/// context.
pub fn binder_set_context_mgr(mgr: &Task) -> Result {
// SAFETY: By the `Task` invariants, `mgr.ptr` is valid.
let ret = unsafe { rust_helper_security_binder_set_context_mgr(mgr.ptr) };
if ret != 0 {
Err(Error::from_kernel_errno(ret))
} else {
Ok(())
}
}

/// Calls the security modules to determine if binder transactions are allowed from task `from` to
/// task `to`.
pub fn binder_transaction(from: &Task, to: &Task) -> Result {
// SAFETY: By the `Task` invariants, `from.ptr` and `to.ptr` are valid.
let ret = unsafe { rust_helper_security_binder_transaction(from.ptr, to.ptr) };
if ret != 0 {
Err(Error::from_kernel_errno(ret))
} else {
Ok(())
}
}

/// Calls the security modules to determine if task `from` is allowed to send binder objects
/// (owned by itself or other processes) to task `to` through a binder transaction.
pub fn binder_transfer_binder(from: &Task, to: &Task) -> Result {
// SAFETY: By the `Task` invariants, `from.ptr` and `to.ptr` are valid.
let ret = unsafe { rust_helper_security_binder_transfer_binder(from.ptr, to.ptr) };
if ret != 0 {
Err(Error::from_kernel_errno(ret))
} else {
Ok(())
}
}

/// Calls the security modules to determine if task `from` is allowed to send the given file to
/// task `to` (which would get its own file descriptor) through a binder transaction.
pub fn binder_transfer_file(from: &Task, to: &Task, file: &File) -> Result {
// SAFETY: By the `Task` invariants, `from.ptr` and `to.ptr` are valid. Similarly, by the
// `File` invariants, `file.ptr` is also valid.
let ret = unsafe { rust_helper_security_binder_transfer_file(from.ptr, to.ptr, file.ptr) };
if ret != 0 {
Err(Error::from_kernel_errno(ret))
} else {
Ok(())
}
}

0 comments on commit dcf2391

Please sign in to comment.