Skip to content

Commit 834594b

Browse files
Blaise BoscaccyKernel Patches Daemon
authored andcommitted
bpftool: Add support for signing program and map hash chains
Add a new mode of operation for program loading which supports the generation of signed hash chains for light skeletons, using the new signed map hash chain UAPI additions. e.g bpftool prog load -S -M -k <private_key> -i <identity_cert> fentry_test.bpf.o The -M or --sign-maps command line switch is introduced. It generates a hash chain such that: H(program, maps) = sha256(sha256(program), sha256(map[0])) Signed-off-by: Blaise Boscaccy <[email protected]>
1 parent d564b58 commit 834594b

File tree

8 files changed

+62
-9
lines changed

8 files changed

+62
-9
lines changed

tools/bpf/bpftool/Documentation/bpftool-gen.rst

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ SYNOPSIS
1616

1717
**bpftool** [*OPTIONS*] **gen** *COMMAND*
1818

19-
*OPTIONS* := { |COMMON_OPTIONS| | { **-L** | **--use-loader** } | [ { **-S** | **--sign** } {**-k** <private_key.pem>} **-i** <certificate.x509> ] }
19+
*OPTIONS* := { |COMMON_OPTIONS| | { **-L** | **--use-loader** } | [ { **-S** | **--sign** } { **-M** | **--sign-maps** } {**-k** <private_key.pem>} **-i** <certificate.x509> ] }
2020

2121
*COMMAND* := { **object** | **skeleton** | **help** }
2222

@@ -190,6 +190,11 @@ OPTIONS
190190
For skeletons, generate a signed skeleton. This option must be used with
191191
**-k** and **-i**. Using this flag implicitly enables **--use-loader**.
192192

193+
-M --sign-maps
194+
For skeletons, generate a signed skeleton that includes a hash chain for the
195+
skeletons maps. This option must be used with **-k** and **-i**. Using this
196+
flag implicitly enables **--use-loader** and **--sign**.
197+
193198
-k <private_key.pem>
194199
Path to the private key file in PEM format, required for signing.
195200

tools/bpf/bpftool/bash-completion/bpftool

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,7 @@ _bpftool()
262262
# Deal with options
263263
if [[ ${words[cword]} == -* ]]; then
264264
local c='--version --json --pretty --bpffs --mapcompat --debug \
265-
--use-loader --base-btf --sign -i -k'
265+
--use-loader --base-btf --sign --sign-maps -i -k'
266266
COMPREPLY=( $( compgen -W "$c" -- "$cur" ) )
267267
return 0
268268
fi

tools/bpf/bpftool/gen.c

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -699,6 +699,9 @@ static int gen_trace(struct bpf_object *obj, const char *obj_name, const char *h
699699
if (sign_progs)
700700
opts.gen_hash = true;
701701

702+
if (sign_maps)
703+
opts.sign_maps = true;
704+
702705
err = bpf_object__gen_loader(obj, &opts);
703706
if (err)
704707
return err;
@@ -793,6 +796,8 @@ static int gen_trace(struct bpf_object *obj, const char *obj_name, const char *h
793796
if (sign_progs) {
794797
sopts.insns = opts.insns;
795798
sopts.insns_sz = opts.insns_sz;
799+
sopts.data = opts.data;
800+
sopts.data_sz = opts.data_sz;
796801
sopts.excl_prog_hash = prog_sha;
797802
sopts.excl_prog_hash_sz = sizeof(prog_sha);
798803
sopts.signature = sig_buf;
@@ -822,6 +827,13 @@ static int gen_trace(struct bpf_object *obj, const char *obj_name, const char *h
822827
\n\
823828
\";\n");
824829

830+
if (sign_maps) {
831+
codegen("\
832+
\n\
833+
static const int opts_signature_maps[1] __attribute__((__aligned__(8))) = {0}; \n\
834+
");
835+
}
836+
825837
codegen("\
826838
\n\
827839
opts.signature = (void *)opts_sig; \n\
@@ -830,6 +842,19 @@ static int gen_trace(struct bpf_object *obj, const char *obj_name, const char *h
830842
opts.excl_prog_hash_sz = sizeof(opts_excl_hash) - 1; \n\
831843
opts.keyring_id = skel->keyring_id; \n\
832844
");
845+
if (sign_maps) {
846+
codegen("\
847+
\n\
848+
opts.signature_maps = (void *)opts_signature_maps; \n\
849+
opts.signature_maps_sz = 1; \n\
850+
");
851+
} else {
852+
codegen("\
853+
\n\
854+
opts.signature_maps = (void *)NULL; \n\
855+
opts.signature_maps_sz = 0; \n\
856+
");
857+
}
833858
}
834859

835860
codegen("\
@@ -1990,7 +2015,7 @@ static int do_help(int argc, char **argv)
19902015
" %1$s %2$s help\n"
19912016
"\n"
19922017
" " HELP_SPEC_OPTIONS " |\n"
1993-
" {-L|--use-loader} | [ {-S|--sign } {-k} <private_key.pem> {-i} <certificate.x509> ]}\n"
2018+
" {-L|--use-loader} | [ {-S|--sign } {-M|--sign-maps } {-k} <private_key.pem> {-i} <certificate.x509> ]}\n"
19942019
"",
19952020
bin_name, "gen");
19962021

tools/bpf/bpftool/main.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ bool use_loader;
3434
struct btf *base_btf;
3535
struct hashmap *refs_table;
3636
bool sign_progs;
37+
bool sign_maps;
3738
const char *private_key_path;
3839
const char *cert_path;
3940

@@ -452,6 +453,7 @@ int main(int argc, char **argv)
452453
{ "debug", no_argument, NULL, 'd' },
453454
{ "use-loader", no_argument, NULL, 'L' },
454455
{ "sign", no_argument, NULL, 'S' },
456+
{ "sign-maps", no_argument, NULL, 'M' },
455457
{ "base-btf", required_argument, NULL, 'B' },
456458
{ 0 }
457459
};
@@ -478,7 +480,7 @@ int main(int argc, char **argv)
478480
bin_name = "bpftool";
479481

480482
opterr = 0;
481-
while ((opt = getopt_long(argc, argv, "VhpjfLmndSi:k:B:l",
483+
while ((opt = getopt_long(argc, argv, "VhpjfLmndSMi:k:B:l",
482484
options, NULL)) >= 0) {
483485
switch (opt) {
484486
case 'V':
@@ -528,6 +530,11 @@ int main(int argc, char **argv)
528530
sign_progs = true;
529531
use_loader = true;
530532
break;
533+
case 'M':
534+
sign_maps = true;
535+
sign_progs = true;
536+
use_loader = true;
537+
break;
531538
case 'k':
532539
private_key_path = optarg;
533540
break;

tools/bpf/bpftool/main.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ extern bool use_loader;
9292
extern struct btf *base_btf;
9393
extern struct hashmap *refs_table;
9494
extern bool sign_progs;
95+
extern bool sign_maps;
9596
extern const char *private_key_path;
9697
extern const char *cert_path;
9798

tools/bpf/bpftool/sign.c

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include <errno.h>
2424

2525
#include <bpf/skel_internal.h>
26+
#include <bpf/libbpf_internal.h>
2627

2728
#include "main.h"
2829

@@ -130,8 +131,17 @@ int bpftool_prog_sign(struct bpf_load_and_run_opts *opts)
130131
long actual_sig_len = 0;
131132
X509 *x509 = NULL;
132133
int err = 0;
133-
134-
bd_in = BIO_new_mem_buf(opts->insns, opts->insns_sz);
134+
unsigned char hash[SHA256_DIGEST_LENGTH * 2];
135+
unsigned char term[SHA256_DIGEST_LENGTH];
136+
137+
if (sign_maps) {
138+
libbpf_sha256(opts->insns, opts->insns_sz, hash);
139+
libbpf_sha256(opts->data, opts->data_sz, hash + SHA256_DIGEST_LENGTH);
140+
libbpf_sha256(hash, sizeof(hash), term);
141+
bd_in = BIO_new_mem_buf(term, sizeof(term));
142+
} else {
143+
bd_in = BIO_new_mem_buf(opts->insns, opts->insns_sz);
144+
}
135145
if (!bd_in) {
136146
err = -ENOMEM;
137147
goto cleanup;
@@ -172,7 +182,7 @@ int bpftool_prog_sign(struct bpf_load_and_run_opts *opts)
172182
EVP_Digest(opts->insns, opts->insns_sz, opts->excl_prog_hash,
173183
&opts->excl_prog_hash_sz, EVP_sha256(), NULL);
174184

175-
bd_out = BIO_new(BIO_s_mem());
185+
bd_out = BIO_new(BIO_s_mem());
176186
if (!bd_out) {
177187
err = -ENOMEM;
178188
goto cleanup;

tools/lib/bpf/libbpf.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1858,9 +1858,10 @@ struct gen_loader_opts {
18581858
__u32 data_sz;
18591859
__u32 insns_sz;
18601860
bool gen_hash;
1861+
bool sign_maps;
18611862
};
18621863

1863-
#define gen_loader_opts__last_field gen_hash
1864+
#define gen_loader_opts__last_field sign_maps
18641865
LIBBPF_API int bpf_object__gen_loader(struct bpf_object *obj,
18651866
struct gen_loader_opts *opts);
18661867

tools/lib/bpf/skel_internal.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ struct bpf_load_and_run_opts {
7474
__s32 keyring_id;
7575
void *excl_prog_hash;
7676
__u32 excl_prog_hash_sz;
77+
const int *signature_maps;
78+
__u32 signature_maps_sz;
7779
};
7880

7981
long kern_sys_bpf(__u32 cmd, void *attr, __u32 attr_size);
@@ -352,7 +354,7 @@ static inline int skel_map_freeze(int fd)
352354

353355
static inline int bpf_load_and_run(struct bpf_load_and_run_opts *opts)
354356
{
355-
const size_t prog_load_attr_sz = offsetofend(union bpf_attr, keyring_id);
357+
const size_t prog_load_attr_sz = offsetofend(union bpf_attr, signature_maps_size);
356358
const size_t test_run_attr_sz = offsetofend(union bpf_attr, test);
357359
int map_fd = -1, prog_fd = -1, key = 0, err;
358360
union bpf_attr attr;
@@ -395,6 +397,8 @@ static inline int bpf_load_and_run(struct bpf_load_and_run_opts *opts)
395397
#ifndef __KERNEL__
396398
attr.signature = (long) opts->signature;
397399
attr.signature_size = opts->signature_sz;
400+
attr.signature_maps = (long) opts->signature_maps;
401+
attr.signature_maps_size = opts->signature_maps_sz;
398402
#else
399403
if (opts->signature || opts->signature_sz)
400404
pr_warn("signatures are not supported from bpf_preload\n");

0 commit comments

Comments
 (0)