task_delete(): Do not permit user applications to delete kernel threads.

This commit is contained in:
Gregory Nutt 2017-10-16 09:07:17 -06:00
parent c8eb0a4880
commit b1a41b7620
3 changed files with 63 additions and 18 deletions

1
TODO
View File

@ -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.

View File

@ -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 <gnutt@nuttx.org>
*
* 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
}

View File

@ -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 <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@ -56,24 +57,25 @@
*
* 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.
* 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;
}