Skip to content

Commit b7f4ea0

Browse files
mjeansonjgalar
authored andcommitted
Fix: lttng: poptGetArg doesn't provide string ownership
The string returned by poptGetArg() is 'const' because it is owned by the popt librairy and is free'd by it when poptFreeContext() is called. Copy those strings when we need to alter them to maintain proper ownership. The latest release of popt (v1.19) introduced a breaking change (changing the ownership of left-over command line arguments) that can cause double free()-s. This is ultimately due to this upstream commit in popt 1.19: rpm-software-management/popt@7182e46 which is derived from a package patch: https://src.fedoraproject.org/rpms/babeltrace/c/d48452beff87b145c038f070e7182358db04336c?branch=rawhide Change-Id: Id2535d1534c0e47cc0747968d6dd60a587f0b810 Signed-off-by: Michael Jeanson <[email protected]> Signed-off-by: Jérémie Galarneau <[email protected]>
1 parent 8aec5b8 commit b7f4ea0

File tree

15 files changed

+230
-170
lines changed

15 files changed

+230
-170
lines changed

src/bin/lttng/commands/clear.c

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -156,8 +156,8 @@ int cmd_clear(int argc, const char **argv)
156156
int ret = CMD_SUCCESS , i, command_ret = CMD_SUCCESS, success = 1;
157157
static poptContext pc;
158158
char *session_name = NULL;
159+
const char *arg_session_name = NULL;
159160
const char *leftover = NULL;
160-
bool free_session_name = false;
161161
struct lttng_session *sessions = NULL;
162162
int count;
163163
int found;
@@ -213,19 +213,22 @@ int cmd_clear(int argc, const char **argv)
213213
}
214214

215215
if (!opt_clear_all) {
216-
session_name = (char *) poptGetArg(pc);
217-
if (!session_name) {
216+
arg_session_name = poptGetArg(pc);
217+
if (!arg_session_name) {
218218
/* No session name specified, lookup default */
219219
session_name = get_session_name();
220+
} else {
221+
session_name = strdup(arg_session_name);
220222
if (session_name == NULL) {
221-
command_ret = CMD_ERROR;
222-
success = 0;
223-
goto mi_closing;
223+
PERROR("Failed to copy session name");
224224
}
225-
free_session_name = true;
226225
}
227-
} else {
228-
session_name = NULL;
226+
227+
if (session_name == NULL) {
228+
command_ret = CMD_ERROR;
229+
success = 0;
230+
goto mi_closing;
231+
}
229232
}
230233

231234
leftover = poptGetArg(pc);
@@ -307,9 +310,7 @@ int cmd_clear(int argc, const char **argv)
307310
}
308311

309312
free(sessions);
310-
if (free_session_name) {
311-
free(session_name);
312-
}
313+
free(session_name);
313314

314315
/* Overwrite ret if an error occurred during clear_session/all */
315316
ret = command_ret ? command_ret : ret;

src/bin/lttng/commands/create.c

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@
3333
#include <lttng/lttng.h>
3434

3535
static char *opt_output_path;
36-
static char *opt_session_name;
3736
static char *opt_url;
3837
static char *opt_ctrl_url;
3938
static char *opt_data_url;
@@ -131,7 +130,7 @@ static int mi_created_session(const char *session_name)
131130
}
132131

133132
static
134-
struct lttng_session_descriptor *create_session_descriptor(void)
133+
struct lttng_session_descriptor *create_session_descriptor(const char *session_name)
135134
{
136135
ssize_t uri_count;
137136
enum output_type output_type;
@@ -203,17 +202,17 @@ struct lttng_session_descriptor *create_session_descriptor(void)
203202
case OUTPUT_UNSPECIFIED:
204203
case OUTPUT_LOCAL:
205204
descriptor = lttng_session_descriptor_snapshot_local_create(
206-
opt_session_name,
205+
session_name,
207206
output_type == OUTPUT_LOCAL ?
208207
local_output_path : NULL);
209208
break;
210209
case OUTPUT_NONE:
211210
descriptor = lttng_session_descriptor_snapshot_create(
212-
opt_session_name);
211+
session_name);
213212
break;
214213
case OUTPUT_NETWORK:
215214
descriptor = lttng_session_descriptor_snapshot_network_create(
216-
opt_session_name, uri_str1, uri_str2);
215+
session_name, uri_str1, uri_str2);
217216
break;
218217
default:
219218
abort();
@@ -226,25 +225,25 @@ struct lttng_session_descriptor *create_session_descriptor(void)
226225
goto end;
227226
}
228227
descriptor = lttng_session_descriptor_live_network_create(
229-
opt_session_name, uri_str1, uri_str2,
228+
session_name, uri_str1, uri_str2,
230229
opt_live_timer);
231230
} else {
232231
/* Regular session. */
233232
switch (output_type) {
234233
case OUTPUT_UNSPECIFIED:
235234
case OUTPUT_LOCAL:
236235
descriptor = lttng_session_descriptor_local_create(
237-
opt_session_name,
236+
session_name,
238237
output_type == OUTPUT_LOCAL ?
239238
local_output_path : NULL);
240239
break;
241240
case OUTPUT_NONE:
242241
descriptor = lttng_session_descriptor_create(
243-
opt_session_name);
242+
session_name);
244243
break;
245244
case OUTPUT_NETWORK:
246245
descriptor = lttng_session_descriptor_network_create(
247-
opt_session_name, uri_str1, uri_str2);
246+
session_name, uri_str1, uri_str2);
248247
break;
249248
default:
250249
abort();
@@ -281,7 +280,7 @@ struct lttng_session_descriptor *create_session_descriptor(void)
281280
*
282281
* Returns one of the CMD_* result constants.
283282
*/
284-
static int create_session(void)
283+
static int create_session(const char *session_name)
285284
{
286285
int ret, i;
287286
char shm_path[LTTNG_PATH_MAX] = {};
@@ -293,8 +292,8 @@ static int create_session(void)
293292
const char *created_session_name;
294293

295294
/* Validate options. */
296-
if (opt_session_name) {
297-
if (strlen(opt_session_name) > NAME_MAX) {
295+
if (session_name) {
296+
if (strlen(session_name) > NAME_MAX) {
298297
ERR("Session name too long. Length must be lower or equal to %d",
299298
NAME_MAX);
300299
ret = CMD_ERROR;
@@ -305,11 +304,11 @@ static int create_session(void)
305304
* Both are reserved for the default session name. See bug #449 to
306305
* understand why we need to check both here.
307306
*/
308-
if ((strncmp(opt_session_name, DEFAULT_SESSION_NAME "-",
307+
if ((strncmp(session_name, DEFAULT_SESSION_NAME "-",
309308
strlen(DEFAULT_SESSION_NAME) + 1) == 0) ||
310-
(strncmp(opt_session_name, DEFAULT_SESSION_NAME,
309+
(strncmp(session_name, DEFAULT_SESSION_NAME,
311310
strlen(DEFAULT_SESSION_NAME)) == 0 &&
312-
strlen(opt_session_name) == strlen(DEFAULT_SESSION_NAME))) {
311+
strlen(session_name) == strlen(DEFAULT_SESSION_NAME))) {
313312
ERR("%s is a reserved keyword for default session(s)",
314313
DEFAULT_SESSION_NAME);
315314
ret = CMD_ERROR;
@@ -329,7 +328,7 @@ static int create_session(void)
329328
goto error;
330329
}
331330

332-
session_descriptor = create_session_descriptor();
331+
session_descriptor = create_session_descriptor(session_name);
333332
if (!session_descriptor) {
334333
ret = CMD_ERROR;
335334
goto error;
@@ -375,7 +374,7 @@ static int create_session(void)
375374
* An auto-generated session name already includes the creation
376375
* timestamp.
377376
*/
378-
if (opt_session_name) {
377+
if (session_name) {
379378
uint64_t creation_time;
380379
struct tm *timeinfo;
381380
time_t creation_time_t;
@@ -655,6 +654,7 @@ int cmd_create(int argc, const char **argv)
655654
{
656655
int opt, ret = CMD_SUCCESS, command_ret = CMD_SUCCESS, success = 1;
657656
char *opt_arg = NULL;
657+
const char *arg_session_name = NULL;
658658
const char *leftover = NULL;
659659
static poptContext pc;
660660

@@ -761,7 +761,9 @@ int cmd_create(int argc, const char **argv)
761761
goto end;
762762
}
763763
}
764-
opt_session_name = (char*) poptGetArg(pc);
764+
765+
/* Get the optional session name argument. */
766+
arg_session_name = poptGetArg(pc);
765767

766768
leftover = poptGetArg(pc);
767769
if (leftover) {
@@ -770,7 +772,7 @@ int cmd_create(int argc, const char **argv)
770772
goto end;
771773
}
772774

773-
command_ret = create_session();
775+
command_ret = create_session(arg_session_name);
774776
if (command_ret) {
775777
success = 0;
776778
}

src/bin/lttng/commands/destroy.c

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
#include <common/sessiond-comm/sessiond-comm.h>
2323
#include <common/utils.h>
2424

25-
static char *opt_session_name;
2625
static int opt_destroy_all;
2726
static int opt_no_wait;
2827

@@ -270,6 +269,7 @@ int cmd_destroy(int argc, const char **argv)
270269
int ret = CMD_SUCCESS , i, command_ret = CMD_SUCCESS, success = 1;
271270
static poptContext pc;
272271
char *session_name = NULL;
272+
const char *arg_session_name = NULL;
273273
const char *leftover = NULL;
274274

275275
struct lttng_session *sessions = NULL;
@@ -342,18 +342,22 @@ int cmd_destroy(int argc, const char **argv)
342342
success = 0;
343343
}
344344
} else {
345-
opt_session_name = (char *) poptGetArg(pc);
345+
arg_session_name = poptGetArg(pc);
346346

347-
if (!opt_session_name) {
347+
if (!arg_session_name) {
348348
/* No session name specified, lookup default */
349349
session_name = get_session_name();
350+
} else {
351+
session_name = strdup(arg_session_name);
350352
if (session_name == NULL) {
351-
command_ret = CMD_ERROR;
352-
success = 0;
353-
goto mi_closing;
353+
PERROR("Failed to copy session name");
354354
}
355-
} else {
356-
session_name = opt_session_name;
355+
}
356+
357+
if (session_name == NULL) {
358+
command_ret = CMD_ERROR;
359+
success = 0;
360+
goto mi_closing;
357361
}
358362

359363
/* Find the corresponding lttng_session struct */
@@ -419,10 +423,7 @@ int cmd_destroy(int argc, const char **argv)
419423
ret = ret ? ret : -LTTNG_ERR_MI_IO_FAIL;
420424
}
421425

422-
if (opt_session_name == NULL) {
423-
free(session_name);
424-
}
425-
426+
free(session_name);
426427
free(sessions);
427428

428429
/* Overwrite ret if an error occurred during destroy_session/all */

src/bin/lttng/commands/disable_channels.c

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020

2121
#include "../command.h"
2222

23-
static char *opt_channels;
2423
static int opt_kernel;
2524
static char *opt_session_name;
2625
static int opt_userspace;
@@ -95,7 +94,7 @@ static int mi_partial_channel_print(char *channel_name, unsigned int enabled,
9594
/*
9695
* Disabling channel using the lttng API.
9796
*/
98-
static int disable_channels(char *session_name)
97+
static int disable_channels(char *session_name, char *channel_list)
9998
{
10099
int ret = CMD_SUCCESS, warn = 0, success;
101100

@@ -134,7 +133,7 @@ static int disable_channels(char *session_name)
134133
}
135134

136135
/* Strip channel list */
137-
channel_name = strtok(opt_channels, ",");
136+
channel_name = strtok(channel_list, ",");
138137
while (channel_name != NULL) {
139138
DBG("Disabling channel %s", channel_name);
140139

@@ -208,6 +207,8 @@ int cmd_disable_channels(int argc, const char **argv)
208207
int opt, ret = CMD_SUCCESS, command_ret = CMD_SUCCESS, success = 1;
209208
static poptContext pc;
210209
char *session_name = NULL;
210+
char *channel_list = NULL;
211+
const char *arg_channel_list = NULL;
211212
const char *leftover = NULL;
212213

213214
pc = poptGetContext(NULL, argc, argv, long_options, 0);
@@ -237,9 +238,16 @@ int cmd_disable_channels(int argc, const char **argv)
237238
goto end;
238239
}
239240

240-
opt_channels = (char*) poptGetArg(pc);
241-
if (opt_channels == NULL) {
242-
ERR("Missing channel name(s).\n");
241+
arg_channel_list = poptGetArg(pc);
242+
if (arg_channel_list == NULL) {
243+
ERR("Missing channel name(s).");
244+
ret = CMD_ERROR;
245+
goto end;
246+
}
247+
248+
channel_list = strdup(arg_channel_list);
249+
if (channel_list == NULL) {
250+
PERROR("Failed to copy channel name");
243251
ret = CMD_ERROR;
244252
goto end;
245253
}
@@ -286,7 +294,7 @@ int cmd_disable_channels(int argc, const char **argv)
286294
}
287295
}
288296

289-
command_ret = disable_channels(session_name);
297+
command_ret = disable_channels(session_name, channel_list);
290298
if (command_ret) {
291299
success = 0;
292300
}
@@ -327,6 +335,8 @@ int cmd_disable_channels(int argc, const char **argv)
327335
free(session_name);
328336
}
329337

338+
free(channel_list);
339+
330340
/* Overwrite ret if an error occurred in disable_channels */
331341
ret = command_ret ? command_ret : ret;
332342

0 commit comments

Comments
 (0)