summaryrefslogtreecommitdiffstats
path: root/kernel/bpf/syscall.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/bpf/syscall.c')
-rw-r--r--kernel/bpf/syscall.c99
1 files changed, 21 insertions, 78 deletions
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
1488static int bpf_prog_attach_check_attach_type(const struct bpf_prog *prog, 1486static 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
1502static 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)
1616static int bpf_prog_detach(const union bpf_attr *attr) 1584static 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)
1681static int bpf_prog_query(const union bpf_attr *attr, 1634static 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;