permissions: preserve suid and sgid bits (#10727)
* Don't overwrite suid/sgid bits when setting permissions * add tests for permission setting
This commit is contained in:
parent
c752af098d
commit
f67a59fabc
@ -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"""
|
||||
|
35
lib/spack/spack/test/permissions.py
Normal file
35
lib/spack/spack/test/permissions.py
Normal file
@ -0,0 +1,35 @@
|
||||
# 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)
|
Loading…
Reference in New Issue
Block a user