Note if you want to backport this, The health thread code was moved between master and 2.10.
I can send the patch if you need. Cheers On Mon, Apr 01, 2019 at 04:33:41PM -0400, Jonathan Rajotte wrote: > Running the test suite under a Yocto musl build resulted in musl > coredump due to double freeing. > > We get the following backtraces: > > 0 a_crash () at ./arch/x86_64/atomic_arch.h:108 > 1 unmap_chunk (self=<optimized out>) at src/malloc/malloc.c:515 > 2 free (p=<optimized out>) at src/malloc/malloc.c:526 > 3 0x00007f46d9dc3849 in __getgrent_a (f=f@entry=0x7f46d9d1f7e0, > gr=gr@entry=0x7f46d9e24460 <gr>, line=line@entry=0x7f46d9e26058 <line>, > size=size@entry=0x7f46d92db550, mem=mem@entry=0x7f46d9e26050 <mem>, > nmem=nmem@entry=0x7f46d92db558, res=0x7f46d92db548) at > src/passwd/getgrent_a.c:45 > 4 0x00007f46d9dc2e6b in __getgr_a (name=0x487242 "tracing", gid=gid@entry=0, > gr=gr@entry=0x7f46d9e24460 <gr>, buf=buf@entry=0x7f46d9e26058 <line>, > size=size@entry=0x7f46d92db550, mem=mem@entry=0x7f46d9e26050 <mem>, > nmem=0x7f46d92db558, res=0x7f46d92db548) at src/passwd/getgr_a.c:30 > 5 0x00007f46d9dc3733 in getgrnam (name=<optimized out>) at > src/passwd/getgrent.c:37 > 6 0x0000000000460b29 in utils_get_group_id (name=<optimized out>) at > ../../../lttng-tools-2.10.6/src/common/utils.c:1241 > 7 0x000000000044ee69 in thread_manage_health (data=<optimized out>) at > ../../../../lttng-tools-2.10.6/src/bin/lttng-sessiond/main.c:4115 > 8 0x00007f46d9de1541 in start (p=<optimized out>) at > src/thread/pthread_create.c:195 > 9 0x00007f46d9dee661 in __clone () at src/thread/x86_64/clone.s:22 > > From another run: > > 0 a_crash () at ./arch/x86_64/atomic_arch.h:108 > 1 unmap_chunk (self=<optimized out>) at src/malloc/malloc.c:515 > 2 free (p=<optimized out>) at src/malloc/malloc.c:526 > 3 0x00007f5abc210849 in __getgrent_a (f=f@entry=0x7f5abc2733e0, > gr=gr@entry=0x7f5abc271460 <gr>, line=line@entry=0x7f5abc273058 <line>, > size=size@entry=0x7f5abaef5510, mem=mem@entry=0x7f5abc273050 <mem>, > nmem=nmem@entry=0x7f5abaef5518, res=0x7f5abaef5508) at > src/passwd/getgrent_a.c:45 > 4 0x00007f5abc20fe6b in __getgr_a (name=0x487242 "tracing", gid=gid@entry=0, > gr=gr@entry=0x7f5abc271460 <gr>, buf=buf@entry=0x7f5abc273058 <line>, > size=size@entry=0x7f5abaef5510, mem=mem@entry=0x7f5abc273050 <mem>, > nmem=0x7f5abaef5518, res=0x7f5abaef5508) at src/passwd/getgr_a.c:30 > 5 0x00007f5abc210733 in getgrnam (name=<optimized out>) at > src/passwd/getgrent.c:37 > 6 0x0000000000460b29 in utils_get_group_id (name=<optimized out>) at > ../../../lttng-tools-2.10.6/src/common/utils.c:1241 > 7 0x000000000042dee4 in notification_channel_socket_create () at > ../../../../lttng-tools-2.10.6/src/bin/lttng-sessiond/notification-thread.c:238 > 8 init_thread_state (state=0x7f5abaef5560, handle=0x7f5abbf9be40) at > ../../../../lttng-tools-2.10.6/src/bin/lttng-sessiond/notification-thread.c:375 > 9 thread_notification (data=0x7f5abbf9be40) at > ../../../../lttng-tools-2.10.6/src/bin/lttng-sessiond/notification-thread.c:495 > 10 0x00007f5abc22e541 in start (p=<optimized out>) at > src/thread/pthread_create.c:195 > 11 0x00007f5abc23b661 in __clone () at src/thread/x86_64/clone.s:22 > > The problem was easily reproducible (~6 crash on ~300 runs). A prototype fix > using mutex around the getgrnam yielded no crash in over 1000 runs. This > patch yielded the same results as the prototype fix. > > Unfortunately we cannot rely on a mutex in liblttng-ctl since we cannot > enforce the locking for the application using the lib. > > Use getgrnam_r instead. > > The previous implementation of utils_get_group_id returned the gid of > the root group (0) on error/not found. lttng_check_tracing_group needs > to know if an error/not found occured, returning the root group is not > enough. We now return the gid via the passed parameter. The caller is > responsible for either defaulting to the root group or propagating the > error. > > We also do not want to warn when used in liblttng-ctl context. We might > want to move the warning elsewhere in the future. For now, pass a bool > if we need to warn or not. > > Signed-off-by: Jonathan Rajotte <jonathan.rajotte-jul...@efficios.com> > --- > src/bin/lttng-consumerd/health-consumerd.c | 10 ++- > src/bin/lttng-relayd/health-relayd.c | 20 ++++-- > src/bin/lttng-sessiond/health.c | 10 ++- > src/bin/lttng-sessiond/main.c | 14 +++- > src/bin/lttng-sessiond/notification-thread.c | 10 ++- > src/common/utils.c | 75 +++++++++++++++++--- > src/common/utils.h | 4 +- > src/lib/lttng-ctl/lttng-ctl.c | 8 +-- > 8 files changed, 122 insertions(+), 29 deletions(-) > > diff --git a/src/bin/lttng-consumerd/health-consumerd.c > b/src/bin/lttng-consumerd/health-consumerd.c > index 1e2f31e48..6045401a4 100644 > --- a/src/bin/lttng-consumerd/health-consumerd.c > +++ b/src/bin/lttng-consumerd/health-consumerd.c > @@ -184,8 +184,14 @@ void *thread_manage_health(void *data) > is_root = !getuid(); > if (is_root) { > /* lttng health client socket path permissions */ > - ret = chown(health_unix_sock_path, 0, > - utils_get_group_id(tracing_group_name)); > + gid_t gid; > + > + ret = utils_get_group_id(tracing_group_name, true, &gid); > + if (ret) { > + gid = 0; /* Default to root group. */ > + } > + > + ret = chown(health_unix_sock_path, 0, gid); > if (ret < 0) { > ERR("Unable to set group on %s", health_unix_sock_path); > PERROR("chown"); > diff --git a/src/bin/lttng-relayd/health-relayd.c > b/src/bin/lttng-relayd/health-relayd.c > index ba996621b..962e88c47 100644 > --- a/src/bin/lttng-relayd/health-relayd.c > +++ b/src/bin/lttng-relayd/health-relayd.c > @@ -105,8 +105,14 @@ static int create_lttng_rundir_with_perm(const char > *rundir) > int is_root = !getuid(); > > if (is_root) { > - ret = chown(rundir, 0, > - utils_get_group_id(tracing_group_name)); > + gid_t gid; > + > + ret = utils_get_group_id(tracing_group_name, true, > &gid); > + if (ret) { > + gid = 0; /* Default to root group.*/ > + } > + > + ret = chown(rundir, 0, gid); > if (ret < 0) { > ERR("Unable to set group on %s", rundir); > PERROR("chown"); > @@ -256,8 +262,14 @@ void *thread_manage_health(void *data) > is_root = !getuid(); > if (is_root) { > /* lttng health client socket path permissions */ > - ret = chown(health_unix_sock_path, 0, > - utils_get_group_id(tracing_group_name)); > + gid_t gid; > + > + ret = utils_get_group_id(tracing_group_name, true, &gid); > + if (ret) { > + gid = 0; /* Default to root group */ > + } > + > + ret = chown(health_unix_sock_path, 0, gid); > if (ret < 0) { > ERR("Unable to set group on %s", health_unix_sock_path); > PERROR("chown"); > diff --git a/src/bin/lttng-sessiond/health.c b/src/bin/lttng-sessiond/health.c > index 921b45261..9e639837b 100644 > --- a/src/bin/lttng-sessiond/health.c > +++ b/src/bin/lttng-sessiond/health.c > @@ -95,8 +95,14 @@ static void *thread_manage_health(void *data) > > if (is_root) { > /* lttng health client socket path permissions */ > - ret = chown(config.health_unix_sock_path.value, 0, > - > utils_get_group_id(config.tracing_group_name.value)); > + gid_t gid; > + > + ret = utils_get_group_id(config.tracing_group_name.value, true, > &gid); > + if (ret) { > + gid = 0; /* Default to root group. */ > + } > + > + ret = chown(config.health_unix_sock_path.value, 0, gid); > if (ret < 0) { > ERR("Unable to set group on %s", > config.health_unix_sock_path.value); > PERROR("chown"); > diff --git a/src/bin/lttng-sessiond/main.c b/src/bin/lttng-sessiond/main.c > index 24855b976..1cbd3c14c 100644 > --- a/src/bin/lttng-sessiond/main.c > +++ b/src/bin/lttng-sessiond/main.c > @@ -1023,7 +1023,10 @@ static int set_permissions(char *rundir) > int ret; > gid_t gid; > > - gid = utils_get_group_id(config.tracing_group_name.value); > + ret = utils_get_group_id(config.tracing_group_name.value, true, &gid); > + if (ret) { > + gid = 0; /* Default to root group */ > + } > > /* Set lttng run dir */ > ret = chown(rundir, 0, gid); > @@ -1134,7 +1137,14 @@ static int set_consumer_sockets(struct consumer_data > *consumer_data) > goto error; > } > if (is_root) { > - ret = chown(path, 0, > utils_get_group_id(config.tracing_group_name.value)); > + gid_t gid; > + > + ret = utils_get_group_id(config.tracing_group_name.value, true, > &gid); > + if (ret) { > + gid = 0; /* Default to root group */ > + } > + > + ret = chown(path, 0, gid); > if (ret < 0) { > ERR("Unable to set group on %s", path); > PERROR("chown"); > diff --git a/src/bin/lttng-sessiond/notification-thread.c > b/src/bin/lttng-sessiond/notification-thread.c > index b42b282e1..5a625eb3c 100644 > --- a/src/bin/lttng-sessiond/notification-thread.c > +++ b/src/bin/lttng-sessiond/notification-thread.c > @@ -239,8 +239,14 @@ int notification_channel_socket_create(void) > } > > if (getuid() == 0) { > - ret = chown(sock_path, 0, > - > utils_get_group_id(config.tracing_group_name.value)); > + gid_t gid; > + > + ret = utils_get_group_id(config.tracing_group_name.value, > true, &gid); > + if (ret) { > + gid = 0; /* Default to root group. */ > + } > + > + ret = chown(sock_path, 0, gid); > if (ret) { > ERR("Failed to set the notification channel socket's > group"); > ret = -1; > diff --git a/src/common/utils.c b/src/common/utils.c > index 4c000e9b4..c79906a29 100644 > --- a/src/common/utils.c > +++ b/src/common/utils.c > @@ -1477,24 +1477,77 @@ size_t utils_get_current_time_str(const char *format, > char *dst, size_t len) > } > > /* > - * Return the group ID matching name, else 0 if it cannot be found. > + * Return 0 on success and set *gid to the group_ID matching the passed name. > + * Else -1 if it cannot be found or an error occurred. > */ > LTTNG_HIDDEN > -gid_t utils_get_group_id(const char *name) > +int utils_get_group_id(const char *name, bool warn, gid_t *gid) > { > - struct group *grp; > + static volatile int warn_once; > > - grp = getgrnam(name); > - if (!grp) { > - static volatile int warn_once; > + int ret; > + long sys_len; > + size_t len; > + struct group grp; > + struct group *result; > + char *buffer = NULL; > > - if (!warn_once) { > - WARN("No tracing group detected"); > - warn_once = 1; > + /* Get the system limit if it exists */ > + sys_len = sysconf(_SC_GETGR_R_SIZE_MAX); > + if (sys_len == -1) { > + len = 1024; > + } else { > + len = (size_t) sys_len; > + } > + > + buffer = malloc(len); > + if (!buffer) { > + PERROR("getgrnam_r malloc"); > + ret = -1; > + goto error; > + } > + > + while ((ret = getgrnam_r(name, &grp, buffer, len, &result)) == ERANGE) > + { > + /* Buffer is not big enough, increase its size. */ > + size_t new_len = 2 * len; > + char *new_buffer = NULL; > + if (new_len < len) { > + ERR("getgrnam_r buffer size overflow"); > + ret = -1; > + goto error; > + } > + len = new_len; > + new_buffer = realloc(buffer, len); > + if (!new_buffer) { > + PERROR("getgrnam_r realloc"); > + ret = -1; > + goto error; > } > - return 0; > + buffer = new_buffer; > + } > + if (ret != 0) { > + PERROR("getgrnam_r"); > + ret = -1; > + goto error; > + } > + > + /* Group not found. */ > + if (!result) { > + ret = -1; > + goto error; > + } > + > + *gid = result->gr_gid; > + ret = 0; > + > +error: > + free(buffer); > + if (ret && warn && !warn_once) { > + WARN("No tracing group detected"); > + warn_once = 1; > } > - return grp->gr_gid; > + return ret; > } > > /* > diff --git a/src/common/utils.h b/src/common/utils.h > index 9e3fa60cd..9dc447378 100644 > --- a/src/common/utils.h > +++ b/src/common/utils.h > @@ -22,6 +22,8 @@ > #include <unistd.h> > #include <stdint.h> > #include <getopt.h> > +#include <stdbool.h> > +#include <sys/types.h> > > #define KIBI_LOG2 10 > #define MEBI_LOG2 20 > @@ -54,7 +56,7 @@ int utils_get_count_order_u64(uint64_t x); > char *utils_get_home_dir(void); > char *utils_get_user_home_dir(uid_t uid); > size_t utils_get_current_time_str(const char *format, char *dst, size_t len); > -gid_t utils_get_group_id(const char *name); > +int utils_get_group_id(const char *name, bool warn, gid_t *gid); > char *utils_generate_optstring(const struct option *long_options, > size_t opt_count); > int utils_create_lock_file(const char *filepath); > diff --git a/src/lib/lttng-ctl/lttng-ctl.c b/src/lib/lttng-ctl/lttng-ctl.c > index 165fef4dc..403aa092b 100644 > --- a/src/lib/lttng-ctl/lttng-ctl.c > +++ b/src/lib/lttng-ctl/lttng-ctl.c > @@ -241,15 +241,13 @@ end: > LTTNG_HIDDEN > int lttng_check_tracing_group(void) > { > - struct group *grp_tracing; /* no free(). See getgrnam(3) */ > - gid_t *grp_list; > + gid_t *grp_list, tracing_gid; > int grp_list_size, grp_id, i; > int ret = -1; > const char *grp_name = tracing_group; > > /* Get GID of group 'tracing' */ > - grp_tracing = getgrnam(grp_name); > - if (!grp_tracing) { > + if (utils_get_group_id(grp_name, false, &tracing_gid)) { > /* If grp_tracing is NULL, the group does not exist. */ > goto end; > } > @@ -274,7 +272,7 @@ int lttng_check_tracing_group(void) > } > > for (i = 0; i < grp_list_size; i++) { > - if (grp_list[i] == grp_tracing->gr_gid) { > + if (grp_list[i] == tracing_gid) { > ret = 1; > break; > } > -- > 2.17.1 > -- Jonathan Rajotte-Julien EfficiOS _______________________________________________ lttng-dev mailing list lttng-dev@lists.lttng.org https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev