@@ -269,6 +269,26 @@ int data_slice_out_of_bounds_skb(struct __sk_buff *skb)
269
269
return SK_PASS ;
270
270
}
271
271
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
+
272
292
SEC ("?raw_tp" )
273
293
__failure __msg ("value is outside of the allowed memory range" )
274
294
int data_slice_out_of_bounds_map_value (void * ctx )
@@ -1089,6 +1109,26 @@ int skb_invalid_slice_write(struct __sk_buff *skb)
1089
1109
return SK_PASS ;
1090
1110
}
1091
1111
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
+
1092
1132
/* The read-only data slice is invalidated whenever a helper changes packet data */
1093
1133
SEC ("?tc" )
1094
1134
__failure __msg ("invalid mem access 'scalar'" )
@@ -1192,6 +1232,188 @@ int skb_invalid_data_slice4(struct __sk_buff *skb)
1192
1232
return SK_PASS ;
1193
1233
}
1194
1234
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
+
1195
1417
/* The read-only data slice is invalidated whenever a helper changes packet data */
1196
1418
SEC ("?xdp" )
1197
1419
__failure __msg ("invalid mem access 'scalar'" )
@@ -1255,6 +1477,19 @@ int skb_invalid_ctx(void *ctx)
1255
1477
return 0 ;
1256
1478
}
1257
1479
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
+
1258
1493
SEC ("fentry/skb_tx_error" )
1259
1494
__failure __msg ("must be referenced or trusted" )
1260
1495
int BPF_PROG (skb_invalid_ctx_fentry , void * skb )
@@ -1665,6 +1900,29 @@ int clone_skb_packet_data(struct __sk_buff *skb)
1665
1900
return 0 ;
1666
1901
}
1667
1902
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
+
1668
1926
/* A xdp clone's data slices should be invalid anytime packet data changes */
1669
1927
SEC ("?xdp" )
1670
1928
__failure __msg ("invalid mem access 'scalar'" )
0 commit comments