utils: share one ls-permission-field parser across NetRocks and adb, and fix its set-id handling - #3533
Open
rctphone wants to merge 1 commit into
Open
utils: share one ls-permission-field parser across NetRocks and adb, and fix its set-id handling#3533rctphone wants to merge 1 commit into
rctphone wants to merge 1 commit into
Conversation
Author
Recovering a mode_t from the textual permission field of an `ls -l` line was implemented three times - NetRocks' ShellParseUtils (used by SHELL and SCP), NetRocks' vendored FTP LIST parser, and the adb plugin - and all three mishandled the set-id and sticky spellings. ShellParseUtils tested the wrong character: if (c[2] == 'x' || c[1] == 's' || c[1] == 't') out |= 1; c[1] is the write position, which is never 's' or 't', so the execute bit was dropped for every set-id or sticky entry; S_ISUID/S_ISGID/S_ISVTX were not extracted at all. FTPParseLIST was looser still - "any character but '-' sets the bit" - so "-rwSr--r--" came out executable (04644 is correct; it produced 0744), and NetWare's "d [RWCEAFMS] ..." form yielded 0777 out of the bracketed flags instead of no permission bits at all. Move one implementation to utils/include/UnixModeStr.h (header-only, in keeping with the dozen other header-only helpers there; the top-level CMakeLists already puts utils/include on every target's include path, so no build changes) and delete all three copies. Net effect is 47 lines of code in the new header against 62 + 44 + 20 removed, so roughly 80 lines less. Behaviour changes worth naming: - far2l renders the set-id and sticky bits from dwUnixMode (mix/panelmix.cpp:487-493), so SHELL, SCP and FTP listings now show them, and FILE_ATTRIBUTE_EXECUTABLE is now set for entries like -rwsr-xr-x. WinPort derives the attribute flags from S_IFMT and the r/w/x bits only (WinPort/src/APIFiles.cpp:24-49), so nothing else in the mapping moves. - Op/OpXfer.cpp propagates the source mode on copy (:469 SetMode, :513 FilePut, :626 DirectoryCreate). Those bits could not previously be present for a SHELL/SCP/FTP source, so copying a setuid binary from such a host now reproduces the setuid bit at the destination, where before it silently did not. That matches what a local-to-local copy already does via real stat(2), but it is a privilege-bit change rather than a cosmetic one. - OpChangeMode now pre-checks the suid/sgid/sticky boxes for these items. Table-tested against all three previous implementations over 17 field shapes - plain/dir/symlink/char/block/fifo/socket, s and S, t and T, truncated and 11-character (ACL/SELinux-suffixed) fields, and the "d?????????" form a shell emits for entries it may not stat. The new parser matches expectations on all 17; ShellParseUtils was wrong on 6, all of them set-id or sticky.
rctphone
force-pushed
the
utils-lsmode
branch
from
September 21, 2026 11:15
d3e4e5a to
b620078
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Recovering a
mode_tfrom the textual permission field of anls -lline was implemented three times — NetRocks'ShellParseUtils(SHELL and SCP), NetRocks' vendored FTP LIST parser, and theadbplugin — and all three mishandled the set-id and sticky spellings.ShellParseUtilstested the wrong character:c[1]is the write position, which is neversort, so the execute bit was dropped for every set-id or sticky entry. AndS_ISUID/S_ISGID/S_ISVTXwere never extracted at all. far2l renders exactly those out ofdwUnixMode(panelmix.cpp), so on a remote listing/system/bin/run-asshowed up as-rwxr-xr-xand/tmpasdrwxrwxrwx.This moves one implementation into
utils/include/UnixModeStr.hand deletes all three copies. The header is enough on its own: the top-levelCMakeLists.txtalready doesinclude_directories(utils/include), so every target sees it without build changes.FTPParseLISTwas looser still — any character but-sets the bit — so-rwSr--r--came out executable, and NetWare'sd [RWCEAFMS] …form yielded0777from the bracketed flags instead of no permission bits:-rwSr--r--46440744— marked executable-rwsr-xr-x47550755— setuid lostdrwxrwxrwt17770777— sticky lostd [RWCEAFMS]00000777Net effect: 78 insertions against 124 deletions across 6 files.
Correctness
Table-tested against the previous NetRocks implementation over 17 field shapes — plain / dir / symlink / char / block / fifo / socket,
sandS,tandT, truncated fields, and thed?????????form a shell emits for entries it may notstat. The new parser matches expectations on all 17; the old one was wrong on 6, every one of them set-id or sticky:-rwsr-xr-x01047550100655-rwxr-sr-x01027550100745drwxrwxrwt00417770040776/tmp)-rwSr--r--01046440100644-rw-r-Sr--01026440100644drwxrwxrwT00417760040776Behaviour changes worth naming
dwUnixMode(mix/panelmix.cpp:487-493), so SHELL, SCP and FTP listings now show them, andFILE_ATTRIBUTE_EXECUTABLEis now set for entries like-rwsr-xr-x. WinPort derives its attribute flags fromS_IFMTplus the r/w/x bits only (WinPort/src/APIFiles.cpp:24-49), so nothing else in that mapping moves. SFTP is unaffected — it takes real permissions from the sftp attributes.Op/OpXfer.cpppropagates the source mode on copy (:469SetMode,:513FilePut,:626DirectoryCreate). Those bits could not previously be present for a SHELL/SCP/FTP source, so copying a setuid binary from such a host now reproduces the setuid bit at the destination where before it silently did not. That matches what a local-to-local copy already does via realstat(2), but it is a privilege-bit change rather than a cosmetic one, so please weigh it.OpChangeModenow pre-checks the suid/sgid/sticky boxes for these items.Made with Orca 🐋