1313#include <unistd.h>
1414#include <sys/syscall.h>
1515#include <sys/mman.h>
16+ #include <linux/keyctl.h>
1617#include <stdlib.h>
1718#include "bpf.h"
1819#endif
1920
21+ #ifndef SHA256_DIGEST_LENGTH
22+ #define SHA256_DIGEST_LENGTH 32
23+ #endif
24+
2025#ifndef __NR_bpf
2126# if defined(__mips__ ) && defined(_ABIO32 )
2227# define __NR_bpf 4355
@@ -64,6 +69,11 @@ struct bpf_load_and_run_opts {
6469 __u32 data_sz ;
6570 __u32 insns_sz ;
6671 const char * errstr ;
72+ void * signature ;
73+ __u32 signature_sz ;
74+ __s32 keyring_id ;
75+ void * excl_prog_hash ;
76+ __u32 excl_prog_hash_sz ;
6777};
6878
6979long kern_sys_bpf (__u32 cmd , void * attr , __u32 attr_size );
@@ -220,14 +230,19 @@ static inline int skel_map_create(enum bpf_map_type map_type,
220230 const char * map_name ,
221231 __u32 key_size ,
222232 __u32 value_size ,
223- __u32 max_entries )
233+ __u32 max_entries ,
234+ const void * excl_prog_hash ,
235+ __u32 excl_prog_hash_sz )
224236{
225- const size_t attr_sz = offsetofend (union bpf_attr , map_extra );
237+ const size_t attr_sz = offsetofend (union bpf_attr , excl_prog_hash_size );
226238 union bpf_attr attr ;
227239
228240 memset (& attr , 0 , attr_sz );
229241
230242 attr .map_type = map_type ;
243+ attr .excl_prog_hash = (unsigned long ) excl_prog_hash ;
244+ attr .excl_prog_hash_size = excl_prog_hash_sz ;
245+
231246 strncpy (attr .map_name , map_name , sizeof (attr .map_name ));
232247 attr .key_size = key_size ;
233248 attr .value_size = value_size ;
@@ -300,6 +315,35 @@ static inline int skel_link_create(int prog_fd, int target_fd,
300315 return skel_sys_bpf (BPF_LINK_CREATE , & attr , attr_sz );
301316}
302317
318+ static inline int skel_obj_get_info_by_fd (int fd )
319+ {
320+ const size_t attr_sz = offsetofend (union bpf_attr , info );
321+ __u8 sha [SHA256_DIGEST_LENGTH ];
322+ struct bpf_map_info info ;
323+ __u32 info_len = sizeof (info );
324+ union bpf_attr attr ;
325+
326+ memset (& info , 0 , sizeof (info ));
327+ info .hash = (long ) & sha ;
328+ info .hash_size = SHA256_DIGEST_LENGTH ;
329+
330+ memset (& attr , 0 , attr_sz );
331+ attr .info .bpf_fd = fd ;
332+ attr .info .info = (long ) & info ;
333+ attr .info .info_len = info_len ;
334+ return skel_sys_bpf (BPF_OBJ_GET_INFO_BY_FD , & attr , attr_sz );
335+ }
336+
337+ static inline int skel_map_freeze (int fd )
338+ {
339+ const size_t attr_sz = offsetofend (union bpf_attr , map_fd );
340+ union bpf_attr attr ;
341+
342+ memset (& attr , 0 , attr_sz );
343+ attr .map_fd = fd ;
344+
345+ return skel_sys_bpf (BPF_MAP_FREEZE , & attr , attr_sz );
346+ }
303347#ifdef __KERNEL__
304348#define set_err
305349#else
@@ -308,12 +352,13 @@ static inline int skel_link_create(int prog_fd, int target_fd,
308352
309353static inline int bpf_load_and_run (struct bpf_load_and_run_opts * opts )
310354{
311- const size_t prog_load_attr_sz = offsetofend (union bpf_attr , fd_array );
355+ const size_t prog_load_attr_sz = offsetofend (union bpf_attr , keyring_id );
312356 const size_t test_run_attr_sz = offsetofend (union bpf_attr , test );
313357 int map_fd = -1 , prog_fd = -1 , key = 0 , err ;
314358 union bpf_attr attr ;
315359
316- err = map_fd = skel_map_create (BPF_MAP_TYPE_ARRAY , "__loader.map" , 4 , opts -> data_sz , 1 );
360+ err = map_fd = skel_map_create (BPF_MAP_TYPE_ARRAY , "__loader.map" , 4 , opts -> data_sz , 1 ,
361+ opts -> excl_prog_hash , opts -> excl_prog_hash_sz );
317362 if (map_fd < 0 ) {
318363 opts -> errstr = "failed to create loader map" ;
319364 set_err ;
@@ -327,11 +372,34 @@ static inline int bpf_load_and_run(struct bpf_load_and_run_opts *opts)
327372 goto out ;
328373 }
329374
375+ #ifndef __KERNEL__
376+ err = skel_map_freeze (map_fd );
377+ if (err < 0 ) {
378+ opts -> errstr = "failed to freeze map" ;
379+ set_err ;
380+ goto out ;
381+ }
382+ err = skel_obj_get_info_by_fd (map_fd );
383+ if (err < 0 ) {
384+ opts -> errstr = "failed to fetch obj info" ;
385+ set_err ;
386+ goto out ;
387+ }
388+ #endif
389+
330390 memset (& attr , 0 , prog_load_attr_sz );
331391 attr .prog_type = BPF_PROG_TYPE_SYSCALL ;
332392 attr .insns = (long ) opts -> insns ;
333393 attr .insn_cnt = opts -> insns_sz / sizeof (struct bpf_insn );
334394 attr .license = (long ) "Dual BSD/GPL" ;
395+ #ifndef __KERNEL__
396+ attr .signature = (long ) opts -> signature ;
397+ attr .signature_size = opts -> signature_sz ;
398+ #else
399+ if (opts -> signature || opts -> signature_sz )
400+ pr_warn ("signatures are not supported from bpf_preload\n" );
401+ #endif
402+ attr .keyring_id = opts -> keyring_id ;
335403 memcpy (attr .prog_name , "__loader.prog" , sizeof ("__loader.prog" ));
336404 attr .fd_array = (long ) & map_fd ;
337405 attr .log_level = opts -> ctx -> log_level ;
0 commit comments