diff --git a/TODO b/TODO index 4c5094c35d..8725d5ec3d 100644 --- a/TODO +++ b/TODO @@ -789,7 +789,6 @@ o Kernel/Protected Build Description: Certain interfaces, such as sched_setparam(), sched_setscheduler(), etc. can be used by user mode tasks to modify the behavior of priviledged kernel threads. - task_delete() could even be used to kill a kernel thread. For a truly secure system. Privileges need to be checked in every interface that permits one thread to modify the properties of another thread. diff --git a/include/nuttx/kthread.h b/include/nuttx/kthread.h index 1adfde5fc5..9ce84eeeb1 100644 --- a/include/nuttx/kthread.h +++ b/include/nuttx/kthread.h @@ -2,7 +2,7 @@ * include/nuttx/kthread.h * Non-standard, NuttX-specific kernel thread-related declarations. * - * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Copyright (C) 2013, 2017 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -83,6 +83,29 @@ extern "C" int kernel_thread(FAR const char *name, int priority, int stack_size, main_t entry, FAR char * const argv[]); +/**************************************************************************** + * Name: kthread_delete + * + * Description: + * This function will terminate a kernel thread. At present, this + * function is equivalent to task_delete.c; the following definition + * simply reserves the name in the name space. + * + * Refer to comments with task_delete() for a more detailed description of + * the operation of this function. + * + * Input Parameters: + * pid - The task ID of the task to delete. A pid of zero + * signifies the calling task. + * + * Returned Value: + * OK on success; or ERROR on failure with the errno variable set + * appropriately. + * + ****************************************************************************/ + +#define kthread_delete(p) task_delete(p) + #undef EXTERN #ifdef __cplusplus } diff --git a/sched/task/task_delete.c b/sched/task/task_delete.c index ebf94c8bd8..936fcc5a9d 100644 --- a/sched/task/task_delete.c +++ b/sched/task/task_delete.c @@ -1,7 +1,8 @@ /**************************************************************************** * sched/task/task_delete.c * - * Copyright (C) 2007-2009, 2011-2013, 2016 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2011-2013, 2016-2017 Gregory Nutt. All rights + * reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -55,25 +56,26 @@ * Name: task_delete * * Description: - * This function causes a specified task to cease to exist. Its stack and - * TCB will be deallocated. This function is the companion to task_create(). - * This is the version of the function exposed to the user; it is simply - * a wrapper around the internal, task_terminate function. + * This function causes a specified task to cease to exist. Its stack and + * TCB will be deallocated. This function is the companion to + * task_create(). This is the version of the function exposed to the + * user; it is simply a wrapper around the internal, task_terminate + * function. * - * The logic in this function only deletes non-running tasks. If the 'pid' - * parameter refers to to the currently runing task, then processing is - * redirected to exit(). This can only happen if a task calls task_delete() - * in order to delete itself. + * The logic in this function only deletes non-running tasks. If the + * 'pid' parameter refers to to the currently runing task, then processing + * is redirected to exit(). This can only happen if a task calls + * task_delete()in order to delete itself. * * This function obeys the semantics of pthread cancellation: task * deletion is deferred if cancellation is disabled or if deferred * cancellation is supported (with cancellation points enabled). * - * Inputs: + * Input Parameters: * pid - The task ID of the task to delete. A pid of zero * signifies the calling task. * - * Return Value: + * Returned Value: * OK on success; or ERROR on failure with the errno variable set * appropriately. * @@ -83,6 +85,7 @@ int task_delete(pid_t pid) { FAR struct tcb_s *dtcb; FAR struct tcb_s *rtcb; + int errcode; int ret; /* Check if the task to delete is the calling task: PID=0 means to delete @@ -105,14 +108,30 @@ int task_delete(pid_t pid) * has probably already exited. */ - set_errno(ESRCH); - return ERROR; + errcode = ESRCH; + goto errout; } - /* Only tasks and kernel threads should use this interface */ + /* Only tasks and kernel threads can be deleted with this interface + * (The semantics of the call should be sufficient to prohibit this). + */ DEBUGASSERT((dtcb->flags & TCB_FLAG_TTYPE_MASK) != TCB_FLAG_TTYPE_PTHREAD); + /* Non-privileged tasks and pthreads may not delete privileged kernel + * threads. + * + * REVISIT: We will need to look at this again in the future if/when + * permissions are supported and a user task might also be priveleged. + */ + + if (((rtcb->flags & TCB_FLAG_TTYPE_MASK) != TCB_FLAG_TTYPE_KERNEL) && + ((dtcb->flags & TCB_FLAG_TTYPE_MASK) == TCB_FLAG_TTYPE_KERNEL)) + { + errcode = EACCES; + goto errout; + } + /* Check to see if this task has the non-cancelable bit set in its * flags. Suppress context changes for a bit so that the flags are stable. * (the flags should not change in interrupt handling). @@ -183,9 +202,13 @@ int task_delete(pid_t pid) ret = task_terminate(pid, false); if (ret < 0) { - set_errno(-ret); - return ERROR; + errcode = -ret; + goto errout; } return OK; + +errout: + set_errno(errcode); + return ERROR; }