-
Notifications
You must be signed in to change notification settings - Fork 126
Test sched family #967
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Test sched family #967
Changes from all commits
f15ef44
7c1756b
d80d152
9bbb3e1
e696895
173cf72
d23a9c9
e1615e1
c816282
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6,9 +6,10 @@ use ax_task::{ | |
| AxCpuMask, current, | ||
| future::{block_on, interruptible, sleep}, | ||
| }; | ||
| use bytemuck::{Pod, Zeroable}; | ||
| use linux_raw_sys::general::{ | ||
| __kernel_clockid_t, CLOCK_MONOTONIC, CLOCK_REALTIME, PRIO_PGRP, PRIO_PROCESS, PRIO_USER, | ||
| SCHED_RR, TIMER_ABSTIME, timespec, | ||
| SCHED_BATCH, SCHED_FIFO, SCHED_IDLE, SCHED_NORMAL, SCHED_RR, TIMER_ABSTIME, timespec, | ||
| }; | ||
| use starry_vm::{VmMutPtr, VmPtr, vm_load, vm_write_slice}; | ||
|
|
||
|
|
@@ -20,6 +21,12 @@ use crate::{ | |
| time::TimeValueLike, | ||
| }; | ||
|
|
||
| #[repr(C)] | ||
| #[derive(Copy, Clone, Pod, Zeroable)] | ||
| struct SchedParam { | ||
| sched_priority: i32, | ||
| } | ||
|
|
||
| pub fn sys_sched_yield() -> AxResult<isize> { | ||
| ax_task::yield_now(); | ||
| Ok(0) | ||
|
|
@@ -107,7 +114,27 @@ pub fn sys_sched_getaffinity(pid: i32, cpusetsize: usize, user_mask: *mut u8) -> | |
| Ok(mask_bytes.len() as _) | ||
| } | ||
|
|
||
| pub fn check_sched_permission(pid: i32) -> AxResult<()> { | ||
| let caller = current().as_thread().cred(); | ||
| let task = get_task_by_sched_pid(pid)?; | ||
| if task.id() == current().id() { | ||
| return Ok(()); | ||
| } | ||
| let target_proc = get_process_data(pid as u32)?; | ||
| let target_cred = process_cred(&target_proc)?; | ||
| if caller.has_cap_sys_nice() | ||
| || caller.euid == target_cred.uid | ||
| || caller.euid == target_cred.euid | ||
| { | ||
| Ok(()) | ||
| } else { | ||
| Err(AxError::OperationNotPermitted) | ||
| } | ||
| } | ||
|
|
||
| pub fn sys_sched_setaffinity(pid: i32, cpusetsize: usize, user_mask: *const u8) -> AxResult<isize> { | ||
| check_sched_permission(pid)?; | ||
| let task = get_task_by_sched_pid(pid)?; | ||
| let size = cpusetsize.min(ax_hal::cpu_num().div_ceil(8)); | ||
| let user_mask = vm_load(user_mask, size)?; | ||
| let mut cpu_mask = AxCpuMask::new(); | ||
|
|
@@ -121,8 +148,6 @@ pub fn sys_sched_setaffinity(pid: i32, cpusetsize: usize, user_mask: *const u8) | |
| if cpu_mask.is_empty() { | ||
| return Err(AxError::InvalidInput); | ||
| } | ||
|
|
||
| let task = get_task_by_sched_pid(pid)?; | ||
| if task.id() == current().id() { | ||
| ax_task::set_current_affinity(cpu_mask); | ||
| } else { | ||
|
|
@@ -141,14 +166,61 @@ fn get_task_by_sched_pid(pid: i32) -> AxResult<ax_task::AxTaskRef> { | |
| } | ||
|
|
||
| pub fn sys_sched_getscheduler(_pid: i32) -> AxResult<isize> { | ||
| Ok(SCHED_RR as _) | ||
| let task = get_task_by_sched_pid(_pid)?; | ||
| Ok(task.sched_policy() as isize) | ||
| } | ||
|
|
||
| pub fn sys_sched_setscheduler(_pid: i32, _policy: i32, _param: *const ()) -> AxResult<isize> { | ||
| check_sched_permission(_pid)?; | ||
| let task = get_task_by_sched_pid(_pid)?; | ||
| if _param.is_null() { | ||
| return Err(AxError::InvalidInput); | ||
| } | ||
| let user_param = vm_load::<SchedParam>(_param.cast(), 1)?; | ||
| let user_param = user_param[0]; | ||
| let mut policy = _policy as u32; | ||
| const SCHED_RESET_ON_FORK: u32 = 0x40000000; | ||
| let _reset_on_fork = (policy & SCHED_RESET_ON_FORK) != 0; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
当前实现接受此标志但不执行实际的 reset-on-fork 行为,即 |
||
| policy &= !SCHED_RESET_ON_FORK; | ||
| let prio = user_param.sched_priority; | ||
| match policy { | ||
| SCHED_NORMAL | SCHED_FIFO | SCHED_RR | SCHED_BATCH | SCHED_IDLE => {} | ||
| _ => return Err(AxError::InvalidInput), | ||
| } | ||
| match policy { | ||
| SCHED_NORMAL | SCHED_BATCH | SCHED_IDLE => { | ||
| if prio != 0 { | ||
| return Err(AxError::InvalidInput); | ||
| } | ||
| } | ||
| SCHED_FIFO | SCHED_RR => { | ||
| if !(1..=99).contains(&prio) { | ||
| return Err(AxError::InvalidInput); | ||
| } | ||
| } | ||
| _ => unreachable!(), | ||
| } | ||
| task.set_sched_policy(policy as i32); | ||
| task.set_sched_priority(prio); | ||
| Ok(0) | ||
| } | ||
|
|
||
| pub fn sys_sched_getparam(_pid: i32, _param: *mut ()) -> AxResult<isize> { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 在 Linux 中, 当前实现允许任意进程读取任意其它进程的调度参数,没有权限检查。虽然 |
||
| let task = get_task_by_sched_pid(_pid)?; | ||
| if _param.is_null() { | ||
| return Err(AxError::InvalidInput); | ||
| } | ||
| let param = SchedParam { | ||
| sched_priority: task.sched_priority(), | ||
| }; | ||
| let ptr = _param as *mut SchedParam; | ||
| unsafe { | ||
| let bytes = core::slice::from_raw_parts( | ||
| ¶m as *const SchedParam as *const u8, | ||
| core::mem::size_of::<SchedParam>(), | ||
| ); | ||
| vm_write_slice(ptr as *mut u8, bytes)?; | ||
| } | ||
| Ok(0) | ||
| } | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| cmake_minimum_required(VERSION 3.20) | ||
| project(test-sched-family C) | ||
| set(CMAKE_C_STANDARD 11) | ||
| set(CMAKE_C_STANDARD_REQUIRED ON) | ||
| set(CMAKE_C_EXTENSIONS OFF) | ||
| add_executable(test-sched-family src/main.c) | ||
| target_include_directories(test-sched-family PRIVATE src) | ||
| target_compile_options(test-sched-family PRIVATE -Wall -Wextra -Werror) | ||
| install(TARGETS test-sched-family RUNTIME DESTINATION usr/bin) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
check_sched_permission(pid)?内部已经调用get_task_by_sched_pid(pid)获取 task 引用做权限校验,但该 task 引用在check_sched_permission返回后被丢弃。紧接着第 137 行又调用get_task_by_sched_pid(pid)重新获取同一个 task。同样的问题存在于
sys_sched_setscheduler(第 174-175 行)。建议:将
check_sched_permission改为返回(AxTaskRef, ())或单独封装一个get_task_with_permission(pid) -> AxResult<AxTaskRef>,避免冗余查找。