[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