@@ -305,6 +305,98 @@ static void check_with_functions(void)
305305 close (map_fd );
306306}
307307
308+ static int set_bpf_jit_harden (char * level )
309+ {
310+ char old_level ;
311+ int err = -1 ;
312+ int fd = -1 ;
313+
314+ fd = open ("/proc/sys/net/core/bpf_jit_harden" , O_RDWR | O_NONBLOCK );
315+ if (fd < 0 ) {
316+ ASSERT_FAIL ("open .../bpf_jit_harden returned %d (errno=%d)" , fd , errno );
317+ return -1 ;
318+ }
319+
320+ err = read (fd , & old_level , 1 );
321+ if (err != 1 ) {
322+ ASSERT_FAIL ("read from .../bpf_jit_harden returned %d (errno=%d)" , err , errno );
323+ err = -1 ;
324+ goto end ;
325+ }
326+
327+ lseek (fd , 0 , SEEK_SET );
328+
329+ err = write (fd , level , 1 );
330+ if (err != 1 ) {
331+ ASSERT_FAIL ("write to .../bpf_jit_harden returned %d (errno=%d)" , err , errno );
332+ err = -1 ;
333+ goto end ;
334+ }
335+
336+ err = 0 ;
337+ * level = old_level ;
338+ end :
339+ if (fd >= 0 )
340+ close (fd );
341+ return err ;
342+ }
343+
344+ static void check_blindness (void )
345+ {
346+ struct bpf_insn insns [] = {
347+ BPF_MOV64_IMM (BPF_REG_0 , 4 ),
348+ BPF_MOV64_IMM (BPF_REG_0 , 3 ),
349+ BPF_MOV64_IMM (BPF_REG_0 , 2 ),
350+ BPF_MOV64_IMM (BPF_REG_0 , 1 ),
351+ BPF_EXIT_INSN (),
352+ };
353+ int prog_fd = -1 , map_fd ;
354+ struct bpf_insn_array_value val = {};
355+ char bpf_jit_harden = '@' ; /* non-exizsting value */
356+ int i ;
357+
358+ map_fd = map_create (BPF_MAP_TYPE_INSN_ARRAY , ARRAY_SIZE (insns ));
359+ if (!ASSERT_GE (map_fd , 0 , "map_create" ))
360+ return ;
361+
362+ for (i = 0 ; i < ARRAY_SIZE (insns ); i ++ ) {
363+ val .xlated_off = i ;
364+ if (!ASSERT_EQ (bpf_map_update_elem (map_fd , & i , & val , 0 ), 0 , "bpf_map_update_elem" ))
365+ goto cleanup ;
366+ }
367+
368+ if (!ASSERT_EQ (bpf_map_freeze (map_fd ), 0 , "bpf_map_freeze" ))
369+ goto cleanup ;
370+
371+ bpf_jit_harden = '2' ;
372+ if (set_bpf_jit_harden (& bpf_jit_harden )) {
373+ bpf_jit_harden = '@' ; /* open, read or write failed => no write was done */
374+ goto cleanup ;
375+ }
376+
377+ prog_fd = prog_load (insns , ARRAY_SIZE (insns ), & map_fd , 1 );
378+ if (!ASSERT_GE (prog_fd , 0 , "bpf(BPF_PROG_LOAD)" ))
379+ goto cleanup ;
380+
381+ for (i = 0 ; i < ARRAY_SIZE (insns ); i ++ ) {
382+ char fmt [32 ];
383+
384+ if (!ASSERT_EQ (bpf_map_lookup_elem (map_fd , & i , & val ), 0 , "bpf_map_lookup_elem" ))
385+ goto cleanup ;
386+
387+ snprintf (fmt , sizeof (fmt ), "val should be equal 3*%d" , i );
388+ ASSERT_EQ (val .xlated_off , i * 3 , fmt );
389+ }
390+
391+ cleanup :
392+ /* restore the old one */
393+ if (bpf_jit_harden != '@' )
394+ set_bpf_jit_harden (& bpf_jit_harden );
395+
396+ close (prog_fd );
397+ close (map_fd );
398+ }
399+
308400/* Once map was initialized, it should be frozen */
309401static void check_load_unfrozen_map (void )
310402{
@@ -462,6 +554,9 @@ void test_bpf_insn_array(void)
462554
463555 if (test__start_subtest ("multiple-functions" ))
464556 check_with_functions ();
557+
558+ if (test__start_subtest ("blindness" ))
559+ check_blindness ();
465560}
466561
467562/* Check all kinds of operations and related restrictions */
0 commit comments