sched: process capabilities

A task group holds PR_CAP_RAWIO, PR_CAP_SPAWN and PR_CAP_ADMIN, inherits
them from its creator and can only drop them. Every build: the kernel and
init start with all three, so nothing changes until a task drops one.
CONFIG_SCHED_CAPABILITIES, off with DEFAULT_SMALL, lets a board short of
flash leave the checks out.

Signed-off-by: Royyan Zahir <royzah@gmail.com>
This commit is contained in:
Royyan Zahir 2026-10-02 06:56:34 +04:00 • committed by Alan C. Assis
parent fdf5ea919e
commit e70cd6bf45
6 changed files with 41 additions and 6 deletions

View file

@ -33,6 +33,7 @@
#include <stdbool.h>
#include <stdint.h>
#include <sched.h>
#include <sys/prctl.h>
#include <signal.h>
#include <pthread.h>
#include <time.h>
@ -456,6 +457,7 @@ struct task_group_s
pid_t tg_pid; /* The ID of the task within the group */
pid_t tg_ppid; /* This is the ID of the parent thread */
uint8_t tg_flags; /* See GROUP_FLAG_* definitions */
uint8_t tg_caps; /* See PR_CAP_* definitions */
/* User identity (POSIX real, effective, and saved-set IDs) ***************/
@ -924,6 +926,12 @@ static inline_function bool nxsched_has_gid(FAR struct tcb_s *tcb,
FAR struct tcb_s *nxsched_self(void);
#ifdef CONFIG_SCHED_CAPABILITIES
# define nxsched_capable(c) ((nxsched_self()->group->tg_caps & (c)) == (c))
#else
# define nxsched_capable(c) true
#endif
/****************************************************************************
* Name: nxsched_foreach
*

View file

@ -78,6 +78,13 @@
#define PR_SET_DUMPABLE 5
#define PR_GET_DUMPABLE 6
#define PR_CAPS_DROP 7
#define PR_CAPS_GET 8
#define PR_CAP_RAWIO (1 << 0)
#define PR_CAP_SPAWN (1 << 1)
#define PR_CAP_ADMIN (1 << 2)
#define PR_CAP_ALL (PR_CAP_RAWIO | PR_CAP_SPAWN | PR_CAP_ADMIN)
/****************************************************************************
* Public Type Definitions

View file

@ -817,6 +817,17 @@ config SCHED_NGROUPS
endif # SCHED_USER_IDENTITY
config SCHED_CAPABILITIES
bool "Process capabilities"
default !DEFAULT_SMALL
---help---
Task groups hold PR_CAP_RAWIO, PR_CAP_SPAWN and PR_CAP_ADMIN,
inherit them from their creator and can drop them with
prctl(PR_CAPS_DROP). Raw storage, mount, spawn, reset and
power-off then need the matching capability. Without this
option every check passes and prctl() refuses PR_CAPS_DROP and
PR_CAPS_GET.
config SCHED_THREAD_LOCAL
bool "Support __thread/thread_local keyword"
default n

View file

@ -196,6 +196,7 @@ int group_allocate(FAR struct tcb_s *tcb, uint8_t ttype)
{
group = &g_kthread_group;
tcb->group = group;
group->tg_caps = PR_CAP_ALL;
if (group->tg_info)
{
return OK;
@ -250,6 +251,9 @@ int group_allocate(FAR struct tcb_s *tcb, uint8_t ttype)
goto errout_with_group;
}
group->tg_caps = this_task()->group != NULL ?
this_task()->group->tg_caps : PR_CAP_ALL;
/* Initialize file descriptors for the TCB */
fdlist_init(&group->tg_fdlist);

View file

@ -476,6 +476,7 @@ static void idle_group_initialize(void)
group_initialize(tcb);
tcb->group->tg_flags = GROUP_FLAG_NOCLDWAIT | GROUP_FLAG_PRIVILEGED;
tcb->group->tg_caps = PR_CAP_ALL;
}
}

View file

@ -187,20 +187,24 @@ int prctl(int option, ...)
goto errout;
#endif
#ifdef CONFIG_SCHED_CAPABILITIES
case PR_CAPS_DROP:
this_task()->group->tg_caps &= ~va_arg(ap, int);
break;
case PR_CAPS_GET:
va_end(ap);
return this_task()->group->tg_caps;
#endif
default:
serr("ERROR: Unrecognized option: %d\n", option);
errcode = EINVAL;
goto errout;
}
/* Not reachable unless CONFIG_TASK_NAME_SIZE is > 0. NOTE: This might
* change if additional commands are supported.
*/
#if CONFIG_TASK_NAME_SIZE > 0
va_end(ap);
return OK;
#endif
errout:
va_end(ap);