From 4f53161737d766afeb40a5e8c21c52f89fafc5fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Thu, 16 Aug 2018 04:19:16 +0200 Subject: minstall: never follow symlinks when setting ownership Since we're supposed to call this for each installed path, we only should go through what we've installed and not what this point to, as it might be outside our scope or not existent. To do this, since shutil.chown doesn't expose the follow_symlink that os.chown has, we can temporarily replace os.chown with a lambda that acutually passes all the values as we want them, and then restore it to the built-in functions. Not the nicest way, but fixes the issue without having to reimplement what shutil does. Fixes #3914 --- mesonbuild/minstall.py | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/mesonbuild/minstall.py b/mesonbuild/minstall.py index 21c114f..ce8e34a 100644 --- a/mesonbuild/minstall.py +++ b/mesonbuild/minstall.py @@ -79,6 +79,24 @@ def append_to_log(lf, line): lf.write('\n') lf.flush() +def set_chown(path, user=None, group=None, dir_fd=None, follow_symlinks=True): + # shutil.chown will call os.chown without passing all the parameters + # and particularly follow_symlinks, thus we replace it temporary + # with a lambda with all the parameters so that follow_symlinks will + # be actually passed properly. + # Not nice, but better than actually rewriting shutil.chown until + # this python bug is fixed: https://bugs.python.org/issue18108 + real_os_chown = os.chown + try: + os.chown = lambda p, u, g: real_os_chown(p, u, g, + dir_fd=dir_fd, + follow_symlinks=follow_symlinks) + shutil.chown(path, user, group) + except: + raise + finally: + os.chown = real_os_chown + def set_chmod(path, mode, dir_fd=None, follow_symlinks=True): try: os.chmod(path, mode, dir_fd=dir_fd, follow_symlinks=follow_symlinks) @@ -105,7 +123,7 @@ def set_mode(path, mode, default_umask): # No chown() on Windows, and must set one of owner/group if not is_windows() and (mode.owner or mode.group) is not None: try: - shutil.chown(path, mode.owner, mode.group) + set_chown(path, mode.owner, mode.group, follow_symlinks=False) except PermissionError as e: msg = '{!r}: Unable to set owner {!r} and group {!r}: {}, ignoring...' print(msg.format(path, mode.owner, mode.group, e.strerror)) -- cgit v1.1