Skip to content
Snippets Groups Projects
Commit f67a59fa authored by Greg Becker's avatar Greg Becker Committed by Todd Gamblin
Browse files

permissions: preserve suid and sgid bits (#10727)

* Don't overwrite suid/sgid bits when setting permissions
* add tests for permission setting
parent c752af09
No related branches found
No related tags found
No related merge requests found
......@@ -4,11 +4,13 @@
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
import os
import stat
from llnl.util.filesystem import chmod_x, chgrp
from spack.package_prefs import get_package_permissions, get_package_group
from spack.package_prefs import get_package_dir_permissions
from spack.error import SpackError
def forall_files(path, fn, args, dir_args=None):
......@@ -31,6 +33,11 @@ def forall_files(path, fn, args, dir_args=None):
def chmod_real_entries(path, perms):
# Don't follow links so we don't change things outside the prefix
if not os.path.islink(path):
mode = os.stat(path).st_mode
perms |= mode & (stat.S_ISUID | stat.S_ISGID | stat.S_ISVTX)
if perms & stat.S_ISUID and perms & stat.S_IWGRP:
raise InvalidPermissionsError(
'Attempting to set suid with world writable')
chmod_x(path, perms)
......@@ -44,3 +51,7 @@ def post_install(spec):
if group:
forall_files(spec.prefix, chgrp, [group])
class InvalidPermissionsError(SpackError):
"""Error class for invalid permission setters"""
# Copyright 2013-2019 Lawrence Livermore National Security, LLC and other
# Spack Project Developers. See the top-level COPYRIGHT file for details.
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
import os
import pytest
import stat
from spack.hooks.permissions_setters import (
chmod_real_entries, InvalidPermissionsError
)
import llnl.util.filesystem as fs
def test_chmod_real_entries_ignores_suid_sgid(tmpdir):
path = str(tmpdir.join('file').ensure())
mode = stat.S_ISUID | stat.S_ISGID | stat.S_ISVTX
os.chmod(path, mode)
mode = os.stat(path).st_mode # adds a high bit we aren't concerned with
perms = stat.S_IRWXU
chmod_real_entries(path, perms)
assert os.stat(path).st_mode == mode | perms & ~stat.S_IXUSR
def test_chmod_rejects_group_writable_suid(tmpdir):
path = str(tmpdir.join('file').ensure())
mode = stat.S_ISUID | stat.S_ISGID | stat.S_ISVTX
fs.chmod_x(path, mode)
perms = stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO
with pytest.raises(InvalidPermissionsError):
chmod_real_entries(path, perms)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment