Skip to content

Rootless preempt-rt mode (Work in Progress)#918

Draft
dwrobel wants to merge 6 commits intoLinuxCNC:masterfrom
dwrobel:rootless
Draft

Rootless preempt-rt mode (Work in Progress)#918
dwrobel wants to merge 6 commits intoLinuxCNC:masterfrom
dwrobel:rootless

Conversation

@dwrobel
Copy link
Copy Markdown
Contributor

@dwrobel dwrobel commented Aug 4, 2020

Allows to run linuxcnc in preempt-rt mode without root (setuid bit).

Benefits:

  • allows to always run using SCHED_FIFO policy (on both rt and non-rt kernels),
  • CI flow can use and tests exactly the same code flow as will be used on the production,
  • latency-test (on modern hardware) should return much more reliable results on non-rt kernel,
  • will help packaging linuxcnc in Fedora (see: setuid removal) and maybe other distros where setuid binaries are not welcome.

How to run it:

  • In order to run it in place, just set the following capabilities:
$ sudo setcap cap_ipc_lock,cap_net_admin,cap_sys_rawio,cap_sys_nice+ep  bin/rtapi_app
  • If you're going to use parallel port, just add yourself to the appropriate group (as you would do for accessing printer).

TODO list:

  • add something like make setcap target to set capabilities on rtapi_app,
  • decide how to clean up the API: like rtapi_is_realtime(),
  • add an option to not invoke iptables in hm2_eth.c (it's much easier and more reliable to configure the rules using firewalld/NetworkManager e.g. on Fedora >=32 firewalld switched from iptables to nftables backend),
  • test with pci cards (currently tested with parport and ethernet based mesa card),
  • very likely other things were missed - would appreciate to get a feedback.

dwrobel added 6 commits August 4, 2020 20:42
Signed-off-by: Damian Wrobel <dwrobel@ertelnet.rybnik.pl>
Signed-off-by: Damian Wrobel <dwrobel@ertelnet.rybnik.pl>
The code tries to unify the codebase of using FIFO_SCHED
between root and non-root as being a root is not a prerequisite
to set FIFO_SCHED scheduler policy (see capabilities(7)).

Signed-off-by: Damian Wrobel <dwrobel@ertelnet.rybnik.pl>
Signed-off-by: Damian Wrobel <dwrobel@ertelnet.rybnik.pl>
Temporarily disable executing iptables.

Signed-off-by: Damian Wrobel <dwrobel@ertelnet.rybnik.pl>
Also print out both linuxcnc_debug.txt and linuxcnc_print.txt
in case of failure.

Signed-off-by: Damian Wrobel <dwrobel@ertelnet.rybnik.pl>
@dwrobel dwrobel marked this pull request as draft August 4, 2020 19:58
@dwrobel dwrobel mentioned this pull request Aug 4, 2020
@jepler
Copy link
Copy Markdown
Contributor

jepler commented Aug 4, 2020

Things to make sure of as you work on this:

  • Top priority: Identify parts of this which can be separated into pull requests which can be incorporated one by one, so that you have to carry less "outstanding work" as the process continues and you can monitor community acceptance of the coding choices you're making instead of getting the real feedback at the end.
    For instance, these immediately strike me as separate PRs that can be evaluated on their own merits:
    • re-working how hm2_eth does firewalls
    • re-working how harden_rt can work without root but with capabilities (if you can keep as-root and as-capabilities intact, or as a configure-time flag)
  • It must remain possible to run LinuxCNC in a pure simulator mode with no elevated privileges required to build it, run the tests, run UIs in simulator mode, etc.
  • It must work on whatever range of platforms we will commit to supporting in our main development branch
  • It must be furnished with the debian packaging work completed as well. I am not familiar with how capabilities are represented in debian packages, so you may have to educate yourself.
  • It must not regress on preventing non-rtapi_app processes from sending packets on the ethernet interface while LinuxCNC is running.

I don't know what's the point of protecting a system against a setuid binary but allowing a binary with cap_sys_rawio, but linux security decisions are a land of contrasts.

@andypugh
Copy link
Copy Markdown
Collaborator

It's been quite a while, but this might still be a good idea. Any comments?

@petterreinholdtsen
Copy link
Copy Markdown
Collaborator

It sound like a great idea to reduce the privileges needed to run linuxcnc. Any hope to get this patch out of draft / work in progress mode?

@smoe smoe added the 2.10-candidate would be nice to have fixed in 2.10 label Jan 18, 2026
@andypugh
Copy link
Copy Markdown
Collaborator

Is this still a live project? It seems that this work would be good to introduce, but it has been "draft" for 6 years.

If this is still something that you are interested in then we can leave it in the PR list, but otherwise it is just going to sit here looking untidy.

grandixximo pushed a commit to grandixximo/linuxcnc that referenced this pull request Apr 24, 2026
PR LinuxCNC#918's SCHED_FIFO unification commit replaced
  setrlimit(RLIMIT_MEMLOCK, unlimited) + unconditional mlockall()
with
  getrlimit + mlockall only when rlim_max >= 2 * PRE_ALLOC_SIZE.
This silently skips mlockall inside Debian-packaging CI containers
where the default RLIMIT_MEMLOCK is 64 KiB, because 64 KiB is less
than the 64 MiB threshold.  Without locked pages, thread scheduling
jitter causes tests/threads.0 to miss counter increments.  Seen as
'line 3097: got 0, expected 10 or 1' on amd64 trixie and sid.

Always call mlockall and log failures.  A best-effort setrlimit is
still attempted (to raise the soft cap to the hard cap without
requiring CAP_SYS_RESOURCE), but the mlockall call itself succeeds
on any kernel as long as the process has CAP_IPC_LOCK, regardless of
the rlimit.
grandixximo pushed a commit to grandixximo/linuxcnc that referenced this pull request Apr 25, 2026
Issue LinuxCNC#3928 reported three bugs in rtapi_is_realtime():

  1. It required a setuid bit on EMC2_BIN_DIR/rtapi_app, ignoring
     file capabilities that grant the same kernel privileges.
  2. It stat()ed a fixed path instead of the running binary, so
     wrapper-based installs (NixOS /run/wrappers and similar) never
     saw the check succeed.
  3. It ran the setuid test before LINUXCNC_FORCE_REALTIME, silently
     discarding the environment variable.

PR LinuxCNC#918 replaced the whole function with 'return 1', which breaks the
sim-vs-rt distinction that GUIs read via hal.is_sim / hal.is_rt and
removes the makeApp() sim fallback.

Rework rtapi_is_realtime() as a runtime capability probe: briefly set
SCHED_FIFO on the calling thread and restore the previous policy,
cache the result.  LINUXCNC_FORCE_REALTIME short-circuits before the
probe, and the RTAI / Xenomai backend detectors still force-true when
those environments are present.

This matches the convention used by comparable userspace-realtime
projects (JACK's jack_is_realtime, PipeWire, rtkit, Xenomai, Klipper):
surface observed capability rather than kernel metadata, and let
callers who need EPERM visibility use the action API directly.

makeApp() drops its own probe and calls rtapi_is_realtime() to choose
between SCHED_FIFO and SCHED_OTHER, falling back to POSIX non-realtime
with a warning that points at 'make setcap' or 'make setuid'.
detect_preempt_rt() is removed -- the probe subsumes it and also works
on kernels that no longer expose /sys/kernel/realtime (6.12+).
grandixximo pushed a commit to grandixximo/linuxcnc that referenced this pull request Apr 25, 2026
PR LinuxCNC#918's SCHED_FIFO unification commit replaced
  setrlimit(RLIMIT_MEMLOCK, unlimited) + unconditional mlockall()
with
  getrlimit + mlockall only when rlim_max >= 2 * PRE_ALLOC_SIZE.
This silently skips mlockall inside Debian-packaging CI containers
where the default RLIMIT_MEMLOCK is 64 KiB, because 64 KiB is less
than the 64 MiB threshold.  Without locked pages, thread scheduling
jitter causes tests/threads.0 to miss counter increments.  Seen as
'line 3097: got 0, expected 10 or 1' on amd64 trixie and sid.

Always call mlockall and log failures.  A best-effort setrlimit is
still attempted (to raise the soft cap to the hard cap without
requiring CAP_SYS_RESOURCE), but the mlockall call itself succeeds
on any kernel as long as the process has CAP_IPC_LOCK, regardless of
the rlimit.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

2.10-candidate would be nice to have fixed in 2.10

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants