af_unix: cleanup

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