[lxc-devel] [lxd/master] seccomp: cleanup + simplify
brauner on Github
lxc-bot at linuxcontainers.org
Fri Jul 12 11:18:12 UTC 2019
A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 364 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20190712/7f890651/attachment-0001.bin>
-------------- next part --------------
From e3271c734c54c54d01458bbe1d9b3eda4087cf46 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Fri, 12 Jul 2019 13:17:03 +0200
Subject: [PATCH] seccomp: cleanup + simplify
Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
lxd/seccomp.go | 158 ++++++++++++++++++++++++++-----------------------
1 file changed, 83 insertions(+), 75 deletions(-)
diff --git a/lxd/seccomp.go b/lxd/seccomp.go
index a8679cec87..0c2907208a 100644
--- a/lxd/seccomp.go
+++ b/lxd/seccomp.go
@@ -267,12 +267,10 @@ static const struct lxd_seccomp_data_arch seccomp_notify_syscall_table[] = {
#endif
};
-static int seccomp_notify_mknod_set_response(int fd_mem,
- struct seccomp_notif *req,
- struct seccomp_notif_resp *resp,
- char *buf, size_t size,
- mode_t *mode, dev_t *dev,
- pid_t *pid)
+static int seccomp_notify_verify_syscall(int fd_mem, struct seccomp_notif *req,
+ struct seccomp_notif_resp *resp,
+ char *buf, size_t size, mode_t *mode,
+ dev_t *dev, pid_t *pid)
{
int ret;
ssize_t bytes;
@@ -282,7 +280,9 @@ static int seccomp_notify_mknod_set_response(int fd_mem,
resp->val = 0;
resp->error = 0;
- for (size_t i = 0; i < (sizeof(seccomp_notify_syscall_table) / sizeof(seccomp_notify_syscall_table[0])); i++) {
+ for (size_t i = 0; i < (sizeof(seccomp_notify_syscall_table) /
+ sizeof(seccomp_notify_syscall_table[0]));
+ i++) {
const struct lxd_seccomp_data_arch *entry = &seccomp_notify_syscall_table[i];
if (entry->arch != req->data.arch)
@@ -375,12 +375,10 @@ static int seccomp_notify_get_sizes(struct seccomp_notif_sizes *sizes)
return -1;
}
-static int seccomp_notify_mknod_set_response(int fd_mem,
- struct seccomp_notif *req,
- struct seccomp_notif_resp *resp,
- char *buf, size_t size,
- mode_t *mode, dev_t *dev,
- pid_t *pid)
+static int seccomp_notify_verify_syscall(int fd_mem, struct seccomp_notif *req,
+ struct seccomp_notif_resp *resp,
+ char *buf, size_t size, mode_t *mode,
+ dev_t *dev, pid_t *pid)
{
errno = ENOSYS;
return -1;
@@ -675,8 +673,8 @@ func (siov *SeccompIovec) IsValidSeccompIovec(size uint64) bool {
return true
}
-func (siov *SeccompIovec) SendSeccompIovec(fd int, goErrno int) error {
- C.seccomp_notify_mknod_update_response(siov.resp, C.int(goErrno))
+func (siov *SeccompIovec) SendSeccompIovec(fd int, errno int) error {
+ C.seccomp_notify_mknod_update_response(siov.resp, C.int(errno))
msghdr := C.struct_msghdr{}
msghdr.msg_iov = siov.iov
@@ -759,9 +757,9 @@ func NewSeccompServer(d *Daemon, path string) (*SeccompServer, error) {
}
if siov.IsValidSeccompIovec(bytes) {
- go s.Handler(c, int(unixFile.Fd()), siov)
+ go s.Handler(int(unixFile.Fd()), siov)
} else {
- go s.InvalidHandler(c, int(unixFile.Fd()), siov)
+ go s.InvalidHandler(int(unixFile.Fd()), siov)
}
}
}()
@@ -822,18 +820,18 @@ func taskUidGid(pid int) (error, int32, int32) {
return nil, uid, gid
}
-func (s *SeccompServer) doMknod(c container, dev types.Device, requestPID int, permissionsOnly bool) int {
- goErrno := int(-C.EPERM)
+func CallForkmknod(c container, dev types.Device, requestPID int, permissionsOnly bool) int {
+ errno := int(-C.EPERM)
rootLink := fmt.Sprintf("/proc/%d/root", requestPID)
rootPath, err := os.Readlink(rootLink)
if err != nil {
- return goErrno
+ return errno
}
err, uid, gid := taskUidGid(requestPID)
if err != nil {
- return goErrno
+ return errno
}
deBool := func() int {
@@ -848,7 +846,7 @@ func (s *SeccompServer) doMknod(c container, dev types.Device, requestPID int, p
cwdLink := fmt.Sprintf("/proc/%d/cwd", requestPID)
prefixPath, err := os.Readlink(cwdLink)
if err != nil {
- return goErrno
+ return errno
}
prefixPath = strings.TrimPrefix(prefixPath, rootPath)
@@ -865,10 +863,10 @@ func (s *SeccompServer) doMknod(c container, dev types.Device, requestPID int, p
if err != nil {
tmp, err2 := strconv.Atoi(stderr)
if err2 == nil && tmp != C.ENOANO {
- goErrno = -tmp
+ errno = -tmp
}
- return goErrno
+ return errno
}
return 0
@@ -876,75 +874,85 @@ func (s *SeccompServer) doMknod(c container, dev types.Device, requestPID int, p
// InvalidHandler sends a dummy message to LXC. LXC will notice the short write
// and send a default message to the kernel thereby avoiding a 30s hang.
-func (s *SeccompServer) InvalidHandler(c net.Conn, clientFd int, siov *SeccompIovec) {
+func (s *SeccompServer) InvalidHandler(fd int, siov *SeccompIovec) {
msghdr := C.struct_msghdr{}
- C.sendmsg(C.int(clientFd), &msghdr, C.MSG_NOSIGNAL)
+ C.sendmsg(C.int(fd), &msghdr, C.MSG_NOSIGNAL)
siov.PutSeccompIovec()
}
-func (s *SeccompServer) Handler(c net.Conn, clientFd int, siov *SeccompIovec) error {
- logger.Debugf("Handling seccomp notification from: %v", siov.ucred.pid)
-
- defer siov.PutSeccompIovec()
-
+func (s *SeccompServer) HandleMknodSyscall(c container, siov *SeccompIovec) int {
var cMode C.mode_t
var cDev C.dev_t
var cPid C.pid_t
- var err error
- goErrno := 0
cPathBuf := [unix.PathMax]C.char{}
- goErrno = int(C.seccomp_notify_mknod_set_response(C.int(siov.memFd), siov.req, siov.resp,
+ errno := int(C.seccomp_notify_verify_syscall(C.int(siov.memFd),
+ siov.req,
+ siov.resp,
&cPathBuf[0],
unix.PathMax, &cMode,
&cDev, &cPid))
- if goErrno == 0 {
- dev := types.Device{}
- dev["type"] = "unix-char"
- dev["mode"] = fmt.Sprintf("%#o", cMode)
- dev["major"] = fmt.Sprintf("%d", unix.Major(uint64(cDev)))
- dev["minor"] = fmt.Sprintf("%d", unix.Minor(uint64(cDev)))
- dev["pid"] = fmt.Sprintf("%d", cPid)
- dev["path"] = C.GoString(&cPathBuf[0])
- dev["mode_t"] = fmt.Sprintf("%d", cMode)
- dev["dev_t"] = fmt.Sprintf("%d", cDev)
-
- c, _ := findContainerForPid(int32(siov.msg.monitor_pid), s.d)
- if c != nil {
- diskIdmap, err2 := c.DiskIdmap()
- if err2 != nil {
- return siov.SendSeccompIovec(clientFd, int(-C.EPERM))
- }
+ if errno != 0 {
+ return errno
+ }
- if s.d.os.Shiftfs && !c.IsPrivileged() && diskIdmap == nil {
- goErrno = s.doMknod(c, dev, int(cPid), true)
- if goErrno == int(-C.ENOMEDIUM) {
- err = c.InsertSeccompUnixDevice(fmt.Sprintf("forkmknod.unix.%d", int(cPid)), dev, int(cPid))
- if err != nil {
- goErrno = int(-C.EPERM)
- } else {
- goErrno = 0
- }
- }
- } else {
- goErrno = s.doMknod(c, dev, int(cPid), false)
- if goErrno == int(-C.ENOMEDIUM) {
- err = c.InsertSeccompUnixDevice(fmt.Sprintf("forkmknod.unix.%d", int(cPid)), dev, int(cPid))
- if err != nil {
- goErrno = int(-C.EPERM)
- } else {
- goErrno = 0
- }
- }
- }
+ diskIdmap, err := c.DiskIdmap()
+ if err != nil {
+ return int(-C.EPERM)
+ }
+
+ dev := types.Device{}
+ dev["type"] = "unix-char"
+ dev["mode"] = fmt.Sprintf("%#o", cMode)
+ dev["major"] = fmt.Sprintf("%d", unix.Major(uint64(cDev)))
+ dev["minor"] = fmt.Sprintf("%d", unix.Minor(uint64(cDev)))
+ dev["pid"] = fmt.Sprintf("%d", cPid)
+ dev["path"] = C.GoString(&cPathBuf[0])
+ dev["mode_t"] = fmt.Sprintf("%d", cMode)
+ dev["dev_t"] = fmt.Sprintf("%d", cDev)
+
+ if s.d.os.Shiftfs && !c.IsPrivileged() && diskIdmap == nil {
+ errno = CallForkmknod(c, dev, int(cPid), true)
+ if errno != int(-C.ENOMEDIUM) {
+ return errno
}
- if goErrno != 0 {
- logger.Errorf("Failed to inject device node into container %s (errno = %d)", c.Name(), -goErrno)
+ err = c.InsertSeccompUnixDevice(fmt.Sprintf("forkmknod.unix.%d", int(cPid)), dev, int(cPid))
+ if err != nil {
+ return int(-C.EPERM)
}
+
+ return 0
+ }
+
+ errno = CallForkmknod(c, dev, int(cPid), false)
+ if errno != int(-C.ENOMEDIUM) {
+ return errno
+ }
+
+ err = c.InsertSeccompUnixDevice(fmt.Sprintf("forkmknod.unix.%d", int(cPid)), dev, int(cPid))
+ if err != nil {
+ return int(-C.EPERM)
+ }
+
+ return 0
+}
+
+func (s *SeccompServer) Handler(fd int, siov *SeccompIovec) error {
+ logger.Debugf("Handling seccomp notification from: %v", siov.ucred.pid)
+
+ defer siov.PutSeccompIovec()
+
+ c, err := findContainerForPid(int32(siov.msg.monitor_pid), s.d)
+ if err != nil {
+ siov.SendSeccompIovec(fd, int(-C.EPERM))
+ return err
}
- err = siov.SendSeccompIovec(clientFd, goErrno)
+ errno := s.HandleMknodSyscall(c, siov)
+
+ err = siov.SendSeccompIovec(fd, errno)
if err != nil {
+ logger.Errorf("Failed to handle seccomp notification from: %v", siov.ucred.pid)
return err
}
More information about the lxc-devel
mailing list