luci-app-netmode: add app for modem network mode switching#8690
luci-app-netmode: add app for modem network mode switching#8690devopnem wants to merge 1 commit into
Conversation
This comment has been minimized.
This comment has been minimized.
1f935ee to
d8c6b5c
Compare
openwrt-ai
left a comment
There was a problem hiding this comment.
Reviewed the new luci-app-netmode app. Main concern is an ACL gap that breaks port auto-detection at runtime, plus an input-validation issue in at.sh. Details inline.
Generated by Claude Code
| "file": { | ||
| "/usr/share/netmode/at.sh": ["exec"] | ||
| } | ||
| } |
There was a problem hiding this comment.
This ACL grants only file exec on at.sh, but load() in netmode.js calls fs.list('/dev') to auto-detect ports. The file.list ubus method requires a "list" permission on the target path (rpcd file.c L548), which is missing here. For a session that only holds this ACL group, the /dev listing is denied; the JS swallows it via .catch(() => []), so _ports stays empty, _device is null, and both auto-detection and the Advanced port selector silently break ("No modem ports found").
Either add a list grant for /dev, e.g.:
| } | |
| "file": { | |
| "/usr/share/netmode/at.sh": ["exec"], | |
| "/dev": ["list"] | |
| } |
or follow luci-app-p910nd, which avoids fs.list and instead execs find against a specific command-line ACL.
Generated by Claude Code
| TMPSCRIPT=$(mktemp /tmp/netmode.XXXXXX) | ||
|
|
||
| printf 'opengt\nset com 115200n81\nset senddelay 0.05\nsend "%s^m"\nwaitfor 8 "OK","ERROR","+COPS:"\nget 1 "^m" $s\nprint $s\n' "$CMD" > "$TMPSCRIPT" | ||
|
|
There was a problem hiding this comment.
$CMD ($*) is interpolated unvalidated into the comgt send "%s^m" string. A " in the argument terminates the comgt string literal and lets the caller inject additional comgt directives; any AT string is also passed straight to the modem. Because the ACL grants blanket exec on this path (no per-command-line match), the per-cmdline check in rpcd is bypassed and any session holding this ACL can invoke at.sh with arbitrary arguments (rpcd file.c L937). Consider validating $CMD against an allowlist (the script only ever needs AT+COPS? and AT+COPS=0[,,,N]) rather than forwarding arbitrary AT commands.
Generated by Claude Code
| function actShort(act) { | ||
| if (act === 7) return '4g'; | ||
| if (act === 2) return '3g'; | ||
| return 'auto'; |
There was a problem hiding this comment.
nit: this only treats act 7 as 4G and act 2 as 3G; the other 3G technologies in actLabels (4 HSDPA, 5 HSUPA, 8 HSPA+) and the LTE/5G values (9 LTE-A, 10 NR) all fall through to 'auto'. So when the modem reports, e.g., HSPA+, the "3G Only" button is not marked active even though the modem is on 3G. Consider mapping all UTRAN-family ACTs to '3g' and all E-UTRAN/NR ACTs to '4g'.
Generated by Claude Code
d8c6b5c to
836f96e
Compare
openwrt-ai
left a comment
There was a problem hiding this comment.
Re-reviewed at head 836f96e. The earlier ACL /dev listing gap, the at.sh arbitrary-AT-command concern, and the actShort 3G/4G mapping were all addressed in this push. One new issue from the added at.sh allowlist is inline.
Generated by Claude Code
| CMD="$*" | ||
|
|
||
| case "$CMD" in | ||
| at+cops\?|at+cops=0|at+cops=0,,,2|at+cops=0,,,7) |
There was a problem hiding this comment.
The allowlist patterns are lowercase, but the frontend sends the AT commands in uppercase: AT+COPS? / AT+COPS=0 / AT+COPS=0,,,7 / AT+COPS=0,,,2.POSIXcasein/bin/sh(ash) is case-sensitive, so every command the app sends falls through to the*)branch and returnsERROR: command not allowed` (exit 1). As written the status query and all three switch buttons are non-functional. Match the uppercase forms the frontend actually sends:
| at+cops\?|at+cops=0|at+cops=0,,,2|at+cops=0,,,7) | |
| AT+COPS\?|AT+COPS=0|AT+COPS=0,,,2|AT+COPS=0,,,7) |
Generated by Claude Code
Add a LuCI JavaScript application that allows users to view and switch modem network access technology via AT commands. Features: - Auto-detection of modem AT port - Display current operator and network mode - Switch between Auto, 4G LTE Only, and 3G Only modes - Non-blocking UI with button state management - Current-mode button is automatically disabled - Collapsible Advanced Settings panel for port selection - Dark-mode friendly (uses theme CSS variables) - Uses comgt for safe AT command communication with timeout Signed-off-by: Devon Openheim <devopenm@proton.me>
836f96e to
d3d8cee
Compare
openwrt-ai
left a comment
There was a problem hiding this comment.
Re-reviewed at head d3d8cee. The only change since my last review (836f96e) is the at.sh allowlist case patterns switching from lowercase to uppercase (AT+COPS\?|AT+COPS=0|AT+COPS=0,,,2|AT+COPS=0,,,7). These now match the four uppercase commands the frontend sends, so the earlier case-sensitivity breakage is resolved. No new issues found.
Generated by Claude Code
9d58aef to
d3d8cee
Compare
Features:
Pull request details
Description
Add a LuCI JavaScript application that allows users to view and switch modem network access technology via AT commands.
Screenshot or video of changes (if applicable)
Tested on
OpenWrt version: OpenWrt 25.12.4 (r32933-4ccb782af7)
LuCI version: openwrt-25.12 branch (26.155.67407~06be235)
Web browser(s): LibreWolf 151.0.1-2
Checklist
Signed-off-by: <my@email.address>row (viagit commit --signoff).<package name>: titlefirst line subject for packages.PKG_VERSIONin the Makefile.