From 073135baa78511c26e502362840f2c950cfddfe2 Mon Sep 17 00:00:00 2001 From: Serge Hallyn Date: Sat, 9 Aug 2014 00:30:12 +0000 Subject: [PATCH] monitor: fix sockname calculation for long lxcpaths MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A long enough lxcpath (and small PATH_MAX through crappy defines) can cause the creation of the string to be hashed to fail. So just use alloca to get the size string we need. More importantly, while I can't explain it, if lxcpath is too long, setting sockname[sizeof(addr->sun_path)-2] to \0 simply doesn't seem to work. So set sockname[sizeof(addr->sun_path)-3] to \0, which does work. With this, and with lxc.lxcpath = /opt/lxc0123456789/lxc0123456789/lxc0123456789/lxc0123456789/lxc0123456789/lxc0123456789/lxc0123456789/lxc0123456789/lxc0123456789/lxc0123456789 in /etc/lxc/lxc.conf, I can run lxc-wait just fine. Without it, it fails (as does lxc-start -d, which uses lxc_wait to verify the container started) Signed-off-by: Serge Hallyn Acked-by: Stéphane Graber --- src/lxc/monitor.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/lxc/monitor.c b/src/lxc/monitor.c index 7c6dbb4a56..59b02b3b90 100644 --- a/src/lxc/monitor.c +++ b/src/lxc/monitor.c @@ -142,7 +142,7 @@ int lxc_monitor_sock_name(const char *lxcpath, struct sockaddr_un *addr) { size_t len; int ret; char *sockname = &addr->sun_path[1]; - char path[PATH_MAX+18]; + char *path; uint64_t hash; /* addr.sun_path is only 108 bytes, so we hash the full name and @@ -150,18 +150,20 @@ int lxc_monitor_sock_name(const char *lxcpath, struct sockaddr_un *addr) { */ memset(addr, 0, sizeof(*addr)); addr->sun_family = AF_UNIX; - len = sizeof(addr->sun_path) - 1; - ret = snprintf(path, sizeof(path), "lxc/%s/monitor-sock", lxcpath); - if (ret < 0 || ret >= sizeof(path)) { - ERROR("lxcpath %s too long for monitor unix socket", lxcpath); + len = strlen(lxcpath) + 18; + path = alloca(len); + ret = snprintf(path, len, "lxc/%s/monitor-sock", lxcpath); + if (ret < 0 || ret >= len) { + ERROR("memory error creating monitor path"); return -1; } + len = sizeof(addr->sun_path) - 1; hash = fnv_64a_buf(path, ret, FNV1A_64_INIT); ret = snprintf(sockname, len, "lxc/%016" PRIx64 "/%s", hash, lxcpath); if (ret < 0) return -1; - sockname[sizeof(addr->sun_path)-2] = '\0'; + sockname[sizeof(addr->sun_path)-3] = '\0'; INFO("using monitor sock name %s", sockname); return 0; }