Commit ba35272e by Christian Brauner Committed by Stéphane Graber

Fix calculations in clone_update_unexp_hooks()

Changes v3: (1) Fix typo (q --> p). (1) This commit fixes the calculations when updating paths in lxc.hooks.* entries. We now also update conf->unexpandend_alloced which hasn't been done prior to this commit. (2) Also we use the stricter check: if (p >= lend) continue; This should deal better with invalid config files. (3) Insert some spaces between operators to increase readability. (4) Use gotos to simplify function and increase readability. Signed-off-by: 's avatarChristian Brauner <christianvanbrauner@gmail.com> Acked-by: 's avatarSerge E. Hallyn <serge.hallyn@ubuntu.com>
parent 108ab951
...@@ -2643,7 +2643,8 @@ next: ...@@ -2643,7 +2643,8 @@ next:
} }
bool clone_update_unexp_hooks(struct lxc_conf *conf, const char *oldpath, bool clone_update_unexp_hooks(struct lxc_conf *conf, const char *oldpath,
const char *newpath, const char *oldname, const char *newname) const char *newpath, const char *oldname,
const char *newname)
{ {
const char *key = "lxc.hook"; const char *key = "lxc.hook";
int ret; int ret;
...@@ -2653,13 +2654,13 @@ bool clone_update_unexp_hooks(struct lxc_conf *conf, const char *oldpath, ...@@ -2653,13 +2654,13 @@ bool clone_update_unexp_hooks(struct lxc_conf *conf, const char *oldpath,
char *olddir = alloca(olddirlen + 1); char *olddir = alloca(olddirlen + 1);
char *newdir = alloca(newdirlen + 1); char *newdir = alloca(newdirlen + 1);
ret = snprintf(olddir, olddirlen+1, "%s/%s", oldpath, oldname); ret = snprintf(olddir, olddirlen + 1, "%s/%s", oldpath, oldname);
if (ret < 0 || ret >= olddirlen+1) { if (ret < 0 || ret >= olddirlen + 1) {
ERROR("Bug in %s", __func__); ERROR("Bug in %s", __func__);
return false; return false;
} }
ret = snprintf(newdir, newdirlen+1, "%s/%s", newpath, newname); ret = snprintf(newdir, newdirlen + 1, "%s/%s", newpath, newname);
if (ret < 0 || ret >= newdirlen+1) { if (ret < 0 || ret >= newdirlen + 1) {
ERROR("Bug in %s", __func__); ERROR("Bug in %s", __func__);
return false; return false;
} }
...@@ -2671,56 +2672,53 @@ bool clone_update_unexp_hooks(struct lxc_conf *conf, const char *oldpath, ...@@ -2671,56 +2672,53 @@ bool clone_update_unexp_hooks(struct lxc_conf *conf, const char *oldpath,
lend = lstart + strlen(lstart); lend = lstart + strlen(lstart);
else else
lend++; lend++;
if (strncmp(lstart, key, strlen(key)) != 0) { if (strncmp(lstart, key, strlen(key)) != 0)
lstart = lend; goto next;
continue; p = strchr(lstart + strlen(key), '=');
} if (!p)
p = strchr(lstart+strlen(key), '='); goto next;
if (!p) {
lstart = lend;
continue;
}
p++; p++;
while (isblank(*p)) while (isblank(*p))
p++; p++;
if (!*p) if (p >= lend)
return true; goto next;
if (strncmp(p, olddir, strlen(olddir)) != 0) { if (strncmp(p, olddir, strlen(olddir)) != 0)
lstart = lend; goto next;
continue;
}
/* replace the olddir with newdir */ /* replace the olddir with newdir */
if (olddirlen >= newdirlen) { if (olddirlen >= newdirlen) {
size_t diff = olddirlen - newdirlen; size_t diff = olddirlen - newdirlen;
memcpy(p, newdir, newdirlen); memcpy(p, newdir, newdirlen);
if (olddirlen != newdirlen) { if (olddirlen != newdirlen) {
memmove(lend-diff, lend, strlen(lend)+1); memmove(p + newdirlen, p + newdirlen + diff,
strlen(p) - newdirlen - diff + 1);
lend -= diff; lend -= diff;
conf->unexpanded_len -= diff; conf->unexpanded_len -= diff;
} }
lstart = lend;
} else { } else {
char *new; char *new;
size_t diff = newdirlen - olddirlen; size_t diff = newdirlen - olddirlen;
size_t oldlen = conf->unexpanded_len; size_t oldlen = conf->unexpanded_len;
size_t newlen = oldlen + diff; size_t newlen = oldlen + diff;
size_t poffset = p - conf->unexpanded_config; size_t poffset = p - conf->unexpanded_config;
new = realloc(conf->unexpanded_config, newlen); new = realloc(conf->unexpanded_config, newlen + 1);
if (!new) { if (!new) {
ERROR("Out of memory"); ERROR("Out of memory");
return false; return false;
} }
conf->unexpanded_len = newlen; conf->unexpanded_len = newlen;
new[newlen-1] = '\0'; conf->unexpanded_alloced = newlen + 1;
new[newlen - 1] = '\0';
lend = new + (lend - conf->unexpanded_config); lend = new + (lend - conf->unexpanded_config);
/* move over the remainder, /$hookname\n$rest */ /* move over the remainder to make room for the newdir */
memmove(new+poffset+newdirlen, memmove(new + poffset + newdirlen,
new+poffset+olddirlen, new + poffset + olddirlen,
oldlen-poffset-olddirlen); oldlen - poffset - olddirlen + 1);
conf->unexpanded_config = new; conf->unexpanded_config = new;
memcpy(new+poffset, newdir, newdirlen); memcpy(new + poffset, newdir, newdirlen);
lstart = lend + diff; lend += diff;
} }
next:
lstart = lend;
} }
return true; return true;
} }
......
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