-
Notifications
You must be signed in to change notification settings - Fork 3.1k
Fix #725 and #729. /tmp/pip-build issues #734
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
Conversation
fd = os.open(path, os.O_RDONLY) | ||
stat = os.fstat(fd) | ||
if os.getuid() != stat.st_uid: | ||
print ("The temporary folder for building (%s) " % path + |
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.
Maybe use logger.fatal
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.
logger isn't used in that module at all at present. Also there is already a case where sys.exit() is called in the file.
… error message if the fd could not be opened (denied). Signed-off-by: David <[email protected]>
woops, sorry, clicked the wrong button : ) |
@qwcode ha! so does that mean you meant to press merge ;) ? |
path = os.path.join(tempfile.gettempdir(), 'pip-build-%s' % \ | ||
getpass.getuser()) | ||
if sys.platform == 'win32': | ||
return path |
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.
help me out, why the quick return for windows?
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.
os.getuid() and other calls used later in the function do not work on windows.
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.
windows temp dirs are user isolated/protected anyway, atleast on some versions of windows.
on windows 7, you get something like this:
tempfile.gettempfir()
c:\users\me\appdata\local\temp
how about a comment mentioning that.
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.
Okay. I don't use windows so I had no idea.
as for tests, unit tests of |
@qwcode if you point me where I should add a test for _get_build_prefix I will write one. As an aside I am not that familiar with the pip code base. I intend to help out with a few security related issues that are present in pip. |
@qwcode also is there an existing appropriate exception I could raise instead of doing sys.exit(1) ? |
you could create a new tests/test_locations.py for your tests. our exceptions are in pip.exceptions. the closest one for this is "InstallationError" I guess, although it could occur on any pip command at import, but the code that's running relates to installation prep. |
…s.exit()'ing and also document that on windows user temp directories are already isolated. Signed-off-by: David <[email protected]>
@qwcode I might get around to writing tests one day. For now I do not think one is required. If you think one is - you write it :-) |
this code is being added to prevent a certain security flaw. |
@guettli, since you opened the issue this relates to, just curious if you have any comments on this fix. |
@qwcode, your does not work if /tmp/pip-build-username is a symbolic link. I changed the code to this:
Look at this example. User "evil" is bad and he wants to modify some files of tguettler, if tguettler uses pip:
That's why you need to use lstat(). |
@guettli the change you have suggest using os.lstat(path) is incorrect - as it would be vulnerable to a time of check vs time of use vulnerability. However, you are correct that I am checking the target and not the link's uid, as I forgot to include the os.O_NOFOLLOW flag in the os.open() call. |
… directory is in fact owned by another user - add the os.O_NOFOLLOW flag to not follow symbolic links. Signed-off-by: David <[email protected]>
@d1b I am not a security expert. Can you please explain why your solution is not vulnerable to a time of check vs time of use vulnerability? |
@guettli I have updated the code so that the os.open() call includes the os.O_NOFOLLOW flag. Responding to to your latest question regarding why this code is not vulnerable to a time of check vs time of use vulnerability: Using file descriptors returned by the operating system is a safe way to check the property of a file. Specifying and checking against a path in general not a safe approach as there could be a 'race' between the path check(with lstat) and later using the checked path. |
@d1b thank you for your explanation. But I think that the current pull request has the same problem like os.lstat(): there could be a 'race' between the path check(with os.open(...)) and later using the checked path. But I don't care about this race condition. The initial bug I found can be closed. |
@guettli there is no such race - unless a daemon or user rm's their temporary build directory :-) |
The current changes look good. What can I do to get this into the main line? |
|
Is it possible to create a file with a different user-id in the unittest? On linux you need root access to change the user-id of a file. I guess that's not possible, but maybe I am wrong. You are right: it is not good to create the build_prefix during import time. But this was done before (at least the file name was created at import time). If creating the build_prefix should be refactored, then it can be done in a different pull request. |
we'd use the "mock" library to mock the fstat and getuid calls, i.e. we wouldn't actually need files owned by other users. we have a few pip tests using mock you can certainly open another pull requests that resuses his commits up to this point, and then add to them. |
another case for our shutil.rmtree onerror function
@qwcode do you want me to rebase on this branch ? |
it's not auto-mergable right now thru github, so the pt of you rebasing on the latest "develop" is to resolve whatever the conflict is. |
windows test fixes
@d1b you should just go ahead and make it mergeble. Start by pulling develop and fixing any conflicts locally then repush to github. |
@pnasrat Sure I'll update it now, but if it becomes un-mergable before it is merged I'll wait until it is about to be merged to fix it again. |
… error message if the fd could not be opened (denied). Signed-off-by: David <[email protected]>
…s.exit()'ing and also document that on windows user temp directories are already isolated. Signed-off-by: David <[email protected]>
… directory is in fact owned by another user - add the os.O_NOFOLLOW flag to not follow symbolic links. Signed-off-by: David <[email protected]>
… use of the_get_build_prefix method to create a user specific build_prefix directory. Signed-off-by: David <[email protected]>
Signed-off-by: David <[email protected]>
…_pip_build_directory Conflicts: pip/locations.py Signed-off-by: David <[email protected]>
If you do this I or Marcus will merge
|
@pnasrat I have re-based the code against develop :-) |
I wasn't looking to merge until after cutting a 1.3 branch and beta (which is soon.) |
This is a security fix, which I feel probably should go in to 1.3, but you're doing most of the work on the release so I'll defer to your judgement. |
ok, I hear you, will look at the new tests later tonight . |
ok, the 2 tests make sense to me. a few thoughts that I won't hold up the merge for (but may fix later):
|
tests fail on windows. http://jenkins.qwcode.com/job/pip_win_33/10/console |
the message from github here is a little misleading. |
sure, np. thanks for being persistent and working on the tests. |
#725: /tmp/pip-build not secure
#729: /tmp/pip-build can't be shared by several linux users
Signed-off-by: David [email protected]