[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Bug-tar] [PATCH] Check for CAP_CHOWN on Linux before defaulting to --sa
From: |
Jürg Billeter |
Subject: |
[Bug-tar] [PATCH] Check for CAP_CHOWN on Linux before defaulting to --same-owner -p |
Date: |
Thu, 15 Feb 2018 13:24:17 +0100 |
tar defaults to --same-owner --same-permissions if the effective UID is
ROOT_UID. On Linux, tar may be running as root with limited privileges,
e.g., in a sandbox where arbitrary chown(2) is not allowed and thus
--same-owner will fail. This adds a check for CAP_CHOWN. If tar is
running as root without that capability, it will behave the same as when
running as non-root user.
---
configure.ac | 3 +++
src/common.h | 1 +
src/extract.c | 3 +--
src/system.c | 21 +++++++++++++++++++++
4 files changed, 26 insertions(+), 2 deletions(-)
diff --git a/configure.ac b/configure.ac
index 0bddbeb..b46c722 100644
--- a/configure.ac
+++ b/configure.ac
@@ -49,6 +49,9 @@ AC_CHECK_HEADERS([sys/buf.h], [], [],
#include <sys/param.h>
#endif])
+AC_CHECK_HEADERS([linux/capability.h], [], [],
+[#include <sys/capability.h>])
+
AC_HEADER_MAJOR
AC_MSG_CHECKING([for st_fstype string in struct stat])
diff --git a/src/common.h b/src/common.h
index bbe167e..125e4e9 100644
--- a/src/common.h
+++ b/src/common.h
@@ -868,6 +868,7 @@ int sys_exec_info_script (const char **archive_name, int
volume_number);
void sys_exec_checkpoint_script (const char *script_name,
const char *archive_name,
int checkpoint_number);
+bool sys_chown_capable_root (void);
/* Module compare.c */
void report_difference (struct tar_stat_info *st, const char *message, ...)
diff --git a/src/extract.c b/src/extract.c
index 395db55..f808007 100644
--- a/src/extract.c
+++ b/src/extract.c
@@ -24,7 +24,6 @@
#include <quotearg.h>
#include <errno.h>
#include <priv-set.h>
-#include <root-uid.h>
#include <utimens.h>
#include "common.h"
@@ -175,7 +174,7 @@ struct string_list
void
extr_init (void)
{
- we_are_root = geteuid () == ROOT_UID;
+ we_are_root = sys_chown_capable_root ();
same_permissions_option += we_are_root;
same_owner_option += we_are_root;
diff --git a/src/system.c b/src/system.c
index b4f6985..4f0510a 100644
--- a/src/system.c
+++ b/src/system.c
@@ -21,9 +21,14 @@
#include "common.h"
#include <priv-set.h>
#include <rmt.h>
+#include <root-uid.h>
#include <signal.h>
#include <wordsplit.h>
+#ifdef HAVE_LINUX_CAPABILITY_H
+#include <sys/capability.h>
+#endif
+
static _Noreturn void
xexec (const char *cmd)
{
@@ -898,3 +903,19 @@ sys_exec_checkpoint_script (const char *script_name,
}
#endif /* not MSDOS */
+
+bool sys_chown_capable_root (void)
+{
+#ifdef HAVE_LINUX_CAPABILITY_H
+ struct __user_cap_header_struct hdr = { _LINUX_CAPABILITY_VERSION_3, 0 };
+ struct __user_cap_data_struct data[2] = { { 0 } };
+
+ if (capget (&hdr, data) == 0)
+ {
+ if ((data[0].effective & (1 << CAP_CHOWN)) == 0)
+ return false;
+ }
+#endif
+
+ return geteuid () == ROOT_UID;
+}
--
2.16.1
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Bug-tar] [PATCH] Check for CAP_CHOWN on Linux before defaulting to --same-owner -p,
Jürg Billeter <=