@@ -269,6 +269,26 @@ int data_slice_out_of_bounds_skb(struct __sk_buff *skb)
269269 return SK_PASS ;
270270}
271271
272+ /* A metadata slice can't be accessed out of bounds */
273+ SEC ("?tc" )
274+ __failure __msg ("value is outside of the allowed memory range" )
275+ int data_slice_out_of_bounds_skb_meta (struct __sk_buff * skb )
276+ {
277+ struct bpf_dynptr meta ;
278+ __u8 * md ;
279+
280+ bpf_dynptr_from_skb_meta (skb , 0 , & meta );
281+
282+ md = bpf_dynptr_slice_rdwr (& meta , 0 , NULL , sizeof (* md ));
283+ if (!md )
284+ return SK_DROP ;
285+
286+ /* this should fail */
287+ * (md + 1 ) = 42 ;
288+
289+ return SK_PASS ;
290+ }
291+
272292SEC ("?raw_tp" )
273293__failure __msg ("value is outside of the allowed memory range" )
274294int data_slice_out_of_bounds_map_value (void * ctx )
@@ -1089,6 +1109,26 @@ int skb_invalid_slice_write(struct __sk_buff *skb)
10891109 return SK_PASS ;
10901110}
10911111
1112+ /* bpf_dynptr_slice()s are read-only and cannot be written to */
1113+ SEC ("?tc" )
1114+ __failure __msg ("R{{[0-9]+}} cannot write into rdonly_mem" )
1115+ int skb_meta_invalid_slice_write (struct __sk_buff * skb )
1116+ {
1117+ struct bpf_dynptr meta ;
1118+ __u8 * md ;
1119+
1120+ bpf_dynptr_from_skb_meta (skb , 0 , & meta );
1121+
1122+ md = bpf_dynptr_slice (& meta , 0 , NULL , sizeof (* md ));
1123+ if (!md )
1124+ return SK_DROP ;
1125+
1126+ /* this should fail */
1127+ * md = 42 ;
1128+
1129+ return SK_PASS ;
1130+ }
1131+
10921132/* The read-only data slice is invalidated whenever a helper changes packet data */
10931133SEC ("?tc" )
10941134__failure __msg ("invalid mem access 'scalar'" )
@@ -1192,6 +1232,188 @@ int skb_invalid_data_slice4(struct __sk_buff *skb)
11921232 return SK_PASS ;
11931233}
11941234
1235+ /* Read-only skb data slice is invalidated on write to skb metadata */
1236+ SEC ("?tc" )
1237+ __failure __msg ("invalid mem access 'scalar'" )
1238+ int ro_skb_slice_invalid_after_metadata_write (struct __sk_buff * skb )
1239+ {
1240+ struct bpf_dynptr data , meta ;
1241+ __u8 * d ;
1242+
1243+ bpf_dynptr_from_skb (skb , 0 , & data );
1244+ bpf_dynptr_from_skb_meta (skb , 0 , & meta );
1245+
1246+ d = bpf_dynptr_slice (& data , 0 , NULL , sizeof (* d ));
1247+ if (!d )
1248+ return SK_DROP ;
1249+
1250+ bpf_dynptr_write (& meta , 0 , "x" , 1 , 0 );
1251+
1252+ /* this should fail */
1253+ val = * d ;
1254+
1255+ return SK_PASS ;
1256+ }
1257+
1258+ /* Read-write skb data slice is invalidated on write to skb metadata */
1259+ SEC ("?tc" )
1260+ __failure __msg ("invalid mem access 'scalar'" )
1261+ int rw_skb_slice_invalid_after_metadata_write (struct __sk_buff * skb )
1262+ {
1263+ struct bpf_dynptr data , meta ;
1264+ __u8 * d ;
1265+
1266+ bpf_dynptr_from_skb (skb , 0 , & data );
1267+ bpf_dynptr_from_skb_meta (skb , 0 , & meta );
1268+
1269+ d = bpf_dynptr_slice_rdwr (& data , 0 , NULL , sizeof (* d ));
1270+ if (!d )
1271+ return SK_DROP ;
1272+
1273+ bpf_dynptr_write (& meta , 0 , "x" , 1 , 0 );
1274+
1275+ /* this should fail */
1276+ * d = 42 ;
1277+
1278+ return SK_PASS ;
1279+ }
1280+
1281+ /* Read-only skb metadata slice is invalidated on write to skb data */
1282+ SEC ("?tc" )
1283+ __failure __msg ("invalid mem access 'scalar'" )
1284+ int ro_skb_meta_slice_invalid_after_payload_write (struct __sk_buff * skb )
1285+ {
1286+ struct bpf_dynptr data , meta ;
1287+ __u8 * md ;
1288+
1289+ bpf_dynptr_from_skb (skb , 0 , & data );
1290+ bpf_dynptr_from_skb_meta (skb , 0 , & meta );
1291+
1292+ md = bpf_dynptr_slice (& meta , 0 , NULL , sizeof (* md ));
1293+ if (!md )
1294+ return SK_DROP ;
1295+
1296+ bpf_dynptr_write (& data , 0 , "x" , 1 , 0 );
1297+
1298+ /* this should fail */
1299+ val = * md ;
1300+
1301+ return SK_PASS ;
1302+ }
1303+
1304+ /* Read-write skb metadata slice is invalidated on write to skb data slice */
1305+ SEC ("?tc" )
1306+ __failure __msg ("invalid mem access 'scalar'" )
1307+ int rw_skb_meta_slice_invalid_after_payload_write (struct __sk_buff * skb )
1308+ {
1309+ struct bpf_dynptr data , meta ;
1310+ __u8 * md ;
1311+
1312+ bpf_dynptr_from_skb (skb , 0 , & data );
1313+ bpf_dynptr_from_skb_meta (skb , 0 , & meta );
1314+
1315+ md = bpf_dynptr_slice_rdwr (& meta , 0 , NULL , sizeof (* md ));
1316+ if (!md )
1317+ return SK_DROP ;
1318+
1319+ bpf_dynptr_write (& data , 0 , "x" , 1 , 0 );
1320+
1321+ /* this should fail */
1322+ * md = 42 ;
1323+
1324+ return SK_PASS ;
1325+ }
1326+
1327+ /* Read-only skb metadata slice is invalidated whenever a helper changes packet data */
1328+ SEC ("?tc" )
1329+ __failure __msg ("invalid mem access 'scalar'" )
1330+ int ro_skb_meta_slice_invalid_after_payload_helper (struct __sk_buff * skb )
1331+ {
1332+ struct bpf_dynptr meta ;
1333+ __u8 * md ;
1334+
1335+ bpf_dynptr_from_skb_meta (skb , 0 , & meta );
1336+
1337+ md = bpf_dynptr_slice (& meta , 0 , NULL , sizeof (* md ));
1338+ if (!md )
1339+ return SK_DROP ;
1340+
1341+ if (bpf_skb_pull_data (skb , skb -> len ))
1342+ return SK_DROP ;
1343+
1344+ /* this should fail */
1345+ val = * md ;
1346+
1347+ return SK_PASS ;
1348+ }
1349+
1350+ /* Read-write skb metadata slice is invalidated whenever a helper changes packet data */
1351+ SEC ("?tc" )
1352+ __failure __msg ("invalid mem access 'scalar'" )
1353+ int rw_skb_meta_slice_invalid_after_payload_helper (struct __sk_buff * skb )
1354+ {
1355+ struct bpf_dynptr meta ;
1356+ __u8 * md ;
1357+
1358+ bpf_dynptr_from_skb_meta (skb , 0 , & meta );
1359+
1360+ md = bpf_dynptr_slice_rdwr (& meta , 0 , NULL , sizeof (* md ));
1361+ if (!md )
1362+ return SK_DROP ;
1363+
1364+ if (bpf_skb_pull_data (skb , skb -> len ))
1365+ return SK_DROP ;
1366+
1367+ /* this should fail */
1368+ * md = 42 ;
1369+
1370+ return SK_PASS ;
1371+ }
1372+
1373+ /* Read-only skb metadata slice is invalidated on write to skb metadata */
1374+ SEC ("?tc" )
1375+ __failure __msg ("invalid mem access 'scalar'" )
1376+ int ro_skb_meta_slice_invalid_after_metadata_write (struct __sk_buff * skb )
1377+ {
1378+ struct bpf_dynptr meta ;
1379+ __u8 * md ;
1380+
1381+ bpf_dynptr_from_skb_meta (skb , 0 , & meta );
1382+
1383+ md = bpf_dynptr_slice (& meta , 0 , NULL , sizeof (* md ));
1384+ if (!md )
1385+ return SK_DROP ;
1386+
1387+ bpf_dynptr_write (& meta , 0 , "x" , 1 , 0 );
1388+
1389+ /* this should fail */
1390+ val = * md ;
1391+
1392+ return SK_PASS ;
1393+ }
1394+
1395+ /* Read-write skb metadata slice is invalidated on write to skb metadata */
1396+ SEC ("?tc" )
1397+ __failure __msg ("invalid mem access 'scalar'" )
1398+ int rw_skb_meta_slice_invalid_after_metadata_write (struct __sk_buff * skb )
1399+ {
1400+ struct bpf_dynptr meta ;
1401+ __u8 * md ;
1402+
1403+ bpf_dynptr_from_skb_meta (skb , 0 , & meta );
1404+
1405+ md = bpf_dynptr_slice_rdwr (& meta , 0 , NULL , sizeof (* md ));
1406+ if (!md )
1407+ return SK_DROP ;
1408+
1409+ bpf_dynptr_write (& meta , 0 , "x" , 1 , 0 );
1410+
1411+ /* this should fail */
1412+ * md = 42 ;
1413+
1414+ return SK_PASS ;
1415+ }
1416+
11951417/* The read-only data slice is invalidated whenever a helper changes packet data */
11961418SEC ("?xdp" )
11971419__failure __msg ("invalid mem access 'scalar'" )
@@ -1255,6 +1477,19 @@ int skb_invalid_ctx(void *ctx)
12551477 return 0 ;
12561478}
12571479
1480+ /* Only supported prog type can create skb_meta-type dynptrs */
1481+ SEC ("?raw_tp" )
1482+ __failure __msg ("calling kernel function bpf_dynptr_from_skb_meta is not allowed" )
1483+ int skb_meta_invalid_ctx (void * ctx )
1484+ {
1485+ struct bpf_dynptr meta ;
1486+
1487+ /* this should fail */
1488+ bpf_dynptr_from_skb_meta (ctx , 0 , & meta );
1489+
1490+ return 0 ;
1491+ }
1492+
12581493SEC ("fentry/skb_tx_error" )
12591494__failure __msg ("must be referenced or trusted" )
12601495int BPF_PROG (skb_invalid_ctx_fentry , void * skb )
@@ -1665,6 +1900,29 @@ int clone_skb_packet_data(struct __sk_buff *skb)
16651900 return 0 ;
16661901}
16671902
1903+ /* A skb clone's metadata slice becomes invalid anytime packet data changes */
1904+ SEC ("?tc" )
1905+ __failure __msg ("invalid mem access 'scalar'" )
1906+ int clone_skb_packet_meta (struct __sk_buff * skb )
1907+ {
1908+ struct bpf_dynptr clone , meta ;
1909+ __u8 * md ;
1910+
1911+ bpf_dynptr_from_skb_meta (skb , 0 , & meta );
1912+ bpf_dynptr_clone (& meta , & clone );
1913+ md = bpf_dynptr_slice_rdwr (& clone , 0 , NULL , sizeof (* md ));
1914+ if (!md )
1915+ return SK_DROP ;
1916+
1917+ if (bpf_skb_pull_data (skb , skb -> len ))
1918+ return SK_DROP ;
1919+
1920+ /* this should fail */
1921+ * md = 42 ;
1922+
1923+ return 0 ;
1924+ }
1925+
16681926/* A xdp clone's data slices should be invalid anytime packet data changes */
16691927SEC ("?xdp" )
16701928__failure __msg ("invalid mem access 'scalar'" )
0 commit comments