@@ -326,12 +326,13 @@ int ing_xdp(struct xdp_md *ctx)
326326}
327327
328328/*
329- * Check that skb->data_meta..skb->data is empty if prog writes to packet
329+ * Check that skb->data_meta..skb->data is kept in tact if prog writes to packet
330330 * _payload_ using packet pointers. Applies only to cloned skbs.
331331 */
332332SEC ("tc" )
333- int clone_data_meta_empty_on_data_write (struct __sk_buff * ctx )
333+ int clone_data_meta_kept_on_data_write (struct __sk_buff * ctx )
334334{
335+ __u8 * meta_have = ctx_ptr (ctx , data_meta );
335336 struct ethhdr * eth = ctx_ptr (ctx , data );
336337
337338 if (eth + 1 > ctx_ptr (ctx , data_end ))
@@ -340,8 +341,10 @@ int clone_data_meta_empty_on_data_write(struct __sk_buff *ctx)
340341 if (eth -> h_proto != 0 )
341342 goto out ;
342343
343- /* Expect no metadata */
344- if (ctx -> data_meta != ctx -> data )
344+ if (meta_have + META_SIZE > eth )
345+ goto out ;
346+
347+ if (!check_metadata (meta_have ))
345348 goto out ;
346349
347350 /* Packet write to trigger unclone in prologue */
@@ -353,40 +356,44 @@ int clone_data_meta_empty_on_data_write(struct __sk_buff *ctx)
353356}
354357
355358/*
356- * Check that skb->data_meta..skb->data is empty if prog writes to packet
359+ * Check that skb->data_meta..skb->data is kept in tact if prog writes to packet
357360 * _metadata_ using packet pointers. Applies only to cloned skbs.
358361 */
359362SEC ("tc" )
360- int clone_data_meta_empty_on_meta_write (struct __sk_buff * ctx )
363+ int clone_data_meta_kept_on_meta_write (struct __sk_buff * ctx )
361364{
365+ __u8 * meta_have = ctx_ptr (ctx , data_meta );
362366 struct ethhdr * eth = ctx_ptr (ctx , data );
363- __u8 * md = ctx_ptr (ctx , data_meta );
364367
365368 if (eth + 1 > ctx_ptr (ctx , data_end ))
366369 goto out ;
367370 /* Ignore non-test packets */
368371 if (eth -> h_proto != 0 )
369372 goto out ;
370373
371- if (md + 1 > ctx_ptr (ctx , data )) {
372- /* Expect no metadata */
373- test_pass = true;
374- } else {
375- /* Metadata write to trigger unclone in prologue */
376- * md = 42 ;
377- }
374+ if (meta_have + META_SIZE > eth )
375+ goto out ;
376+
377+ if (!check_metadata (meta_have ))
378+ goto out ;
379+
380+ /* Metadata write to trigger unclone in prologue */
381+ * meta_have = 42 ;
382+
383+ test_pass = true;
378384out :
379385 return TC_ACT_SHOT ;
380386}
381387
382388/*
383- * Check that skb_meta dynptr is writable but empty if prog writes to packet
384- * _payload_ using a dynptr slice . Applies only to cloned skbs.
389+ * Check that skb_meta dynptr is writable and was kept in tact if prog creates a
390+ * r/w slice to packet _payload_ . Applies only to cloned skbs.
385391 */
386392SEC ("tc" )
387- int clone_dynptr_empty_on_data_slice_write (struct __sk_buff * ctx )
393+ int clone_dynptr_kept_on_data_slice_write (struct __sk_buff * ctx )
388394{
389395 struct bpf_dynptr data , meta ;
396+ __u8 meta_have [META_SIZE ];
390397 struct ethhdr * eth ;
391398
392399 bpf_dynptr_from_skb (ctx , 0 , & data );
@@ -397,29 +404,26 @@ int clone_dynptr_empty_on_data_slice_write(struct __sk_buff *ctx)
397404 if (eth -> h_proto != 0 )
398405 goto out ;
399406
400- /* Expect no metadata */
401407 bpf_dynptr_from_skb_meta (ctx , 0 , & meta );
402- if (bpf_dynptr_is_rdonly (& meta ) || bpf_dynptr_size (& meta ) > 0 )
408+ bpf_dynptr_read (meta_have , META_SIZE , & meta , 0 , 0 );
409+ if (!check_metadata (meta_have ))
403410 goto out ;
404411
405- /* Packet write to trigger unclone in prologue */
406- eth -> h_proto = 42 ;
407-
408412 test_pass = true;
409413out :
410414 return TC_ACT_SHOT ;
411415}
412416
413417/*
414- * Check that skb_meta dynptr is writable but empty if prog writes to packet
415- * _metadata_ using a dynptr slice . Applies only to cloned skbs.
418+ * Check that skb_meta dynptr is writable and was kept in tact if prog creates
419+ * an r/w slice to packet _metadata_ . Applies only to cloned skbs.
416420 */
417421SEC ("tc" )
418- int clone_dynptr_empty_on_meta_slice_write (struct __sk_buff * ctx )
422+ int clone_dynptr_kept_on_meta_slice_write (struct __sk_buff * ctx )
419423{
420424 struct bpf_dynptr data , meta ;
421425 const struct ethhdr * eth ;
422- __u8 * md ;
426+ __u8 * meta_have ;
423427
424428 bpf_dynptr_from_skb (ctx , 0 , & data );
425429 eth = bpf_dynptr_slice (& data , 0 , NULL , sizeof (* eth ));
@@ -429,16 +433,13 @@ int clone_dynptr_empty_on_meta_slice_write(struct __sk_buff *ctx)
429433 if (eth -> h_proto != 0 )
430434 goto out ;
431435
432- /* Expect no metadata */
433436 bpf_dynptr_from_skb_meta (ctx , 0 , & meta );
434- if (bpf_dynptr_is_rdonly (& meta ) || bpf_dynptr_size (& meta ) > 0 )
437+ meta_have = bpf_dynptr_slice_rdwr (& meta , 0 , NULL , META_SIZE );
438+ if (!meta_have )
435439 goto out ;
436440
437- /* Metadata write to trigger unclone in prologue */
438- bpf_dynptr_from_skb_meta (ctx , 0 , & meta );
439- md = bpf_dynptr_slice_rdwr (& meta , 0 , NULL , sizeof (* md ));
440- if (md )
441- * md = 42 ;
441+ if (!check_metadata (meta_have ))
442+ goto out ;
442443
443444 test_pass = true;
444445out :
@@ -447,12 +448,14 @@ int clone_dynptr_empty_on_meta_slice_write(struct __sk_buff *ctx)
447448
448449/*
449450 * Check that skb_meta dynptr is read-only before prog writes to packet payload
450- * using dynptr_write helper. Applies only to cloned skbs.
451+ * using dynptr_write helper, and becomes read-write afterwards. Applies only to
452+ * cloned skbs.
451453 */
452454SEC ("tc" )
453- int clone_dynptr_rdonly_before_data_dynptr_write (struct __sk_buff * ctx )
455+ int clone_dynptr_rdonly_before_data_dynptr_write_then_rw (struct __sk_buff * ctx )
454456{
455457 struct bpf_dynptr data , meta ;
458+ __u8 meta_have [META_SIZE ];
456459 const struct ethhdr * eth ;
457460
458461 bpf_dynptr_from_skb (ctx , 0 , & data );
@@ -465,15 +468,23 @@ int clone_dynptr_rdonly_before_data_dynptr_write(struct __sk_buff *ctx)
465468
466469 /* Expect read-only metadata before unclone */
467470 bpf_dynptr_from_skb_meta (ctx , 0 , & meta );
468- if (!bpf_dynptr_is_rdonly (& meta ) || bpf_dynptr_size (& meta ) != META_SIZE )
471+ if (!bpf_dynptr_is_rdonly (& meta ))
472+ goto out ;
473+
474+ bpf_dynptr_read (meta_have , META_SIZE , & meta , 0 , 0 );
475+ if (!check_metadata (meta_have ))
469476 goto out ;
470477
471478 /* Helper write to payload will unclone the packet */
472479 bpf_dynptr_write (& data , offsetof(struct ethhdr , h_proto ), "x" , 1 , 0 );
473480
474- /* Expect no metadata after unclone */
481+ /* Expect r/w metadata after unclone */
475482 bpf_dynptr_from_skb_meta (ctx , 0 , & meta );
476- if (bpf_dynptr_is_rdonly (& meta ) || bpf_dynptr_size (& meta ) != 0 )
483+ if (bpf_dynptr_is_rdonly (& meta ))
484+ goto out ;
485+
486+ bpf_dynptr_read (meta_have , META_SIZE , & meta , 0 , 0 );
487+ if (!check_metadata (meta_have ))
477488 goto out ;
478489
479490 test_pass = true;
0 commit comments