aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian Behlendorf <[email protected]>2020-07-19 09:56:21 -0700
committerGitHub <[email protected]>2020-07-19 09:56:21 -0700
commite862b7ecfc6049df19cf0d439510f385a7707b8b (patch)
tree0522c698a48c711d37e3a1c0e7bbbb222f9e7c53
parent8fbf432ae274fc227c38012230c3bf23bda64d64 (diff)
Linux 4.10 compat: has_capability()
Stock kernels older than 4.10 do not export the has_capability() function which is required by commit e59a377. To avoid breaking the build on older kernels revert to the safe legacy behavior and return EACCES when privileges cannot be checked. Reviewed-by: Ryan Moeller <[email protected]> Reviewed-by: Matt Ahrens <[email protected]> Signed-off-by: Brian Behlendorf <[email protected]> Closes #10565 Closes #10573
-rw-r--r--config/kernel-userns-capabilities.m429
-rw-r--r--module/os/linux/zfs/policy.c9
-rwxr-xr-xtests/test-runner/bin/zts-report.py.in2
-rwxr-xr-xtests/zfs-tests/tests/functional/limits/filesystem_limit.ksh12
-rwxr-xr-xtests/zfs-tests/tests/functional/limits/snapshot_limit.ksh12
5 files changed, 64 insertions, 0 deletions
diff --git a/config/kernel-userns-capabilities.m4 b/config/kernel-userns-capabilities.m4
index 68a7bd62c..026503623 100644
--- a/config/kernel-userns-capabilities.m4
+++ b/config/kernel-userns-capabilities.m4
@@ -20,6 +20,33 @@ AC_DEFUN([ZFS_AC_KERNEL_NS_CAPABLE], [
])
dnl #
+dnl # 4.10 API change
+dnl # has_capability() was exported.
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_SRC_HAS_CAPABILITY], [
+ ZFS_LINUX_TEST_SRC([has_capability], [
+ #include <linux/capability.h>
+ ],[
+ struct task_struct *task = NULL;
+ int cap = 0;
+ bool result __attribute__ ((unused));
+
+ result = has_capability(task, cap);
+ ])
+])
+
+AC_DEFUN([ZFS_AC_KERNEL_HAS_CAPABILITY], [
+ AC_MSG_CHECKING([whether has_capability() is available])
+ ZFS_LINUX_TEST_RESULT_SYMBOL([has_capability],
+ [has_capability], [kernel/capability.c], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_HAS_CAPABILITY, 1, [has_capability() is available])
+ ],[
+ AC_MSG_RESULT(no)
+ ])
+])
+
+dnl #
dnl # 2.6.39 API change
dnl # struct user_namespace was added to struct cred_t as cred->user_ns member
dnl #
@@ -66,12 +93,14 @@ AC_DEFUN([ZFS_AC_KERNEL_KUID_HAS_MAPPING], [
AC_DEFUN([ZFS_AC_KERNEL_SRC_USERNS_CAPABILITIES], [
ZFS_AC_KERNEL_SRC_NS_CAPABLE
+ ZFS_AC_KERNEL_SRC_HAS_CAPABILITY
ZFS_AC_KERNEL_SRC_CRED_USER_NS
ZFS_AC_KERNEL_SRC_KUID_HAS_MAPPING
])
AC_DEFUN([ZFS_AC_KERNEL_USERNS_CAPABILITIES], [
ZFS_AC_KERNEL_NS_CAPABLE
+ ZFS_AC_KERNEL_HAS_CAPABILITY
ZFS_AC_KERNEL_CRED_USER_NS
ZFS_AC_KERNEL_KUID_HAS_MAPPING
])
diff --git a/module/os/linux/zfs/policy.c b/module/os/linux/zfs/policy.c
index eaa5372f2..5267d67ee 100644
--- a/module/os/linux/zfs/policy.c
+++ b/module/os/linux/zfs/policy.c
@@ -249,13 +249,22 @@ secpolicy_zfs(const cred_t *cr)
* Equivalent to secpolicy_zfs(), but works even if the cred_t is not that of
* the current process. Takes both cred_t and proc_t so that this can work
* easily on all platforms.
+ *
+ * The has_capability() function was first exported in the 4.10 Linux kernel
+ * then backported to some LTS kernels. Prior to this change there was no
+ * mechanism to perform this check therefore EACCES is returned when the
+ * functionality is not present in the kernel.
*/
int
secpolicy_zfs_proc(const cred_t *cr, proc_t *proc)
{
+#if defined(HAVE_HAS_CAPABILITY)
if (!has_capability(proc, CAP_SYS_ADMIN))
return (EACCES);
return (0);
+#else
+ return (EACCES);
+#endif
}
void
diff --git a/tests/test-runner/bin/zts-report.py.in b/tests/test-runner/bin/zts-report.py.in
index a2d81ceda..51e6e52db 100755
--- a/tests/test-runner/bin/zts-report.py.in
+++ b/tests/test-runner/bin/zts-report.py.in
@@ -263,6 +263,8 @@ elif sys.platform.startswith('linux'):
'cli_root/zpool_expand/zpool_expand_001_pos': ['FAIL', known_reason],
'cli_root/zpool_expand/zpool_expand_005_pos': ['FAIL', known_reason],
'cli_root/zpool_reopen/zpool_reopen_003_pos': ['FAIL', known_reason],
+ 'limits/filesystem_limit': ['SKIP', known_reason],
+ 'limits/snapshot_limit': ['SKIP', known_reason],
'refreserv/refreserv_raidz': ['FAIL', known_reason],
'rsend/rsend_007_pos': ['FAIL', known_reason],
'rsend/rsend_010_pos': ['FAIL', known_reason],
diff --git a/tests/zfs-tests/tests/functional/limits/filesystem_limit.ksh b/tests/zfs-tests/tests/functional/limits/filesystem_limit.ksh
index cd1e054bf..fbfc141be 100755
--- a/tests/zfs-tests/tests/functional/limits/filesystem_limit.ksh
+++ b/tests/zfs-tests/tests/functional/limits/filesystem_limit.ksh
@@ -30,6 +30,18 @@
verify_runnable "both"
+#
+# The has_capability() function was first exported in the 4.10 Linux kernel
+# then backported to some LTS kernels. Prior to this change there was no
+# mechanism to perform the needed permission check. Therefore, this test
+# is expected to fail on older kernels and is skipped.
+#
+if is_linux; then
+ if [[ $(linux_version) -lt $(linux_version "4.10") ]]; then
+ log_unsupported "Requires has_capability() kernel function"
+ fi
+fi
+
function setup
{
# We can't delegate 'mount' privs under Linux: to avoid issues with
diff --git a/tests/zfs-tests/tests/functional/limits/snapshot_limit.ksh b/tests/zfs-tests/tests/functional/limits/snapshot_limit.ksh
index 860a0da92..62f14466e 100755
--- a/tests/zfs-tests/tests/functional/limits/snapshot_limit.ksh
+++ b/tests/zfs-tests/tests/functional/limits/snapshot_limit.ksh
@@ -31,6 +31,18 @@
verify_runnable "both"
+#
+# The has_capability() function was first exported in the 4.10 Linux kernel
+# then backported to some LTS kernels. Prior to this change there was no
+# mechanism to perform the needed permission check. Therefore, this test
+# is expected to fail on older kernels and is skipped.
+#
+if is_linux; then
+ if [[ $(linux_version) -lt $(linux_version "4.10") ]]; then
+ log_unsupported "Requires has_capability() kernel function"
+ fi
+fi
+
function setup
{
# We can't delegate 'mount' privs under Linux: to avoid issues with