diff options
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/bpf/cgroup.c | 54 | ||||
| -rw-r--r-- | kernel/bpf/sockmap.c | 18 | ||||
| -rw-r--r-- | kernel/bpf/syscall.c | 99 |
3 files changed, 93 insertions, 78 deletions
diff --git a/kernel/bpf/cgroup.c b/kernel/bpf/cgroup.c index f7c00bd6f8e4..3d83ee7df381 100644 --- a/kernel/bpf/cgroup.c +++ b/kernel/bpf/cgroup.c | |||
| @@ -428,6 +428,60 @@ int __cgroup_bpf_query(struct cgroup *cgrp, const union bpf_attr *attr, | |||
| 428 | return ret; | 428 | return ret; |
| 429 | } | 429 | } |
| 430 | 430 | ||
| 431 | int cgroup_bpf_prog_attach(const union bpf_attr *attr, | ||
| 432 | enum bpf_prog_type ptype, struct bpf_prog *prog) | ||
| 433 | { | ||
| 434 | struct cgroup *cgrp; | ||
| 435 | int ret; | ||
| 436 | |||
| 437 | cgrp = cgroup_get_from_fd(attr->target_fd); | ||
| 438 | if (IS_ERR(cgrp)) | ||
| 439 | return PTR_ERR(cgrp); | ||
| 440 | |||
| 441 | ret = cgroup_bpf_attach(cgrp, prog, attr->attach_type, | ||
| 442 | attr->attach_flags); | ||
| 443 | cgroup_put(cgrp); | ||
| 444 | return ret; | ||
| 445 | } | ||
| 446 | |||
| 447 | int cgroup_bpf_prog_detach(const union bpf_attr *attr, enum bpf_prog_type ptype) | ||
| 448 | { | ||
| 449 | struct bpf_prog *prog; | ||
| 450 | struct cgroup *cgrp; | ||
| 451 | int ret; | ||
| 452 | |||
| 453 | cgrp = cgroup_get_from_fd(attr->target_fd); | ||
| 454 | if (IS_ERR(cgrp)) | ||
| 455 | return PTR_ERR(cgrp); | ||
| 456 | |||
| 457 | prog = bpf_prog_get_type(attr->attach_bpf_fd, ptype); | ||
| 458 | if (IS_ERR(prog)) | ||
| 459 | prog = NULL; | ||
| 460 | |||
| 461 | ret = cgroup_bpf_detach(cgrp, prog, attr->attach_type, 0); | ||
| 462 | if (prog) | ||
| 463 | bpf_prog_put(prog); | ||
| 464 | |||
| 465 | cgroup_put(cgrp); | ||
| 466 | return ret; | ||
| 467 | } | ||
| 468 | |||
| 469 | int cgroup_bpf_prog_query(const union bpf_attr *attr, | ||
| 470 | union bpf_attr __user *uattr) | ||
| 471 | { | ||
| 472 | struct cgroup *cgrp; | ||
| 473 | int ret; | ||
| 474 | |||
| 475 | cgrp = cgroup_get_from_fd(attr->query.target_fd); | ||
| 476 | if (IS_ERR(cgrp)) | ||
| 477 | return PTR_ERR(cgrp); | ||
| 478 | |||
| 479 | ret = cgroup_bpf_query(cgrp, attr, uattr); | ||
| 480 | |||
| 481 | cgroup_put(cgrp); | ||
| 482 | return ret; | ||
| 483 | } | ||
| 484 | |||
| 431 | /** | 485 | /** |
| 432 | * __cgroup_bpf_run_filter_skb() - Run a program for packet filtering | 486 | * __cgroup_bpf_run_filter_skb() - Run a program for packet filtering |
| 433 | * @sk: The socket sending or receiving traffic | 487 | * @sk: The socket sending or receiving traffic |
diff --git a/kernel/bpf/sockmap.c b/kernel/bpf/sockmap.c index 52a91d816c0e..81d0c55a77aa 100644 --- a/kernel/bpf/sockmap.c +++ b/kernel/bpf/sockmap.c | |||
| @@ -1915,6 +1915,24 @@ int sock_map_prog(struct bpf_map *map, struct bpf_prog *prog, u32 type) | |||
| 1915 | return 0; | 1915 | return 0; |
| 1916 | } | 1916 | } |
| 1917 | 1917 | ||
| 1918 | int sockmap_get_from_fd(const union bpf_attr *attr, int type, | ||
| 1919 | struct bpf_prog *prog) | ||
| 1920 | { | ||
| 1921 | int ufd = attr->target_fd; | ||
| 1922 | struct bpf_map *map; | ||
| 1923 | struct fd f; | ||
| 1924 | int err; | ||
| 1925 | |||
| 1926 | f = fdget(ufd); | ||
| 1927 | map = __bpf_map_get(f); | ||
| 1928 | if (IS_ERR(map)) | ||
| 1929 | return PTR_ERR(map); | ||
| 1930 | |||
| 1931 | err = sock_map_prog(map, prog, attr->attach_type); | ||
| 1932 | fdput(f); | ||
| 1933 | return err; | ||
| 1934 | } | ||
| 1935 | |||
| 1918 | static void *sock_map_lookup(struct bpf_map *map, void *key) | 1936 | static void *sock_map_lookup(struct bpf_map *map, void *key) |
| 1919 | { | 1937 | { |
| 1920 | return NULL; | 1938 | return NULL; |
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c index 35dc466641f2..d10ecd78105f 100644 --- a/kernel/bpf/syscall.c +++ b/kernel/bpf/syscall.c | |||
| @@ -1483,8 +1483,6 @@ out_free_tp: | |||
| 1483 | return err; | 1483 | return err; |
| 1484 | } | 1484 | } |
| 1485 | 1485 | ||
| 1486 | #ifdef CONFIG_CGROUP_BPF | ||
| 1487 | |||
| 1488 | static int bpf_prog_attach_check_attach_type(const struct bpf_prog *prog, | 1486 | static int bpf_prog_attach_check_attach_type(const struct bpf_prog *prog, |
| 1489 | enum bpf_attach_type attach_type) | 1487 | enum bpf_attach_type attach_type) |
| 1490 | { | 1488 | { |
| @@ -1499,40 +1497,6 @@ static int bpf_prog_attach_check_attach_type(const struct bpf_prog *prog, | |||
| 1499 | 1497 | ||
| 1500 | #define BPF_PROG_ATTACH_LAST_FIELD attach_flags | 1498 | #define BPF_PROG_ATTACH_LAST_FIELD attach_flags |
| 1501 | 1499 | ||
| 1502 | static int sockmap_get_from_fd(const union bpf_attr *attr, | ||
| 1503 | int type, bool attach) | ||
| 1504 | { | ||
| 1505 | struct bpf_prog *prog = NULL; | ||
| 1506 | int ufd = attr->target_fd; | ||
| 1507 | struct bpf_map *map; | ||
| 1508 | struct fd f; | ||
| 1509 | int err; | ||
| 1510 | |||
| 1511 | f = fdget(ufd); | ||
| 1512 | map = __bpf_map_get(f); | ||
| 1513 | if (IS_ERR(map)) | ||
| 1514 | return PTR_ERR(map); | ||
| 1515 | |||
| 1516 | if (attach) { | ||
| 1517 | prog = bpf_prog_get_type(attr->attach_bpf_fd, type); | ||
| 1518 | if (IS_ERR(prog)) { | ||
| 1519 | fdput(f); | ||
| 1520 | return PTR_ERR(prog); | ||
| 1521 | } | ||
| 1522 | } | ||
| 1523 | |||
| 1524 | err = sock_map_prog(map, prog, attr->attach_type); | ||
| 1525 | if (err) { | ||
| 1526 | fdput(f); | ||
| 1527 | if (prog) | ||
| 1528 | bpf_prog_put(prog); | ||
| 1529 | return err; | ||
| 1530 | } | ||
| 1531 | |||
| 1532 | fdput(f); | ||
| 1533 | return 0; | ||
| 1534 | } | ||
| 1535 | |||
| 1536 | #define BPF_F_ATTACH_MASK \ | 1500 | #define BPF_F_ATTACH_MASK \ |
| 1537 | (BPF_F_ALLOW_OVERRIDE | BPF_F_ALLOW_MULTI) | 1501 | (BPF_F_ALLOW_OVERRIDE | BPF_F_ALLOW_MULTI) |
| 1538 | 1502 | ||
| @@ -1540,7 +1504,6 @@ static int bpf_prog_attach(const union bpf_attr *attr) | |||
| 1540 | { | 1504 | { |
| 1541 | enum bpf_prog_type ptype; | 1505 | enum bpf_prog_type ptype; |
| 1542 | struct bpf_prog *prog; | 1506 | struct bpf_prog *prog; |
| 1543 | struct cgroup *cgrp; | ||
| 1544 | int ret; | 1507 | int ret; |
| 1545 | 1508 | ||
| 1546 | if (!capable(CAP_NET_ADMIN)) | 1509 | if (!capable(CAP_NET_ADMIN)) |
| @@ -1577,12 +1540,15 @@ static int bpf_prog_attach(const union bpf_attr *attr) | |||
| 1577 | ptype = BPF_PROG_TYPE_CGROUP_DEVICE; | 1540 | ptype = BPF_PROG_TYPE_CGROUP_DEVICE; |
| 1578 | break; | 1541 | break; |
| 1579 | case BPF_SK_MSG_VERDICT: | 1542 | case BPF_SK_MSG_VERDICT: |
| 1580 | return sockmap_get_from_fd(attr, BPF_PROG_TYPE_SK_MSG, true); | 1543 | ptype = BPF_PROG_TYPE_SK_MSG; |
| 1544 | break; | ||
| 1581 | case BPF_SK_SKB_STREAM_PARSER: | 1545 | case BPF_SK_SKB_STREAM_PARSER: |
| 1582 | case BPF_SK_SKB_STREAM_VERDICT: | 1546 | case BPF_SK_SKB_STREAM_VERDICT: |
| 1583 | return sockmap_get_from_fd(attr, BPF_PROG_TYPE_SK_SKB, true); | 1547 | ptype = BPF_PROG_TYPE_SK_SKB; |
| 1548 | break; | ||
| 1584 | case BPF_LIRC_MODE2: | 1549 | case BPF_LIRC_MODE2: |
| 1585 | return lirc_prog_attach(attr); | 1550 | ptype = BPF_PROG_TYPE_LIRC_MODE2; |
| 1551 | break; | ||
| 1586 | default: | 1552 | default: |
| 1587 | return -EINVAL; | 1553 | return -EINVAL; |
| 1588 | } | 1554 | } |
| @@ -1596,18 +1562,20 @@ static int bpf_prog_attach(const union bpf_attr *attr) | |||
| 1596 | return -EINVAL; | 1562 | return -EINVAL; |
| 1597 | } | 1563 | } |
| 1598 | 1564 | ||
| 1599 | cgrp = cgroup_get_from_fd(attr->target_fd); | 1565 | switch (ptype) { |
| 1600 | if (IS_ERR(cgrp)) { | 1566 | case BPF_PROG_TYPE_SK_SKB: |
| 1601 | bpf_prog_put(prog); | 1567 | case BPF_PROG_TYPE_SK_MSG: |
| 1602 | return PTR_ERR(cgrp); | 1568 | ret = sockmap_get_from_fd(attr, ptype, prog); |
| 1569 | break; | ||
| 1570 | case BPF_PROG_TYPE_LIRC_MODE2: | ||
| 1571 | ret = lirc_prog_attach(attr, prog); | ||
| 1572 | break; | ||
| 1573 | default: | ||
| 1574 | ret = cgroup_bpf_prog_attach(attr, ptype, prog); | ||
| 1603 | } | 1575 | } |
| 1604 | 1576 | ||
| 1605 | ret = cgroup_bpf_attach(cgrp, prog, attr->attach_type, | ||
| 1606 | attr->attach_flags); | ||
| 1607 | if (ret) | 1577 | if (ret) |
| 1608 | bpf_prog_put(prog); | 1578 | bpf_prog_put(prog); |
| 1609 | cgroup_put(cgrp); | ||
| 1610 | |||
| 1611 | return ret; | 1579 | return ret; |
| 1612 | } | 1580 | } |
| 1613 | 1581 | ||
| @@ -1616,9 +1584,6 @@ static int bpf_prog_attach(const union bpf_attr *attr) | |||
| 1616 | static int bpf_prog_detach(const union bpf_attr *attr) | 1584 | static int bpf_prog_detach(const union bpf_attr *attr) |
| 1617 | { | 1585 | { |
| 1618 | enum bpf_prog_type ptype; | 1586 | enum bpf_prog_type ptype; |
| 1619 | struct bpf_prog *prog; | ||
| 1620 | struct cgroup *cgrp; | ||
| 1621 | int ret; | ||
| 1622 | 1587 | ||
| 1623 | if (!capable(CAP_NET_ADMIN)) | 1588 | if (!capable(CAP_NET_ADMIN)) |
| 1624 | return -EPERM; | 1589 | return -EPERM; |
| @@ -1651,29 +1616,17 @@ static int bpf_prog_detach(const union bpf_attr *attr) | |||
| 1651 | ptype = BPF_PROG_TYPE_CGROUP_DEVICE; | 1616 | ptype = BPF_PROG_TYPE_CGROUP_DEVICE; |
| 1652 | break; | 1617 | break; |
| 1653 | case BPF_SK_MSG_VERDICT: | 1618 | case BPF_SK_MSG_VERDICT: |
| 1654 | return sockmap_get_from_fd(attr, BPF_PROG_TYPE_SK_MSG, false); | 1619 | return sockmap_get_from_fd(attr, BPF_PROG_TYPE_SK_MSG, NULL); |
| 1655 | case BPF_SK_SKB_STREAM_PARSER: | 1620 | case BPF_SK_SKB_STREAM_PARSER: |
| 1656 | case BPF_SK_SKB_STREAM_VERDICT: | 1621 | case BPF_SK_SKB_STREAM_VERDICT: |
| 1657 | return sockmap_get_from_fd(attr, BPF_PROG_TYPE_SK_SKB, false); | 1622 | return sockmap_get_from_fd(attr, BPF_PROG_TYPE_SK_SKB, NULL); |
| 1658 | case BPF_LIRC_MODE2: | 1623 | case BPF_LIRC_MODE2: |
| 1659 | return lirc_prog_detach(attr); | 1624 | return lirc_prog_detach(attr); |
| 1660 | default: | 1625 | default: |
| 1661 | return -EINVAL; | 1626 | return -EINVAL; |
| 1662 | } | 1627 | } |
| 1663 | 1628 | ||
| 1664 | cgrp = cgroup_get_from_fd(attr->target_fd); | 1629 | return cgroup_bpf_prog_detach(attr, ptype); |
| 1665 | if (IS_ERR(cgrp)) | ||
| 1666 | return PTR_ERR(cgrp); | ||
| 1667 | |||
| 1668 | prog = bpf_prog_get_type(attr->attach_bpf_fd, ptype); | ||
| 1669 | if (IS_ERR(prog)) | ||
| 1670 | prog = NULL; | ||
| 1671 | |||
| 1672 | ret = cgroup_bpf_detach(cgrp, prog, attr->attach_type, 0); | ||
| 1673 | if (prog) | ||
| 1674 | bpf_prog_put(prog); | ||
| 1675 | cgroup_put(cgrp); | ||
| 1676 | return ret; | ||
| 1677 | } | 1630 | } |
| 1678 | 1631 | ||
| 1679 | #define BPF_PROG_QUERY_LAST_FIELD query.prog_cnt | 1632 | #define BPF_PROG_QUERY_LAST_FIELD query.prog_cnt |
| @@ -1681,9 +1634,6 @@ static int bpf_prog_detach(const union bpf_attr *attr) | |||
| 1681 | static int bpf_prog_query(const union bpf_attr *attr, | 1634 | static int bpf_prog_query(const union bpf_attr *attr, |
| 1682 | union bpf_attr __user *uattr) | 1635 | union bpf_attr __user *uattr) |
| 1683 | { | 1636 | { |
| 1684 | struct cgroup *cgrp; | ||
| 1685 | int ret; | ||
| 1686 | |||
| 1687 | if (!capable(CAP_NET_ADMIN)) | 1637 | if (!capable(CAP_NET_ADMIN)) |
| 1688 | return -EPERM; | 1638 | return -EPERM; |
| 1689 | if (CHECK_ATTR(BPF_PROG_QUERY)) | 1639 | if (CHECK_ATTR(BPF_PROG_QUERY)) |
| @@ -1711,14 +1661,9 @@ static int bpf_prog_query(const union bpf_attr *attr, | |||
| 1711 | default: | 1661 | default: |
| 1712 | return -EINVAL; | 1662 | return -EINVAL; |
| 1713 | } | 1663 | } |
| 1714 | cgrp = cgroup_get_from_fd(attr->query.target_fd); | 1664 | |
| 1715 | if (IS_ERR(cgrp)) | 1665 | return cgroup_bpf_prog_query(attr, uattr); |
| 1716 | return PTR_ERR(cgrp); | ||
| 1717 | ret = cgroup_bpf_query(cgrp, attr, uattr); | ||
| 1718 | cgroup_put(cgrp); | ||
| 1719 | return ret; | ||
| 1720 | } | 1666 | } |
| 1721 | #endif /* CONFIG_CGROUP_BPF */ | ||
| 1722 | 1667 | ||
| 1723 | #define BPF_PROG_TEST_RUN_LAST_FIELD test.duration | 1668 | #define BPF_PROG_TEST_RUN_LAST_FIELD test.duration |
| 1724 | 1669 | ||
| @@ -2365,7 +2310,6 @@ SYSCALL_DEFINE3(bpf, int, cmd, union bpf_attr __user *, uattr, unsigned int, siz | |||
| 2365 | case BPF_OBJ_GET: | 2310 | case BPF_OBJ_GET: |
| 2366 | err = bpf_obj_get(&attr); | 2311 | err = bpf_obj_get(&attr); |
| 2367 | break; | 2312 | break; |
| 2368 | #ifdef CONFIG_CGROUP_BPF | ||
| 2369 | case BPF_PROG_ATTACH: | 2313 | case BPF_PROG_ATTACH: |
| 2370 | err = bpf_prog_attach(&attr); | 2314 | err = bpf_prog_attach(&attr); |
| 2371 | break; | 2315 | break; |
| @@ -2375,7 +2319,6 @@ SYSCALL_DEFINE3(bpf, int, cmd, union bpf_attr __user *, uattr, unsigned int, siz | |||
| 2375 | case BPF_PROG_QUERY: | 2319 | case BPF_PROG_QUERY: |
| 2376 | err = bpf_prog_query(&attr, uattr); | 2320 | err = bpf_prog_query(&attr, uattr); |
| 2377 | break; | 2321 | break; |
| 2378 | #endif | ||
| 2379 | case BPF_PROG_TEST_RUN: | 2322 | case BPF_PROG_TEST_RUN: |
| 2380 | err = bpf_prog_test_run(&attr, uattr); | 2323 | err = bpf_prog_test_run(&attr, uattr); |
| 2381 | break; | 2324 | break; |
