-
-
Notifications
You must be signed in to change notification settings - Fork 33.7k
bpo-31940: Reject faulty lchmod implementations #4783
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
bpo-31940: Reject faulty lchmod implementations #4783
Conversation
|
@asottile nice, can't understand how there's a coredump in the test_shutil.py (under clang). |
85ba86a to
d16cd68
Compare
|
@fruch woops, forgot an |
d16cd68 to
5ed4b99
Compare
|
Please don't merge this yet, it depends on changes made in #4797 |
a735a41 to
130279d
Compare
|
I've rebased this now that #4797 is merged, should be ready for review again |
Modules/posixmodule.c
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, there are two different error codes? Which one is raised on muslc?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
muslc raises EOPNOTSUPP (errno 95) though on my platform they were #defined to the same thing. I simply picked the same errnos as fchmodat catches below -- I suspect implementations use fchmodat to implement lchown (or the other way around).
86425d2 to
d64773b
Compare
d64773b to
2e57192
Compare
|
@vstinner would love another review :) no rush though! |
|
@vstinner friendly ping :) |
|
Looking through devguide -- maybe @giampaolo can review the |
upstream issue: https://bugs.python.org/issue31940 There are two PR's proposed to fix this, but both seem to be stalling waiting for review. I previously used what appears to be the favored of the two approaches[1] to fix this, with plan of keeping it musl-only until PR was merged. However, while writing up a commit message explaining the problem and why it needed fixing... I investigated a bit and found it increasingly hard to justify anything other than ... simply not using lchmod. Here's what I found: * lchmod is non-POSIX, seems BSD-only these days * Functionality of lchmod isn't supported on Linux * best scenario on Linux would be an error * POSIX does provide lchmod-esque functionality with fchmodat(), which AFAICT is generally preferred. * Python intentionally overlooks fchmodat()[2] electing instead to use lchmod() behavior as a proxy for whether fchmodat() "works". I'm not sure I follow their reasoning... * both glibc and musl provide lchmod impls: * glibc returns ENOSYS "not implemented" * musl implements lchmod with fchmodat(), and so returns EOPNOTSUPP "op not supported" * Python doesn't expect EOPNOTSUPP from lchmod, since it's not valid on BSD's lchmod. * "configure" doesn't actually check lchmod usefully, instead checks for glibc preprocessor defines to indicate if the function is just a stub[3]; somewhat fittingly, if the magic macros are defined then the next line of the C source is "choke me", causing the compiler to trip, fall, and point a finger at whatever is near where it ends up. (somewhat amusing, but AFAIK effective way to get an error :P) I'm leaving out links to threads on mailing lists and such, but for now I hope I've convinced you (or to those reading commit history: explained my reasons) that this is a bit of a mess[4]. And so instead of making a big mess messier, and with hopes of never thinking about this again, I propose we simply tell Python "don't use lchmod" on Linux. [1] python/cpython#4783 [2] https://github.com/python/cpython/blob/28453feaa8d88bbcbf6d834b1d5ca396d17265f2/Lib/os.py#L144 [3] https://github.com/python/cpython/blob/28453feaa8d88bbcbf6d834b1d5ca396d17265f2/configure#L2198 [4] Messes happen, no good intention goes unpunished :).
upstream issue: https://bugs.python.org/issue31940 There are two PR's proposed to fix this, but both seem to be stalling waiting for review. I previously used what appears to be the favored of the two approaches[1] to fix this, with plan of keeping it musl-only until PR was merged. However, while writing up a commit message explaining the problem and why it needed fixing... I investigated a bit and found it increasingly hard to justify anything other than ... simply not using lchmod. Here's what I found: * lchmod is non-POSIX, seems BSD-only these days * Functionality of lchmod isn't supported on Linux * best scenario on Linux would be an error * POSIX does provide lchmod-esque functionality with fchmodat(), which AFAICT is generally preferred. * Python intentionally overlooks fchmodat()[2] electing instead to use lchmod() behavior as a proxy for whether fchmodat() "works". I'm not sure I follow their reasoning... * both glibc and musl provide lchmod impls: * glibc returns ENOSYS "not implemented" * musl implements lchmod with fchmodat(), and so returns EOPNOTSUPP "op not supported" * Python doesn't expect EOPNOTSUPP from lchmod, since it's not valid on BSD's lchmod. * "configure" doesn't actually check lchmod usefully, instead checks for glibc preprocessor defines to indicate if the function is just a stub[3]; somewhat fittingly, if the magic macros are defined then the next line of the C source is "choke me", causing the compiler to trip, fall, and point a finger at whatever is near where it ends up. (somewhat amusing, but AFAIK effective way to get an error :P) I'm leaving out links to threads on mailing lists and such, but for now I hope I've convinced you (or to those reading commit history: explained my reasons) that this is a bit of a mess[4]. And so instead of making a big mess messier, and with hopes of never thinking about this again, I propose we simply tell Python "don't use lchmod" on Linux. [1] python/cpython#4783 [2] https://github.com/python/cpython/blob/28453feaa8d88bbcbf6d834b1d5ca396d17265f2/Lib/os.py#L144 [3] https://github.com/python/cpython/blob/28453feaa8d88bbcbf6d834b1d5ca396d17265f2/configure#L2198 [4] Messes happen, no good intention goes unpunished :).
upstream issue: https://bugs.python.org/issue31940 There are two PR's proposed to fix this, but both seem to be stalling waiting for review. I previously used what appears to be the favored of the two approaches[1] to fix this, with plan of keeping it musl-only until PR was merged. However, while writing up a commit message explaining the problem and why it needed fixing... I investigated a bit and found it increasingly hard to justify anything other than ... simply not using lchmod. Here's what I found: * lchmod is non-POSIX, seems BSD-only these days * Functionality of lchmod isn't supported on Linux * best scenario on Linux would be an error * POSIX does provide lchmod-esque functionality with fchmodat(), which AFAICT is generally preferred. * Python intentionally overlooks fchmodat()[2] electing instead to use lchmod() behavior as a proxy for whether fchmodat() "works". I'm not sure I follow their reasoning... * both glibc and musl provide lchmod impls: * glibc returns ENOSYS "not implemented" * musl implements lchmod with fchmodat(), and so returns EOPNOTSUPP "op not supported" * Python doesn't expect EOPNOTSUPP from lchmod, since it's not valid on BSD's lchmod. * "configure" doesn't actually check lchmod usefully, instead checks for glibc preprocessor defines to indicate if the function is just a stub[3]; somewhat fittingly, if the magic macros are defined then the next line of the C source is "choke me", causing the compiler to trip, fall, and point a finger at whatever is near where it ends up. (somewhat amusing, but AFAIK effective way to get an error :P) I'm leaving out links to threads on mailing lists and such, but for now I hope I've convinced you (or to those reading commit history: explained my reasons) that this is a bit of a mess[4]. And so instead of making a big mess messier, and with hopes of never thinking about this again, I propose we simply tell Python "don't use lchmod" on Linux. [1] python/cpython#4783 [2] https://github.com/python/cpython/blob/28453feaa8d88bbcbf6d834b1d5ca396d17265f2/Lib/os.py#L144 [3] https://github.com/python/cpython/blob/28453feaa8d88bbcbf6d834b1d5ca396d17265f2/configure#L2198 [4] Messes happen, no good intention goes unpunished :).
| if not support.can_symlink() or not hasattr(os, 'lchmod'): | ||
| return False | ||
|
|
||
| fname = tempfile.mktemp() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be mkstemp? mktemp seems to be deprecated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was copied from adjacent test (in the original PR). It's not exactly that mktemp is deprecated, it's that it's insecure. However in this case, the same security problem would exist since it's essentially:
mkstemp- unlink the file made by
mkstemp - symlink to the location made by
mkstemp
There's a race between 2 and 3 where something could create a file
Fortunately it doesn't really matter since it's just a test.
2e57192 to
46ea965
Compare
|
Almost this branch's birthday -- rebased to resolve conflicts |
|
@asottile anything I could do to help ? |
|
@fruch iirc an approving review (even from an outsider) will move the state from [awaiting review] to [awaiting core review] which might (???) gather more attention from core devs |
TheKevJames
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changeset LGTM, but I have not worked with this chunk of the cpython codebase before. Would be great to get a core contributor review as well!
|
Dunno if this can help but i encountered the issue (https://bugs.python.org/issue31940) with a python-3.6 tox environment within an alpine image Since tox on a python2 environment works well on Edit :
|
46ea965 to
3460a76
Compare
|
@jdubost looks like alpine is working around this bug by manually turning off HAVE_LCHMOD: It looks like @benjaminp forced this to off on all linuxes in 40caa05 which looks eerily similar to my rejected patch in #4267 😭 |
|
Hmm, I didn't see any of this. I don't understand the objection to a compile-time check. Whether you're targeting Linux or not is something you must know at compile time. It would be one thing if an operating system existed that sometimes returned |
|
unclear as well. I guess since this is solved I can close this and we can resolve the linked issue. I think some of the changes in the patch are useful so I'll make a separate bpo and propose them (notably, |
This is a runtime attempt at implementing #4267
A few notes:
lchmodattempts, however I don't think this is doable:lchmodis used for both symlinks and not symlinks iffollow_symlinks=False-- it works fine for normal filesfchmodatadjacent to thelchmodcode serves as precedent for both of these decisionshttps://bugs.python.org/issue31940