]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
af_unix: cleanup
authorChristian Brauner <christian.brauner@ubuntu.com>
Wed, 4 Mar 2020 14:21:18 +0000 (15:21 +0100)
committerChristian Brauner <christian.brauner@ubuntu.com>
Mon, 9 Mar 2020 13:24:11 +0000 (14:24 +0100)
Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
src/lxc/af_unix.c

index 7f8c88b1a2fc65fc51b92e11fef98a85be5412e9..e70e0c9e224ee35407faa780a8d187b1e9cbb70d 100644 (file)
@@ -16,6 +16,7 @@
 
 #include "config.h"
 #include "log.h"
+#include "macro.h"
 #include "memory_utils.h"
 #include "raw_syscalls.h"
 #include "utils.h"
 lxc_log_define(af_unix, lxc);
 
 static ssize_t lxc_abstract_unix_set_sockaddr(struct sockaddr_un *addr,
-                               const char *path)
+                                             const char *path)
 {
        size_t len;
 
-       if (!addr || !path) {
-               errno = EINVAL;
-               return -1;
-       }
+       if (!addr || !path)
+               return ret_errno(EINVAL);
 
        /* Clear address structure */
        memset(addr, 0, sizeof(*addr));
@@ -44,10 +43,8 @@ static ssize_t lxc_abstract_unix_set_sockaddr(struct sockaddr_un *addr,
        len = strlen(&path[1]);
 
        /* do not enforce \0-termination */
-       if (len >= INT_MAX || len >= sizeof(addr->sun_path)) {
-               errno = ENAMETOOLONG;
-               return -1;
-       }
+       if (len >= INT_MAX || len >= sizeof(addr->sun_path))
+               return ret_errno(ENAMETOOLONG);
 
        /* do not enforce \0-termination */
        memcpy(&addr->sun_path[1], &path[1], len);
@@ -56,7 +53,8 @@ static ssize_t lxc_abstract_unix_set_sockaddr(struct sockaddr_un *addr,
 
 int lxc_abstract_unix_open(const char *path, int type, int flags)
 {
-       int fd, ret;
+       __do_close_prot_errno int fd = -EBADF;
+       int ret;
        ssize_t len;
        struct sockaddr_un addr;
 
@@ -65,36 +63,24 @@ int lxc_abstract_unix_open(const char *path, int type, int flags)
                return -1;
 
        if (!path)
-               return fd;
+               return move_fd(fd);
 
        len = lxc_abstract_unix_set_sockaddr(&addr, path);
-       if (len < 0) {
-               int saved_errno = errno;
-               close(fd);
-               errno = saved_errno;
+       if (len < 0)
                return -1;
-       }
 
        ret = bind(fd, (struct sockaddr *)&addr,
                   offsetof(struct sockaddr_un, sun_path) + len + 1);
-       if (ret < 0) {
-               int saved_errno = errno;
-               close(fd);
-               errno = saved_errno;
+       if (ret < 0)
                return -1;
-       }
 
        if (type == SOCK_STREAM) {
                ret = listen(fd, 100);
-               if (ret < 0) {
-                       int saved_errno = errno;
-                       close(fd);
-                       errno = saved_errno;
+               if (ret < 0)
                        return -1;
-               }
        }
 
-       return fd;
+       return move_fd(fd);
 }
 
 void lxc_abstract_unix_close(int fd)
@@ -104,7 +90,8 @@ void lxc_abstract_unix_close(int fd)
 
 int lxc_abstract_unix_connect(const char *path)
 {
-       int fd, ret;
+       __do_close_prot_errno int fd = -EBADF;
+       int ret;
        ssize_t len;
        struct sockaddr_un addr;
 
@@ -113,23 +100,15 @@ int lxc_abstract_unix_connect(const char *path)
                return -1;
 
        len = lxc_abstract_unix_set_sockaddr(&addr, path);
-       if (len < 0) {
-               int saved_errno = errno;
-               close(fd);
-               errno = saved_errno;
+       if (len < 0)
                return -1;
-       }
 
        ret = connect(fd, (struct sockaddr *)&addr,
                      offsetof(struct sockaddr_un, sun_path) + len + 1);
-       if (ret < 0) {
-               int saved_errno = errno;
-               close(fd);
-               errno = saved_errno;
+       if (ret < 0)
                return -1;
-       }
 
-       return fd;
+       return move_fd(fd);
 }
 
 int lxc_abstract_unix_send_fds_iov(int fd, int *sendfds, int num_sendfds,
@@ -164,11 +143,9 @@ int lxc_abstract_unix_send_fds_iov(int fd, int *sendfds, int num_sendfds,
        msg.msg_iov = iov;
        msg.msg_iovlen = iovlen;
 
-again:
-       ret = sendmsg(fd, &msg, MSG_NOSIGNAL);
-       if (ret < 0)
-               if (errno == EINTR)
-                       goto again;
+       do {
+               ret = sendmsg(fd, &msg, MSG_NOSIGNAL);
+       } while (ret < 0 && errno == EINTR);
 
        return ret;
 }
@@ -181,8 +158,7 @@ int lxc_abstract_unix_send_fds(int fd, int *sendfds, int num_sendfds,
                .iov_base = data ? data : buf,
                .iov_len = data ? size : sizeof(buf),
        };
-       return lxc_abstract_unix_send_fds_iov(fd, sendfds, num_sendfds, &iov,
-                                             1);
+       return lxc_abstract_unix_send_fds_iov(fd, sendfds, num_sendfds, &iov, 1);
 }
 
 int lxc_unix_send_fds(int fd, int *sendfds, int num_sendfds, void *data,
@@ -197,17 +173,14 @@ static int lxc_abstract_unix_recv_fds_iov(int fd, int *recvfds, int num_recvfds,
        __do_free char *cmsgbuf = NULL;
        int ret;
        struct msghdr msg;
-       struct cmsghdr *cmsg = NULL;
        size_t cmsgbufsize = CMSG_SPACE(sizeof(struct ucred)) +
                             CMSG_SPACE(num_recvfds * sizeof(int));
 
        memset(&msg, 0, sizeof(msg));
 
        cmsgbuf = malloc(cmsgbufsize);
-       if (!cmsgbuf) {
-               errno = ENOMEM;
-               return -1;
-       }
+       if (!cmsgbuf)
+               return ret_errno(ENOMEM);
 
        msg.msg_control = cmsgbuf;
        msg.msg_controllen = cmsgbufsize;
@@ -215,21 +188,17 @@ static int lxc_abstract_unix_recv_fds_iov(int fd, int *recvfds, int num_recvfds,
        msg.msg_iov = iov;
        msg.msg_iovlen = iovlen;
 
-again:
-       ret = recvmsg(fd, &msg, 0);
-       if (ret < 0) {
-               if (errno == EINTR)
-                       goto again;
+       do {
+               ret = recvmsg(fd, &msg, 0);
+       } while (ret < 0 && errno == EINTR);
+       if (!ret)
+               return 0;
 
-               goto out;
-       }
-       if (ret == 0)
-               goto out;
 
        /*
         * If SO_PASSCRED is set we will always get a ucred message.
         */
-       for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
+       for (struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
                if (cmsg->cmsg_type != SCM_RIGHTS)
                        continue;
 
@@ -241,7 +210,6 @@ again:
                break;
        }
 
-out:
        return ret;
 }
 
@@ -262,7 +230,9 @@ int lxc_abstract_unix_send_credential(int fd, void *data, size_t size)
        struct iovec iov;
        struct cmsghdr *cmsg;
        struct ucred cred = {
-           .pid = lxc_raw_getpid(), .uid = getuid(), .gid = getgid(),
+               .pid = lxc_raw_getpid(),
+               .uid = getuid(),
+               .gid = getgid(),
        };
        char cmsgbuf[CMSG_SPACE(sizeof(cred))] = {0};
        char buf[1] = {0};
@@ -309,7 +279,7 @@ int lxc_abstract_unix_rcv_credential(int fd, void *data, size_t size)
 
        ret = recvmsg(fd, &msg, 0);
        if (ret <= 0)
-               goto out;
+               return ret;
 
        cmsg = CMSG_FIRSTHDR(&msg);
 
@@ -317,15 +287,13 @@ int lxc_abstract_unix_rcv_credential(int fd, void *data, size_t size)
            cmsg->cmsg_level == SOL_SOCKET &&
            cmsg->cmsg_type == SCM_CREDENTIALS) {
                memcpy(&cred, CMSG_DATA(cmsg), sizeof(cred));
-               if (cred.uid &&
-                   (cred.uid != getuid() || cred.gid != getgid())) {
-                       INFO("Message denied for '%d/%d'", cred.uid, cred.gid);
-                       errno = EACCES;
-                       return -1;
-               }
+
+               if (cred.uid && (cred.uid != getuid() || cred.gid != getgid()))
+                       return log_error_errno(-1, EACCES,
+                                              "Message denied for '%d/%d'",
+                                              cred.uid, cred.gid);
        }
 
-out:
        return ret;
 }
 
@@ -364,10 +332,9 @@ int lxc_unix_connect_type(struct sockaddr_un *addr, int type)
        ssize_t len;
 
        fd = socket(AF_UNIX, type | SOCK_CLOEXEC, 0);
-       if (fd < 0) {
-               SYSERROR("Failed to open new AF_UNIX socket");
-               return -1;
-       }
+       if (fd < 0)
+               return log_error_errno(-1, errno,
+                                      "Failed to open new AF_UNIX socket");
 
        if (addr->sun_path[0] == '\0')
                len = strlen(&addr->sun_path[1]);
@@ -376,10 +343,9 @@ int lxc_unix_connect_type(struct sockaddr_un *addr, int type)
 
        ret = connect(fd, (struct sockaddr *)addr,
                      offsetof(struct sockaddr_un, sun_path) + len);
-       if (ret < 0) {
-               SYSERROR("Failed to bind new AF_UNIX socket");
-               return -1;
-       }
+       if (ret < 0)
+               return log_error_errno(-1, errno,
+                                      "Failed to bind new AF_UNIX socket");
 
        return move_fd(fd);
 }