Skip to content

testing/ostest: test process capabilities - #3805

Open
royzah wants to merge 1 commit into
apache:masterfrom
royzah:caps
Open

royzah wants to merge 1 commit into
apache:masterfrom
royzah:caps

Conversation

@royzah

@royzah royzah commented Oct 2, 2026

Copy link
Copy Markdown

Note: Please adhere to Contributing Guidelines.

Summary

ostest coverage for process capabilities, apache/nuttx#20417 (PR_CAPS_GET, PR_CAPS_DROP; PR_CAP_SPAWN, PR_CAP_RAWIO, PR_CAP_ADMIN).

Step Checks
child starts with all caps
child drops ADMIN, spawns the grandchild inherits the reduced set
child drops SPAWN task_create() fails with EPERM
child drops RAWIO mount() fails with EPERM; ENOSYS when the build has no mountable fs, since there is nothing to guard
parent keeps its full set

Built only with CONFIG_SCHED_CAPABILITIES, CONFIG_SCHED_WAITPID and a flat or protected build (task_create()). The option comes with apache/nuttx#20417, so this compiles to nothing until that merges, and on boards that turn it off.

Impact

testing/ostest only. No change where CONFIG_SCHED_CAPABILITIES is unset.

Testing

Host: Ubuntu 24.04.3, x86_64. Builds and runs in ghcr.io/apache/nuttx/apache-nuttx-ci-linux (GCC 12.3). sim:ostest, CONFIG_TESTING_OSTEST_LOOPS=1.

nuttx Config Result
apache/nuttx#20417 sim:ostest caps_test: PASSED; ostest exits 0
apache/nuttx#20417 sim:ostest + CONFIG_FS_TMPFS caps_test: PASSED; with a mountable fs, mount() reaches the RAWIO check; ostest exits 0
master sim:ostest caps.c not built; ostest exits 0

tools/checkpatch.sh -c -u -m -g clean. The logs below are cut to the boot, the caps test and the end; each full run is about 4,200 lines, happy to post them.

apache/nuttx#20417, sim:ostest + CONFIG_FS_TMPFS
stdio_test: write fd=1
stdio_test: Standard I/O Check: printf
stdio_test: write fd=2
ostest_main: putenv(Variable1=BadValue3)
ostest_main: setenv(Variable1, GoodValue1, TRUE)
ostest_main: setenv(Variable2, BadValue1, FALSE)
ostest_main: setenv(Variable2, GoodValue2, TRUE)
ostest_main: setenv(Variable3, GoodValue3, FALSE)
ostest_main: setenv(Variable3, BadValue2, FALSE)
show_variable: Variable=Variable1 has value=GoodValue1
show_variable: Variable=Variable2 has value=GoodValue2
show_variable: Variable=Variable3 has value=GoodValue3
...

user_main: caps test
caps_test: Starting test
caps_test: PASSED

End of test memory usage:
VARIABLE  BEFORE   AFTER
======== ======== ========
arena     3effff8  3effff8
ordblks         2        2
mxordblk  3eaac88  3eaac88
uordblks    45078    45078
fordblks  3ebaf80  3ebaf80

...
Final memory usage:
VARIABLE  BEFORE   AFTER
======== ======== ========
arena     3effff8  3effff8
ordblks         2        5
mxordblk  3eaac88  3eaac88
uordblks    450f0    453a8
fordblks  3ebaf08  3ebac50
user_main: Exiting
ostest_main: Exiting with status 0
apache/nuttx#20417, sim:ostest
stdio_test: write fd=1
stdio_test: Standard I/O Check: printf
stdio_test: write fd=2
ostest_main: putenv(Variable1=BadValue3)
ostest_main: setenv(Variable1, GoodValue1, TRUE)
ostest_main: setenv(Variable2, BadValue1, FALSE)
ostest_main: setenv(Variable2, GoodValue2, TRUE)
ostest_main: setenv(Variable3, GoodValue3, FALSE)
ostest_main: setenv(Variable3, BadValue2, FALSE)
show_variable: Variable=Variable1 has value=GoodValue1
show_variable: Variable=Variable2 has value=GoodValue2
show_variable: Variable=Variable3 has value=GoodValue3
...

user_main: caps test
caps_test: Starting test
caps_test: PASSED

End of test memory usage:
VARIABLE  BEFORE   AFTER
======== ======== ========
arena     3effff8  3effff8
ordblks         2        2
mxordblk  3eaad78  3eaad78
uordblks    44f88    44f88
fordblks  3ebb070  3ebb070

...
Final memory usage:
VARIABLE  BEFORE   AFTER
======== ======== ========
arena     3effff8  3effff8
ordblks         2        5
mxordblk  3eaad78  3eaad78
uordblks    45000    452b8
fordblks  3ebaff8  3ebad40
user_main: Exiting
ostest_main: Exiting with status 0
master, sim:ostest
stdio_test: write fd=1
stdio_test: Standard I/O Check: printf
stdio_test: write fd=2
ostest_main: putenv(Variable1=BadValue3)
ostest_main: setenv(Variable1, GoodValue1, TRUE)
ostest_main: setenv(Variable2, BadValue1, FALSE)
ostest_main: setenv(Variable2, GoodValue2, TRUE)
ostest_main: setenv(Variable3, GoodValue3, FALSE)
ostest_main: setenv(Variable3, BadValue2, FALSE)
show_variable: Variable=Variable1 has value=GoodValue1
show_variable: Variable=Variable2 has value=GoodValue2
show_variable: Variable=Variable3 has value=GoodValue3
...
Final memory usage:
VARIABLE  BEFORE   AFTER
======== ======== ========
arena     3effff8  3effff8
ordblks         2        5
mxordblk  3eaad78  3eaad78
uordblks    45000    452b8
fordblks  3ebaff8  3ebad40
user_main: Exiting
ostest_main: Exiting with status 0

Comment thread testing/ostest/caps.c Outdated
Comment thread testing/ostest/ostest.h
A child starts with all three, a grandchild inherits a dropped set, and
task_create() and mount() fail with EPERM once SPAWN and RAWIO are gone.
The parent keeps its full set. Built only with CONFIG_SCHED_CAPABILITIES
(apache/nuttx#20417), so small boards that turn it off, and trees without
it, are untouched.

Signed-off-by: Royyan Zahir <royzah@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants