task_delete(): Do not permit user applications to delete kernel threads.
This commit is contained in:
parent
c8eb0a4880
commit
b1a41b7620
1
TODO
1
TODO
@ -789,7 +789,6 @@ o Kernel/Protected Build
|
|||||||
Description: Certain interfaces, such as sched_setparam(),
|
Description: Certain interfaces, such as sched_setparam(),
|
||||||
sched_setscheduler(), etc. can be used by user mode tasks to
|
sched_setscheduler(), etc. can be used by user mode tasks to
|
||||||
modify the behavior of priviledged kernel threads.
|
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
|
For a truly secure system. Privileges need to be checked in
|
||||||
every interface that permits one thread to modify the
|
every interface that permits one thread to modify the
|
||||||
properties of another thread.
|
properties of another thread.
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* include/nuttx/kthread.h
|
* include/nuttx/kthread.h
|
||||||
* Non-standard, NuttX-specific kernel thread-related declarations.
|
* 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>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* 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,
|
int kernel_thread(FAR const char *name, int priority, int stack_size,
|
||||||
main_t entry, FAR char * const argv[]);
|
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
|
#undef EXTERN
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* sched/task/task_delete.c
|
* 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>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@ -55,25 +56,26 @@
|
|||||||
* Name: task_delete
|
* Name: task_delete
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* This function causes a specified task to cease to exist. Its stack and
|
* 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().
|
* TCB will be deallocated. This function is the companion to
|
||||||
* This is the version of the function exposed to the user; it is simply
|
* task_create(). This is the version of the function exposed to the
|
||||||
* a wrapper around the internal, task_terminate function.
|
* 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'
|
* The logic in this function only deletes non-running tasks. If the
|
||||||
* parameter refers to to the currently runing task, then processing is
|
* 'pid' parameter refers to to the currently runing task, then processing
|
||||||
* redirected to exit(). This can only happen if a task calls task_delete()
|
* is redirected to exit(). This can only happen if a task calls
|
||||||
* in order to delete itself.
|
* task_delete()in order to delete itself.
|
||||||
*
|
*
|
||||||
* This function obeys the semantics of pthread cancellation: task
|
* This function obeys the semantics of pthread cancellation: task
|
||||||
* deletion is deferred if cancellation is disabled or if deferred
|
* deletion is deferred if cancellation is disabled or if deferred
|
||||||
* cancellation is supported (with cancellation points enabled).
|
* cancellation is supported (with cancellation points enabled).
|
||||||
*
|
*
|
||||||
* Inputs:
|
* Input Parameters:
|
||||||
* pid - The task ID of the task to delete. A pid of zero
|
* pid - The task ID of the task to delete. A pid of zero
|
||||||
* signifies the calling task.
|
* signifies the calling task.
|
||||||
*
|
*
|
||||||
* Return Value:
|
* Returned Value:
|
||||||
* OK on success; or ERROR on failure with the errno variable set
|
* OK on success; or ERROR on failure with the errno variable set
|
||||||
* appropriately.
|
* appropriately.
|
||||||
*
|
*
|
||||||
@ -83,6 +85,7 @@ int task_delete(pid_t pid)
|
|||||||
{
|
{
|
||||||
FAR struct tcb_s *dtcb;
|
FAR struct tcb_s *dtcb;
|
||||||
FAR struct tcb_s *rtcb;
|
FAR struct tcb_s *rtcb;
|
||||||
|
int errcode;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* Check if the task to delete is the calling task: PID=0 means to delete
|
/* 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.
|
* has probably already exited.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
set_errno(ESRCH);
|
errcode = ESRCH;
|
||||||
return ERROR;
|
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);
|
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
|
/* 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.
|
* flags. Suppress context changes for a bit so that the flags are stable.
|
||||||
* (the flags should not change in interrupt handling).
|
* (the flags should not change in interrupt handling).
|
||||||
@ -183,9 +202,13 @@ int task_delete(pid_t pid)
|
|||||||
ret = task_terminate(pid, false);
|
ret = task_terminate(pid, false);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
set_errno(-ret);
|
errcode = -ret;
|
||||||
return ERROR;
|
goto errout;
|
||||||
}
|
}
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
|
|
||||||
|
errout:
|
||||||
|
set_errno(errcode);
|
||||||
|
return ERROR;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user