@@ -769,6 +769,9 @@ static int userns_obj_priv_btf_success(int mnt_fd)
769
769
return validate_struct_ops_load (mnt_fd , true /* should succeed */ );
770
770
}
771
771
772
+ #define TOKEN_ENVVAR "LIBBPF_BPF_TOKEN_PATH"
773
+ #define TOKEN_BPFFS_CUSTOM "/bpf-token-fs"
774
+
772
775
static int userns_obj_priv_implicit_token (int mnt_fd )
773
776
{
774
777
LIBBPF_OPTS (bpf_object_open_opts , opts );
@@ -791,6 +794,20 @@ static int userns_obj_priv_implicit_token(int mnt_fd)
791
794
if (!ASSERT_OK (err , "move_mount_bpffs" ))
792
795
return - EINVAL ;
793
796
797
+ /* disable implicit BPF token creation by setting
798
+ * LIBBPF_BPF_TOKEN_PATH envvar to empty value, load should fail
799
+ */
800
+ err = setenv (TOKEN_ENVVAR , "" , 1 /*overwrite*/ );
801
+ if (!ASSERT_OK (err , "setenv_token_path" ))
802
+ return - EINVAL ;
803
+ skel = dummy_st_ops_success__open_and_load ();
804
+ if (!ASSERT_ERR_PTR (skel , "obj_token_envvar_disabled_load" )) {
805
+ unsetenv (TOKEN_ENVVAR );
806
+ dummy_st_ops_success__destroy (skel );
807
+ return - EINVAL ;
808
+ }
809
+ unsetenv (TOKEN_ENVVAR );
810
+
794
811
/* now the same struct_ops skeleton should succeed thanks to libppf
795
812
* creating BPF token from /sys/fs/bpf mount point
796
813
*/
@@ -826,6 +843,90 @@ static int userns_obj_priv_implicit_token(int mnt_fd)
826
843
return 0 ;
827
844
}
828
845
846
+ static int userns_obj_priv_implicit_token_envvar (int mnt_fd )
847
+ {
848
+ LIBBPF_OPTS (bpf_object_open_opts , opts );
849
+ struct dummy_st_ops_success * skel ;
850
+ int err ;
851
+
852
+ /* before we mount BPF FS with token delegation, struct_ops skeleton
853
+ * should fail to load
854
+ */
855
+ skel = dummy_st_ops_success__open_and_load ();
856
+ if (!ASSERT_ERR_PTR (skel , "obj_tokenless_load" )) {
857
+ dummy_st_ops_success__destroy (skel );
858
+ return - EINVAL ;
859
+ }
860
+
861
+ /* mount custom BPF FS over custom location, so libbpf can't create
862
+ * BPF token implicitly, unless pointed to it through
863
+ * LIBBPF_BPF_TOKEN_PATH envvar
864
+ */
865
+ rmdir (TOKEN_BPFFS_CUSTOM );
866
+ if (!ASSERT_OK (mkdir (TOKEN_BPFFS_CUSTOM , 0777 ), "mkdir_bpffs_custom" ))
867
+ goto err_out ;
868
+ err = sys_move_mount (mnt_fd , "" , AT_FDCWD , TOKEN_BPFFS_CUSTOM , MOVE_MOUNT_F_EMPTY_PATH );
869
+ if (!ASSERT_OK (err , "move_mount_bpffs" ))
870
+ goto err_out ;
871
+
872
+ /* even though we have BPF FS with delegation, it's not at default
873
+ * /sys/fs/bpf location, so we still fail to load until envvar is set up
874
+ */
875
+ skel = dummy_st_ops_success__open_and_load ();
876
+ if (!ASSERT_ERR_PTR (skel , "obj_tokenless_load2" )) {
877
+ dummy_st_ops_success__destroy (skel );
878
+ goto err_out ;
879
+ }
880
+
881
+ err = setenv (TOKEN_ENVVAR , TOKEN_BPFFS_CUSTOM , 1 /*overwrite*/ );
882
+ if (!ASSERT_OK (err , "setenv_token_path" ))
883
+ goto err_out ;
884
+
885
+ /* now the same struct_ops skeleton should succeed thanks to libppf
886
+ * creating BPF token from custom mount point
887
+ */
888
+ skel = dummy_st_ops_success__open_and_load ();
889
+ if (!ASSERT_OK_PTR (skel , "obj_implicit_token_load" ))
890
+ goto err_out ;
891
+
892
+ dummy_st_ops_success__destroy (skel );
893
+
894
+ /* now disable implicit token through empty bpf_token_path, envvar
895
+ * will be ignored, should fail
896
+ */
897
+ opts .bpf_token_path = "" ;
898
+ skel = dummy_st_ops_success__open_opts (& opts );
899
+ if (!ASSERT_OK_PTR (skel , "obj_empty_token_path_open" ))
900
+ goto err_out ;
901
+
902
+ err = dummy_st_ops_success__load (skel );
903
+ dummy_st_ops_success__destroy (skel );
904
+ if (!ASSERT_ERR (err , "obj_empty_token_path_load" ))
905
+ goto err_out ;
906
+
907
+ /* now disable implicit token through negative bpf_token_fd, envvar
908
+ * will be ignored, should fail
909
+ */
910
+ opts .bpf_token_path = NULL ;
911
+ opts .bpf_token_fd = -1 ;
912
+ skel = dummy_st_ops_success__open_opts (& opts );
913
+ if (!ASSERT_OK_PTR (skel , "obj_neg_token_fd_open" ))
914
+ goto err_out ;
915
+
916
+ err = dummy_st_ops_success__load (skel );
917
+ dummy_st_ops_success__destroy (skel );
918
+ if (!ASSERT_ERR (err , "obj_neg_token_fd_load" ))
919
+ goto err_out ;
920
+
921
+ rmdir (TOKEN_BPFFS_CUSTOM );
922
+ unsetenv (TOKEN_ENVVAR );
923
+ return 0 ;
924
+ err_out :
925
+ rmdir (TOKEN_BPFFS_CUSTOM );
926
+ unsetenv (TOKEN_ENVVAR );
927
+ return - EINVAL ;
928
+ }
929
+
829
930
#define bit (n ) (1ULL << (n))
830
931
831
932
void test_token (void )
@@ -904,4 +1005,15 @@ void test_token(void)
904
1005
905
1006
subtest_userns (& opts , userns_obj_priv_implicit_token );
906
1007
}
1008
+ if (test__start_subtest ("obj_priv_implicit_token_envvar" )) {
1009
+ struct bpffs_opts opts = {
1010
+ /* allow BTF loading */
1011
+ .cmds = bit (BPF_BTF_LOAD ) | bit (BPF_MAP_CREATE ) | bit (BPF_PROG_LOAD ),
1012
+ .maps = bit (BPF_MAP_TYPE_STRUCT_OPS ),
1013
+ .progs = bit (BPF_PROG_TYPE_STRUCT_OPS ),
1014
+ .attachs = ~0ULL ,
1015
+ };
1016
+
1017
+ subtest_userns (& opts , userns_obj_priv_implicit_token_envvar );
1018
+ }
907
1019
}
0 commit comments