Merge pull request #2691 from 2xsec/bugfix

Some redundancy codes of abstract unix socket are removed with log cleanups.
This commit is contained in:
Christian Brauner 2018-10-12 10:39:57 +02:00 committed by GitHub
commit a22d1745d7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 56 additions and 54 deletions

View File

@ -1244,24 +1244,17 @@ out_close:
int lxc_cmd_init(const char *name, const char *lxcpath, const char *suffix) int lxc_cmd_init(const char *name, const char *lxcpath, const char *suffix)
{ {
int fd, len, ret; int fd, ret;
char path[LXC_AUDS_ADDR_LEN] = {0}; char path[LXC_AUDS_ADDR_LEN] = {0};
char *offset = &path[1];
/* -2 here because this is an abstract unix socket so it needs a ret = lxc_make_abstract_socket_name(path, sizeof(path), name, lxcpath, NULL, suffix);
* leading \0, and we null terminate, so it needs a trailing \0.
* Although null termination isn't required by the API, we do it anyway
* because we print the sockname out sometimes.
*/
len = sizeof(path) - 2;
ret = lxc_make_abstract_socket_name(offset, len, name, lxcpath, NULL, suffix);
if (ret < 0) if (ret < 0)
return -1; return -1;
TRACE("Creating abstract unix socket \"%s\"", offset); TRACE("Creating abstract unix socket \"%s\"", &path[1]);
fd = lxc_abstract_unix_open(path, SOCK_STREAM, 0); fd = lxc_abstract_unix_open(path, SOCK_STREAM, 0);
if (fd < 0) { if (fd < 0) {
SYSERROR("Failed to create command socket %s", offset); SYSERROR("Failed to create command socket %s", &path[1]);
if (errno == EADDRINUSE) if (errno == EADDRINUSE)
ERROR("Container \"%s\" appears to be already running", name); ERROR("Container \"%s\" appears to be already running", name);

View File

@ -96,24 +96,38 @@ int lxc_cmd_sock_get_state(const char *name, const char *lxcpath,
return ret; return ret;
} }
int lxc_make_abstract_socket_name(char *path, int len, const char *lxcname, int lxc_make_abstract_socket_name(char *path, size_t pathlen,
const char *lxcname,
const char *lxcpath, const char *lxcpath,
const char *hashed_sock_name, const char *hashed_sock_name,
const char *suffix) const char *suffix)
{ {
const char *name; const char *name;
char *offset;
char *tmppath; char *tmppath;
size_t len;
size_t tmplen; size_t tmplen;
uint64_t hash; uint64_t hash;
int ret; int ret;
if (!path)
return -1;
offset = &path[1];
/* -2 here because this is an abstract unix socket so it needs a
* leading \0, and we null terminate, so it needs a trailing \0.
* Although null termination isn't required by the API, we do it anyway
* because we print the sockname out sometimes.
*/
len = pathlen -2;
name = lxcname; name = lxcname;
if (!name) if (!name)
name = ""; name = "";
if (hashed_sock_name != NULL) { if (hashed_sock_name != NULL) {
ret = ret = snprintf(offset, len, "lxc/%s/%s", hashed_sock_name, suffix);
snprintf(path, len, "lxc/%s/%s", hashed_sock_name, suffix);
if (ret < 0 || ret >= len) { if (ret < 0 || ret >= len) {
ERROR("Failed to create abstract socket name"); ERROR("Failed to create abstract socket name");
return -1; return -1;
@ -129,7 +143,7 @@ int lxc_make_abstract_socket_name(char *path, int len, const char *lxcname,
} }
} }
ret = snprintf(path, len, "%s/%s/%s", lxcpath, name, suffix); ret = snprintf(offset, len, "%s/%s/%s", lxcpath, name, suffix);
if (ret < 0) { if (ret < 0) {
ERROR("Failed to create abstract socket name"); ERROR("Failed to create abstract socket name");
return -1; return -1;
@ -147,7 +161,7 @@ int lxc_make_abstract_socket_name(char *path, int len, const char *lxcname,
} }
hash = fnv_64a_buf(tmppath, ret, FNV1A_64_INIT); hash = fnv_64a_buf(tmppath, ret, FNV1A_64_INIT);
ret = snprintf(path, len, "lxc/%016" PRIx64 "/%s", hash, suffix); ret = snprintf(offset, len, "lxc/%016" PRIx64 "/%s", hash, suffix);
if (ret < 0 || ret >= len) { if (ret < 0 || ret >= len) {
ERROR("Failed to create abstract socket name"); ERROR("Failed to create abstract socket name");
return -1; return -1;
@ -161,15 +175,8 @@ int lxc_cmd_connect(const char *name, const char *lxcpath,
{ {
int ret, client_fd; int ret, client_fd;
char path[LXC_AUDS_ADDR_LEN] = {0}; char path[LXC_AUDS_ADDR_LEN] = {0};
char *offset = &path[1];
/* -2 here because this is an abstract unix socket so it needs a ret = lxc_make_abstract_socket_name(path, sizeof(path), name, lxcpath,
* leading \0, and we null terminate, so it needs a trailing \0.
* Although null termination isn't required by the API, we do it anyway
* because we print the sockname out sometimes.
*/
size_t len = sizeof(path) - 2;
ret = lxc_make_abstract_socket_name(offset, len, name, lxcpath,
hashed_sock_name, suffix); hashed_sock_name, suffix);
if (ret < 0) if (ret < 0)
return -1; return -1;

View File

@ -25,7 +25,8 @@
#include "state.h" #include "state.h"
#include "commands.h" #include "commands.h"
int lxc_make_abstract_socket_name(char *path, int len, const char *lxcname, int lxc_make_abstract_socket_name(char *path, size_t pathlen,
const char *lxcname,
const char *lxcpath, const char *lxcpath,
const char *hashed_sock_name, const char *hashed_sock_name,
const char *suffix); const char *suffix);

View File

@ -73,7 +73,7 @@ int lxc_monitor_fifo_name(const char *lxcpath, char *fifo_path, size_t fifo_path
if (do_mkdirp) { if (do_mkdirp) {
ret = snprintf(fifo_path, fifo_path_sz, "%s/lxc/%s", rundir, lxcpath); ret = snprintf(fifo_path, fifo_path_sz, "%s/lxc/%s", rundir, lxcpath);
if (ret < 0 || (size_t)ret >= fifo_path_sz) { if (ret < 0 || (size_t)ret >= fifo_path_sz) {
ERROR("rundir/lxcpath (%s/%s) too long for monitor fifo.", rundir, lxcpath); ERROR("rundir/lxcpath (%s/%s) too long for monitor fifo", rundir, lxcpath);
free(rundir); free(rundir);
return -1; return -1;
} }
@ -86,7 +86,7 @@ int lxc_monitor_fifo_name(const char *lxcpath, char *fifo_path, size_t fifo_path
} }
ret = snprintf(fifo_path, fifo_path_sz, "%s/lxc/%s/monitor-fifo", rundir, lxcpath); ret = snprintf(fifo_path, fifo_path_sz, "%s/lxc/%s/monitor-fifo", rundir, lxcpath);
if (ret < 0 || (size_t)ret >= fifo_path_sz) { if (ret < 0 || (size_t)ret >= fifo_path_sz) {
ERROR("rundir/lxcpath (%s/%s) too long for monitor fifo.", rundir, lxcpath); ERROR("rundir/lxcpath (%s/%s) too long for monitor fifo", rundir, lxcpath);
free(rundir); free(rundir);
return -1; return -1;
} }
@ -128,7 +128,7 @@ static void lxc_monitor_fifo_send(struct lxc_msg *msg, const char *lxcpath)
ret = lxc_write_nointr(fd, msg, sizeof(*msg)); ret = lxc_write_nointr(fd, msg, sizeof(*msg));
if (ret != sizeof(*msg)) { if (ret != sizeof(*msg)) {
close(fd); close(fd);
SYSERROR("Failed to write to monitor fifo \"%s\".", fifo_path); SYSERROR("Failed to write to monitor fifo \"%s\"", fifo_path);
return; return;
} }
@ -168,7 +168,8 @@ int lxc_monitor_close(int fd)
* have a maximum of 106 chars. But to not break backwards compatibility we keep * have a maximum of 106 chars. But to not break backwards compatibility we keep
* the limit at 105. * the limit at 105.
*/ */
int lxc_monitor_sock_name(const char *lxcpath, struct sockaddr_un *addr) { int lxc_monitor_sock_name(const char *lxcpath, struct sockaddr_un *addr)
{
size_t len; size_t len;
int ret; int ret;
char *path; char *path;
@ -185,7 +186,7 @@ int lxc_monitor_sock_name(const char *lxcpath, struct sockaddr_un *addr) {
path = alloca(len); path = alloca(len);
ret = snprintf(path, len, "lxc/%s/monitor-sock", lxcpath); ret = snprintf(path, len, "lxc/%s/monitor-sock", lxcpath);
if (ret < 0 || (size_t)ret >= len) { if (ret < 0 || (size_t)ret >= len) {
ERROR("failed to create name for monitor socket"); ERROR("Failed to create name for monitor socket");
return -1; return -1;
} }
@ -198,15 +199,22 @@ int lxc_monitor_sock_name(const char *lxcpath, struct sockaddr_un *addr) {
hash = fnv_64a_buf(path, ret, FNV1A_64_INIT); hash = fnv_64a_buf(path, ret, FNV1A_64_INIT);
ret = snprintf(addr->sun_path, len, "@lxc/%016" PRIx64 "/%s", hash, lxcpath); ret = snprintf(addr->sun_path, len, "@lxc/%016" PRIx64 "/%s", hash, lxcpath);
if (ret < 0) { if (ret < 0) {
ERROR("failed to create hashed name for monitor socket"); ERROR("Failed to create hashed name for monitor socket");
return -1; goto on_error;
} else if ((size_t)ret >= len) {
errno = ENAMETOOLONG;
SYSERROR("The name of monitor socket too long (%d bytes)", ret);
goto on_error;
} }
/* replace @ with \0 */ /* replace @ with \0 */
addr->sun_path[0] = '\0'; addr->sun_path[0] = '\0';
INFO("using monitor socket name \"%s\" (length of socket name %zu must be <= %zu)", &addr->sun_path[1], strlen(&addr->sun_path[1]), sizeof(addr->sun_path) - 3); INFO("Using monitor socket name \"%s\" (length of socket name %zu must be <= %zu)", &addr->sun_path[1], strlen(&addr->sun_path[1]), sizeof(addr->sun_path) - 3);
return 0; return 0;
on_error:
return -1;
} }
int lxc_monitor_open(const char *lxcpath) int lxc_monitor_open(const char *lxcpath)
@ -214,19 +222,12 @@ int lxc_monitor_open(const char *lxcpath)
struct sockaddr_un addr; struct sockaddr_un addr;
int fd; int fd;
size_t retry; size_t retry;
size_t len;
int backoff_ms[] = {10, 50, 100}; int backoff_ms[] = {10, 50, 100};
if (lxc_monitor_sock_name(lxcpath, &addr) < 0) if (lxc_monitor_sock_name(lxcpath, &addr) < 0)
return -1; return -1;
len = strlen(&addr.sun_path[1]); DEBUG("Opening monitor socket %s with len %zu", &addr.sun_path[1], strlen(&addr.sun_path[1]));
DEBUG("opening monitor socket %s with len %zu", &addr.sun_path[1], len);
if (len >= sizeof(addr.sun_path) - 1) {
errno = ENAMETOOLONG;
SYSERROR("The name of monitor socket too long (%zu bytes)", len);
return -1;
}
for (retry = 0; retry < sizeof(backoff_ms) / sizeof(backoff_ms[0]); retry++) { for (retry = 0; retry < sizeof(backoff_ms) / sizeof(backoff_ms[0]); retry++) {
fd = lxc_abstract_unix_connect(addr.sun_path); fd = lxc_abstract_unix_connect(addr.sun_path);
@ -272,7 +273,7 @@ int lxc_monitor_read_fdset(struct pollfd *fds, nfds_t nfds, struct lxc_msg *msg,
} }
} }
SYSERROR("No ready fd found."); SYSERROR("No ready fd found");
return -1; return -1;
} }
@ -315,33 +316,33 @@ int lxc_monitord_spawn(const char *lxcpath)
/* double fork to avoid zombies when monitord exits */ /* double fork to avoid zombies when monitord exits */
pid1 = fork(); pid1 = fork();
if (pid1 < 0) { if (pid1 < 0) {
SYSERROR("Failed to fork()."); SYSERROR("Failed to fork()");
return -1; return -1;
} }
if (pid1) { if (pid1) {
DEBUG("Going to wait for pid %d.", pid1); DEBUG("Going to wait for pid %d", pid1);
if (waitpid(pid1, NULL, 0) != pid1) if (waitpid(pid1, NULL, 0) != pid1)
return -1; return -1;
DEBUG("Finished waiting on pid %d.", pid1); DEBUG("Finished waiting on pid %d", pid1);
return 0; return 0;
} }
if (pipe(pipefd) < 0) { if (pipe(pipefd) < 0) {
SYSERROR("Failed to create pipe."); SYSERROR("Failed to create pipe");
_exit(EXIT_FAILURE); _exit(EXIT_FAILURE);
} }
pid2 = fork(); pid2 = fork();
if (pid2 < 0) { if (pid2 < 0) {
SYSERROR("Failed to fork()."); SYSERROR("Failed to fork()");
_exit(EXIT_FAILURE); _exit(EXIT_FAILURE);
} }
if (pid2) { if (pid2) {
DEBUG("Trying to sync with child process."); DEBUG("Trying to sync with child process");
char c; char c;
/* Wait for daemon to create socket. */ /* Wait for daemon to create socket. */
close(pipefd[1]); close(pipefd[1]);
@ -356,18 +357,18 @@ int lxc_monitord_spawn(const char *lxcpath)
close(pipefd[0]); close(pipefd[0]);
DEBUG("Successfully synced with child process."); DEBUG("Successfully synced with child process");
_exit(EXIT_SUCCESS); _exit(EXIT_SUCCESS);
} }
if (setsid() < 0) { if (setsid() < 0) {
SYSERROR("Failed to setsid()."); SYSERROR("Failed to setsid()");
_exit(EXIT_FAILURE); _exit(EXIT_FAILURE);
} }
lxc_check_inherited(NULL, true, &pipefd[1], 1); lxc_check_inherited(NULL, true, &pipefd[1], 1);
if (null_stdfds() < 0) { if (null_stdfds() < 0) {
SYSERROR("Failed to dup2() standard file descriptors to /dev/null."); SYSERROR("Failed to dup2() standard file descriptors to /dev/null");
_exit(EXIT_FAILURE); _exit(EXIT_FAILURE);
} }
@ -375,14 +376,14 @@ int lxc_monitord_spawn(const char *lxcpath)
ret = snprintf(pipefd_str, sizeof(pipefd_str), "%d", pipefd[1]); ret = snprintf(pipefd_str, sizeof(pipefd_str), "%d", pipefd[1]);
if (ret < 0 || ret >= sizeof(pipefd_str)) { if (ret < 0 || ret >= sizeof(pipefd_str)) {
ERROR("Failed to create pid argument to pass to monitord."); ERROR("Failed to create pid argument to pass to monitord");
_exit(EXIT_FAILURE); _exit(EXIT_FAILURE);
} }
DEBUG("Using pipe file descriptor %d for monitord.", pipefd[1]); DEBUG("Using pipe file descriptor %d for monitord", pipefd[1]);
execvp(args[0], args); execvp(args[0], args);
SYSERROR("failed to exec lxc-monitord"); SYSERROR("Failed to exec lxc-monitord");
_exit(EXIT_FAILURE); _exit(EXIT_FAILURE);
} }