Skip to content

Commit e18bf61

Browse files
committed
fix(interrupt): add missing "task context" check to set_priority
1 parent 3ef4de8 commit e18bf61

File tree

3 files changed

+76
-4
lines changed

3 files changed

+76
-4
lines changed

src/constance/src/kernel/interrupt.rs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,16 +76,22 @@ impl<System: Kernel> InterruptLine<System> {
7676
self,
7777
value: InterruptPriority,
7878
) -> Result<(), SetInterruptLinePriorityError> {
79-
let _lock = utils::lock_cpu::<System>()?;
79+
let mut lock = utils::lock_cpu::<System>()?;
80+
81+
// Deny a non-task context
82+
if System::is_interrupt_context() {
83+
return Err(SetInterruptLinePriorityError::BadContext);
84+
}
8085

8186
// Deny unmanaged priority
8287
if !System::MANAGED_INTERRUPT_PRIORITY_RANGE.contains(&value) {
8388
return Err(SetInterruptLinePriorityError::BadParam);
8489
}
8590

86-
// Safety: (1) We are the kernel, so it's okay to call `Port`'s methods.
87-
// (2) CPU Lock active
88-
unsafe { System::set_interrupt_line_priority(self.0, value) }
91+
// Safety: (1) Some of the preconditions of `set_priority_unchecked`,
92+
// which are upheld by the caller.
93+
// (2) A task context.
94+
unsafe { self.set_priority_unchecked_inner(value, lock.borrow_mut()) }
8995
}
9096

9197
/// Set the priority of the interrupt line without checking if the new
@@ -109,6 +115,7 @@ impl<System: Kernel> InterruptLine<System> {
109115
) -> Result<(), SetInterruptLinePriorityError> {
110116
let mut lock = utils::lock_cpu::<System>()?;
111117

118+
// Deny a non-task context
112119
if System::is_interrupt_context() {
113120
return Err(SetInterruptLinePriorityError::BadContext);
114121
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
//! Checks the return codes of disallowed system calls made in an interrupt
2+
//! context.
3+
use constance::{
4+
kernel::{self, InterruptHandler, InterruptLine, Task},
5+
prelude::*,
6+
};
7+
8+
use super::Driver;
9+
10+
#[derive(Debug)]
11+
pub struct App<System> {
12+
int: Option<InterruptLine<System>>,
13+
}
14+
15+
impl<System: Kernel> App<System> {
16+
constance::configure! {
17+
pub const fn new<D: Driver<Self>>(_: &mut CfgBuilder<System>) -> Self {
18+
new! { Task<_>, start = task_body::<System, D>, priority = 0, active = true };
19+
20+
let int = if let [int_line, ..] = *D::INTERRUPT_LINES {
21+
unsafe {
22+
new! { InterruptHandler<_>,
23+
line = int_line, start = isr::<System, D>, unmanaged };
24+
}
25+
26+
Some(new! { InterruptLine<_>, line = int_line, enabled = true })
27+
} else {
28+
None
29+
};
30+
31+
App { int }
32+
}
33+
}
34+
}
35+
36+
fn task_body<System: Kernel, D: Driver<App<System>>>(_: usize) {
37+
let int = if let Some(int) = D::app().int {
38+
int
39+
} else {
40+
log::warn!("No interrupt lines defined, skipping the test");
41+
D::success();
42+
return;
43+
};
44+
45+
int.pend().unwrap();
46+
}
47+
48+
fn isr<System: Kernel, D: Driver<App<System>>>(_: usize) {
49+
// Disallowed in a non-task context
50+
assert_eq!(
51+
D::app().int.unwrap().set_priority(1),
52+
Err(kernel::SetInterruptLinePriorityError::BadContext),
53+
);
54+
assert_eq!(
55+
unsafe { D::app().int.unwrap().set_priority_unchecked(1) },
56+
Err(kernel::SetInterruptLinePriorityError::BadContext),
57+
);
58+
assert_eq!(
59+
System::boost_priority(),
60+
Err(kernel::BoostPriorityError::BadContext),
61+
);
62+
63+
D::success();
64+
}

src/constance_test_suite/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ pub mod kernel_tests {
145145
(mod event_group_order_task_priority {}, "event_group_order_task_priority"),
146146
(mod event_group_set_and_dispatch {}, "event_group_set_and_dispatch"),
147147
(mod event_group_wait_types {}, "event_group_wait_types"),
148+
(mod interrupt_disallowed_services {}, "interrupt_disallowed_services"),
148149
(mod interrupt_misc {}, "interrupt_misc"),
149150
(mod interrupt_priority {}, "interrupt_priority"),
150151
(mod priority_boost {}, "priority_boost"),

0 commit comments

Comments
 (0)