Skip to content

Commit 453b7f0

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]>
1 parent 0b22bc9 commit 453b7f0

File tree

1 file changed

+33
-42
lines changed

1 file changed

+33
-42
lines changed

tools/bpf/bpftool/token.c

Lines changed: 33 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -28,123 +28,114 @@ static bool has_delegate_options(const char *mnt_ops)
2828
strstr(mnt_ops, "delegate_attachs");
2929
}
3030

31-
static char *get_delegate_value(const char *opts, const char *key)
31+
static char *get_delegate_value(char *opts, const char *key)
3232
{
3333
char *token, *rest, *ret = NULL;
34-
char *opts_copy = strdup(opts);
3534

36-
if (!opts_copy)
35+
if (!opts)
3736
return NULL;
3837

39-
for (token = strtok_r(opts_copy, ",", &rest); token;
38+
for (token = strtok_r(opts, ",", &rest); token;
4039
token = strtok_r(NULL, ",", &rest)) {
4140
if (strncmp(token, key, strlen(key)) == 0 &&
4241
token[strlen(key)] == '=') {
4342
ret = token + strlen(key) + 1;
4443
break;
4544
}
4645
}
47-
free(opts_copy);
4846

4947
return ret;
5048
}
5149

52-
static void print_items_per_line(const char *input, int items_per_line)
50+
static void print_items_per_line(char *input, int items_per_line)
5351
{
54-
char *str, *rest, *strs;
52+
char *str, *rest;
5553
int cnt = 0;
5654

5755
if (!input)
5856
return;
5957

60-
strs = strdup(input);
61-
if (!strs)
62-
return;
63-
64-
for (str = strtok_r(strs, ":", &rest); str;
58+
for (str = strtok_r(input, ":", &rest); str;
6559
str = strtok_r(NULL, ":", &rest)) {
6660
if (cnt % items_per_line == 0)
6761
printf("\n\t ");
6862

6963
printf("%-20s", str);
7064
cnt++;
7165
}
72-
73-
free(strs);
7466
}
7567

68+
#define PRINT_DELEGATE_OPT(opt_name) do { \
69+
char *opts, *value; \
70+
opts = strdup(mntent->mnt_opts); \
71+
value = get_delegate_value(opts, opt_name); \
72+
print_items_per_line(value, ITEMS_PER_LINE); \
73+
free(opts); \
74+
} while (0)
75+
7676
#define ITEMS_PER_LINE 4
7777
static void show_token_info_plain(struct mntent *mntent)
7878
{
79-
char *value;
8079

8180
printf("token_info %s", mntent->mnt_dir);
8281

8382
printf("\n\tallowed_cmds:");
84-
value = get_delegate_value(mntent->mnt_opts, "delegate_cmds");
85-
print_items_per_line(value, ITEMS_PER_LINE);
83+
PRINT_DELEGATE_OPT("delegate_cmds");
8684

8785
printf("\n\tallowed_maps:");
88-
value = get_delegate_value(mntent->mnt_opts, "delegate_maps");
89-
print_items_per_line(value, ITEMS_PER_LINE);
86+
PRINT_DELEGATE_OPT("delegate_maps");
9087

9188
printf("\n\tallowed_progs:");
92-
value = get_delegate_value(mntent->mnt_opts, "delegate_progs");
93-
print_items_per_line(value, ITEMS_PER_LINE);
89+
PRINT_DELEGATE_OPT("delegate_progs");
9490

9591
printf("\n\tallowed_attachs:");
96-
value = get_delegate_value(mntent->mnt_opts, "delegate_attachs");
97-
print_items_per_line(value, ITEMS_PER_LINE);
92+
PRINT_DELEGATE_OPT("delegate_attachs");
9893
printf("\n");
9994
}
10095

101-
static void split_json_array_str(const char *input)
96+
static void split_json_array_str(char *input)
10297
{
103-
char *str, *rest, *strs;
98+
char *str, *rest;
10499

105100
if (!input) {
106101
jsonw_start_array(json_wtr);
107102
jsonw_end_array(json_wtr);
108103
return;
109104
}
110105

111-
strs = strdup(input);
112-
if (!strs)
113-
return;
114-
115106
jsonw_start_array(json_wtr);
116-
for (str = strtok_r(strs, ":", &rest); str;
107+
for (str = strtok_r(input, ":", &rest); str;
117108
str = strtok_r(NULL, ":", &rest)) {
118109
jsonw_string(json_wtr, str);
119110
}
120111
jsonw_end_array(json_wtr);
121-
122-
free(strs);
123112
}
124113

114+
#define PRINT_DELEGATE_OPT_JSON(opt_name) do { \
115+
char *opts, *value; \
116+
opts = strdup(mntent->mnt_opts); \
117+
value = get_delegate_value(opts, opt_name); \
118+
split_json_array_str(value); \
119+
free(opts); \
120+
} while (0)
121+
125122
static void show_token_info_json(struct mntent *mntent)
126123
{
127-
char *value;
128-
129124
jsonw_start_object(json_wtr);
130125

131126
jsonw_string_field(json_wtr, "token_info", mntent->mnt_dir);
132127

133128
jsonw_name(json_wtr, "allowed_cmds");
134-
value = get_delegate_value(mntent->mnt_opts, "delegate_cmds");
135-
split_json_array_str(value);
129+
PRINT_DELEGATE_OPT_JSON("delegate_cmds");
136130

137131
jsonw_name(json_wtr, "allowed_maps");
138-
value = get_delegate_value(mntent->mnt_opts, "delegate_maps");
139-
split_json_array_str(value);
132+
PRINT_DELEGATE_OPT_JSON("delegate_maps");
140133

141134
jsonw_name(json_wtr, "allowed_progs");
142-
value = get_delegate_value(mntent->mnt_opts, "delegate_progs");
143-
split_json_array_str(value);
135+
PRINT_DELEGATE_OPT_JSON("delegate_progs");
144136

145137
jsonw_name(json_wtr, "allowed_attachs");
146-
value = get_delegate_value(mntent->mnt_opts, "delegate_attachs");
147-
split_json_array_str(value);
138+
PRINT_DELEGATE_OPT_JSON("delegate_attachs");
148139

149140
jsonw_end_object(json_wtr);
150141
}

0 commit comments

Comments
 (0)