Skip to content

Commit fd0a06b

Browse files
Tao ChenKernel Patches Daemon
authored andcommitted
bpftool: Fix UAF in get_delegate_value
The return value ret pointer is pointing opts_copy, but opts_copy gets freed in get_delegate_value before return, fix this by free the mntent->mnt_opts strdup memory after show delegate value. Fixes: 2d81231 ("bpftool: Add bpf_token show") Signed-off-by: Tao Chen <[email protected]> Reviewed-by: Quentin Monnet <[email protected]>
1 parent efd3a6b commit fd0a06b

File tree

1 file changed

+37
-53
lines changed

1 file changed

+37
-53
lines changed

tools/bpf/bpftool/token.c

Lines changed: 37 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,16 @@
2020

2121
#define MOUNTS_FILE "/proc/mounts"
2222

23+
struct {
24+
const char *header;
25+
const char *key;
26+
} sets[] = {
27+
{"allowed_cmds", "delegate_cmds"},
28+
{"allowed_maps", "delegate_maps"},
29+
{"allowed_progs", "delegate_progs"},
30+
{"allowed_attachs", "delegate_attachs"},
31+
};
32+
2333
static bool has_delegate_options(const char *mnt_ops)
2434
{
2535
return strstr(mnt_ops, "delegate_cmds") ||
@@ -28,123 +38,97 @@ static bool has_delegate_options(const char *mnt_ops)
2838
strstr(mnt_ops, "delegate_attachs");
2939
}
3040

31-
static char *get_delegate_value(const char *opts, const char *key)
41+
static char *get_delegate_value(char *opts, const char *key)
3242
{
3343
char *token, *rest, *ret = NULL;
34-
char *opts_copy = strdup(opts);
3544

36-
if (!opts_copy)
45+
if (!opts)
3746
return NULL;
3847

39-
for (token = strtok_r(opts_copy, ",", &rest); token;
48+
for (token = strtok_r(opts, ",", &rest); token;
4049
token = strtok_r(NULL, ",", &rest)) {
4150
if (strncmp(token, key, strlen(key)) == 0 &&
4251
token[strlen(key)] == '=') {
4352
ret = token + strlen(key) + 1;
4453
break;
4554
}
4655
}
47-
free(opts_copy);
4856

4957
return ret;
5058
}
5159

52-
static void print_items_per_line(const char *input, int items_per_line)
60+
static void print_items_per_line(char *input, int items_per_line)
5361
{
54-
char *str, *rest, *strs;
62+
char *str, *rest;
5563
int cnt = 0;
5664

5765
if (!input)
5866
return;
5967

60-
strs = strdup(input);
61-
if (!strs)
62-
return;
63-
64-
for (str = strtok_r(strs, ":", &rest); str;
68+
for (str = strtok_r(input, ":", &rest); str;
6569
str = strtok_r(NULL, ":", &rest)) {
6670
if (cnt % items_per_line == 0)
6771
printf("\n\t ");
6872

6973
printf("%-20s", str);
7074
cnt++;
7175
}
72-
73-
free(strs);
7476
}
7577

7678
#define ITEMS_PER_LINE 4
7779
static void show_token_info_plain(struct mntent *mntent)
7880
{
79-
char *value;
81+
size_t i;
8082

8183
printf("token_info %s", mntent->mnt_dir);
8284

83-
printf("\n\tallowed_cmds:");
84-
value = get_delegate_value(mntent->mnt_opts, "delegate_cmds");
85-
print_items_per_line(value, ITEMS_PER_LINE);
86-
87-
printf("\n\tallowed_maps:");
88-
value = get_delegate_value(mntent->mnt_opts, "delegate_maps");
89-
print_items_per_line(value, ITEMS_PER_LINE);
85+
for (i = 0; i < ARRAY_SIZE(sets); i++) {
86+
char *opts, *value;
9087

91-
printf("\n\tallowed_progs:");
92-
value = get_delegate_value(mntent->mnt_opts, "delegate_progs");
93-
print_items_per_line(value, ITEMS_PER_LINE);
88+
printf("\n\t%s:", sets[i].header);
89+
opts = strdup(mntent->mnt_opts);
90+
value = get_delegate_value(opts, sets[i].key);
91+
print_items_per_line(value, ITEMS_PER_LINE);
92+
free(opts);
93+
}
9494

95-
printf("\n\tallowed_attachs:");
96-
value = get_delegate_value(mntent->mnt_opts, "delegate_attachs");
97-
print_items_per_line(value, ITEMS_PER_LINE);
9895
printf("\n");
9996
}
10097

101-
static void split_json_array_str(const char *input)
98+
static void split_json_array_str(char *input)
10299
{
103-
char *str, *rest, *strs;
100+
char *str, *rest;
104101

105102
if (!input) {
106103
jsonw_start_array(json_wtr);
107104
jsonw_end_array(json_wtr);
108105
return;
109106
}
110107

111-
strs = strdup(input);
112-
if (!strs)
113-
return;
114-
115108
jsonw_start_array(json_wtr);
116-
for (str = strtok_r(strs, ":", &rest); str;
109+
for (str = strtok_r(input, ":", &rest); str;
117110
str = strtok_r(NULL, ":", &rest)) {
118111
jsonw_string(json_wtr, str);
119112
}
120113
jsonw_end_array(json_wtr);
121-
122-
free(strs);
123114
}
124115

125116
static void show_token_info_json(struct mntent *mntent)
126117
{
127-
char *value;
118+
size_t i;
128119

129120
jsonw_start_object(json_wtr);
130-
131121
jsonw_string_field(json_wtr, "token_info", mntent->mnt_dir);
132122

133-
jsonw_name(json_wtr, "allowed_cmds");
134-
value = get_delegate_value(mntent->mnt_opts, "delegate_cmds");
135-
split_json_array_str(value);
123+
for (i = 0; i < ARRAY_SIZE(sets); i++) {
124+
char *opts, *value;
136125

137-
jsonw_name(json_wtr, "allowed_maps");
138-
value = get_delegate_value(mntent->mnt_opts, "delegate_maps");
139-
split_json_array_str(value);
140-
141-
jsonw_name(json_wtr, "allowed_progs");
142-
value = get_delegate_value(mntent->mnt_opts, "delegate_progs");
143-
split_json_array_str(value);
144-
145-
jsonw_name(json_wtr, "allowed_attachs");
146-
value = get_delegate_value(mntent->mnt_opts, "delegate_attachs");
147-
split_json_array_str(value);
126+
jsonw_name(json_wtr, sets[i].header);
127+
opts = strdup(mntent->mnt_opts);
128+
value = get_delegate_value(opts, sets[i].key);
129+
split_json_array_str(value);
130+
free(opts);
131+
}
148132

149133
jsonw_end_object(json_wtr);
150134
}

0 commit comments

Comments
 (0)