2018-06-03 15:59:43 -07:00
// SPDX-License-Identifier: GPL-2.0
// Copyright (c) 2018 Facebook
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# include <errno.h>
# include <fcntl.h>
# include <syscall.h>
# include <unistd.h>
# include <linux/perf_event.h>
# include <sys/ioctl.h>
# include <sys/time.h>
# include <sys/types.h>
# include <sys/stat.h>
# include <linux/bpf.h>
# include <bpf/bpf.h>
# include <bpf/libbpf.h>
# include "cgroup_helpers.h"
2021-11-03 15:08:44 -07:00
# include "testing_helpers.h"
2018-06-03 15:59:43 -07:00
# define CHECK(condition, tag, format...) ({ \
int __ret = ! ! ( condition ) ; \
if ( __ret ) { \
printf ( " %s:FAIL:%s " , __func__ , tag ) ; \
printf ( format ) ; \
} else { \
printf ( " %s:PASS:%s \n " , __func__ , tag ) ; \
} \
__ret ; \
} )
static int bpf_find_map ( const char * test , struct bpf_object * obj ,
const char * name )
{
struct bpf_map * map ;
map = bpf_object__find_map_by_name ( obj , name ) ;
if ( ! map )
return - 1 ;
return bpf_map__fd ( map ) ;
}
# define TEST_CGROUP " / test-bpf-get-cgroup-id / "
int main ( int argc , char * * argv )
{
const char * probe_name = " syscalls/sys_enter_nanosleep " ;
2022-09-01 22:22:53 +00:00
const char * file = " get_cgroup_id_kern.bpf.o " ;
2018-06-03 15:59:43 -07:00
int err , bytes , efd , prog_fd , pmu_fd ;
2018-06-06 09:12:44 -07:00
int cgroup_fd , cgidmap_fd , pidmap_fd ;
2018-06-03 15:59:43 -07:00
struct perf_event_attr attr = { } ;
struct bpf_object * obj ;
__u64 kcgid = 0 , ucgid ;
2018-06-06 09:12:44 -07:00
__u32 key = 0 , pid ;
2018-06-03 15:59:43 -07:00
int exit_code = 1 ;
char buf [ 256 ] ;
2021-03-16 21:00:48 +05:30
const struct timespec req = {
. tv_sec = 1 ,
. tv_nsec = 0 ,
} ;
2018-06-03 15:59:43 -07:00
2020-07-31 15:09:14 -07:00
cgroup_fd = cgroup_setup_and_join ( TEST_CGROUP ) ;
if ( CHECK ( cgroup_fd < 0 , " cgroup_setup_and_join " , " err %d errno %d \n " , cgroup_fd , errno ) )
2018-06-03 15:59:43 -07:00
return 1 ;
2022-04-09 12:59:56 +00:00
/* Use libbpf 1.0 API mode */
libbpf_set_strict_mode ( LIBBPF_STRICT_ALL ) ;
2021-11-03 15:08:44 -07:00
err = bpf_prog_test_load ( file , BPF_PROG_TYPE_TRACEPOINT , & obj , & prog_fd ) ;
if ( CHECK ( err , " bpf_prog_test_load " , " err %d errno %d \n " , err , errno ) )
2018-06-03 15:59:43 -07:00
goto cleanup_cgroup_env ;
cgidmap_fd = bpf_find_map ( __func__ , obj , " cg_ids " ) ;
if ( CHECK ( cgidmap_fd < 0 , " bpf_find_map " , " err %d errno %d \n " ,
cgidmap_fd , errno ) )
goto close_prog ;
2018-06-06 09:12:44 -07:00
pidmap_fd = bpf_find_map ( __func__ , obj , " pidmap " ) ;
if ( CHECK ( pidmap_fd < 0 , " bpf_find_map " , " err %d errno %d \n " ,
pidmap_fd , errno ) )
goto close_prog ;
pid = getpid ( ) ;
bpf_map_update_elem ( pidmap_fd , & key , & pid , 0 ) ;
2018-06-03 15:59:43 -07:00
snprintf ( buf , sizeof ( buf ) ,
" /sys/kernel/debug/tracing/events/%s/id " , probe_name ) ;
efd = open ( buf , O_RDONLY , 0 ) ;
if ( CHECK ( efd < 0 , " open " , " err %d errno %d \n " , efd , errno ) )
goto close_prog ;
bytes = read ( efd , buf , sizeof ( buf ) ) ;
close ( efd ) ;
if ( CHECK ( bytes < = 0 | | bytes > = sizeof ( buf ) , " read " ,
" bytes %d errno %d \n " , bytes , errno ) )
goto close_prog ;
attr . config = strtol ( buf , NULL , 0 ) ;
attr . type = PERF_TYPE_TRACEPOINT ;
attr . sample_type = PERF_SAMPLE_RAW ;
attr . sample_period = 1 ;
attr . wakeup_events = 1 ;
/* attach to this pid so the all bpf invocations will be in the
* cgroup associated with this pid .
*/
pmu_fd = syscall ( __NR_perf_event_open , & attr , getpid ( ) , - 1 , - 1 , 0 ) ;
if ( CHECK ( pmu_fd < 0 , " perf_event_open " , " err %d errno %d \n " , pmu_fd ,
errno ) )
goto close_prog ;
err = ioctl ( pmu_fd , PERF_EVENT_IOC_ENABLE , 0 ) ;
if ( CHECK ( err , " perf_event_ioc_enable " , " err %d errno %d \n " , err ,
errno ) )
goto close_pmu ;
err = ioctl ( pmu_fd , PERF_EVENT_IOC_SET_BPF , prog_fd ) ;
if ( CHECK ( err , " perf_event_ioc_set_bpf " , " err %d errno %d \n " , err ,
errno ) )
goto close_pmu ;
/* trigger some syscalls */
2021-03-16 21:00:48 +05:30
syscall ( __NR_nanosleep , & req , NULL ) ;
2018-06-03 15:59:43 -07:00
err = bpf_map_lookup_elem ( cgidmap_fd , & key , & kcgid ) ;
if ( CHECK ( err , " bpf_map_lookup_elem " , " err %d errno %d \n " , err , errno ) )
goto close_pmu ;
ucgid = get_cgroup_id ( TEST_CGROUP ) ;
if ( CHECK ( kcgid ! = ucgid , " compare_cgroup_id " ,
" kern cgid %llx user cgid %llx " , kcgid , ucgid ) )
goto close_pmu ;
exit_code = 0 ;
printf ( " %s:PASS \n " , argv [ 0 ] ) ;
close_pmu :
close ( pmu_fd ) ;
close_prog :
bpf_object__close ( obj ) ;
cleanup_cgroup_env :
cleanup_cgroup_environment ( ) ;
return exit_code ;
}