summaryrefslogtreecommitdiff
path: root/src/login
diff options
context:
space:
mode:
authorDavid Herrmann <dh.herrmann@gmail.com>2015-06-14 15:08:52 +0200
committerSven Eden <yamakuzure@gmx.net>2017-03-14 10:02:58 +0100
commit801daa75024fb177df1535f8e16a450bc68619fd (patch)
tree4972cfd5d0c58f37ed241547091fb8d9a85ad06b /src/login
parentbe954dc04aca638c0f374dc36736e3d1d7100ee8 (diff)
tree-wide: fix memory leaks in users of bus_map_all_properties()
If you use bus_map_all_properties(), you must be aware that it might touch output variables even though it may fail. This is, because we parse many different bus-properties and cannot tell how to clean them up, in case we fail deep down in the parser. Fix all callers of bus_map_all_properties() to correctly cleanup any context structures at all times.
Diffstat (limited to 'src/login')
-rw-r--r--src/login/loginctl.c105
1 files changed, 67 insertions, 38 deletions
diff --git a/src/login/loginctl.c b/src/login/loginctl.c
index d00fc9ce2..a47563b50 100644
--- a/src/login/loginctl.c
+++ b/src/login/loginctl.c
@@ -279,42 +279,81 @@ static int show_unit_cgroup(sd_bus *bus, const char *interface, const char *unit
}
typedef struct SessionStatusInfo {
- const char *id;
+ char *id;
uid_t uid;
- const char *name;
+ char *name;
struct dual_timestamp timestamp;
unsigned int vtnr;
- const char *seat;
- const char *tty;
- const char *display;
+ char *seat;
+ char *tty;
+ char *display;
bool remote;
- const char *remote_host;
- const char *remote_user;
- const char *service;
+ char *remote_host;
+ char *remote_user;
+ char *service;
pid_t leader;
- const char *type;
- const char *class;
- const char *state;
- const char *scope;
- const char *desktop;
+ char *type;
+ char *class;
+ char *state;
+ char *scope;
+ char *desktop;
} SessionStatusInfo;
typedef struct UserStatusInfo {
uid_t uid;
- const char *name;
+ char *name;
struct dual_timestamp timestamp;
- const char *state;
+ char *state;
char **sessions;
- const char *display;
- const char *slice;
+ char *display;
+ char *slice;
} UserStatusInfo;
typedef struct SeatStatusInfo {
- const char *id;
- const char *active_session;
+ char *id;
+ char *active_session;
char **sessions;
} SeatStatusInfo;
+static void session_status_info_clear(SessionStatusInfo *info) {
+ if (info) {
+ free(info->id);
+ free(info->name);
+ free(info->seat);
+ free(info->tty);
+ free(info->display);
+ free(info->remote_host);
+ free(info->remote_user);
+ free(info->service);
+ free(info->type);
+ free(info->class);
+ free(info->state);
+ free(info->scope);
+ free(info->desktop);
+ zero(*info);
+ }
+}
+
+static void user_status_info_clear(UserStatusInfo *info) {
+ if (info) {
+ free(info->name);
+ free(info->state);
+ strv_free(info->sessions);
+ free(info->display);
+ free(info->slice);
+ zero(*info);
+ }
+}
+
+static void seat_status_info_clear(SeatStatusInfo *info) {
+ if (info) {
+ free(info->id);
+ free(info->active_session);
+ strv_free(info->sessions);
+ zero(*info);
+ }
+}
+
static int prop_map_first_of_struct(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata) {
const char *contents;
int r;
@@ -406,7 +445,7 @@ static int print_session_status_info(sd_bus *bus, const char *path, bool *new_li
char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1;
char since2[FORMAT_TIMESTAMP_MAX], *s2;
- SessionStatusInfo i = {};
+ _cleanup_(session_status_info_clear) SessionStatusInfo i = {};
int r;
r = bus_map_all_properties(bus, "org.freedesktop.login1", path, map, &i);
@@ -535,14 +574,12 @@ static int print_user_status_info(sd_bus *bus, const char *path, bool *new_line)
char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1;
char since2[FORMAT_TIMESTAMP_MAX], *s2;
- UserStatusInfo i = {};
+ _cleanup_(user_status_info_clear) UserStatusInfo i = {};
int r;
r = bus_map_all_properties(bus, "org.freedesktop.login1", path, map, &i);
- if (r < 0) {
- log_error_errno(r, "Could not get properties: %m");
- goto finish;
- }
+ if (r < 0)
+ return log_error_errno(r, "Could not get properties: %m");
if (*new_line)
printf("\n");
@@ -598,10 +635,7 @@ static int print_user_status_info(sd_bus *bus, const char *path, bool *new_line)
#endif
}
-finish:
- strv_free(i.sessions);
-
- return r;
+ return 0;
}
static int print_seat_status_info(sd_bus *bus, const char *path, bool *new_line) {
@@ -613,14 +647,12 @@ static int print_seat_status_info(sd_bus *bus, const char *path, bool *new_line)
{}
};
- SeatStatusInfo i = {};
+ _cleanup_(seat_status_info_clear) SeatStatusInfo i = {};
int r;
r = bus_map_all_properties(bus, "org.freedesktop.login1", path, map, &i);
- if (r < 0) {
- log_error_errno(r, "Could not get properties: %m");
- goto finish;
- }
+ if (r < 0)
+ return log_error_errno(r, "Could not get properties: %m");
if (*new_line)
printf("\n");
@@ -657,10 +689,7 @@ static int print_seat_status_info(sd_bus *bus, const char *path, bool *new_line)
show_sysfs(i.id, "\t\t ", c);
}
-finish:
- strv_free(i.sessions);
-
- return r;
+ return 0;
}
static int show_properties(sd_bus *bus, const char *path, bool *new_line) {