nut: improve rpcd acl / luci-app-acl effectiveness - #30055
nut: improve rpcd acl / luci-app-acl effectiveness#30055danielfdickinson wants to merge 4 commits into
Conversation
openwrt-ai
left a comment
There was a problem hiding this comment.
Reviewed 1 new commit; the commit message accurately describes the changes.
Generated by Claude Code
4846a40 to
19955db
Compare
openwrt-ai
left a comment
There was a problem hiding this comment.
Reviewed 1 new commit; no new issues found.
The changes since the last review are all correct fixes: removing the duplicate check_safe_hostname_or_ip definition, correcting the log_config_load_error label to nut_monitor_root, fixing the interface_reload_delay validation (the value is now assigned from val before the check), and switching exit 1 to return 1 in loop_through_drivers for consistency with its callers.
Generated by Claude Code
There was a problem hiding this comment.
Pull request overview
Strengthens NUT’s UCI→runtime configuration pipeline to reduce privilege-escalation and config-injection opportunities when an untrusted user has UCI write access, primarily by separating “root-equivalent” settings into dedicated *_root UCI configs and tightening how UCI values are retrieved.
Changes:
- Added
config_get_singlehelper to sanitize UCI-sourced values (printable 7-bit ASCII) and migrated many call sites to use it. - Split configurations into service configs vs. new
*_rootconfigs, and adjusted init/config-generation scripts to load them in subshells to avoid mixed UCI contexts. - Updated init scripts and triggers to account for the new
*_rootconfigs (install + conffiles + reload triggers), plus related hotplug adjustments.
Reviewed changes
Copilot reviewed 17 out of 17 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| net/nut/Makefile | Bumps release; installs and marks new *_root UCI config templates as conffiles. |
| net/nut/files/nut-service.sh.functions | Switches triggerlist retrieval to config_get_single. |
| net/nut/files/nut-server.init | Uses config_get_single broadly; isolates root config loads via subshells; adds reload trigger for nut_server_root. |
| net/nut/files/nut-server-service.sh.functions | Adds helper to fetch sanitized UPS option values from nut_server in an isolated subshell. |
| net/nut/files/nut-server-config.sh.functions | Migrates UCI reads to config_get_single; separates user/root bits into nut_server_root loading. |
| net/nut/files/nut-serial.hotplug | Uses config_get_single for port to reduce unsafe UCI value handling. |
| net/nut/files/nut-monitor.init | Moves RUNAS lookup into nut_monitor_root via subshell; adds reload trigger for nut_monitor_root. |
| net/nut/files/nut-monitor-config.sh.functions | Splits non-root vs root options (e.g., NOTIFYCMD/SHUTDOWNCMD) into nut_monitor_root; uses isolated config_load subshells. |
| net/nut/files/nut-common.sh.functions | Introduces config_get_single and config_get_single_unsafe. |
| net/nut/files/nut-cgi.init | Splits nut_cgi vs nut_cgi_root loads into subshells; adds reload trigger for nut_cgi_root. |
| net/nut/files/nut_server_root | New root-only UCI template for upsd_root and user sections. |
| net/nut/files/nut_server | Removes user/runas/statepath examples from non-root config template. |
| net/nut/files/nut_monitor_root | New root-only UCI template for RUNAS/notify/shutdown and monitor credentials/notifications. |
| net/nut/files/nut_monitor | Removes root-equivalent examples from non-root config template. |
| net/nut/files/nut_cgi_root | New root-only UCI template for upsset enable flag. |
| net/nut/files/nut_cgi | Removes upsset section from non-root config template. |
| net/nut/files/libhid-ups.hotplug | Uses config_get_single for vendor/product IDs when matching USB devices. |
Suppressed comments (1)
net/nut/files/nut-monitor-config.sh.functions:266
- This block runs inside a subshell
(...). Usingreturn 1here can behave unexpectedly (or return from the outer function rather than failing the subshell). Useexit 1so the subshell reliably fails and the outer) || return 1handles it.
for event in $event_notify_flags_not_found; do
if ! printf "NOTIFYFLAG %s %s\n" "$event" "$defaultnotify" >>"$config_file"; then
log_error "upsmon section '$cfg' failed to write 'NOTIFYFLAG' for '$event'" nut-monitor-config.sh nut-monitor-config
return 1
fi
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
19955db to
41a0fc7
Compare
openwrt-ai
left a comment
There was a problem hiding this comment.
Reviewed the rebased commit. The four changes since the last review (comment typo, dead SHUTDOWNCMD case removal, return→exit inside the notify-flag subshell, exit→return in service_preconditions) all look correct: SHUTDOWNCMD is no longer in NUT_UPSMON_OPTIONS so the removed case really was unreachable, and exit 1 at nut-monitor-config.sh.functions:250 now matches the other bail-outs in that same subshell.
While re-reading the surrounding blocks I found two find_* call sites in nut-server.init that still pass the pre-split package name, which makes the new nut_server_root settings inert — details inline. Nothing here blocks a merge decision beyond that; the rest is one nit.
Generated by Claude Code
8095f4b to
e5addb4
Compare
openwrt-ai
left a comment
There was a problem hiding this comment.
Reviewed the changes since the last review (rebase onto master plus three fixes). All three are correct: the find_statepath/find_runas call sites in nut-server.init now pass nut_server_root and drop the dead printf, and nut-monitor.init now captures find_runas's stdout instead of testing an unset RUNAS. The commit message still matches the diff.
One question on the new nut-monitor.init fallback, and — from re-reading the config split as a whole — one thing that looks like it could bite on upgrade: the sections that moved to the *_root configs have no migration path, so an existing install keeps them in the old conffile where nothing reads them any more. Details inline; the rest is two nits.
Generated by Claude Code
e5addb4 to
c969dbe
Compare
openwrt-ai
left a comment
There was a problem hiding this comment.
Reviewed the 3 new commits since the last review (1a8141f hotplug-remove short-circuits, fd0037d NOTIFYMSG quoting, c969dbe service-thrashing refactor). Commit messages match their diffs. One inline issue on the c969dbe boot-sentinel gate in nut-serial.hotplug.
Generated by Claude Code
Reduce opportunities for an untrusted user with UCI write access to escalate privileges or write arbitrary configurations (i.e. config not part of their ACL). * Introduces config_get_single which only allows accepts 7-bit ASCII characters from UCI configuration settings * Splits UCI configuration files into main for each service, and a [service]_root config. The _root configuration holds any configuration which is or could lead to root-equivalence (such as setting RUNAS user, and defining executable notification commands). * Uses config_load in a subshell where needed, so that the _root configurations do not get mixed in with the non-_root configurations. * More validation of inputs Hotplug scripts do not require changes, as they only use the non-root upsd configs, and have a separate variable context, so isolating their config_load in a subshell is not necessary. Signed-off-by: Daniel F. Dickinson <dfdpublic@wildtechgarden.ca>
Short-circuit parts of the hotplug script on remove, and only do some parts for ACTION='add'. Signed-off-by: Daniel F. Dickinson <dfdpublic@wildtechgarden.ca>
Messages with spaces must be enclosed in double-quotes. Signed-off-by: Daniel F. Dickinson <dfdpublic@wildtechgarden.ca>
On boot, hotplug events were causing excessive start and stop action
for the upsd daemon and driver daemons. We fix that with two primary
actions:
1. Don't restart service daemons on hotplug until after first boot
has completed.
2. Use more robust handling of procd instance starts by ensuring
that the first start starts the nut-server service and all
others add to the nut-server service (rather than replacing it).
Also introduce some a 'sleep' in hotplug to reduce bouncing, and
ignore hotplug events without a DEVNAME.
In addition clean up some logging.
Signed-off-by: Daniel F. Dickinson <dfdpublic@wildtechgarden.ca>
c969dbe to
1fccc74
Compare
📦 Package Details
Maintainer: @danielfdickinson
Description:
Reduce opportunities for an untrusted user with UCI write access to escalate privileges or write arbitrary configurations (i.e. config not part of their ACL).
Hotplug scripts only use the non-root upsd configs, and have a separate variable context, so isolating their config_load in a subshell is not necessary.
We do however improve hotplug behavior for remove
and add logic to prevent thrashing on boot or hotplug
On boot, hotplug events were causing excessive start and stop action
for the upsd daemon and driver daemons. We fix that with two primary
actions:
has completed.
that the first start starts the nut-server service and all
others add to the nut-server service (rather than replacing it).
Also introduce some a 'sleep' in hotplug to reduce bouncing, and
ignore hotplug events without a DEVNAME.
In addition clean up some logging and fix custom notification message config generation.
Corresponding LuCI PR is openwrt/luci#8851
🧪 Run Testing Details
Lightly tested
Re-tested on
TODO: Re-test SSL (using a second device).
✅ Formalities