Skip to content

Commit 5731fed

Browse files
Tao ChenKernel Patches Daemon
authored andcommitted
bpftool: Add bpf_token show
Add `bpftool token show` command to get token info from bpf fs 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 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" ] } Signed-off-by: Tao Chen <[email protected]>
1 parent 749128d commit 5731fed

File tree

3 files changed

+232
-1
lines changed

3 files changed

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

0 commit comments

Comments
 (0)