Skip to content

Commit 2d81231

Browse files
Tao ChenAlexei Starovoitov
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"] }] Reviewed-by: Quentin Monnet <[email protected]> Signed-off-by: Tao Chen <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Alexei Starovoitov <[email protected]>
1 parent e56f416 commit 2d81231

File tree

3 files changed

+228
-1
lines changed

3 files changed

+228
-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: 225 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,225 @@
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") ||
26+
strstr(mnt_ops, "delegate_maps") ||
27+
strstr(mnt_ops, "delegate_progs") ||
28+
strstr(mnt_ops, "delegate_attachs");
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;
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;
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;
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+
if (json_output)
155+
show_token_info_json(mntent);
156+
else
157+
show_token_info_plain(mntent);
158+
159+
return 0;
160+
}
161+
162+
static int show_token_info(void)
163+
{
164+
FILE *fp;
165+
struct mntent *ent;
166+
167+
fp = setmntent(MOUNTS_FILE, "r");
168+
if (!fp) {
169+
p_err("Failed to open: %s", MOUNTS_FILE);
170+
return -1;
171+
}
172+
173+
if (json_output)
174+
jsonw_start_array(json_wtr);
175+
176+
while ((ent = getmntent(fp)) != NULL) {
177+
if (strncmp(ent->mnt_type, "bpf", 3) == 0) {
178+
if (has_delegate_options(ent->mnt_opts))
179+
__show_token_info(ent);
180+
}
181+
}
182+
183+
if (json_output)
184+
jsonw_end_array(json_wtr);
185+
186+
endmntent(fp);
187+
188+
return 0;
189+
}
190+
191+
static int do_show(int argc, char **argv)
192+
{
193+
if (argc)
194+
return BAD_ARG();
195+
196+
return show_token_info();
197+
}
198+
199+
static int do_help(int argc, char **argv)
200+
{
201+
if (json_output) {
202+
jsonw_null(json_wtr);
203+
return 0;
204+
}
205+
206+
fprintf(stderr,
207+
"Usage: %1$s %2$s { show | list }\n"
208+
" %1$s %2$s help\n"
209+
"\n"
210+
"",
211+
bin_name, argv[-2]);
212+
return 0;
213+
}
214+
215+
static const struct cmd cmds[] = {
216+
{ "show", do_show },
217+
{ "list", do_show },
218+
{ "help", do_help },
219+
{ 0 }
220+
};
221+
222+
int do_token(int argc, char **argv)
223+
{
224+
return cmd_select(cmds, argc, argv, do_help);
225+
}

0 commit comments

Comments
 (0)