mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	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: f4364dcfc8 ("media: rc: introduce BPF_PROG_LIRC_MODE2")
Signed-off-by: Sean Young <sean@mess.org>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
			
			
This commit is contained in:
		
							parent
							
								
									68d676a089
								
							
						
					
					
						commit
						fdb5c4531c
					
				
					 7 changed files with 132 additions and 92 deletions
				
			
		| 
						 | 
					@ -207,29 +207,19 @@ void lirc_bpf_free(struct rc_dev *rcdev)
 | 
				
			||||||
	bpf_prog_array_free(rcdev->raw->progs);
 | 
						bpf_prog_array_free(rcdev->raw->progs);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int lirc_prog_attach(const union bpf_attr *attr)
 | 
					int lirc_prog_attach(const union bpf_attr *attr, struct bpf_prog *prog)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct bpf_prog *prog;
 | 
					 | 
				
			||||||
	struct rc_dev *rcdev;
 | 
						struct rc_dev *rcdev;
 | 
				
			||||||
	int ret;
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (attr->attach_flags)
 | 
						if (attr->attach_flags)
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	prog = bpf_prog_get_type(attr->attach_bpf_fd,
 | 
					 | 
				
			||||||
				 BPF_PROG_TYPE_LIRC_MODE2);
 | 
					 | 
				
			||||||
	if (IS_ERR(prog))
 | 
					 | 
				
			||||||
		return PTR_ERR(prog);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	rcdev = rc_dev_get_from_fd(attr->target_fd);
 | 
						rcdev = rc_dev_get_from_fd(attr->target_fd);
 | 
				
			||||||
	if (IS_ERR(rcdev)) {
 | 
						if (IS_ERR(rcdev))
 | 
				
			||||||
		bpf_prog_put(prog);
 | 
					 | 
				
			||||||
		return PTR_ERR(rcdev);
 | 
							return PTR_ERR(rcdev);
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ret = lirc_bpf_attach(rcdev, prog);
 | 
						ret = lirc_bpf_attach(rcdev, prog);
 | 
				
			||||||
	if (ret)
 | 
					 | 
				
			||||||
		bpf_prog_put(prog);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	put_device(&rcdev->dev);
 | 
						put_device(&rcdev->dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -188,12 +188,38 @@ int __cgroup_bpf_check_dev_permission(short dev_type, u32 major, u32 minor,
 | 
				
			||||||
									      \
 | 
														      \
 | 
				
			||||||
	__ret;								      \
 | 
						__ret;								      \
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
 | 
					int cgroup_bpf_prog_attach(const union bpf_attr *attr,
 | 
				
			||||||
 | 
								   enum bpf_prog_type ptype, struct bpf_prog *prog);
 | 
				
			||||||
 | 
					int cgroup_bpf_prog_detach(const union bpf_attr *attr,
 | 
				
			||||||
 | 
								   enum bpf_prog_type ptype);
 | 
				
			||||||
 | 
					int cgroup_bpf_prog_query(const union bpf_attr *attr,
 | 
				
			||||||
 | 
								  union bpf_attr __user *uattr);
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct bpf_prog;
 | 
				
			||||||
struct cgroup_bpf {};
 | 
					struct cgroup_bpf {};
 | 
				
			||||||
static inline void cgroup_bpf_put(struct cgroup *cgrp) {}
 | 
					static inline void cgroup_bpf_put(struct cgroup *cgrp) {}
 | 
				
			||||||
static inline int cgroup_bpf_inherit(struct cgroup *cgrp) { return 0; }
 | 
					static inline int cgroup_bpf_inherit(struct cgroup *cgrp) { return 0; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline int cgroup_bpf_prog_attach(const union bpf_attr *attr,
 | 
				
			||||||
 | 
										 enum bpf_prog_type ptype,
 | 
				
			||||||
 | 
										 struct bpf_prog *prog)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return -EINVAL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline int cgroup_bpf_prog_detach(const union bpf_attr *attr,
 | 
				
			||||||
 | 
										 enum bpf_prog_type ptype)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return -EINVAL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline int cgroup_bpf_prog_query(const union bpf_attr *attr,
 | 
				
			||||||
 | 
										union bpf_attr __user *uattr)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return -EINVAL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define cgroup_bpf_enabled (0)
 | 
					#define cgroup_bpf_enabled (0)
 | 
				
			||||||
#define BPF_CGROUP_PRE_CONNECT_ENABLED(sk) (0)
 | 
					#define BPF_CGROUP_PRE_CONNECT_ENABLED(sk) (0)
 | 
				
			||||||
#define BPF_CGROUP_RUN_PROG_INET_INGRESS(sk,skb) ({ 0; })
 | 
					#define BPF_CGROUP_RUN_PROG_INET_INGRESS(sk,skb) ({ 0; })
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -696,6 +696,8 @@ static inline void bpf_map_offload_map_free(struct bpf_map *map)
 | 
				
			||||||
struct sock  *__sock_map_lookup_elem(struct bpf_map *map, u32 key);
 | 
					struct sock  *__sock_map_lookup_elem(struct bpf_map *map, u32 key);
 | 
				
			||||||
struct sock  *__sock_hash_lookup_elem(struct bpf_map *map, void *key);
 | 
					struct sock  *__sock_hash_lookup_elem(struct bpf_map *map, void *key);
 | 
				
			||||||
int sock_map_prog(struct bpf_map *map, struct bpf_prog *prog, u32 type);
 | 
					int sock_map_prog(struct bpf_map *map, struct bpf_prog *prog, u32 type);
 | 
				
			||||||
 | 
					int sockmap_get_from_fd(const union bpf_attr *attr, int type,
 | 
				
			||||||
 | 
								struct bpf_prog *prog);
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
static inline struct sock  *__sock_map_lookup_elem(struct bpf_map *map, u32 key)
 | 
					static inline struct sock  *__sock_map_lookup_elem(struct bpf_map *map, u32 key)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -714,6 +716,12 @@ static inline int sock_map_prog(struct bpf_map *map,
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return -EOPNOTSUPP;
 | 
						return -EOPNOTSUPP;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline int sockmap_get_from_fd(const union bpf_attr *attr, int type,
 | 
				
			||||||
 | 
									      struct bpf_prog *prog)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return -EINVAL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if defined(CONFIG_XDP_SOCKETS)
 | 
					#if defined(CONFIG_XDP_SOCKETS)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5,11 +5,12 @@
 | 
				
			||||||
#include <uapi/linux/bpf.h>
 | 
					#include <uapi/linux/bpf.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef CONFIG_BPF_LIRC_MODE2
 | 
					#ifdef CONFIG_BPF_LIRC_MODE2
 | 
				
			||||||
int lirc_prog_attach(const union bpf_attr *attr);
 | 
					int lirc_prog_attach(const union bpf_attr *attr, struct bpf_prog *prog);
 | 
				
			||||||
int lirc_prog_detach(const union bpf_attr *attr);
 | 
					int lirc_prog_detach(const union bpf_attr *attr);
 | 
				
			||||||
int lirc_prog_query(const union bpf_attr *attr, union bpf_attr __user *uattr);
 | 
					int lirc_prog_query(const union bpf_attr *attr, union bpf_attr __user *uattr);
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
static inline int lirc_prog_attach(const union bpf_attr *attr)
 | 
					static inline int lirc_prog_attach(const union bpf_attr *attr,
 | 
				
			||||||
 | 
									   struct bpf_prog *prog)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return -EINVAL;
 | 
						return -EINVAL;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -428,6 +428,60 @@ int __cgroup_bpf_query(struct cgroup *cgrp, const union bpf_attr *attr,
 | 
				
			||||||
	return ret;
 | 
						return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int cgroup_bpf_prog_attach(const union bpf_attr *attr,
 | 
				
			||||||
 | 
								   enum bpf_prog_type ptype, struct bpf_prog *prog)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cgroup *cgrp;
 | 
				
			||||||
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cgrp = cgroup_get_from_fd(attr->target_fd);
 | 
				
			||||||
 | 
						if (IS_ERR(cgrp))
 | 
				
			||||||
 | 
							return PTR_ERR(cgrp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ret = cgroup_bpf_attach(cgrp, prog, attr->attach_type,
 | 
				
			||||||
 | 
									attr->attach_flags);
 | 
				
			||||||
 | 
						cgroup_put(cgrp);
 | 
				
			||||||
 | 
						return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int cgroup_bpf_prog_detach(const union bpf_attr *attr, enum bpf_prog_type ptype)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct bpf_prog *prog;
 | 
				
			||||||
 | 
						struct cgroup *cgrp;
 | 
				
			||||||
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cgrp = cgroup_get_from_fd(attr->target_fd);
 | 
				
			||||||
 | 
						if (IS_ERR(cgrp))
 | 
				
			||||||
 | 
							return PTR_ERR(cgrp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						prog = bpf_prog_get_type(attr->attach_bpf_fd, ptype);
 | 
				
			||||||
 | 
						if (IS_ERR(prog))
 | 
				
			||||||
 | 
							prog = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ret = cgroup_bpf_detach(cgrp, prog, attr->attach_type, 0);
 | 
				
			||||||
 | 
						if (prog)
 | 
				
			||||||
 | 
							bpf_prog_put(prog);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cgroup_put(cgrp);
 | 
				
			||||||
 | 
						return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int cgroup_bpf_prog_query(const union bpf_attr *attr,
 | 
				
			||||||
 | 
								  union bpf_attr __user *uattr)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cgroup *cgrp;
 | 
				
			||||||
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cgrp = cgroup_get_from_fd(attr->query.target_fd);
 | 
				
			||||||
 | 
						if (IS_ERR(cgrp))
 | 
				
			||||||
 | 
							return PTR_ERR(cgrp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ret = cgroup_bpf_query(cgrp, attr, uattr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cgroup_put(cgrp);
 | 
				
			||||||
 | 
						return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * __cgroup_bpf_run_filter_skb() - Run a program for packet filtering
 | 
					 * __cgroup_bpf_run_filter_skb() - Run a program for packet filtering
 | 
				
			||||||
 * @sk: The socket sending or receiving traffic
 | 
					 * @sk: The socket sending or receiving traffic
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1915,6 +1915,24 @@ int sock_map_prog(struct bpf_map *map, struct bpf_prog *prog, u32 type)
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int sockmap_get_from_fd(const union bpf_attr *attr, int type,
 | 
				
			||||||
 | 
								struct bpf_prog *prog)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int ufd = attr->target_fd;
 | 
				
			||||||
 | 
						struct bpf_map *map;
 | 
				
			||||||
 | 
						struct fd f;
 | 
				
			||||||
 | 
						int err;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						f = fdget(ufd);
 | 
				
			||||||
 | 
						map = __bpf_map_get(f);
 | 
				
			||||||
 | 
						if (IS_ERR(map))
 | 
				
			||||||
 | 
							return PTR_ERR(map);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						err = sock_map_prog(map, prog, attr->attach_type);
 | 
				
			||||||
 | 
						fdput(f);
 | 
				
			||||||
 | 
						return err;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void *sock_map_lookup(struct bpf_map *map, void *key)
 | 
					static void *sock_map_lookup(struct bpf_map *map, void *key)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return NULL;
 | 
						return NULL;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1483,8 +1483,6 @@ static int bpf_raw_tracepoint_open(const union bpf_attr *attr)
 | 
				
			||||||
	return err;
 | 
						return err;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef CONFIG_CGROUP_BPF
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int bpf_prog_attach_check_attach_type(const struct bpf_prog *prog,
 | 
					static int bpf_prog_attach_check_attach_type(const struct bpf_prog *prog,
 | 
				
			||||||
					     enum bpf_attach_type attach_type)
 | 
										     enum bpf_attach_type attach_type)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -1499,40 +1497,6 @@ static int bpf_prog_attach_check_attach_type(const struct bpf_prog *prog,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define BPF_PROG_ATTACH_LAST_FIELD attach_flags
 | 
					#define BPF_PROG_ATTACH_LAST_FIELD attach_flags
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int sockmap_get_from_fd(const union bpf_attr *attr,
 | 
					 | 
				
			||||||
			       int type, bool attach)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct bpf_prog *prog = NULL;
 | 
					 | 
				
			||||||
	int ufd = attr->target_fd;
 | 
					 | 
				
			||||||
	struct bpf_map *map;
 | 
					 | 
				
			||||||
	struct fd f;
 | 
					 | 
				
			||||||
	int err;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	f = fdget(ufd);
 | 
					 | 
				
			||||||
	map = __bpf_map_get(f);
 | 
					 | 
				
			||||||
	if (IS_ERR(map))
 | 
					 | 
				
			||||||
		return PTR_ERR(map);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (attach) {
 | 
					 | 
				
			||||||
		prog = bpf_prog_get_type(attr->attach_bpf_fd, type);
 | 
					 | 
				
			||||||
		if (IS_ERR(prog)) {
 | 
					 | 
				
			||||||
			fdput(f);
 | 
					 | 
				
			||||||
			return PTR_ERR(prog);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	err = sock_map_prog(map, prog, attr->attach_type);
 | 
					 | 
				
			||||||
	if (err) {
 | 
					 | 
				
			||||||
		fdput(f);
 | 
					 | 
				
			||||||
		if (prog)
 | 
					 | 
				
			||||||
			bpf_prog_put(prog);
 | 
					 | 
				
			||||||
		return err;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	fdput(f);
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define BPF_F_ATTACH_MASK \
 | 
					#define BPF_F_ATTACH_MASK \
 | 
				
			||||||
	(BPF_F_ALLOW_OVERRIDE | BPF_F_ALLOW_MULTI)
 | 
						(BPF_F_ALLOW_OVERRIDE | BPF_F_ALLOW_MULTI)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1540,7 +1504,6 @@ static int bpf_prog_attach(const union bpf_attr *attr)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	enum bpf_prog_type ptype;
 | 
						enum bpf_prog_type ptype;
 | 
				
			||||||
	struct bpf_prog *prog;
 | 
						struct bpf_prog *prog;
 | 
				
			||||||
	struct cgroup *cgrp;
 | 
					 | 
				
			||||||
	int ret;
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!capable(CAP_NET_ADMIN))
 | 
						if (!capable(CAP_NET_ADMIN))
 | 
				
			||||||
| 
						 | 
					@ -1577,12 +1540,15 @@ static int bpf_prog_attach(const union bpf_attr *attr)
 | 
				
			||||||
		ptype = BPF_PROG_TYPE_CGROUP_DEVICE;
 | 
							ptype = BPF_PROG_TYPE_CGROUP_DEVICE;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case BPF_SK_MSG_VERDICT:
 | 
						case BPF_SK_MSG_VERDICT:
 | 
				
			||||||
		return sockmap_get_from_fd(attr, BPF_PROG_TYPE_SK_MSG, true);
 | 
							ptype = BPF_PROG_TYPE_SK_MSG;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
	case BPF_SK_SKB_STREAM_PARSER:
 | 
						case BPF_SK_SKB_STREAM_PARSER:
 | 
				
			||||||
	case BPF_SK_SKB_STREAM_VERDICT:
 | 
						case BPF_SK_SKB_STREAM_VERDICT:
 | 
				
			||||||
		return sockmap_get_from_fd(attr, BPF_PROG_TYPE_SK_SKB, true);
 | 
							ptype = BPF_PROG_TYPE_SK_SKB;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
	case BPF_LIRC_MODE2:
 | 
						case BPF_LIRC_MODE2:
 | 
				
			||||||
		return lirc_prog_attach(attr);
 | 
							ptype = BPF_PROG_TYPE_LIRC_MODE2;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -1596,18 +1562,20 @@ static int bpf_prog_attach(const union bpf_attr *attr)
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	cgrp = cgroup_get_from_fd(attr->target_fd);
 | 
						switch (ptype) {
 | 
				
			||||||
	if (IS_ERR(cgrp)) {
 | 
						case BPF_PROG_TYPE_SK_SKB:
 | 
				
			||||||
		bpf_prog_put(prog);
 | 
						case BPF_PROG_TYPE_SK_MSG:
 | 
				
			||||||
		return PTR_ERR(cgrp);
 | 
							ret = sockmap_get_from_fd(attr, ptype, prog);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case BPF_PROG_TYPE_LIRC_MODE2:
 | 
				
			||||||
 | 
							ret = lirc_prog_attach(attr, prog);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							ret = cgroup_bpf_prog_attach(attr, ptype, prog);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ret = cgroup_bpf_attach(cgrp, prog, attr->attach_type,
 | 
					 | 
				
			||||||
				attr->attach_flags);
 | 
					 | 
				
			||||||
	if (ret)
 | 
						if (ret)
 | 
				
			||||||
		bpf_prog_put(prog);
 | 
							bpf_prog_put(prog);
 | 
				
			||||||
	cgroup_put(cgrp);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return ret;
 | 
						return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1616,9 +1584,6 @@ static int bpf_prog_attach(const union bpf_attr *attr)
 | 
				
			||||||
static int bpf_prog_detach(const union bpf_attr *attr)
 | 
					static int bpf_prog_detach(const union bpf_attr *attr)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	enum bpf_prog_type ptype;
 | 
						enum bpf_prog_type ptype;
 | 
				
			||||||
	struct bpf_prog *prog;
 | 
					 | 
				
			||||||
	struct cgroup *cgrp;
 | 
					 | 
				
			||||||
	int ret;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!capable(CAP_NET_ADMIN))
 | 
						if (!capable(CAP_NET_ADMIN))
 | 
				
			||||||
		return -EPERM;
 | 
							return -EPERM;
 | 
				
			||||||
| 
						 | 
					@ -1651,29 +1616,17 @@ static int bpf_prog_detach(const union bpf_attr *attr)
 | 
				
			||||||
		ptype = BPF_PROG_TYPE_CGROUP_DEVICE;
 | 
							ptype = BPF_PROG_TYPE_CGROUP_DEVICE;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case BPF_SK_MSG_VERDICT:
 | 
						case BPF_SK_MSG_VERDICT:
 | 
				
			||||||
		return sockmap_get_from_fd(attr, BPF_PROG_TYPE_SK_MSG, false);
 | 
							return sockmap_get_from_fd(attr, BPF_PROG_TYPE_SK_MSG, NULL);
 | 
				
			||||||
	case BPF_SK_SKB_STREAM_PARSER:
 | 
						case BPF_SK_SKB_STREAM_PARSER:
 | 
				
			||||||
	case BPF_SK_SKB_STREAM_VERDICT:
 | 
						case BPF_SK_SKB_STREAM_VERDICT:
 | 
				
			||||||
		return sockmap_get_from_fd(attr, BPF_PROG_TYPE_SK_SKB, false);
 | 
							return sockmap_get_from_fd(attr, BPF_PROG_TYPE_SK_SKB, NULL);
 | 
				
			||||||
	case BPF_LIRC_MODE2:
 | 
						case BPF_LIRC_MODE2:
 | 
				
			||||||
		return lirc_prog_detach(attr);
 | 
							return lirc_prog_detach(attr);
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	cgrp = cgroup_get_from_fd(attr->target_fd);
 | 
						return cgroup_bpf_prog_detach(attr, ptype);
 | 
				
			||||||
	if (IS_ERR(cgrp))
 | 
					 | 
				
			||||||
		return PTR_ERR(cgrp);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	prog = bpf_prog_get_type(attr->attach_bpf_fd, ptype);
 | 
					 | 
				
			||||||
	if (IS_ERR(prog))
 | 
					 | 
				
			||||||
		prog = NULL;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	ret = cgroup_bpf_detach(cgrp, prog, attr->attach_type, 0);
 | 
					 | 
				
			||||||
	if (prog)
 | 
					 | 
				
			||||||
		bpf_prog_put(prog);
 | 
					 | 
				
			||||||
	cgroup_put(cgrp);
 | 
					 | 
				
			||||||
	return ret;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define BPF_PROG_QUERY_LAST_FIELD query.prog_cnt
 | 
					#define BPF_PROG_QUERY_LAST_FIELD query.prog_cnt
 | 
				
			||||||
| 
						 | 
					@ -1681,9 +1634,6 @@ static int bpf_prog_detach(const union bpf_attr *attr)
 | 
				
			||||||
static int bpf_prog_query(const union bpf_attr *attr,
 | 
					static int bpf_prog_query(const union bpf_attr *attr,
 | 
				
			||||||
			  union bpf_attr __user *uattr)
 | 
								  union bpf_attr __user *uattr)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct cgroup *cgrp;
 | 
					 | 
				
			||||||
	int ret;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (!capable(CAP_NET_ADMIN))
 | 
						if (!capable(CAP_NET_ADMIN))
 | 
				
			||||||
		return -EPERM;
 | 
							return -EPERM;
 | 
				
			||||||
	if (CHECK_ATTR(BPF_PROG_QUERY))
 | 
						if (CHECK_ATTR(BPF_PROG_QUERY))
 | 
				
			||||||
| 
						 | 
					@ -1711,14 +1661,9 @@ static int bpf_prog_query(const union bpf_attr *attr,
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	cgrp = cgroup_get_from_fd(attr->query.target_fd);
 | 
					
 | 
				
			||||||
	if (IS_ERR(cgrp))
 | 
						return cgroup_bpf_prog_query(attr, uattr);
 | 
				
			||||||
		return PTR_ERR(cgrp);
 | 
					 | 
				
			||||||
	ret = cgroup_bpf_query(cgrp, attr, uattr);
 | 
					 | 
				
			||||||
	cgroup_put(cgrp);
 | 
					 | 
				
			||||||
	return ret;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif /* CONFIG_CGROUP_BPF */
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define BPF_PROG_TEST_RUN_LAST_FIELD test.duration
 | 
					#define BPF_PROG_TEST_RUN_LAST_FIELD test.duration
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2365,7 +2310,6 @@ SYSCALL_DEFINE3(bpf, int, cmd, union bpf_attr __user *, uattr, unsigned int, siz
 | 
				
			||||||
	case BPF_OBJ_GET:
 | 
						case BPF_OBJ_GET:
 | 
				
			||||||
		err = bpf_obj_get(&attr);
 | 
							err = bpf_obj_get(&attr);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
#ifdef CONFIG_CGROUP_BPF
 | 
					 | 
				
			||||||
	case BPF_PROG_ATTACH:
 | 
						case BPF_PROG_ATTACH:
 | 
				
			||||||
		err = bpf_prog_attach(&attr);
 | 
							err = bpf_prog_attach(&attr);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
| 
						 | 
					@ -2375,7 +2319,6 @@ SYSCALL_DEFINE3(bpf, int, cmd, union bpf_attr __user *, uattr, unsigned int, siz
 | 
				
			||||||
	case BPF_PROG_QUERY:
 | 
						case BPF_PROG_QUERY:
 | 
				
			||||||
		err = bpf_prog_query(&attr, uattr);
 | 
							err = bpf_prog_query(&attr, uattr);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
	case BPF_PROG_TEST_RUN:
 | 
						case BPF_PROG_TEST_RUN:
 | 
				
			||||||
		err = bpf_prog_test_run(&attr, uattr);
 | 
							err = bpf_prog_test_run(&attr, uattr);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue