diff options
| author | Sean Young <sean@mess.org> | 2018-06-18 19:04:24 -0400 |
|---|---|---|
| committer | Daniel Borkmann <daniel@iogearbox.net> | 2018-06-26 05:28:38 -0400 |
| commit | fdb5c4531c1e0e50e609df83f736b6f3a02896e2 (patch) | |
| tree | c2ca0792e966f0bfb00f08d4df3401f2d68d52a9 | |
| parent | 68d676a089625daed9d61df56ac63b5cd7189efe (diff) | |
bpf: fix attach type BPF_LIRC_MODE2 dependency wrt CONFIG_CGROUP_BPF
If the kernel is compiled with CONFIG_CGROUP_BPF not enabled, it is not
possible to attach, detach or query IR BPF programs to /dev/lircN devices,
making them impossible to use. For embedded devices, it should be possible
to use IR decoding without cgroups or CONFIG_CGROUP_BPF enabled.
This change requires some refactoring, since bpf_prog_{attach,detach,query}
functions are now always compiled, but their code paths for cgroups need
moving out. Rather than a #ifdef CONFIG_CGROUP_BPF in kernel/bpf/syscall.c,
moving them to kernel/bpf/cgroup.c and kernel/bpf/sockmap.c does not
require #ifdefs since that is already conditionally compiled.
Fixes: f4364dcfc86d ("media: rc: introduce BPF_PROG_LIRC_MODE2")
Signed-off-by: Sean Young <sean@mess.org>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
| -rw-r--r-- | drivers/media/rc/bpf-lirc.c | 14 | ||||
| -rw-r--r-- | include/linux/bpf-cgroup.h | 26 | ||||
| -rw-r--r-- | include/linux/bpf.h | 8 | ||||
| -rw-r--r-- | include/linux/bpf_lirc.h | 5 | ||||
| -rw-r--r-- | kernel/bpf/cgroup.c | 54 | ||||
| -rw-r--r-- | kernel/bpf/sockmap.c | 18 | ||||
| -rw-r--r-- | kernel/bpf/syscall.c | 99 |
7 files changed, 132 insertions, 92 deletions
diff --git a/drivers/media/rc/bpf-lirc.c b/drivers/media/rc/bpf-lirc.c index 40826bba06b6..fcfab6635f9c 100644 --- a/drivers/media/rc/bpf-lirc.c +++ b/drivers/media/rc/bpf-lirc.c | |||
| @@ -207,29 +207,19 @@ void lirc_bpf_free(struct rc_dev *rcdev) | |||
| 207 | bpf_prog_array_free(rcdev->raw->progs); | 207 | bpf_prog_array_free(rcdev->raw->progs); |
| 208 | } | 208 | } |
| 209 | 209 | ||
| 210 | int lirc_prog_attach(const union bpf_attr *attr) | 210 | int lirc_prog_attach(const union bpf_attr *attr, struct bpf_prog *prog) |
| 211 | { | 211 | { |
| 212 | struct bpf_prog *prog; | ||
| 213 | struct rc_dev *rcdev; | 212 | struct rc_dev *rcdev; |
| 214 | int ret; | 213 | int ret; |
| 215 | 214 | ||
| 216 | if (attr->attach_flags) | 215 | if (attr->attach_flags) |
| 217 | return -EINVAL; | 216 | return -EINVAL; |
| 218 | 217 | ||
| 219 | prog = bpf_prog_get_type(attr->attach_bpf_fd, | ||
| 220 | BPF_PROG_TYPE_LIRC_MODE2); | ||
| 221 | if (IS_ERR(prog)) | ||
| 222 | return PTR_ERR(prog); | ||
| 223 | |||
| 224 | rcdev = rc_dev_get_from_fd(attr->target_fd); | 218 | rcdev = rc_dev_get_from_fd(attr->target_fd); |
| 225 | if (IS_ERR(rcdev)) { | 219 | if (IS_ERR(rcdev)) |
| 226 | bpf_prog_put(prog); | ||
| 227 | return PTR_ERR(rcdev); | 220 | return PTR_ERR(rcdev); |
| 228 | } | ||
| 229 | 221 | ||
| 230 | ret = lirc_bpf_attach(rcdev, prog); | 222 | ret = lirc_bpf_attach(rcdev, prog); |
| 231 | if (ret) | ||
| 232 | bpf_prog_put(prog); | ||
| 233 | 223 | ||
| 234 | put_device(&rcdev->dev); | 224 | put_device(&rcdev->dev); |
| 235 | 225 | ||
diff --git a/include/linux/bpf-cgroup.h b/include/linux/bpf-cgroup.h index 975fb4cf1bb7..79795c5fa7c3 100644 --- a/include/linux/bpf-cgroup.h +++ b/include/linux/bpf-cgroup.h | |||
| @@ -188,12 +188,38 @@ int __cgroup_bpf_check_dev_permission(short dev_type, u32 major, u32 minor, | |||
| 188 | \ | 188 | \ |
| 189 | __ret; \ | 189 | __ret; \ |
| 190 | }) | 190 | }) |
| 191 | int cgroup_bpf_prog_attach(const union bpf_attr *attr, | ||
| 192 | enum bpf_prog_type ptype, struct bpf_prog *prog); | ||
| 193 | int cgroup_bpf_prog_detach(const union bpf_attr *attr, | ||
| 194 | enum bpf_prog_type ptype); | ||
| 195 | int cgroup_bpf_prog_query(const union bpf_attr *attr, | ||
| 196 | union bpf_attr __user *uattr); | ||
| 191 | #else | 197 | #else |
| 192 | 198 | ||
| 199 | struct bpf_prog; | ||
| 193 | struct cgroup_bpf {}; | 200 | struct cgroup_bpf {}; |
| 194 | static inline void cgroup_bpf_put(struct cgroup *cgrp) {} | 201 | static inline void cgroup_bpf_put(struct cgroup *cgrp) {} |
| 195 | static inline int cgroup_bpf_inherit(struct cgroup *cgrp) { return 0; } | 202 | static inline int cgroup_bpf_inherit(struct cgroup *cgrp) { return 0; } |
| 196 | 203 | ||
| 204 | static inline int cgroup_bpf_prog_attach(const union bpf_attr *attr, | ||
| 205 | enum bpf_prog_type ptype, | ||
| 206 | struct bpf_prog *prog) | ||
| 207 | { | ||
| 208 | return -EINVAL; | ||
| 209 | } | ||
| 210 | |||
| 211 | static inline int cgroup_bpf_prog_detach(const union bpf_attr *attr, | ||
| 212 | enum bpf_prog_type ptype) | ||
| 213 | { | ||
| 214 | return -EINVAL; | ||
| 215 | } | ||
| 216 | |||
| 217 | static inline int cgroup_bpf_prog_query(const union bpf_attr *attr, | ||
| 218 | union bpf_attr __user *uattr) | ||
| 219 | { | ||
| 220 | return -EINVAL; | ||
| 221 | } | ||
| 222 | |||
| 197 | #define cgroup_bpf_enabled (0) | 223 | #define cgroup_bpf_enabled (0) |
| 198 | #define BPF_CGROUP_PRE_CONNECT_ENABLED(sk) (0) | 224 | #define BPF_CGROUP_PRE_CONNECT_ENABLED(sk) (0) |
| 199 | #define BPF_CGROUP_RUN_PROG_INET_INGRESS(sk,skb) ({ 0; }) | 225 | #define BPF_CGROUP_RUN_PROG_INET_INGRESS(sk,skb) ({ 0; }) |
diff --git a/include/linux/bpf.h b/include/linux/bpf.h index 7df32a3200f7..8827e797ff97 100644 --- a/include/linux/bpf.h +++ b/include/linux/bpf.h | |||
| @@ -696,6 +696,8 @@ static inline void bpf_map_offload_map_free(struct bpf_map *map) | |||
| 696 | struct sock *__sock_map_lookup_elem(struct bpf_map *map, u32 key); | 696 | struct sock *__sock_map_lookup_elem(struct bpf_map *map, u32 key); |
| 697 | struct sock *__sock_hash_lookup_elem(struct bpf_map *map, void *key); | 697 | struct sock *__sock_hash_lookup_elem(struct bpf_map *map, void *key); |
| 698 | int sock_map_prog(struct bpf_map *map, struct bpf_prog *prog, u32 type); | 698 | int sock_map_prog(struct bpf_map *map, struct bpf_prog *prog, u32 type); |
| 699 | int sockmap_get_from_fd(const union bpf_attr *attr, int type, | ||
| 700 | struct bpf_prog *prog); | ||
| 699 | #else | 701 | #else |
| 700 | static inline struct sock *__sock_map_lookup_elem(struct bpf_map *map, u32 key) | 702 | static inline struct sock *__sock_map_lookup_elem(struct bpf_map *map, u32 key) |
| 701 | { | 703 | { |
| @@ -714,6 +716,12 @@ static inline int sock_map_prog(struct bpf_map *map, | |||
| 714 | { | 716 | { |
| 715 | return -EOPNOTSUPP; | 717 | return -EOPNOTSUPP; |
| 716 | } | 718 | } |
| 719 | |||
| 720 | static inline int sockmap_get_from_fd(const union bpf_attr *attr, int type, | ||
| 721 | struct bpf_prog *prog) | ||
| 722 | { | ||
| 723 | return -EINVAL; | ||
| 724 | } | ||
| 717 | #endif | 725 | #endif |
| 718 | 726 | ||
| 719 | #if defined(CONFIG_XDP_SOCKETS) | 727 | #if defined(CONFIG_XDP_SOCKETS) |
diff --git a/include/linux/bpf_lirc.h b/include/linux/bpf_lirc.h index 5f8a4283092d..9d9ff755ec29 100644 --- a/include/linux/bpf_lirc.h +++ b/include/linux/bpf_lirc.h | |||
| @@ -5,11 +5,12 @@ | |||
| 5 | #include <uapi/linux/bpf.h> | 5 | #include <uapi/linux/bpf.h> |
| 6 | 6 | ||
| 7 | #ifdef CONFIG_BPF_LIRC_MODE2 | 7 | #ifdef CONFIG_BPF_LIRC_MODE2 |
| 8 | int lirc_prog_attach(const union bpf_attr *attr); | 8 | int lirc_prog_attach(const union bpf_attr *attr, struct bpf_prog *prog); |
| 9 | int lirc_prog_detach(const union bpf_attr *attr); | 9 | int lirc_prog_detach(const union bpf_attr *attr); |
| 10 | int lirc_prog_query(const union bpf_attr *attr, union bpf_attr __user *uattr); | 10 | int lirc_prog_query(const union bpf_attr *attr, union bpf_attr __user *uattr); |
| 11 | #else | 11 | #else |
| 12 | static inline int lirc_prog_attach(const union bpf_attr *attr) | 12 | static inline int lirc_prog_attach(const union bpf_attr *attr, |
| 13 | struct bpf_prog *prog) | ||
| 13 | { | 14 | { |
| 14 | return -EINVAL; | 15 | return -EINVAL; |
| 15 | } | 16 | } |
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; |
