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.

Merge tag 'bpf-next-6.12-struct-fd' of git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next

Pull bpf 'struct fd' updates from Alexei Starovoitov:
"This includes struct_fd BPF changes from Al and Andrii"

* tag 'bpf-next-6.12-struct-fd' of git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next:
bpf: convert bpf_token_create() to CLASS(fd, ...)
security,bpf: constify struct path in bpf_token_create() LSM hook
bpf: more trivial fdget() conversions
bpf: trivial conversions for fdget()
bpf: switch maps to CLASS(fd, ...)
bpf: factor out fetching bpf_map from FD and adding it to used_maps list
bpf: switch fdget_raw() uses to CLASS(fd_raw, ...)
bpf: convert __bpf_prog_get() to CLASS(fd, ...)

+181 -305
+10 -1
include/linux/bpf.h
··· 2246 2246 2247 2247 struct bpf_map *bpf_map_get(u32 ufd); 2248 2248 struct bpf_map *bpf_map_get_with_uref(u32 ufd); 2249 - struct bpf_map *__bpf_map_get(struct fd f); 2249 + 2250 + static inline struct bpf_map *__bpf_map_get(struct fd f) 2251 + { 2252 + if (fd_empty(f)) 2253 + return ERR_PTR(-EBADF); 2254 + if (unlikely(fd_file(f)->f_op != &bpf_map_fops)) 2255 + return ERR_PTR(-EINVAL); 2256 + return fd_file(f)->private_data; 2257 + } 2258 + 2250 2259 void bpf_map_inc(struct bpf_map *map); 2251 2260 void bpf_map_inc_with_uref(struct bpf_map *map); 2252 2261 struct bpf_map *__bpf_map_inc_not_zero(struct bpf_map *map, bool uref);
+1 -1
include/linux/lsm_hook_defs.h
··· 431 431 struct bpf_token *token) 432 432 LSM_HOOK(void, LSM_RET_VOID, bpf_prog_free, struct bpf_prog *prog) 433 433 LSM_HOOK(int, 0, bpf_token_create, struct bpf_token *token, union bpf_attr *attr, 434 - struct path *path) 434 + const struct path *path) 435 435 LSM_HOOK(void, LSM_RET_VOID, bpf_token_free, struct bpf_token *token) 436 436 LSM_HOOK(int, 0, bpf_token_cmd, const struct bpf_token *token, enum bpf_cmd cmd) 437 437 LSM_HOOK(int, 0, bpf_token_capable, const struct bpf_token *token, int cap)
+2 -2
include/linux/security.h
··· 2182 2182 struct bpf_token *token); 2183 2183 extern void security_bpf_prog_free(struct bpf_prog *prog); 2184 2184 extern int security_bpf_token_create(struct bpf_token *token, union bpf_attr *attr, 2185 - struct path *path); 2185 + const struct path *path); 2186 2186 extern void security_bpf_token_free(struct bpf_token *token); 2187 2187 extern int security_bpf_token_cmd(const struct bpf_token *token, enum bpf_cmd cmd); 2188 2188 extern int security_bpf_token_capable(const struct bpf_token *token, int cap); ··· 2222 2222 { } 2223 2223 2224 2224 static inline int security_bpf_token_create(struct bpf_token *token, union bpf_attr *attr, 2225 - struct path *path) 2225 + const struct path *path) 2226 2226 { 2227 2227 return 0; 2228 2228 }
+8 -16
kernel/bpf/bpf_inode_storage.c
··· 78 78 static void *bpf_fd_inode_storage_lookup_elem(struct bpf_map *map, void *key) 79 79 { 80 80 struct bpf_local_storage_data *sdata; 81 - struct fd f = fdget_raw(*(int *)key); 81 + CLASS(fd_raw, f)(*(int *)key); 82 82 83 - if (!fd_file(f)) 83 + if (fd_empty(f)) 84 84 return ERR_PTR(-EBADF); 85 85 86 86 sdata = inode_storage_lookup(file_inode(fd_file(f)), map, true); 87 - fdput(f); 88 87 return sdata ? sdata->data : NULL; 89 88 } 90 89 ··· 91 92 void *value, u64 map_flags) 92 93 { 93 94 struct bpf_local_storage_data *sdata; 94 - struct fd f = fdget_raw(*(int *)key); 95 + CLASS(fd_raw, f)(*(int *)key); 95 96 96 - if (!fd_file(f)) 97 + if (fd_empty(f)) 97 98 return -EBADF; 98 - if (!inode_storage_ptr(file_inode(fd_file(f)))) { 99 - fdput(f); 99 + if (!inode_storage_ptr(file_inode(fd_file(f)))) 100 100 return -EBADF; 101 - } 102 101 103 102 sdata = bpf_local_storage_update(file_inode(fd_file(f)), 104 103 (struct bpf_local_storage_map *)map, 105 104 value, map_flags, GFP_ATOMIC); 106 - fdput(f); 107 105 return PTR_ERR_OR_ZERO(sdata); 108 106 } 109 107 ··· 119 123 120 124 static long bpf_fd_inode_storage_delete_elem(struct bpf_map *map, void *key) 121 125 { 122 - struct fd f = fdget_raw(*(int *)key); 123 - int err; 126 + CLASS(fd_raw, f)(*(int *)key); 124 127 125 - if (!fd_file(f)) 128 + if (fd_empty(f)) 126 129 return -EBADF; 127 - 128 - err = inode_storage_delete(file_inode(fd_file(f)), map); 129 - fdput(f); 130 - return err; 130 + return inode_storage_delete(file_inode(fd_file(f)), map); 131 131 } 132 132 133 133 /* *gfp_flags* is a hidden argument provided by the verifier */
+3 -8
kernel/bpf/btf.c
··· 7711 7711 struct btf *btf_get_by_fd(int fd) 7712 7712 { 7713 7713 struct btf *btf; 7714 - struct fd f; 7714 + CLASS(fd, f)(fd); 7715 7715 7716 - f = fdget(fd); 7717 - 7718 - if (!fd_file(f)) 7716 + if (fd_empty(f)) 7719 7717 return ERR_PTR(-EBADF); 7720 7718 7721 - if (fd_file(f)->f_op != &btf_fops) { 7722 - fdput(f); 7719 + if (fd_file(f)->f_op != &btf_fops) 7723 7720 return ERR_PTR(-EINVAL); 7724 - } 7725 7721 7726 7722 btf = fd_file(f)->private_data; 7727 7723 refcount_inc(&btf->refcnt); 7728 - fdput(f); 7729 7724 7730 7725 return btf; 7731 7726 }
+11 -27
kernel/bpf/map_in_map.c
··· 11 11 { 12 12 struct bpf_map *inner_map, *inner_map_meta; 13 13 u32 inner_map_meta_size; 14 - struct fd f; 15 - int ret; 14 + CLASS(fd, f)(inner_map_ufd); 16 15 17 - f = fdget(inner_map_ufd); 18 16 inner_map = __bpf_map_get(f); 19 17 if (IS_ERR(inner_map)) 20 18 return inner_map; 21 19 22 20 /* Does not support >1 level map-in-map */ 23 - if (inner_map->inner_map_meta) { 24 - ret = -EINVAL; 25 - goto put; 26 - } 21 + if (inner_map->inner_map_meta) 22 + return ERR_PTR(-EINVAL); 27 23 28 - if (!inner_map->ops->map_meta_equal) { 29 - ret = -ENOTSUPP; 30 - goto put; 31 - } 24 + if (!inner_map->ops->map_meta_equal) 25 + return ERR_PTR(-ENOTSUPP); 32 26 33 27 inner_map_meta_size = sizeof(*inner_map_meta); 34 28 /* In some cases verifier needs to access beyond just base map. */ ··· 30 36 inner_map_meta_size = sizeof(struct bpf_array); 31 37 32 38 inner_map_meta = kzalloc(inner_map_meta_size, GFP_USER); 33 - if (!inner_map_meta) { 34 - ret = -ENOMEM; 35 - goto put; 36 - } 39 + if (!inner_map_meta) 40 + return ERR_PTR(-ENOMEM); 37 41 38 42 inner_map_meta->map_type = inner_map->map_type; 39 43 inner_map_meta->key_size = inner_map->key_size; ··· 45 53 * invalid/empty/valid, but ERR_PTR in case of errors. During 46 54 * equality NULL or IS_ERR is equivalent. 47 55 */ 48 - ret = PTR_ERR(inner_map_meta->record); 49 - goto free; 56 + struct bpf_map *ret = ERR_CAST(inner_map_meta->record); 57 + kfree(inner_map_meta); 58 + return ret; 50 59 } 51 60 /* Note: We must use the same BTF, as we also used btf_record_dup above 52 61 * which relies on BTF being same for both maps, as some members like ··· 70 77 inner_array_meta->elem_size = inner_array->elem_size; 71 78 inner_map_meta->bypass_spec_v1 = inner_map->bypass_spec_v1; 72 79 } 73 - 74 - fdput(f); 75 80 return inner_map_meta; 76 - free: 77 - kfree(inner_map_meta); 78 - put: 79 - fdput(f); 80 - return ERR_PTR(ret); 81 81 } 82 82 83 83 void bpf_map_meta_free(struct bpf_map *map_meta) ··· 96 110 int ufd) 97 111 { 98 112 struct bpf_map *inner_map, *inner_map_meta; 99 - struct fd f; 113 + CLASS(fd, f)(ufd); 100 114 101 - f = fdget(ufd); 102 115 inner_map = __bpf_map_get(f); 103 116 if (IS_ERR(inner_map)) 104 117 return inner_map; ··· 108 123 else 109 124 inner_map = ERR_PTR(-EINVAL); 110 125 111 - fdput(f); 112 126 return inner_map; 113 127 } 114 128
+49 -132
kernel/bpf/syscall.c
··· 1425 1425 return err; 1426 1426 } 1427 1427 1428 - /* if error is returned, fd is released. 1429 - * On success caller should complete fd access with matching fdput() 1430 - */ 1431 - struct bpf_map *__bpf_map_get(struct fd f) 1432 - { 1433 - if (!fd_file(f)) 1434 - return ERR_PTR(-EBADF); 1435 - if (fd_file(f)->f_op != &bpf_map_fops) { 1436 - fdput(f); 1437 - return ERR_PTR(-EINVAL); 1438 - } 1439 - 1440 - return fd_file(f)->private_data; 1441 - } 1442 - 1443 1428 void bpf_map_inc(struct bpf_map *map) 1444 1429 { 1445 1430 atomic64_inc(&map->refcnt); ··· 1440 1455 1441 1456 struct bpf_map *bpf_map_get(u32 ufd) 1442 1457 { 1443 - struct fd f = fdget(ufd); 1444 - struct bpf_map *map; 1458 + CLASS(fd, f)(ufd); 1459 + struct bpf_map *map = __bpf_map_get(f); 1445 1460 1446 - map = __bpf_map_get(f); 1447 - if (IS_ERR(map)) 1448 - return map; 1449 - 1450 - bpf_map_inc(map); 1451 - fdput(f); 1461 + if (!IS_ERR(map)) 1462 + bpf_map_inc(map); 1452 1463 1453 1464 return map; 1454 1465 } ··· 1452 1471 1453 1472 struct bpf_map *bpf_map_get_with_uref(u32 ufd) 1454 1473 { 1455 - struct fd f = fdget(ufd); 1456 - struct bpf_map *map; 1474 + CLASS(fd, f)(ufd); 1475 + struct bpf_map *map = __bpf_map_get(f); 1457 1476 1458 - map = __bpf_map_get(f); 1459 - if (IS_ERR(map)) 1460 - return map; 1461 - 1462 - bpf_map_inc_with_uref(map); 1463 - fdput(f); 1477 + if (!IS_ERR(map)) 1478 + bpf_map_inc_with_uref(map); 1464 1479 1465 1480 return map; 1466 1481 } ··· 1521 1544 { 1522 1545 void __user *ukey = u64_to_user_ptr(attr->key); 1523 1546 void __user *uvalue = u64_to_user_ptr(attr->value); 1524 - int ufd = attr->map_fd; 1525 1547 struct bpf_map *map; 1526 1548 void *key, *value; 1527 1549 u32 value_size; 1528 - struct fd f; 1529 1550 int err; 1530 1551 1531 1552 if (CHECK_ATTR(BPF_MAP_LOOKUP_ELEM)) ··· 1532 1557 if (attr->flags & ~BPF_F_LOCK) 1533 1558 return -EINVAL; 1534 1559 1535 - f = fdget(ufd); 1560 + CLASS(fd, f)(attr->map_fd); 1536 1561 map = __bpf_map_get(f); 1537 1562 if (IS_ERR(map)) 1538 1563 return PTR_ERR(map); 1539 - if (!(map_get_sys_perms(map, f) & FMODE_CAN_READ)) { 1540 - err = -EPERM; 1541 - goto err_put; 1542 - } 1564 + if (!(map_get_sys_perms(map, f) & FMODE_CAN_READ)) 1565 + return -EPERM; 1543 1566 1544 1567 if ((attr->flags & BPF_F_LOCK) && 1545 - !btf_record_has_field(map->record, BPF_SPIN_LOCK)) { 1546 - err = -EINVAL; 1547 - goto err_put; 1548 - } 1568 + !btf_record_has_field(map->record, BPF_SPIN_LOCK)) 1569 + return -EINVAL; 1549 1570 1550 1571 key = __bpf_copy_key(ukey, map->key_size); 1551 - if (IS_ERR(key)) { 1552 - err = PTR_ERR(key); 1553 - goto err_put; 1554 - } 1572 + if (IS_ERR(key)) 1573 + return PTR_ERR(key); 1555 1574 1556 1575 value_size = bpf_map_value_size(map); 1557 1576 ··· 1576 1607 kvfree(value); 1577 1608 free_key: 1578 1609 kvfree(key); 1579 - err_put: 1580 - fdput(f); 1581 1610 return err; 1582 1611 } 1583 1612 ··· 1586 1619 { 1587 1620 bpfptr_t ukey = make_bpfptr(attr->key, uattr.is_kernel); 1588 1621 bpfptr_t uvalue = make_bpfptr(attr->value, uattr.is_kernel); 1589 - int ufd = attr->map_fd; 1590 1622 struct bpf_map *map; 1591 1623 void *key, *value; 1592 1624 u32 value_size; 1593 - struct fd f; 1594 1625 int err; 1595 1626 1596 1627 if (CHECK_ATTR(BPF_MAP_UPDATE_ELEM)) 1597 1628 return -EINVAL; 1598 1629 1599 - f = fdget(ufd); 1630 + CLASS(fd, f)(attr->map_fd); 1600 1631 map = __bpf_map_get(f); 1601 1632 if (IS_ERR(map)) 1602 1633 return PTR_ERR(map); ··· 1632 1667 kvfree(key); 1633 1668 err_put: 1634 1669 bpf_map_write_active_dec(map); 1635 - fdput(f); 1636 1670 return err; 1637 1671 } 1638 1672 ··· 1640 1676 static int map_delete_elem(union bpf_attr *attr, bpfptr_t uattr) 1641 1677 { 1642 1678 bpfptr_t ukey = make_bpfptr(attr->key, uattr.is_kernel); 1643 - int ufd = attr->map_fd; 1644 1679 struct bpf_map *map; 1645 - struct fd f; 1646 1680 void *key; 1647 1681 int err; 1648 1682 1649 1683 if (CHECK_ATTR(BPF_MAP_DELETE_ELEM)) 1650 1684 return -EINVAL; 1651 1685 1652 - f = fdget(ufd); 1686 + CLASS(fd, f)(attr->map_fd); 1653 1687 map = __bpf_map_get(f); 1654 1688 if (IS_ERR(map)) 1655 1689 return PTR_ERR(map); ··· 1684 1722 kvfree(key); 1685 1723 err_put: 1686 1724 bpf_map_write_active_dec(map); 1687 - fdput(f); 1688 1725 return err; 1689 1726 } 1690 1727 ··· 1694 1733 { 1695 1734 void __user *ukey = u64_to_user_ptr(attr->key); 1696 1735 void __user *unext_key = u64_to_user_ptr(attr->next_key); 1697 - int ufd = attr->map_fd; 1698 1736 struct bpf_map *map; 1699 1737 void *key, *next_key; 1700 - struct fd f; 1701 1738 int err; 1702 1739 1703 1740 if (CHECK_ATTR(BPF_MAP_GET_NEXT_KEY)) 1704 1741 return -EINVAL; 1705 1742 1706 - f = fdget(ufd); 1743 + CLASS(fd, f)(attr->map_fd); 1707 1744 map = __bpf_map_get(f); 1708 1745 if (IS_ERR(map)) 1709 1746 return PTR_ERR(map); 1710 - if (!(map_get_sys_perms(map, f) & FMODE_CAN_READ)) { 1711 - err = -EPERM; 1712 - goto err_put; 1713 - } 1747 + if (!(map_get_sys_perms(map, f) & FMODE_CAN_READ)) 1748 + return -EPERM; 1714 1749 1715 1750 if (ukey) { 1716 1751 key = __bpf_copy_key(ukey, map->key_size); 1717 - if (IS_ERR(key)) { 1718 - err = PTR_ERR(key); 1719 - goto err_put; 1720 - } 1752 + if (IS_ERR(key)) 1753 + return PTR_ERR(key); 1721 1754 } else { 1722 1755 key = NULL; 1723 1756 } ··· 1743 1788 kvfree(next_key); 1744 1789 free_key: 1745 1790 kvfree(key); 1746 - err_put: 1747 - fdput(f); 1748 1791 return err; 1749 1792 } 1750 1793 ··· 1971 2018 { 1972 2019 void __user *ukey = u64_to_user_ptr(attr->key); 1973 2020 void __user *uvalue = u64_to_user_ptr(attr->value); 1974 - int ufd = attr->map_fd; 1975 2021 struct bpf_map *map; 1976 2022 void *key, *value; 1977 2023 u32 value_size; 1978 - struct fd f; 1979 2024 int err; 1980 2025 1981 2026 if (CHECK_ATTR(BPF_MAP_LOOKUP_AND_DELETE_ELEM)) ··· 1982 2031 if (attr->flags & ~BPF_F_LOCK) 1983 2032 return -EINVAL; 1984 2033 1985 - f = fdget(ufd); 2034 + CLASS(fd, f)(attr->map_fd); 1986 2035 map = __bpf_map_get(f); 1987 2036 if (IS_ERR(map)) 1988 2037 return PTR_ERR(map); ··· 2052 2101 kvfree(key); 2053 2102 err_put: 2054 2103 bpf_map_write_active_dec(map); 2055 - fdput(f); 2056 2104 return err; 2057 2105 } 2058 2106 ··· 2059 2109 2060 2110 static int map_freeze(const union bpf_attr *attr) 2061 2111 { 2062 - int err = 0, ufd = attr->map_fd; 2112 + int err = 0; 2063 2113 struct bpf_map *map; 2064 - struct fd f; 2065 2114 2066 2115 if (CHECK_ATTR(BPF_MAP_FREEZE)) 2067 2116 return -EINVAL; 2068 2117 2069 - f = fdget(ufd); 2118 + CLASS(fd, f)(attr->map_fd); 2070 2119 map = __bpf_map_get(f); 2071 2120 if (IS_ERR(map)) 2072 2121 return PTR_ERR(map); 2073 2122 2074 - if (map->map_type == BPF_MAP_TYPE_STRUCT_OPS || !IS_ERR_OR_NULL(map->record)) { 2075 - fdput(f); 2123 + if (map->map_type == BPF_MAP_TYPE_STRUCT_OPS || !IS_ERR_OR_NULL(map->record)) 2076 2124 return -ENOTSUPP; 2077 - } 2078 2125 2079 - if (!(map_get_sys_perms(map, f) & FMODE_CAN_WRITE)) { 2080 - fdput(f); 2126 + if (!(map_get_sys_perms(map, f) & FMODE_CAN_WRITE)) 2081 2127 return -EPERM; 2082 - } 2083 2128 2084 2129 mutex_lock(&map->freeze_mutex); 2085 2130 if (bpf_map_write_active(map)) { ··· 2089 2144 WRITE_ONCE(map->frozen, true); 2090 2145 err_put: 2091 2146 mutex_unlock(&map->freeze_mutex); 2092 - fdput(f); 2093 2147 return err; 2094 2148 } 2095 2149 ··· 2358 2414 O_RDWR | O_CLOEXEC); 2359 2415 } 2360 2416 2361 - static struct bpf_prog *____bpf_prog_get(struct fd f) 2362 - { 2363 - if (!fd_file(f)) 2364 - return ERR_PTR(-EBADF); 2365 - if (fd_file(f)->f_op != &bpf_prog_fops) { 2366 - fdput(f); 2367 - return ERR_PTR(-EINVAL); 2368 - } 2369 - 2370 - return fd_file(f)->private_data; 2371 - } 2372 - 2373 2417 void bpf_prog_add(struct bpf_prog *prog, int i) 2374 2418 { 2375 2419 atomic64_add(i, &prog->aux->refcnt); ··· 2413 2481 static struct bpf_prog *__bpf_prog_get(u32 ufd, enum bpf_prog_type *attach_type, 2414 2482 bool attach_drv) 2415 2483 { 2416 - struct fd f = fdget(ufd); 2484 + CLASS(fd, f)(ufd); 2417 2485 struct bpf_prog *prog; 2418 2486 2419 - prog = ____bpf_prog_get(f); 2420 - if (IS_ERR(prog)) 2421 - return prog; 2422 - if (!bpf_prog_get_ok(prog, attach_type, attach_drv)) { 2423 - prog = ERR_PTR(-EINVAL); 2424 - goto out; 2425 - } 2487 + if (fd_empty(f)) 2488 + return ERR_PTR(-EBADF); 2489 + if (fd_file(f)->f_op != &bpf_prog_fops) 2490 + return ERR_PTR(-EINVAL); 2491 + 2492 + prog = fd_file(f)->private_data; 2493 + if (!bpf_prog_get_ok(prog, attach_type, attach_drv)) 2494 + return ERR_PTR(-EINVAL); 2426 2495 2427 2496 bpf_prog_inc(prog); 2428 - out: 2429 - fdput(f); 2430 2497 return prog; 2431 2498 } 2432 2499 ··· 3194 3263 3195 3264 struct bpf_link *bpf_link_get_from_fd(u32 ufd) 3196 3265 { 3197 - struct fd f = fdget(ufd); 3266 + CLASS(fd, f)(ufd); 3198 3267 struct bpf_link *link; 3199 3268 3200 - if (!fd_file(f)) 3269 + if (fd_empty(f)) 3201 3270 return ERR_PTR(-EBADF); 3202 - if (fd_file(f)->f_op != &bpf_link_fops && fd_file(f)->f_op != &bpf_link_fops_poll) { 3203 - fdput(f); 3271 + if (fd_file(f)->f_op != &bpf_link_fops && fd_file(f)->f_op != &bpf_link_fops_poll) 3204 3272 return ERR_PTR(-EINVAL); 3205 - } 3206 3273 3207 3274 link = fd_file(f)->private_data; 3208 3275 bpf_link_inc(link); 3209 - fdput(f); 3210 - 3211 3276 return link; 3212 3277 } 3213 3278 EXPORT_SYMBOL(bpf_link_get_from_fd); ··· 4908 4981 static int bpf_obj_get_info_by_fd(const union bpf_attr *attr, 4909 4982 union bpf_attr __user *uattr) 4910 4983 { 4911 - int ufd = attr->info.bpf_fd; 4912 - struct fd f; 4913 - int err; 4914 - 4915 4984 if (CHECK_ATTR(BPF_OBJ_GET_INFO_BY_FD)) 4916 4985 return -EINVAL; 4917 4986 4918 - f = fdget(ufd); 4919 - if (!fd_file(f)) 4987 + CLASS(fd, f)(attr->info.bpf_fd); 4988 + if (fd_empty(f)) 4920 4989 return -EBADFD; 4921 4990 4922 4991 if (fd_file(f)->f_op == &bpf_prog_fops) 4923 - err = bpf_prog_get_info_by_fd(fd_file(f), fd_file(f)->private_data, attr, 4992 + return bpf_prog_get_info_by_fd(fd_file(f), fd_file(f)->private_data, attr, 4924 4993 uattr); 4925 4994 else if (fd_file(f)->f_op == &bpf_map_fops) 4926 - err = bpf_map_get_info_by_fd(fd_file(f), fd_file(f)->private_data, attr, 4995 + return bpf_map_get_info_by_fd(fd_file(f), fd_file(f)->private_data, attr, 4927 4996 uattr); 4928 4997 else if (fd_file(f)->f_op == &btf_fops) 4929 - err = bpf_btf_get_info_by_fd(fd_file(f), fd_file(f)->private_data, attr, uattr); 4998 + return bpf_btf_get_info_by_fd(fd_file(f), fd_file(f)->private_data, attr, uattr); 4930 4999 else if (fd_file(f)->f_op == &bpf_link_fops || fd_file(f)->f_op == &bpf_link_fops_poll) 4931 - err = bpf_link_get_info_by_fd(fd_file(f), fd_file(f)->private_data, 5000 + return bpf_link_get_info_by_fd(fd_file(f), fd_file(f)->private_data, 4932 5001 attr, uattr); 4933 - else 4934 - err = -EINVAL; 4935 - 4936 - fdput(f); 4937 - return err; 5002 + return -EINVAL; 4938 5003 } 4939 5004 4940 5005 #define BPF_BTF_LOAD_LAST_FIELD btf_token_fd ··· 5114 5195 cmd == BPF_MAP_LOOKUP_AND_DELETE_BATCH; 5115 5196 bool has_write = cmd != BPF_MAP_LOOKUP_BATCH; 5116 5197 struct bpf_map *map; 5117 - int err, ufd; 5118 - struct fd f; 5198 + int err; 5119 5199 5120 5200 if (CHECK_ATTR(BPF_MAP_BATCH)) 5121 5201 return -EINVAL; 5122 5202 5123 - ufd = attr->batch.map_fd; 5124 - f = fdget(ufd); 5203 + CLASS(fd, f)(attr->batch.map_fd); 5204 + 5125 5205 map = __bpf_map_get(f); 5126 5206 if (IS_ERR(map)) 5127 5207 return PTR_ERR(map); ··· 5148 5230 maybe_wait_bpf_programs(map); 5149 5231 bpf_map_write_active_dec(map); 5150 5232 } 5151 - fdput(f); 5152 5233 return err; 5153 5234 } 5154 5235
+26 -48
kernel/bpf/token.c
··· 116 116 struct user_namespace *userns; 117 117 struct inode *inode; 118 118 struct file *file; 119 + CLASS(fd, f)(attr->token_create.bpffs_fd); 119 120 struct path path; 120 - struct fd f; 121 + struct super_block *sb; 121 122 umode_t mode; 122 123 int err, fd; 123 124 124 - f = fdget(attr->token_create.bpffs_fd); 125 - if (!fd_file(f)) 125 + if (fd_empty(f)) 126 126 return -EBADF; 127 127 128 128 path = fd_file(f)->f_path; 129 - path_get(&path); 130 - fdput(f); 129 + sb = path.dentry->d_sb; 131 130 132 - if (path.dentry != path.mnt->mnt_sb->s_root) { 133 - err = -EINVAL; 134 - goto out_path; 135 - } 136 - if (path.mnt->mnt_sb->s_op != &bpf_super_ops) { 137 - err = -EINVAL; 138 - goto out_path; 139 - } 131 + if (path.dentry != sb->s_root) 132 + return -EINVAL; 133 + if (sb->s_op != &bpf_super_ops) 134 + return -EINVAL; 140 135 err = path_permission(&path, MAY_ACCESS); 141 136 if (err) 142 - goto out_path; 137 + return err; 143 138 144 - userns = path.dentry->d_sb->s_user_ns; 139 + userns = sb->s_user_ns; 145 140 /* 146 141 * Enforce that creators of BPF tokens are in the same user 147 142 * namespace as the BPF FS instance. This makes reasoning about 148 143 * permissions a lot easier and we can always relax this later. 149 144 */ 150 - if (current_user_ns() != userns) { 151 - err = -EPERM; 152 - goto out_path; 153 - } 154 - if (!ns_capable(userns, CAP_BPF)) { 155 - err = -EPERM; 156 - goto out_path; 157 - } 145 + if (current_user_ns() != userns) 146 + return -EPERM; 147 + if (!ns_capable(userns, CAP_BPF)) 148 + return -EPERM; 158 149 159 150 /* Creating BPF token in init_user_ns doesn't make much sense. */ 160 - if (current_user_ns() == &init_user_ns) { 161 - err = -EOPNOTSUPP; 162 - goto out_path; 163 - } 151 + if (current_user_ns() == &init_user_ns) 152 + return -EOPNOTSUPP; 164 153 165 - mnt_opts = path.dentry->d_sb->s_fs_info; 154 + mnt_opts = sb->s_fs_info; 166 155 if (mnt_opts->delegate_cmds == 0 && 167 156 mnt_opts->delegate_maps == 0 && 168 157 mnt_opts->delegate_progs == 0 && 169 - mnt_opts->delegate_attachs == 0) { 170 - err = -ENOENT; /* no BPF token delegation is set up */ 171 - goto out_path; 172 - } 158 + mnt_opts->delegate_attachs == 0) 159 + return -ENOENT; /* no BPF token delegation is set up */ 173 160 174 161 mode = S_IFREG | ((S_IRUSR | S_IWUSR) & ~current_umask()); 175 - inode = bpf_get_inode(path.mnt->mnt_sb, NULL, mode); 176 - if (IS_ERR(inode)) { 177 - err = PTR_ERR(inode); 178 - goto out_path; 179 - } 162 + inode = bpf_get_inode(sb, NULL, mode); 163 + if (IS_ERR(inode)) 164 + return PTR_ERR(inode); 180 165 181 166 inode->i_op = &bpf_token_iops; 182 167 inode->i_fop = &bpf_token_fops; ··· 170 185 file = alloc_file_pseudo(inode, path.mnt, BPF_TOKEN_INODE_NAME, O_RDWR, &bpf_token_fops); 171 186 if (IS_ERR(file)) { 172 187 iput(inode); 173 - err = PTR_ERR(file); 174 - goto out_path; 188 + return PTR_ERR(file); 175 189 } 176 190 177 191 token = kzalloc(sizeof(*token), GFP_USER); ··· 202 218 file->private_data = token; 203 219 fd_install(fd, file); 204 220 205 - path_put(&path); 206 221 return fd; 207 222 208 223 out_token: 209 224 bpf_token_free(token); 210 225 out_file: 211 226 fput(file); 212 - out_path: 213 - path_put(&path); 214 227 return err; 215 228 } 216 229 217 230 struct bpf_token *bpf_token_get_from_fd(u32 ufd) 218 231 { 219 - struct fd f = fdget(ufd); 232 + CLASS(fd, f)(ufd); 220 233 struct bpf_token *token; 221 234 222 - if (!fd_file(f)) 235 + if (fd_empty(f)) 223 236 return ERR_PTR(-EBADF); 224 - if (fd_file(f)->f_op != &bpf_token_fops) { 225 - fdput(f); 237 + if (fd_file(f)->f_op != &bpf_token_fops) 226 238 return ERR_PTR(-EINVAL); 227 - } 228 239 229 240 token = fd_file(f)->private_data; 230 241 bpf_token_inc(token); 231 - fdput(f); 232 242 233 243 return token; 234 244 }
+63 -51
kernel/bpf/verifier.c
··· 18920 18920 map->map_type == BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE); 18921 18921 } 18922 18922 18923 + /* Add map behind fd to used maps list, if it's not already there, and return 18924 + * its index. Also set *reused to true if this map was already in the list of 18925 + * used maps. 18926 + * Returns <0 on error, or >= 0 index, on success. 18927 + */ 18928 + static int add_used_map_from_fd(struct bpf_verifier_env *env, int fd, bool *reused) 18929 + { 18930 + CLASS(fd, f)(fd); 18931 + struct bpf_map *map; 18932 + int i; 18933 + 18934 + map = __bpf_map_get(f); 18935 + if (IS_ERR(map)) { 18936 + verbose(env, "fd %d is not pointing to valid bpf_map\n", fd); 18937 + return PTR_ERR(map); 18938 + } 18939 + 18940 + /* check whether we recorded this map already */ 18941 + for (i = 0; i < env->used_map_cnt; i++) { 18942 + if (env->used_maps[i] == map) { 18943 + *reused = true; 18944 + return i; 18945 + } 18946 + } 18947 + 18948 + if (env->used_map_cnt >= MAX_USED_MAPS) { 18949 + verbose(env, "The total number of maps per program has reached the limit of %u\n", 18950 + MAX_USED_MAPS); 18951 + return -E2BIG; 18952 + } 18953 + 18954 + if (env->prog->sleepable) 18955 + atomic64_inc(&map->sleepable_refcnt); 18956 + 18957 + /* hold the map. If the program is rejected by verifier, 18958 + * the map will be released by release_maps() or it 18959 + * will be used by the valid program until it's unloaded 18960 + * and all maps are released in bpf_free_used_maps() 18961 + */ 18962 + bpf_map_inc(map); 18963 + 18964 + *reused = false; 18965 + env->used_maps[env->used_map_cnt++] = map; 18966 + 18967 + return env->used_map_cnt - 1; 18968 + } 18969 + 18923 18970 /* find and rewrite pseudo imm in ld_imm64 instructions: 18924 18971 * 18925 18972 * 1. if it accesses map FD, replace it with actual map pointer. ··· 18978 18931 { 18979 18932 struct bpf_insn *insn = env->prog->insnsi; 18980 18933 int insn_cnt = env->prog->len; 18981 - int i, j, err; 18934 + int i, err; 18982 18935 18983 18936 err = bpf_prog_calc_tag(env->prog); 18984 18937 if (err) ··· 18995 18948 if (insn[0].code == (BPF_LD | BPF_IMM | BPF_DW)) { 18996 18949 struct bpf_insn_aux_data *aux; 18997 18950 struct bpf_map *map; 18998 - struct fd f; 18951 + int map_idx; 18999 18952 u64 addr; 19000 18953 u32 fd; 18954 + bool reused; 19001 18955 19002 18956 if (i == insn_cnt - 1 || insn[1].code != 0 || 19003 18957 insn[1].dst_reg != 0 || insn[1].src_reg != 0 || ··· 19059 19011 break; 19060 19012 } 19061 19013 19062 - f = fdget(fd); 19063 - map = __bpf_map_get(f); 19064 - if (IS_ERR(map)) { 19065 - verbose(env, "fd %d is not pointing to valid bpf_map\n", fd); 19066 - return PTR_ERR(map); 19067 - } 19068 - 19069 - err = check_map_prog_compatibility(env, map, env->prog); 19070 - if (err) { 19071 - fdput(f); 19072 - return err; 19073 - } 19014 + map_idx = add_used_map_from_fd(env, fd, &reused); 19015 + if (map_idx < 0) 19016 + return map_idx; 19017 + map = env->used_maps[map_idx]; 19074 19018 19075 19019 aux = &env->insn_aux_data[i]; 19020 + aux->map_index = map_idx; 19021 + 19022 + err = check_map_prog_compatibility(env, map, env->prog); 19023 + if (err) 19024 + return err; 19025 + 19076 19026 if (insn[0].src_reg == BPF_PSEUDO_MAP_FD || 19077 19027 insn[0].src_reg == BPF_PSEUDO_MAP_IDX) { 19078 19028 addr = (unsigned long)map; ··· 19079 19033 19080 19034 if (off >= BPF_MAX_VAR_OFF) { 19081 19035 verbose(env, "direct value offset of %u is not allowed\n", off); 19082 - fdput(f); 19083 19036 return -EINVAL; 19084 19037 } 19085 19038 19086 19039 if (!map->ops->map_direct_value_addr) { 19087 19040 verbose(env, "no direct value access support for this map type\n"); 19088 - fdput(f); 19089 19041 return -EINVAL; 19090 19042 } 19091 19043 ··· 19091 19047 if (err) { 19092 19048 verbose(env, "invalid access to map value pointer, value_size=%u off=%u\n", 19093 19049 map->value_size, off); 19094 - fdput(f); 19095 19050 return err; 19096 19051 } 19097 19052 ··· 19101 19058 insn[0].imm = (u32)addr; 19102 19059 insn[1].imm = addr >> 32; 19103 19060 19104 - /* check whether we recorded this map already */ 19105 - for (j = 0; j < env->used_map_cnt; j++) { 19106 - if (env->used_maps[j] == map) { 19107 - aux->map_index = j; 19108 - fdput(f); 19109 - goto next_insn; 19110 - } 19111 - } 19112 - 19113 - if (env->used_map_cnt >= MAX_USED_MAPS) { 19114 - verbose(env, "The total number of maps per program has reached the limit of %u\n", 19115 - MAX_USED_MAPS); 19116 - fdput(f); 19117 - return -E2BIG; 19118 - } 19119 - 19120 - if (env->prog->sleepable) 19121 - atomic64_inc(&map->sleepable_refcnt); 19122 - /* hold the map. If the program is rejected by verifier, 19123 - * the map will be released by release_maps() or it 19124 - * will be used by the valid program until it's unloaded 19125 - * and all maps are released in bpf_free_used_maps() 19126 - */ 19127 - bpf_map_inc(map); 19128 - 19129 - aux->map_index = env->used_map_cnt; 19130 - env->used_maps[env->used_map_cnt++] = map; 19061 + /* proceed with extra checks only if its newly added used map */ 19062 + if (reused) 19063 + goto next_insn; 19131 19064 19132 19065 if (bpf_map_is_cgroup_storage(map) && 19133 19066 bpf_cgroup_storage_assign(env->prog->aux, map)) { 19134 19067 verbose(env, "only one cgroup storage of each type is allowed\n"); 19135 - fdput(f); 19136 19068 return -EBUSY; 19137 19069 } 19138 19070 if (map->map_type == BPF_MAP_TYPE_ARENA) { 19139 19071 if (env->prog->aux->arena) { 19140 19072 verbose(env, "Only one arena per program\n"); 19141 - fdput(f); 19142 19073 return -EBUSY; 19143 19074 } 19144 19075 if (!env->allow_ptr_leaks || !env->bpf_capable) { 19145 19076 verbose(env, "CAP_BPF and CAP_PERFMON are required to use arena\n"); 19146 - fdput(f); 19147 19077 return -EPERM; 19148 19078 } 19149 19079 if (!env->prog->jit_requested) { 19150 19080 verbose(env, "JIT is required to use arena\n"); 19151 - fdput(f); 19152 19081 return -EOPNOTSUPP; 19153 19082 } 19154 19083 if (!bpf_jit_supports_arena()) { 19155 19084 verbose(env, "JIT doesn't support arena\n"); 19156 - fdput(f); 19157 19085 return -EOPNOTSUPP; 19158 19086 } 19159 19087 env->prog->aux->arena = (void *)map; 19160 19088 if (!bpf_arena_get_user_vm_start(env->prog->aux->arena)) { 19161 19089 verbose(env, "arena's user address must be set via map_extra or mmap()\n"); 19162 - fdput(f); 19163 19090 return -EINVAL; 19164 19091 } 19165 19092 } 19166 19093 19167 - fdput(f); 19168 19094 next_insn: 19169 19095 insn++; 19170 19096 i++;
+6 -17
net/core/sock_map.c
··· 67 67 68 68 int sock_map_get_from_fd(const union bpf_attr *attr, struct bpf_prog *prog) 69 69 { 70 - u32 ufd = attr->target_fd; 71 70 struct bpf_map *map; 72 - struct fd f; 73 71 int ret; 74 72 75 73 if (attr->attach_flags || attr->replace_bpf_fd) 76 74 return -EINVAL; 77 75 78 - f = fdget(ufd); 76 + CLASS(fd, f)(attr->target_fd); 79 77 map = __bpf_map_get(f); 80 78 if (IS_ERR(map)) 81 79 return PTR_ERR(map); 82 80 mutex_lock(&sockmap_mutex); 83 81 ret = sock_map_prog_update(map, prog, NULL, NULL, attr->attach_type); 84 82 mutex_unlock(&sockmap_mutex); 85 - fdput(f); 86 83 return ret; 87 84 } 88 85 89 86 int sock_map_prog_detach(const union bpf_attr *attr, enum bpf_prog_type ptype) 90 87 { 91 - u32 ufd = attr->target_fd; 92 88 struct bpf_prog *prog; 93 89 struct bpf_map *map; 94 - struct fd f; 95 90 int ret; 96 91 97 92 if (attr->attach_flags || attr->replace_bpf_fd) 98 93 return -EINVAL; 99 94 100 - f = fdget(ufd); 95 + CLASS(fd, f)(attr->target_fd); 101 96 map = __bpf_map_get(f); 102 97 if (IS_ERR(map)) 103 98 return PTR_ERR(map); 104 99 105 100 prog = bpf_prog_get(attr->attach_bpf_fd); 106 - if (IS_ERR(prog)) { 107 - ret = PTR_ERR(prog); 108 - goto put_map; 109 - } 101 + if (IS_ERR(prog)) 102 + return PTR_ERR(prog); 110 103 111 104 if (prog->type != ptype) { 112 105 ret = -EINVAL; ··· 111 118 mutex_unlock(&sockmap_mutex); 112 119 put_prog: 113 120 bpf_prog_put(prog); 114 - put_map: 115 - fdput(f); 116 121 return ret; 117 122 } 118 123 ··· 1542 1551 union bpf_attr __user *uattr) 1543 1552 { 1544 1553 __u32 __user *prog_ids = u64_to_user_ptr(attr->query.prog_ids); 1545 - u32 prog_cnt = 0, flags = 0, ufd = attr->target_fd; 1554 + u32 prog_cnt = 0, flags = 0; 1546 1555 struct bpf_prog **pprog; 1547 1556 struct bpf_prog *prog; 1548 1557 struct bpf_map *map; 1549 - struct fd f; 1550 1558 u32 id = 0; 1551 1559 int ret; 1552 1560 1553 1561 if (attr->query.query_flags) 1554 1562 return -EINVAL; 1555 1563 1556 - f = fdget(ufd); 1564 + CLASS(fd, f)(attr->target_fd); 1557 1565 map = __bpf_map_get(f); 1558 1566 if (IS_ERR(map)) 1559 1567 return PTR_ERR(map); ··· 1584 1594 copy_to_user(&uattr->query.prog_cnt, &prog_cnt, sizeof(prog_cnt))) 1585 1595 ret = -EFAULT; 1586 1596 1587 - fdput(f); 1588 1597 return ret; 1589 1598 } 1590 1599
+1 -1
security/security.c
··· 5681 5681 * Return: Returns 0 on success, error on failure. 5682 5682 */ 5683 5683 int security_bpf_token_create(struct bpf_token *token, union bpf_attr *attr, 5684 - struct path *path) 5684 + const struct path *path) 5685 5685 { 5686 5686 return call_int_hook(bpf_token_create, token, attr, path); 5687 5687 }
+1 -1
security/selinux/hooks.c
··· 6933 6933 } 6934 6934 6935 6935 static int selinux_bpf_token_create(struct bpf_token *token, union bpf_attr *attr, 6936 - struct path *path) 6936 + const struct path *path) 6937 6937 { 6938 6938 struct bpf_security_struct *bpfsec; 6939 6939