Skip to content

Commit c5c1e31

Browse files
theihorAlexei Starovoitov
authored andcommitted
resolve_btfids: Fix memory leaks reported by ASAN
Running resolve_btfids with ASAN reveals memory leaks in btf_id handling. - Change get_id() to use a local buffer - Make btf_id__add() strdup the name internally - Add btf_id__free_all() that frees all nodese of a tree - Call the cleanup function on exit for every tree Acked-by: Jiri Olsa <jolsa@kernel.org> Signed-off-by: Ihor Solodrai <ihor.solodrai@linux.dev> Link: https://lore.kernel.org/r/20260223190736.649171-8-ihor.solodrai@linux.dev Signed-off-by: Alexei Starovoitov <ast@kernel.org>
1 parent 4021848 commit c5c1e31

1 file changed

Lines changed: 54 additions & 27 deletions

File tree

  • tools/bpf/resolve_btfids

tools/bpf/resolve_btfids/main.c

Lines changed: 54 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,7 @@ static struct btf_id *btf_id__find(struct rb_root *root, const char *name)
226226
}
227227

228228
static struct btf_id *__btf_id__add(struct rb_root *root,
229-
char *name,
229+
const char *name,
230230
enum btf_id_kind kind,
231231
bool unique)
232232
{
@@ -250,25 +250,33 @@ static struct btf_id *__btf_id__add(struct rb_root *root,
250250
id = zalloc(sizeof(*id));
251251
if (id) {
252252
pr_debug("adding symbol %s\n", name);
253-
id->name = name;
253+
id->name = strdup(name);
254+
if (!id->name) {
255+
free(id);
256+
return NULL;
257+
}
254258
id->kind = kind;
255259
rb_link_node(&id->rb_node, parent, p);
256260
rb_insert_color(&id->rb_node, root);
257261
}
258262
return id;
259263
}
260264

261-
static inline struct btf_id *btf_id__add(struct rb_root *root, char *name, enum btf_id_kind kind)
265+
static inline struct btf_id *btf_id__add(struct rb_root *root,
266+
const char *name,
267+
enum btf_id_kind kind)
262268
{
263269
return __btf_id__add(root, name, kind, false);
264270
}
265271

266-
static inline struct btf_id *btf_id__add_unique(struct rb_root *root, char *name, enum btf_id_kind kind)
272+
static inline struct btf_id *btf_id__add_unique(struct rb_root *root,
273+
const char *name,
274+
enum btf_id_kind kind)
267275
{
268276
return __btf_id__add(root, name, kind, true);
269277
}
270278

271-
static char *get_id(const char *prefix_end)
279+
static int get_id(const char *prefix_end, char *buf, size_t buf_sz)
272280
{
273281
/*
274282
* __BTF_ID__func__vfs_truncate__0
@@ -277,28 +285,28 @@ static char *get_id(const char *prefix_end)
277285
*/
278286
int len = strlen(prefix_end);
279287
int pos = sizeof("__") - 1;
280-
char *p, *id;
288+
char *p;
281289

282290
if (pos >= len)
283-
return NULL;
291+
return -1;
284292

285-
id = strdup(prefix_end + pos);
286-
if (id) {
287-
/*
288-
* __BTF_ID__func__vfs_truncate__0
289-
* id = ^
290-
*
291-
* cut the unique id part
292-
*/
293-
p = strrchr(id, '_');
294-
p--;
295-
if (*p != '_') {
296-
free(id);
297-
return NULL;
298-
}
299-
*p = '\0';
300-
}
301-
return id;
293+
if (len - pos >= buf_sz)
294+
return -1;
295+
296+
strcpy(buf, prefix_end + pos);
297+
/*
298+
* __BTF_ID__func__vfs_truncate__0
299+
* buf = ^
300+
*
301+
* cut the unique id part
302+
*/
303+
p = strrchr(buf, '_');
304+
p--;
305+
if (*p != '_')
306+
return -1;
307+
*p = '\0';
308+
309+
return 0;
302310
}
303311

304312
static struct btf_id *add_set(struct object *obj, char *name, enum btf_id_kind kind)
@@ -335,17 +343,31 @@ static struct btf_id *add_set(struct object *obj, char *name, enum btf_id_kind k
335343

336344
static struct btf_id *add_symbol(struct rb_root *root, char *name, size_t size)
337345
{
338-
char *id;
346+
char id[KSYM_NAME_LEN];
339347

340-
id = get_id(name + size);
341-
if (!id) {
348+
if (get_id(name + size, id, sizeof(id))) {
342349
pr_err("FAILED to parse symbol name: %s\n", name);
343350
return NULL;
344351
}
345352

346353
return btf_id__add(root, id, BTF_ID_KIND_SYM);
347354
}
348355

356+
static void btf_id__free_all(struct rb_root *root)
357+
{
358+
struct rb_node *next;
359+
struct btf_id *id;
360+
361+
next = rb_first(root);
362+
while (next) {
363+
id = rb_entry(next, struct btf_id, rb_node);
364+
next = rb_next(&id->rb_node);
365+
rb_erase(&id->rb_node, root);
366+
free(id->name);
367+
free(id);
368+
}
369+
}
370+
349371
static void bswap_32_data(void *data, u32 nr_bytes)
350372
{
351373
u32 cnt, i;
@@ -1547,6 +1569,11 @@ int main(int argc, const char **argv)
15471569
out:
15481570
btf__free(obj.base_btf);
15491571
btf__free(obj.btf);
1572+
btf_id__free_all(&obj.structs);
1573+
btf_id__free_all(&obj.unions);
1574+
btf_id__free_all(&obj.typedefs);
1575+
btf_id__free_all(&obj.funcs);
1576+
btf_id__free_all(&obj.sets);
15501577
if (obj.efile.elf) {
15511578
elf_end(obj.efile.elf);
15521579
close(obj.efile.fd);

0 commit comments

Comments
 (0)