Skip to content

Commit bbdcbc8

Browse files
Tao ChenKernel Patches Daemon
authored andcommitted
bpftool: Add bpf_token show
Add `bpftool token show` command to get token info from bpffs in /proc/mounts. Example plain output for `token show`: token_info /sys/fs/bpf/token allowed_cmds: map_create prog_load allowed_maps: allowed_progs: kprobe allowed_attachs: xdp token_info /sys/fs/bpf/token2 allowed_cmds: map_create prog_load allowed_maps: allowed_progs: kprobe allowed_attachs: xdp Example json output for `token show`: [{ "token_info": "/sys/fs/bpf/token", "allowed_cmds": ["map_create", "prog_load"], "allowed_maps": [], "allowed_progs": ["kprobe"], "allowed_attachs": ["xdp"] }, { "token_info": "/sys/fs/bpf/token2", "allowed_cmds": ["map_create", "prog_load"], "allowed_maps": [], "allowed_progs": ["kprobe"], "allowed_attachs": ["xdp"] }] Signed-off-by: Tao Chen <[email protected]>
1 parent 4bae2d4 commit bbdcbc8

File tree

3 files changed

+235
-1
lines changed

3 files changed

+235
-1
lines changed

tools/bpf/bpftool/main.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ static int do_help(int argc, char **argv)
6161
" %s batch file FILE\n"
6262
" %s version\n"
6363
"\n"
64-
" OBJECT := { prog | map | link | cgroup | perf | net | feature | btf | gen | struct_ops | iter }\n"
64+
" OBJECT := { prog | map | link | cgroup | perf | net | feature | btf | gen | struct_ops | iter | token }\n"
6565
" " HELP_SPEC_OPTIONS " |\n"
6666
" {-V|--version} }\n"
6767
"",
@@ -87,6 +87,7 @@ static const struct cmd commands[] = {
8787
{ "gen", do_gen },
8888
{ "struct_ops", do_struct_ops },
8989
{ "iter", do_iter },
90+
{ "token", do_token },
9091
{ "version", do_version },
9192
{ 0 }
9293
};

tools/bpf/bpftool/main.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,7 @@ int do_tracelog(int argc, char **arg) __weak;
166166
int do_feature(int argc, char **argv) __weak;
167167
int do_struct_ops(int argc, char **argv) __weak;
168168
int do_iter(int argc, char **argv) __weak;
169+
int do_token(int argc, char **argv) __weak;
169170

170171
int parse_u32_arg(int *argc, char ***argv, __u32 *val, const char *what);
171172
int prog_parse_fd(int *argc, char ***argv);

tools/bpf/bpftool/token.c

Lines changed: 232 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,232 @@
1+
// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2+
/* Copyright (C) 2025 Didi Technology Co., Tao Chen */
3+
4+
#ifndef _GNU_SOURCE
5+
#define _GNU_SOURCE
6+
#endif
7+
#include <errno.h>
8+
#include <fcntl.h>
9+
#include <stdbool.h>
10+
#include <stdio.h>
11+
#include <stdlib.h>
12+
#include <string.h>
13+
#include <unistd.h>
14+
#include <mntent.h>
15+
#include <sys/types.h>
16+
#include <sys/stat.h>
17+
18+
#include "json_writer.h"
19+
#include "main.h"
20+
21+
#define MOUNTS_FILE "/proc/mounts"
22+
23+
static bool has_delegate_options(const char *mnt_ops)
24+
{
25+
return strstr(mnt_ops, "delegate_cmds") != NULL ||
26+
strstr(mnt_ops, "delegate_maps") != NULL ||
27+
strstr(mnt_ops, "delegate_progs") != NULL ||
28+
strstr(mnt_ops, "delegate_attachs") != NULL;
29+
}
30+
31+
static char *get_delegate_value(const char *opts, const char *key)
32+
{
33+
char *token, *rest, *ret = NULL;
34+
char *opts_copy = strdup(opts);
35+
36+
if (!opts_copy)
37+
return NULL;
38+
39+
for (token = strtok_r(opts_copy, ",", &rest); token != NULL;
40+
token = strtok_r(NULL, ",", &rest)) {
41+
if (strncmp(token, key, strlen(key)) == 0 &&
42+
token[strlen(key)] == '=') {
43+
ret = token + strlen(key) + 1;
44+
break;
45+
}
46+
}
47+
free(opts_copy);
48+
49+
return ret;
50+
}
51+
52+
static void print_items_per_line(const char *input, int items_per_line)
53+
{
54+
char *str, *rest, *strs;
55+
int cnt = 0;
56+
57+
if (!input)
58+
return;
59+
60+
strs = strdup(input);
61+
if (!strs)
62+
return;
63+
64+
for (str = strtok_r(strs, ":", &rest); str != NULL;
65+
str = strtok_r(NULL, ":", &rest)) {
66+
if (cnt % items_per_line == 0)
67+
printf("\n\t ");
68+
69+
printf("%-20s", str);
70+
cnt++;
71+
}
72+
73+
free(strs);
74+
}
75+
76+
#define ITEMS_PER_LINE 4
77+
static void show_token_info_plain(struct mntent *mntent)
78+
{
79+
char *value;
80+
81+
printf("token_info %s", mntent->mnt_dir);
82+
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);
90+
91+
printf("\n\tallowed_progs:");
92+
value = get_delegate_value(mntent->mnt_opts, "delegate_progs");
93+
print_items_per_line(value, ITEMS_PER_LINE);
94+
95+
printf("\n\tallowed_attachs:");
96+
value = get_delegate_value(mntent->mnt_opts, "delegate_attachs");
97+
print_items_per_line(value, ITEMS_PER_LINE);
98+
printf("\n");
99+
}
100+
101+
static void split_json_array_str(const char *input)
102+
{
103+
char *str, *rest, *strs;
104+
105+
if (!input) {
106+
jsonw_start_array(json_wtr);
107+
jsonw_end_array(json_wtr);
108+
return;
109+
}
110+
111+
strs = strdup(input);
112+
if (!strs)
113+
return;
114+
115+
jsonw_start_array(json_wtr);
116+
for (str = strtok_r(strs, ":", &rest); str != NULL;
117+
str = strtok_r(NULL, ":", &rest)) {
118+
jsonw_string(json_wtr, str);
119+
}
120+
jsonw_end_array(json_wtr);
121+
122+
free(strs);
123+
}
124+
125+
static void show_token_info_json(struct mntent *mntent)
126+
{
127+
char *value;
128+
129+
jsonw_start_object(json_wtr);
130+
131+
jsonw_string_field(json_wtr, "token_info", mntent->mnt_dir);
132+
133+
jsonw_name(json_wtr, "allowed_cmds");
134+
value = get_delegate_value(mntent->mnt_opts, "delegate_cmds");
135+
split_json_array_str(value);
136+
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);
148+
149+
jsonw_end_object(json_wtr);
150+
}
151+
152+
static int __show_token_info(struct mntent *mntent)
153+
{
154+
155+
if (json_output)
156+
show_token_info_json(mntent);
157+
else
158+
show_token_info_plain(mntent);
159+
160+
return 0;
161+
}
162+
163+
static int show_token_info(void)
164+
{
165+
FILE *fp;
166+
struct mntent *ent;
167+
bool hit = false;
168+
169+
fp = setmntent(MOUNTS_FILE, "r");
170+
if (!fp) {
171+
p_err("Failed to open: %s", MOUNTS_FILE);
172+
return -1;
173+
}
174+
175+
if (json_output)
176+
jsonw_start_array(json_wtr);
177+
178+
while ((ent = getmntent(fp)) != NULL) {
179+
if (strncmp(ent->mnt_type, "bpf", 3) == 0) {
180+
if (has_delegate_options(ent->mnt_opts)) {
181+
__show_token_info(ent);
182+
hit = true;
183+
}
184+
}
185+
}
186+
187+
if (json_output)
188+
jsonw_end_array(json_wtr);
189+
190+
if (!hit)
191+
p_info("Token info not found");
192+
193+
endmntent(fp);
194+
195+
return 0;
196+
}
197+
198+
static int do_show(int argc, char **argv)
199+
{
200+
if (argc)
201+
return BAD_ARG();
202+
203+
return show_token_info();
204+
}
205+
206+
static int do_help(int argc, char **argv)
207+
{
208+
if (json_output) {
209+
jsonw_null(json_wtr);
210+
return 0;
211+
}
212+
213+
fprintf(stderr,
214+
"Usage: %1$s %2$s { show | list }\n"
215+
" %1$s %2$s help\n"
216+
"\n"
217+
"",
218+
bin_name, argv[-2]);
219+
return 0;
220+
}
221+
222+
static const struct cmd cmds[] = {
223+
{ "show", do_show },
224+
{ "list", do_show },
225+
{ "help", do_help },
226+
{ 0 }
227+
};
228+
229+
int do_token(int argc, char **argv)
230+
{
231+
return cmd_select(cmds, argc, argv, do_help);
232+
}

0 commit comments

Comments
 (0)