Commit edfa9af0 authored by Daniel Borkmann's avatar Daniel Borkmann Committed by Martin KaFai Lau
Browse files

bpf: Handle bpf_mprog_query with NULL entry



Improve consistency for bpf_mprog_query() API and let the latter also handle
a NULL entry as can be the case for tcx. Instead of returning -ENOENT, we
copy a count of 0 and revision of 1 to user space, so that this can be fed
into a subsequent bpf_mprog_attach() call as expected_revision. A BPF self-
test as part of this series has been added to assert this case.

Suggested-by: default avatarLorenz Bauer <lmb@isovalent.com>
Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
Link: https://lore.kernel.org/r/20231006220655.1653-2-daniel@iogearbox.net


Signed-off-by: default avatarMartin KaFai Lau <martin.lau@kernel.org>
parent a4fe7838
Loading
Loading
Loading
Loading
+6 −4
Original line number Diff line number Diff line
@@ -401,14 +401,16 @@ int bpf_mprog_query(const union bpf_attr *attr, union bpf_attr __user *uattr,
	struct bpf_mprog_cp *cp;
	struct bpf_prog *prog;
	const u32 flags = 0;
	u32 id, count = 0;
	u64 revision = 1;
	int i, ret = 0;
	u32 id, count;
	u64 revision;

	if (attr->query.query_flags || attr->query.attach_flags)
		return -EINVAL;
	if (entry) {
		revision = bpf_mprog_revision(entry);
		count = bpf_mprog_total(entry);
	}
	if (copy_to_user(&uattr->query.attach_flags, &flags, sizeof(flags)))
		return -EFAULT;
	if (copy_to_user(&uattr->query.revision, &revision, sizeof(revision)))
+1 −7
Original line number Diff line number Diff line
@@ -123,7 +123,6 @@ int tcx_prog_query(const union bpf_attr *attr, union bpf_attr __user *uattr)
{
	bool ingress = attr->query.attach_type == BPF_TCX_INGRESS;
	struct net *net = current->nsproxy->net_ns;
	struct bpf_mprog_entry *entry;
	struct net_device *dev;
	int ret;

@@ -133,12 +132,7 @@ int tcx_prog_query(const union bpf_attr *attr, union bpf_attr __user *uattr)
		ret = -ENODEV;
		goto out;
	}
	entry = tcx_entry_fetch(dev, ingress);
	if (!entry) {
		ret = -ENOENT;
		goto out;
	}
	ret = bpf_mprog_query(attr, uattr, entry);
	ret = bpf_mprog_query(attr, uattr, tcx_entry_fetch(dev, ingress));
out:
	rtnl_unlock();
	return ret;