Samsung / TizenRT

TizenRT is a lightweight RTOS-based platform to support low-end IoT devices
Apache License 2.0
573 stars 574 forks source link

Many kernel task handle function lack of permission check when calling it #5794

Open peanuts62 opened 1 year ago

peanuts62 commented 1 year ago

In the os/kernel/task/ have many task or kernel thread handle function. But all of them were lack of checking for calling task.So if a normal task call task_delete with a high level task pid or call task_create set a high priority or a large stack it will keeps taking up other tasks and eventually becomes Dos.

attack case 1:

int attack_init(){
       pid = task_create("attack_demo", SCHED_PRIORITY_MIN, 16384, attack_demo, argv);
}
int attack_demo(int argc, char *argv[]){
         pid = task_create("attack_function", SCHED_PRIORITY_MAX, 16384, attack_function, argv);
}

// attack_demo was a low priority and it can create a  high priorty without any check.

attack case 2:

int a(){
        printf("which will be delete!");
}
int b(int pid){
       task_delete(pid);
       printf("delete success!");
}
int main_init(){
         pid = task_create("a", SCHED_PRIORITY_MAX, 16384, a, argv);
         pid = task_create("b", SCHED_PRIORITY_MAX, 16384, b, pid);
         // a will delete by b, because task_delete not check delete permission
}

List of kernel task function which lack of permission check when the task call it

int task_delete(pid_t pid)
int task_activate(FAR struct tcb_s *tcb)
int atexit(void (*func)(void))
void notify_cancellation(FAR struct tcb_s *tcb)
int task_create(FAR const char *name, int priority, int stack_size, main_t entry, FAR char *const argv[])
void task_show_tcbinfo(struct tcb_s *tcb)
int execv(FAR const char *path, FAR char *const argv[])
int task_exit(void)
void task_exithook(FAR struct tcb_s *tcb, int status, bool nonblocking)
FAR struct task_group_s *task_getgroup(pid_t pid)
pid_t getpid(void)
int task_init(FAR struct tcb_s *tcb, const char *name, int priority, FAR uint32_t *stack, uint32_t stack_size, main_t entry, FAR char *const argv[])
int on_exit(CODE void (*func)(int, FAR void *), FAR void *arg)
void task_recover(FAR struct tcb_s *tcb)
int task_reparent(pid_t ppid, pid_t chpid)
int task_restart(pid_t pid)
int task_setcancelstate(int state, FAR int *oldstate)
int task_setcanceltype(int type, FAR int *oldtype)
static int thread_schedsetup(FAR struct tcb_s *tcb, int priority, start_t start, CODE void *entry, uint8_t ttype)
etc.....
sunghan-chang commented 1 year ago

@peanuts62 TizenRT has no permission on task management. I don't know what issue is with the attack cases above.

peanuts62 commented 1 year ago

The issue was that there is no permission control method or task in TizenRT. If the developer uses this framework to create several tasks, and one of the tasks has an exploitable vulnerability in the user mode, the attacker can use ROP or It is the way of shellcode execution to call these syscalls to create a high-priority task and to modify or close the task of key services, in which the kernel does not do any isolation and inspection.

The correct way should be to properly isolate the operations between tasks.

In addition, I want to report another issue here. There is an MPU design under the arm architecture. The documentation is here https://github.com/Samsung/TizenRT/blob/master/docs/HowToUseMPU.md , the mpu design book It is to isolate the kernel and user mode, so as to ensure that the problem of user mode will not affect the kernel, but the same as the above situation, if there is a vulnerability in user mode that can ROP or execute shellcode, then the attacker can easily call mpu_control(false) invalidates the settings of the mpu to obtain user data protected by the mpu or change the mpu protect memory. Those functions didn’t any protect when the attacker call them.

we are working on the protection architecture for those vulnerability, if you want to know more detail about protection architecture can connect yueqi.chen@colorado.edu

chenyueqi commented 1 year ago

I want to follow up on the discussion by clarifying the security issues described at the very beginning. The problem lies in lacking sufficient checks during mode switching. Taking task_create as an example, attackers who already have control over a non-privileged task can call this function to create a task with the highest scheduling priority to occupy the CPU and prevent other tasks from being executed. Therefore, inside task_create, there should be a check that examines whether a non-privileged task is allowed to set the highest scheduling priority. task_create is just an example. In other functions, if the legitimacy of their arguments is not examined, attackers can, for example, provide a kernel address as a pointer argument of the function. This address will later be overwritten with a value that also originates from the function argument controlled by attackers, without being examined.