[lxc-devel] [lxd/master] shared/idmap: test fcaps support
stgraber on Github
lxc-bot at linuxcontainers.org
Fri Aug 17 18:10:56 UTC 2018
A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 419 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20180817/f600854f/attachment.bin>
-------------- next part --------------
From 0505a8b5078b2e1ee276a37995ba8397d79ae46c Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Fri, 17 Aug 2018 17:03:23 +0200
Subject: [PATCH] shared/idmap: test fcaps support
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
shared/idmap/idmapset_linux.go | 17 +++++++++--
shared/idmap/shift_linux.go | 53 ++++++++++++++++++++++++++++++++++
2 files changed, 67 insertions(+), 3 deletions(-)
diff --git a/shared/idmap/idmapset_linux.go b/shared/idmap/idmapset_linux.go
index ea3779384..d6e7bdf49 100644
--- a/shared/idmap/idmapset_linux.go
+++ b/shared/idmap/idmapset_linux.go
@@ -469,6 +469,14 @@ func (m IdmapSet) ShiftFromNs(uid int64, gid int64) (int64, int64) {
}
func (set *IdmapSet) doUidshiftIntoContainer(dir string, testmode bool, how string, skipper func(dir string, absPath string, fi os.FileInfo) bool) error {
+ v3Caps := true
+ if how == "in" {
+ if !supportsV3Fcaps(dir) {
+ logger.Debugf("System doesn't support unprivileged file capabilities")
+ v3Caps = false
+ }
+ }
+
// Expand any symlink before the final path component
tmp := filepath.Dir(dir)
tmp, err := filepath.EvalSymlinks(tmp)
@@ -546,9 +554,12 @@ func (set *IdmapSet) doUidshiftIntoContainer(dir string, testmode bool, how stri
if how == "in" {
rootUid, _ = set.ShiftIntoNs(0, 0)
}
- err = SetCaps(path, caps, rootUid)
- if err != nil {
- logger.Warnf("Unable to set file capabilities on %s", path)
+
+ if how != "in" || v3Caps {
+ err = SetCaps(path, caps, rootUid)
+ if err != nil {
+ logger.Warnf("Unable to set file capabilities on %s", path)
+ }
}
}
}
diff --git a/shared/idmap/shift_linux.go b/shared/idmap/shift_linux.go
index 920789a4c..9045fe395 100644
--- a/shared/idmap/shift_linux.go
+++ b/shared/idmap/shift_linux.go
@@ -5,6 +5,10 @@ package idmap
import (
"fmt"
+ "io/ioutil"
+ "os"
+ "os/exec"
+ "syscall"
"unsafe"
"github.com/lxc/lxd/shared"
@@ -70,6 +74,20 @@ int set_vfs_ns_caps(char *path, char *caps, ssize_t len, uint32_t uid)
return setxattr(path, "security.capability", &ns_xattr, sizeof(ns_xattr), 0);
}
+int set_dummy_fs_ns_caps(const char *path)
+{
+ #define __raise_cap_permitted(x, ns_cap_data) ns_cap_data.data[(x)>>5].permitted |= (1<<((x)&31))
+
+ struct vfs_ns_cap_data ns_xattr;
+
+ memset(&ns_xattr, 0, sizeof(ns_xattr));
+ __raise_cap_permitted(CAP_NET_RAW, ns_xattr);
+ ns_xattr.magic_etc |= VFS_CAP_REVISION_3 | VFS_CAP_FLAGS_EFFECTIVE;
+ ns_xattr.rootid = BE32_TO_LE32(1000000);
+
+ return setxattr(path, "security.capability", &ns_xattr, sizeof(ns_xattr), 0);
+}
+
int shiftowner(char *basepath, char *path, int uid, int gid)
{
int fd, ret;
@@ -279,3 +297,38 @@ func shiftAclType(path string, aclType _Ctype_acl_type_t, shiftIds func(uid int6
return nil
}
+
+func supportsV3Fcaps(prefix string) bool {
+ tmpfile, err := ioutil.TempFile(prefix, ".lxd_fcaps_v3_")
+ if err != nil {
+ return false
+ }
+ tmpfile.Close()
+ defer os.Remove(tmpfile.Name())
+
+ err = os.Chmod(tmpfile.Name(), 0001)
+ if err != nil {
+ return false
+ }
+
+ cpath := C.CString(tmpfile.Name())
+ defer C.free(unsafe.Pointer(cpath))
+
+ r := C.set_dummy_fs_ns_caps(cpath)
+ if r != 0 {
+ return false
+ }
+
+ cmd := exec.Command(tmpfile.Name())
+ err = cmd.Run()
+ if err != nil {
+ errno, isErrno := shared.GetErrno(err)
+ if isErrno && (errno == syscall.ERANGE || errno == syscall.EOVERFLOW) {
+ return false
+ }
+
+ return true
+ }
+
+ return true
+}
More information about the lxc-devel
mailing list