client: prohibit unprivileged users from setting sgid/suid bits#64356
client: prohibit unprivileged users from setting sgid/suid bits#64356
Conversation
src/client/Client.cc
Outdated
| bool clearing_suid_sgid = false; | ||
| static const uint16_t SUID_SGID_MASK = S_ISUID | S_ISGID; | ||
| if ((in->mode & ~SUID_SGID_MASK) == (stx->stx_mode & ~SUID_SGID_MASK) && // other bits unchanged | ||
| (in->mode & SUID_SGID_MASK) > (stx->stx_mode & SUID_SGID_MASK)) { // only clearing |
There was a problem hiding this comment.
I thought about using a greater than comparison check with a combined mask initially, but AFAICT that still breaks as one can clear the higher significant bit while setting the lower one, Here is a simplified example of what I mean:
existing mode: b10 == 2 would be bigger than new mode: b01 == 1 while a bit got set for the new one.
I'm not sure what effect that would have in practice, but I think it might still lead to an attack if the group or user (whatever the lower significant bit maps to) of the file is one that has more privileges. And even if not, it would IMO be rather confusing and might lead to issues down the line if this gets copied somewhere else with the assumption it's safe.
While it's less clever and needs more code, it might be the best to check each bit separately, e.g. something like:
if ((in->mode & ~(S_ISUID | S_ISGID)) == (stx->stx_mode & ~(S_ISUID | S_ISGID)) && // other bits unchanged
(in->mode & S_ISUID) > (stx->stx_mode & S_ISUID) && // only clearing SUID
(in->mode & S_ISGID) > (stx->stx_mode & S_ISGID)) { // only clearing SGID
clearing_suid_sgid = true;
}There was a problem hiding this comment.
@ThomasLamprecht hi Thomas, i was reading the related linux kernel, and realized that there were chances that only the S_ISUID is cleared, so we might not want to prohibit this case. i updated my change accordingly.
|
changelog
|
Thanks @tchaikov - I will have a look. |
vshankar
left a comment
There was a problem hiding this comment.
Minor nit. Otherwise LGTM.
I'm trying to run the test locally, but running in issues.
|
changelog
|
|
jenkins test windows |
ThomasLamprecht
left a comment
There was a problem hiding this comment.
Your new variant makes the code easier to read, the change itself LGTM too:
Reviewed-by: Thomas Lamprecht t.lamprecht@proxmox.com
|
jenkins test windows |
1 similar comment
|
jenkins test windows |
|
@tchaikov I think the windows failure is legit. Mind having a look please? |
Prior to fb1b72d, unprivileged users could add mode bits as long as S_ISUID and S_ISGID were not included in the change. After fb1b72d, unprivileged users were allowed to modify S_ISUID and S_ISGID bits only when no other mode bits were changed in the same operation. This inadvertently permitted unprivileged users to set S_ISUID and/or S_ISGID bits when they were the sole bits being modified. This behavior should not be allowed. Unprivileged users should be prohibited from setting S_ISUID and/or S_ISGID bits under any circumstances. This change tightens the permission check to prevent unprivileged users from setting these privileged bits in all cases. Signed-off-by: Kefu Chai <tchaikov@gmail.com>
|
@vshankar hi Venky, i think that the failures were caused by the new negative tests which intended to chmod by clearing suid / sgid directly with an unprivileged user. these tests failed because of |
|
changelog:
|
Makes sense. We could however add a test for this specific case, correct? I.e., dropping suid/sgid bits from an executable by an unprivileged user. |
we already have tests for this in the same test case. see
|
Got it. Thx! This change is good to run through tests. |
|
jenkins test make check |
|
jenkins test api |
|
This PR is under test in https://tracker.ceph.com/issues/72073. |
|
@vshankar hi Venky, thank you for testing this change. now that this change has been verified at least at https://pulpito.ceph.com/vshankar-2025-07-14_15:05:46-fs-wip-vshankar-testing-20250714.111344-debug-testing-default-smithi/8385861/. and the test passed. is there anything else i can do to move this PR forward? |
This is ready to merge. It's just waiting on me to prepare run wiki which I have been a bit slow due to other stuff needing my attention. |
|
Ahh, I see. Thanks again! |
Prior to fb1b72d, unprivileged users could add mode bits as long as S_ISUID and S_ISGID were not included in the change.
After fb1b72d, unprivileged users were allowed to modify S_ISUID and S_ISGID bits only when no other mode bits were changed in the same operation. This inadvertently permitted unprivileged users to set S_ISUID and/or S_ISGID bits when they were the sole bits being modified.
This behavior should not be allowed. Unprivileged users should be prohibited from setting S_ISUID and/or S_ISGID bits under any circumstances.
This change tightens the permission check to prevent unprivileged users from setting these privileged bits in all cases.
Contribution Guidelines
To sign and title your commits, please refer to Submitting Patches to Ceph.
If you are submitting a fix for a stable branch (e.g. "quincy"), please refer to Submitting Patches to Ceph - Backports for the proper workflow.
When filling out the below checklist, you may click boxes directly in the GitHub web UI. When entering or editing the entire PR message in the GitHub web UI editor, you may also select a checklist item by adding an
xbetween the brackets:[x]. Spaces and capitalization matter when checking off items this way.Checklist
Show available Jenkins commands
jenkins test classic perfJenkins Job | Jenkins Job Definitionjenkins test crimson perfJenkins Job | Jenkins Job Definitionjenkins test signedJenkins Job | Jenkins Job Definitionjenkins test make checkJenkins Job | Jenkins Job Definitionjenkins test make check arm64Jenkins Job | Jenkins Job Definitionjenkins test submodulesJenkins Job | Jenkins Job Definitionjenkins test dashboardJenkins Job | Jenkins Job Definitionjenkins test dashboard cephadmJenkins Job | Jenkins Job Definitionjenkins test apiJenkins Job | Jenkins Job Definitionjenkins test docsReadTheDocs | Github Workflow Definitionjenkins test ceph-volume allJenkins Jobs | Jenkins Jobs Definitionjenkins test windowsJenkins Job | Jenkins Job Definitionjenkins test rook e2eJenkins Job | Jenkins Job Definition