Merge pull request #2624 from 2xsec/bugfix

af_unix: add function to remove duplicated codes for set sockaddr
This commit is contained in:
Christian Brauner 2018-09-20 21:55:08 +02:00 committed by GitHub
commit 7fc5ee66fe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -42,50 +42,70 @@
lxc_log_define(af_unix, lxc); lxc_log_define(af_unix, lxc);
static ssize_t lxc_abstract_unix_set_sockaddr(struct sockaddr_un *addr,
const char *path)
{
size_t len;
if (!addr || !path) {
errno = EINVAL;
return -1;
}
/* Clear address structure */
memset(addr, 0, sizeof(*addr));
addr->sun_family = AF_UNIX;
len = strlen(&path[1]);
/* do not enforce \0-termination */
if (len >= INT_MAX || len >= sizeof(addr->sun_path)) {
errno = ENAMETOOLONG;
return -1;
}
/* do not enforce \0-termination */
memcpy(&addr->sun_path[1], &path[1], len);
return len;
}
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; int fd, ret;
size_t len; ssize_t len;
struct sockaddr_un addr; struct sockaddr_un addr;
fd = socket(PF_UNIX, type, 0); fd = socket(PF_UNIX, type, 0);
if (fd < 0) if (fd < 0)
return -1; return -1;
/* Clear address structure */
memset(&addr, 0, sizeof(addr));
if (!path) if (!path)
return fd; return fd;
addr.sun_family = AF_UNIX; len = lxc_abstract_unix_set_sockaddr(&addr, path);
if (len < 0) {
len = strlen(&path[1]); int saved_errno = errno;
/* do not enforce \0-termination */
if (len >= sizeof(addr.sun_path)) {
close(fd); close(fd);
errno = ENAMETOOLONG; errno = saved_errno;
return -1; return -1;
} }
/* do not enforce \0-termination */
memcpy(&addr.sun_path[1], &path[1], len);
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_erron = errno; int saved_errno = errno;
close(fd); close(fd);
errno = saved_erron; 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_erron = errno; int saved_errno = errno;
close(fd); close(fd);
errno = saved_erron; errno = saved_errno;
return -1; return -1;
} }
} }
@ -101,28 +121,21 @@ 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; int fd, ret;
size_t len; ssize_t len;
struct sockaddr_un addr; struct sockaddr_un addr;
fd = socket(PF_UNIX, SOCK_STREAM, 0); fd = socket(PF_UNIX, SOCK_STREAM, 0);
if (fd < 0) if (fd < 0)
return -1; return -1;
memset(&addr, 0, sizeof(addr)); len = lxc_abstract_unix_set_sockaddr(&addr, path);
if (len < 0) {
addr.sun_family = AF_UNIX; int saved_errno = errno;
len = strlen(&path[1]);
/* do not enforce \0-termination */
if (len >= sizeof(addr.sun_path)) {
close(fd); close(fd);
errno = ENAMETOOLONG; errno = saved_errno;
return -1; return -1;
} }
/* do not enforce \0-termination */
memcpy(&addr.sun_path[1], &path[1], len);
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) {