@@ -227,6 +227,98 @@ static void check_incorrect_index(void)
227227 check_mid_insn_index ();
228228}
229229
230+ static int set_bpf_jit_harden (char * level )
231+ {
232+ char old_level ;
233+ int err = -1 ;
234+ int fd = -1 ;
235+
236+ fd = open ("/proc/sys/net/core/bpf_jit_harden" , O_RDWR | O_NONBLOCK );
237+ if (fd < 0 ) {
238+ ASSERT_FAIL ("open .../bpf_jit_harden returned %d (errno=%d)" , fd , errno );
239+ return -1 ;
240+ }
241+
242+ err = read (fd , & old_level , 1 );
243+ if (err != 1 ) {
244+ ASSERT_FAIL ("read from .../bpf_jit_harden returned %d (errno=%d)" , err , errno );
245+ err = -1 ;
246+ goto end ;
247+ }
248+
249+ lseek (fd , 0 , SEEK_SET );
250+
251+ err = write (fd , level , 1 );
252+ if (err != 1 ) {
253+ ASSERT_FAIL ("write to .../bpf_jit_harden returned %d (errno=%d)" , err , errno );
254+ err = -1 ;
255+ goto end ;
256+ }
257+
258+ err = 0 ;
259+ * level = old_level ;
260+ end :
261+ if (fd >= 0 )
262+ close (fd );
263+ return err ;
264+ }
265+
266+ static void check_blindness (void )
267+ {
268+ struct bpf_insn insns [] = {
269+ BPF_MOV64_IMM (BPF_REG_0 , 4 ),
270+ BPF_MOV64_IMM (BPF_REG_0 , 3 ),
271+ BPF_MOV64_IMM (BPF_REG_0 , 2 ),
272+ BPF_MOV64_IMM (BPF_REG_0 , 1 ),
273+ BPF_EXIT_INSN (),
274+ };
275+ int prog_fd = -1 , map_fd ;
276+ struct bpf_insn_array_value val = {};
277+ char bpf_jit_harden = '@' ; /* non-exizsting value */
278+ int i ;
279+
280+ map_fd = map_create (BPF_MAP_TYPE_INSN_ARRAY , ARRAY_SIZE (insns ));
281+ if (!ASSERT_GE (map_fd , 0 , "map_create" ))
282+ return ;
283+
284+ for (i = 0 ; i < ARRAY_SIZE (insns ); i ++ ) {
285+ val .orig_off = i ;
286+ if (!ASSERT_EQ (bpf_map_update_elem (map_fd , & i , & val , 0 ), 0 , "bpf_map_update_elem" ))
287+ goto cleanup ;
288+ }
289+
290+ if (!ASSERT_EQ (bpf_map_freeze (map_fd ), 0 , "bpf_map_freeze" ))
291+ goto cleanup ;
292+
293+ bpf_jit_harden = '2' ;
294+ if (set_bpf_jit_harden (& bpf_jit_harden )) {
295+ bpf_jit_harden = '@' ; /* open, read or write failed => no write was done */
296+ goto cleanup ;
297+ }
298+
299+ prog_fd = prog_load (insns , ARRAY_SIZE (insns ), & map_fd , 1 );
300+ if (!ASSERT_GE (prog_fd , 0 , "bpf(BPF_PROG_LOAD)" ))
301+ goto cleanup ;
302+
303+ for (i = 0 ; i < ARRAY_SIZE (insns ); i ++ ) {
304+ char fmt [32 ];
305+
306+ if (!ASSERT_EQ (bpf_map_lookup_elem (map_fd , & i , & val ), 0 , "bpf_map_lookup_elem" ))
307+ goto cleanup ;
308+
309+ snprintf (fmt , sizeof (fmt ), "val should be equal 3*%d" , i );
310+ ASSERT_EQ (val .xlated_off , i * 3 , fmt );
311+ }
312+
313+ cleanup :
314+ /* restore the old one */
315+ if (bpf_jit_harden != '@' )
316+ set_bpf_jit_harden (& bpf_jit_harden );
317+
318+ close (prog_fd );
319+ close (map_fd );
320+ }
321+
230322/* Once map was initialized, it should be frozen */
231323static void check_load_unfrozen_map (void )
232324{
@@ -382,6 +474,9 @@ static void __test_bpf_insn_array(void)
382474 if (test__start_subtest ("deletions-with-functions" ))
383475 check_deletions_with_functions ();
384476
477+ if (test__start_subtest ("blindness" ))
478+ check_blindness ();
479+
385480 /* Check all kinds of operations and related restrictions */
386481
387482 if (test__start_subtest ("incorrect-index" ))
0 commit comments