tmpfiles: fix obscure leak in error path

The leak was because of the single return in midst of all
'goto finish'es. Using automatic cleanup simplifies things.
This commit is contained in:
Zbigniew Jędrzejewski-Szmek 2013-03-31 16:29:46 -04:00
parent e62d8c3944
commit 7f2c1f4dbf

View file

@ -1021,7 +1021,8 @@ static bool item_equal(Item *a, Item *b) {
} }
static int parse_line(const char *fname, unsigned line, const char *buffer) { static int parse_line(const char *fname, unsigned line, const char *buffer) {
Item *i, *existing; Item _cleanup_free_ *i = NULL;
Item *existing;
char _cleanup_free_ char _cleanup_free_
*mode = NULL, *user = NULL, *group = NULL, *age = NULL; *mode = NULL, *user = NULL, *group = NULL, *age = NULL;
char type; char type;
@ -1047,8 +1048,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
&n); &n);
if (r < 2) { if (r < 2) {
log_error("[%s:%u] Syntax error.", fname, line); log_error("[%s:%u] Syntax error.", fname, line);
r = -EIO; return -EIO;
goto finish;
} }
if (n >= 0) { if (n >= 0) {
@ -1078,16 +1078,14 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
case CREATE_SYMLINK: case CREATE_SYMLINK:
if (!i->argument) { if (!i->argument) {
log_error("[%s:%u] Symlink file requires argument.", fname, line); log_error("[%s:%u] Symlink file requires argument.", fname, line);
r = -EBADMSG; return -EBADMSG;
goto finish;
} }
break; break;
case WRITE_FILE: case WRITE_FILE:
if (!i->argument) { if (!i->argument) {
log_error("[%s:%u] Write file requires argument.", fname, line); log_error("[%s:%u] Write file requires argument.", fname, line);
r = -EBADMSG; return -EBADMSG;
goto finish;
} }
break; break;
@ -1097,14 +1095,12 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
if (!i->argument) { if (!i->argument) {
log_error("[%s:%u] Device file requires argument.", fname, line); log_error("[%s:%u] Device file requires argument.", fname, line);
r = -EBADMSG; return -EBADMSG;
goto finish;
} }
if (sscanf(i->argument, "%u:%u", &major, &minor) != 2) { if (sscanf(i->argument, "%u:%u", &major, &minor) != 2) {
log_error("[%s:%u] Can't parse device file major/minor '%s'.", fname, line, i->argument); log_error("[%s:%u] Can't parse device file major/minor '%s'.", fname, line, i->argument);
r = -EBADMSG; return -EBADMSG;
goto finish;
} }
i->major_minor = makedev(major, minor); i->major_minor = makedev(major, minor);
@ -1113,24 +1109,20 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
default: default:
log_error("[%s:%u] Unknown file type '%c'.", fname, line, type); log_error("[%s:%u] Unknown file type '%c'.", fname, line, type);
r = -EBADMSG; return -EBADMSG;
goto finish;
} }
i->type = type; i->type = type;
if (!path_is_absolute(i->path)) { if (!path_is_absolute(i->path)) {
log_error("[%s:%u] Path '%s' not absolute.", fname, line, i->path); log_error("[%s:%u] Path '%s' not absolute.", fname, line, i->path);
r = -EBADMSG; return -EBADMSG;
goto finish;
} }
path_kill_slashes(i->path); path_kill_slashes(i->path);
if (arg_prefix && !path_startswith(i->path, arg_prefix)) { if (arg_prefix && !path_startswith(i->path, arg_prefix))
r = 0; return 0;
goto finish;
}
if (user && !streq(user, "-")) { if (user && !streq(user, "-")) {
const char *u = user; const char *u = user;
@ -1138,7 +1130,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
r = get_user_creds(&u, &i->uid, NULL, NULL, NULL); r = get_user_creds(&u, &i->uid, NULL, NULL, NULL);
if (r < 0) { if (r < 0) {
log_error("[%s:%u] Unknown user '%s'.", fname, line, user); log_error("[%s:%u] Unknown user '%s'.", fname, line, user);
goto finish; return r;
} }
i->uid_set = true; i->uid_set = true;
@ -1150,7 +1142,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
r = get_group_creds(&g, &i->gid); r = get_group_creds(&g, &i->gid);
if (r < 0) { if (r < 0) {
log_error("[%s:%u] Unknown group '%s'.", fname, line, group); log_error("[%s:%u] Unknown group '%s'.", fname, line, group);
goto finish; return r;
} }
i->gid_set = true; i->gid_set = true;
@ -1161,8 +1153,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
if (sscanf(mode, "%o", &m) != 1) { if (sscanf(mode, "%o", &m) != 1) {
log_error("[%s:%u] Invalid mode '%s'.", fname, line, mode); log_error("[%s:%u] Invalid mode '%s'.", fname, line, mode);
r = -ENOENT; return -ENOENT;
goto finish;
} }
i->mode = m; i->mode = m;
@ -1182,8 +1173,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
if (parse_usec(a, &i->age) < 0) { if (parse_usec(a, &i->age) < 0) {
log_error("[%s:%u] Invalid age '%s'.", fname, line, age); log_error("[%s:%u] Invalid age '%s'.", fname, line, age);
r = -EBADMSG; return -EBADMSG;
goto finish;
} }
i->age_set = true; i->age_set = true;
@ -1198,24 +1188,18 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
if (!item_equal(existing, i)) if (!item_equal(existing, i))
log_warning("Two or more conflicting lines for %s configured, ignoring.", i->path); log_warning("Two or more conflicting lines for %s configured, ignoring.", i->path);
r = 0; return 0;
goto finish;
} }
r = hashmap_put(h, i->path, i); r = hashmap_put(h, i->path, i);
if (r < 0) { if (r < 0) {
log_error("Failed to insert item %s: %s", i->path, strerror(-r)); log_error("Failed to insert item %s: %s", i->path, strerror(-r));
goto finish; return r;
} }
i = NULL; i = NULL; /* avoid cleanup */
r = 0;
finish: return 0;
if (i)
item_free(i);
return r;
} }
static int help(void) { static int help(void) {