Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

bpf: Use kvmalloc for map keys in syscalls

Same as previous patch but for the keys. memdup_bpfptr is renamed
to kvmemdup_bpfptr (and converted to kvmalloc).

Signed-off-by: Stanislav Fomichev <sdf@google.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Song Liu <songliubraving@fb.com>
Link: https://lore.kernel.org/bpf/20210818235216.1159202-2-sdf@google.com

authored by

Stanislav Fomichev and committed by
Daniel Borkmann
44779a4b f0dce1d9

+27 -19
+10 -2
include/linux/bpfptr.h
··· 62 62 return copy_to_sockptr_offset((sockptr_t) dst, offset, src, size); 63 63 } 64 64 65 - static inline void *memdup_bpfptr(bpfptr_t src, size_t len) 65 + static inline void *kvmemdup_bpfptr(bpfptr_t src, size_t len) 66 66 { 67 - return memdup_sockptr((sockptr_t) src, len); 67 + void *p = kvmalloc(len, GFP_USER | __GFP_NOWARN); 68 + 69 + if (!p) 70 + return ERR_PTR(-ENOMEM); 71 + if (copy_from_bpfptr(p, src, len)) { 72 + kvfree(p); 73 + return ERR_PTR(-EFAULT); 74 + } 75 + return p; 68 76 } 69 77 70 78 static inline long strncpy_from_bpfptr(char *dst, bpfptr_t src, size_t count)
+17 -17
kernel/bpf/syscall.c
··· 1013 1013 static void *__bpf_copy_key(void __user *ukey, u64 key_size) 1014 1014 { 1015 1015 if (key_size) 1016 - return memdup_user(ukey, key_size); 1016 + return vmemdup_user(ukey, key_size); 1017 1017 1018 1018 if (ukey) 1019 1019 return ERR_PTR(-EINVAL); ··· 1024 1024 static void *___bpf_copy_key(bpfptr_t ukey, u64 key_size) 1025 1025 { 1026 1026 if (key_size) 1027 - return memdup_bpfptr(ukey, key_size); 1027 + return kvmemdup_bpfptr(ukey, key_size); 1028 1028 1029 1029 if (!bpfptr_is_null(ukey)) 1030 1030 return ERR_PTR(-EINVAL); ··· 1093 1093 free_value: 1094 1094 kvfree(value); 1095 1095 free_key: 1096 - kfree(key); 1096 + kvfree(key); 1097 1097 err_put: 1098 1098 fdput(f); 1099 1099 return err; ··· 1153 1153 free_value: 1154 1154 kvfree(value); 1155 1155 free_key: 1156 - kfree(key); 1156 + kvfree(key); 1157 1157 err_put: 1158 1158 fdput(f); 1159 1159 return err; ··· 1205 1205 bpf_enable_instrumentation(); 1206 1206 maybe_wait_bpf_programs(map); 1207 1207 out: 1208 - kfree(key); 1208 + kvfree(key); 1209 1209 err_put: 1210 1210 fdput(f); 1211 1211 return err; ··· 1247 1247 } 1248 1248 1249 1249 err = -ENOMEM; 1250 - next_key = kmalloc(map->key_size, GFP_USER); 1250 + next_key = kvmalloc(map->key_size, GFP_USER); 1251 1251 if (!next_key) 1252 1252 goto free_key; 1253 1253 ··· 1270 1270 err = 0; 1271 1271 1272 1272 free_next_key: 1273 - kfree(next_key); 1273 + kvfree(next_key); 1274 1274 free_key: 1275 - kfree(key); 1275 + kvfree(key); 1276 1276 err_put: 1277 1277 fdput(f); 1278 1278 return err; ··· 1299 1299 if (!max_count) 1300 1300 return 0; 1301 1301 1302 - key = kmalloc(map->key_size, GFP_USER | __GFP_NOWARN); 1302 + key = kvmalloc(map->key_size, GFP_USER | __GFP_NOWARN); 1303 1303 if (!key) 1304 1304 return -ENOMEM; 1305 1305 ··· 1326 1326 if (copy_to_user(&uattr->batch.count, &cp, sizeof(cp))) 1327 1327 err = -EFAULT; 1328 1328 1329 - kfree(key); 1329 + kvfree(key); 1330 1330 return err; 1331 1331 } 1332 1332 ··· 1357 1357 if (!max_count) 1358 1358 return 0; 1359 1359 1360 - key = kmalloc(map->key_size, GFP_USER | __GFP_NOWARN); 1360 + key = kvmalloc(map->key_size, GFP_USER | __GFP_NOWARN); 1361 1361 if (!key) 1362 1362 return -ENOMEM; 1363 1363 1364 1364 value = kvmalloc(value_size, GFP_USER | __GFP_NOWARN); 1365 1365 if (!value) { 1366 - kfree(key); 1366 + kvfree(key); 1367 1367 return -ENOMEM; 1368 1368 } 1369 1369 ··· 1385 1385 err = -EFAULT; 1386 1386 1387 1387 kvfree(value); 1388 - kfree(key); 1388 + kvfree(key); 1389 1389 return err; 1390 1390 } 1391 1391 ··· 1419 1419 if (put_user(0, &uattr->batch.count)) 1420 1420 return -EFAULT; 1421 1421 1422 - buf_prevkey = kmalloc(map->key_size, GFP_USER | __GFP_NOWARN); 1422 + buf_prevkey = kvmalloc(map->key_size, GFP_USER | __GFP_NOWARN); 1423 1423 if (!buf_prevkey) 1424 1424 return -ENOMEM; 1425 1425 1426 1426 buf = kvmalloc(map->key_size + value_size, GFP_USER | __GFP_NOWARN); 1427 1427 if (!buf) { 1428 - kfree(buf_prevkey); 1428 + kvfree(buf_prevkey); 1429 1429 return -ENOMEM; 1430 1430 } 1431 1431 ··· 1485 1485 err = -EFAULT; 1486 1486 1487 1487 free_buf: 1488 - kfree(buf_prevkey); 1488 + kvfree(buf_prevkey); 1489 1489 kvfree(buf); 1490 1490 return err; 1491 1491 } ··· 1575 1575 free_value: 1576 1576 kvfree(value); 1577 1577 free_key: 1578 - kfree(key); 1578 + kvfree(key); 1579 1579 err_put: 1580 1580 fdput(f); 1581 1581 return err;