Skip to content

Commit 99cedeb

Browse files
committed
rust: add support for calling some security functions.
This allows drivers to call functions in security modules that take objects for which we have abstractions (e.g., files and tasks) as arguments. Signed-off-by: Wedson Almeida Filho <[email protected]>
1 parent fc4c293 commit 99cedeb

File tree

4 files changed

+110
-0
lines changed

4 files changed

+110
-0
lines changed

rust/helpers.c

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <linux/errname.h>
1111
#include <linux/mutex.h>
1212
#include <linux/platform_device.h>
13+
#include <linux/security.h>
1314

1415
void rust_helper_BUG(void)
1516
{
@@ -183,6 +184,34 @@ void rust_helper_put_task_struct(struct task_struct * t)
183184
}
184185
EXPORT_SYMBOL_GPL(rust_helper_put_task_struct);
185186

187+
int rust_helper_security_binder_set_context_mgr(struct task_struct *mgr)
188+
{
189+
return security_binder_set_context_mgr(mgr);
190+
}
191+
EXPORT_SYMBOL_GPL(rust_helper_security_binder_set_context_mgr);
192+
193+
int rust_helper_security_binder_transaction(struct task_struct *from,
194+
struct task_struct *to)
195+
{
196+
return security_binder_transaction(from, to);
197+
}
198+
EXPORT_SYMBOL_GPL(rust_helper_security_binder_transaction);
199+
200+
int rust_helper_security_binder_transfer_binder(struct task_struct *from,
201+
struct task_struct *to)
202+
{
203+
return security_binder_transfer_binder(from, to);
204+
}
205+
EXPORT_SYMBOL_GPL(rust_helper_security_binder_transfer_binder);
206+
207+
int rust_helper_security_binder_transfer_file(struct task_struct *from,
208+
struct task_struct *to,
209+
struct file *file)
210+
{
211+
return security_binder_transfer_file(from, to, file);
212+
}
213+
EXPORT_SYMBOL_GPL(rust_helper_security_binder_transfer_file);
214+
186215
/* We use bindgen's --size_t-is-usize option to bind the C size_t type
187216
* as the Rust usize type, so we can use it in contexts where Rust
188217
* expects a usize like slice (array) indices. usize is defined to be

rust/kernel/bindings_helper.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include <uapi/linux/android/binder.h>
1818
#include <linux/platform_device.h>
1919
#include <linux/of_platform.h>
20+
#include <linux/security.h>
2021

2122
// `bindgen` gets confused at certain things
2223
const gfp_t BINDINGS_GFP_KERNEL = GFP_KERNEL;

rust/kernel/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ pub mod file;
5050
pub mod file_operations;
5151
pub mod miscdev;
5252
pub mod pages;
53+
pub mod security;
5354
pub mod str;
5455
pub mod task;
5556
pub mod traits;

rust/kernel/security.rs

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
3+
//! Linux Security Modules (LSM).
4+
//!
5+
//! C header: [`include/linux/security.h`](../../../../include/linux/security.h).
6+
7+
use crate::{bindings, c_types, error::Error, file::File, task::Task, Result};
8+
9+
extern "C" {
10+
#[allow(improper_ctypes)]
11+
fn rust_helper_security_binder_set_context_mgr(
12+
mgr: *mut bindings::task_struct,
13+
) -> c_types::c_int;
14+
#[allow(improper_ctypes)]
15+
fn rust_helper_security_binder_transaction(
16+
from: *mut bindings::task_struct,
17+
to: *mut bindings::task_struct,
18+
) -> c_types::c_int;
19+
#[allow(improper_ctypes)]
20+
fn rust_helper_security_binder_transfer_binder(
21+
from: *mut bindings::task_struct,
22+
to: *mut bindings::task_struct,
23+
) -> c_types::c_int;
24+
#[allow(improper_ctypes)]
25+
fn rust_helper_security_binder_transfer_file(
26+
from: *mut bindings::task_struct,
27+
to: *mut bindings::task_struct,
28+
file: *mut bindings::file,
29+
) -> c_types::c_int;
30+
}
31+
32+
/// Calls the security modules to determine if the given task can become the manager of a binder
33+
/// context.
34+
pub fn binder_set_context_mgr(mgr: &Task) -> Result {
35+
// SAFETY: By the `Task` invariants, `mgr.ptr` is valid.
36+
let ret = unsafe { rust_helper_security_binder_set_context_mgr(mgr.ptr) };
37+
if ret != 0 {
38+
Err(Error::from_kernel_errno(ret))
39+
} else {
40+
Ok(())
41+
}
42+
}
43+
44+
/// Calls the security modules to determine if binder transactions are allowed from task `from` to
45+
/// task `to`.
46+
pub fn binder_transaction(from: &Task, to: &Task) -> Result {
47+
// SAFETY: By the `Task` invariants, `from.ptr` and `to.ptr` are valid.
48+
let ret = unsafe { rust_helper_security_binder_transaction(from.ptr, to.ptr) };
49+
if ret != 0 {
50+
Err(Error::from_kernel_errno(ret))
51+
} else {
52+
Ok(())
53+
}
54+
}
55+
56+
/// Calls the security modules to determine if task `from` is allowed to send binder objects
57+
/// (owned by itself or other processes) to task `to` through a binder transaction.
58+
pub fn binder_transfer_binder(from: &Task, to: &Task) -> Result {
59+
// SAFETY: By the `Task` invariants, `from.ptr` and `to.ptr` are valid.
60+
let ret = unsafe { rust_helper_security_binder_transfer_binder(from.ptr, to.ptr) };
61+
if ret != 0 {
62+
Err(Error::from_kernel_errno(ret))
63+
} else {
64+
Ok(())
65+
}
66+
}
67+
68+
/// Calls the security modules to determine if task `from` is allowed to send the given file to
69+
/// task `to` (which would get its own file descriptor) through a binder transaction.
70+
pub fn binder_transfer_file(from: &Task, to: &Task, file: &File) -> Result {
71+
// SAFETY: By the `Task` invariants, `from.ptr` and `to.ptr` are valid. Similarly, by the
72+
// `File` invariants, `file.ptr` is also valid.
73+
let ret = unsafe { rust_helper_security_binder_transfer_file(from.ptr, to.ptr, file.ptr) };
74+
if ret != 0 {
75+
Err(Error::from_kernel_errno(ret))
76+
} else {
77+
Ok(())
78+
}
79+
}

0 commit comments

Comments
 (0)