macOS: validate target of privileged SetFileOwner (restrict to disk device nodes)#1758
Open
damianrickard wants to merge 1 commit into
Open
Conversation
The privileged CoreService handler for SetFileOwnerRequest passed the client-supplied path straight to chown() as root with no validation -- unlike the adjacent APFS formatter handler, which strictly validates its device argument. Every legitimate macOS caller of the elevated SetFileOwner targets a real disk device node (/dev/[r]diskN[sM]), so a crafted IPC request, or a symlink planted at the target, could otherwise make the root process change ownership of an arbitrary path. Validate the target service-side: require the strict device-path form already used by the formatter, and lstat() it to confirm a block or character device (rejecting symlinks rather than following them) before the chown. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Member
|
@damianrickard The commit is marked as co-authored by Claude Fable 5: While I'm not against the use of AI for development, commits should be authored by humans only to take full responsibility and ownership of the changes. co-ownership with AI is not accepted. Please amend the commit to remove the Claude Fable 5 co-author. Once the commit is amended to remove Claude Fable 5 co-author (if you take full responsibility and ownership of the changes), I will merge this PR. |
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.
Summary
Defense-in-depth hardening for the macOS privileged helper. The elevated
CoreServicehandler forSetFileOwnerRequestpassed the client-supplied path straight tochown()running as root, with no validation — unlike the adjacentExecuteMacOSXAPFSFormatterRequesthandler, which strictly validates its device argument viaIsMacOSXFormatterDevicePath().Background
On macOS, when the user is not an administrator, the volume creation / format flows temporarily transfer ownership of the target disk device node to the invoking user through the root-elevated service (
VolumeCreator,GraphicUserInterface,TextUserInterface,MacOSXFormatterDevice.h). Every legitimate caller of the elevatedSetFileOwnertargets a/dev/[r]diskN[sM]device.The service side, however, performed no validation — it would
chown()any path to any uid as root. Becausechown()follows symlinks, a symlink planted at the target (or a crafted IPC request) could redirect the root-owned chown to an arbitrary path.Reachability is limited (the service channel is private to the authenticated session, and the real callers only ever target devices), so this is hardening rather than a directly weaponizable issue. But the asymmetry with the already-validated formatter handler is worth closing.
Change
Add
ValidateMacOSXSetFileOwnerTarget()inCoreService.cpp, invoked before the elevated chown:IsMacOSXFormatterDevicePath: exactly/dev/disk<N>or/dev/disk<N>s<M>, plus therdiskvariants, with no trailing characters).lstat()the path (notstat) and requireS_ISBLKorS_ISCHR, so a symlink is rejected outright rather than followed.No behavior change for legitimate flows — all macOS callers already target device nodes. Other platforms are unaffected (
#ifdef TC_MACOSX).Testing
Built on Apple Silicon (arm64, macOS); volume create + mount still succeed. The validator accepts
/dev/diskN(block) and/dev/rdiskN(character) device nodes and rejects non-device paths and symlinks.