From: Lorenz Bauer <lmb@cloudflare.com>
To: andrii@kernel.org, ast@kernel.org, daniel@iogearbox.net
Cc: bpf@vger.kernel.org, kernel-team@cloudflare.com,
Lorenz Bauer <lmb@cloudflare.com>
Subject: [RFC 6/9] bpf: split map modification structs
Date: Thu, 14 Oct 2021 15:34:31 +0100 [thread overview]
Message-ID: <20211014143436.54470-8-lmb@cloudflare.com> (raw)
In-Reply-To: <20211014143436.54470-1-lmb@cloudflare.com>
---
include/uapi/linux/bpf.h | 51 +++++++++++++++++++++++------
kernel/bpf/syscall.c | 70 ++++++++++++++++------------------------
2 files changed, 70 insertions(+), 51 deletions(-)
diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
index f1c163778d7a..d3acd12d98c1 100644
--- a/include/uapi/linux/bpf.h
+++ b/include/uapi/linux/bpf.h
@@ -1294,18 +1294,41 @@ struct bpf_map_create_attr {
*/
};
+struct bpf_map_lookup_elem_attr {
+ __u32 map_fd;
+ __bpf_md_ptr(const void *, key);
+ __bpf_md_ptr(void *, value);
+ __u64 flags;
+};
+
+struct bpf_map_update_elem_attr {
+ __u32 map_fd;
+ __bpf_md_ptr(const void *, key);
+ __bpf_md_ptr(void *, value);
+ __u64 flags;
+};
+
+struct bpf_map_delete_elem_attr {
+ __u32 map_fd;
+ __bpf_md_ptr(const void *, key);
+};
+
+struct bpf_map_get_next_key_attr {
+ __u32 map_fd;
+ __bpf_md_ptr(const void *, key);
+ __bpf_md_ptr(void *, next_key);
+};
+
union bpf_attr {
struct bpf_map_create_attr map_create;
- struct { /* anonymous struct used by BPF_MAP_*_ELEM commands */
- __u32 map_fd;
- __aligned_u64 key;
- union {
- __aligned_u64 value;
- __aligned_u64 next_key;
- };
- __u64 flags;
- };
+ struct bpf_map_lookup_elem_attr map_lookup_elem;
+
+ struct bpf_map_update_elem_attr map_update_elem;
+
+ struct bpf_map_delete_elem_attr map_delete_elem;
+
+ struct bpf_map_get_next_key_attr map_get_next_key;
struct { /* struct used by BPF_MAP_*_BATCH commands */
__aligned_u64 in_batch; /* start batch,
@@ -1524,6 +1547,16 @@ union bpf_attr {
__u32 btf_value_type_id;
__u32 btf_vmlinux_value_type_id;
};
+
+ struct { /* anonymous struct used by BPF_MAP_*_ELEM commands */
+ __u32 map_fd;
+ __aligned_u64 key;
+ union {
+ __aligned_u64 value;
+ __aligned_u64 next_key;
+ };
+ __u64 flags;
+ };
} __attribute__((aligned(8)));
/* The description below is an attempt at providing documentation to eBPF
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index f7b57877acd2..c4aecdbb390e 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -728,6 +728,11 @@ int bpf_get_file_flag(int flags)
__tmp; \
})
+#define CHECK_ATTR_TAIL(attr, field) \
+ (memchr_inv((void *)(attr) + offsetofend(typeof(*attr), field), 0, \
+ sizeof(*(attr)) - offsetofend(typeof(*attr), field)) != NULL ? -EINVAL : 0)
+
+
/* dst and src must have at least "size" number of bytes.
* Return strlen on success and < 0 on error.
*/
@@ -1041,23 +1046,17 @@ static void *___bpf_copy_key(bpfptr_t ukey, u64 key_size)
return NULL;
}
-/* last field in 'union bpf_attr' used by this command */
-#define BPF_MAP_LOOKUP_ELEM_LAST_FIELD flags
-
-static int map_lookup_elem(union bpf_attr *attr)
+static int map_lookup_elem(struct bpf_map_lookup_elem_attr *attr)
{
- void __user *ukey = u64_to_user_ptr(attr->key);
- void __user *uvalue = u64_to_user_ptr(attr->value);
- int ufd = attr->map_fd;
+ void __user *ukey = u64_to_user_ptr(attr->key_u64);
+ void __user *uvalue = u64_to_user_ptr(attr->value_u64);
+ int ufd = attr->fd;
struct bpf_map *map;
void *key, *value;
u32 value_size;
struct fd f;
int err;
- if (CHECK_ATTR(BPF_MAP_LOOKUP_ELEM))
- return -EINVAL;
-
if (attr->flags & ~BPF_F_LOCK)
return -EINVAL;
@@ -1108,23 +1107,17 @@ static int map_lookup_elem(union bpf_attr *attr)
return err;
}
-
-#define BPF_MAP_UPDATE_ELEM_LAST_FIELD flags
-
-static int map_update_elem(union bpf_attr *attr, bpfptr_t uattr)
+static int map_update_elem(struct bpf_map_update_elem_attr *attr, bpfptr_t uattr)
{
- bpfptr_t ukey = make_bpfptr(attr->key, uattr.is_kernel);
- bpfptr_t uvalue = make_bpfptr(attr->value, uattr.is_kernel);
- int ufd = attr->map_fd;
+ bpfptr_t ukey = make_bpfptr(attr->key_u64, uattr.is_kernel);
+ bpfptr_t uvalue = make_bpfptr(attr->value_u64, uattr.is_kernel);
+ int ufd = attr->fd;
struct bpf_map *map;
void *key, *value;
u32 value_size;
struct fd f;
int err;
- if (CHECK_ATTR(BPF_MAP_UPDATE_ELEM))
- return -EINVAL;
-
f = fdget(ufd);
map = __bpf_map_get(f);
if (IS_ERR(map))
@@ -1168,20 +1161,15 @@ static int map_update_elem(union bpf_attr *attr, bpfptr_t uattr)
return err;
}
-#define BPF_MAP_DELETE_ELEM_LAST_FIELD key
-
-static int map_delete_elem(union bpf_attr *attr)
+static int map_delete_elem(struct bpf_map_delete_elem_attr *attr)
{
- void __user *ukey = u64_to_user_ptr(attr->key);
- int ufd = attr->map_fd;
+ void __user *ukey = u64_to_user_ptr(attr->key_u64);
+ int ufd = attr->fd;
struct bpf_map *map;
struct fd f;
void *key;
int err;
- if (CHECK_ATTR(BPF_MAP_DELETE_ELEM))
- return -EINVAL;
-
f = fdget(ufd);
map = __bpf_map_get(f);
if (IS_ERR(map))
@@ -1220,22 +1208,16 @@ static int map_delete_elem(union bpf_attr *attr)
return err;
}
-/* last field in 'union bpf_attr' used by this command */
-#define BPF_MAP_GET_NEXT_KEY_LAST_FIELD next_key
-
-static int map_get_next_key(union bpf_attr *attr)
+static int map_get_next_key(struct bpf_map_get_next_key_attr *attr)
{
- void __user *ukey = u64_to_user_ptr(attr->key);
- void __user *unext_key = u64_to_user_ptr(attr->next_key);
- int ufd = attr->map_fd;
+ void __user *ukey = u64_to_user_ptr(attr->key_u64);
+ void __user *unext_key = u64_to_user_ptr(attr->next_key_u64);
+ int ufd = attr->fd;
struct bpf_map *map;
void *key, *next_key;
struct fd f;
int err;
- if (CHECK_ATTR(BPF_MAP_GET_NEXT_KEY))
- return -EINVAL;
-
f = fdget(ufd);
map = __bpf_map_get(f);
if (IS_ERR(map))
@@ -4578,16 +4560,20 @@ static int __sys_bpf(int cmd, bpfptr_t uattr, unsigned int size)
err = map_create(ATTR_FIELD(&attr, map_create));
break;
case BPF_MAP_LOOKUP_ELEM:
- err = map_lookup_elem(&attr);
+ err = CHECK_ATTR_TAIL(&attr, map_lookup_elem);
+ err = err ?: map_lookup_elem(&attr.map_lookup_elem);
break;
case BPF_MAP_UPDATE_ELEM:
- err = map_update_elem(&attr, uattr);
+ err = CHECK_ATTR_TAIL(&attr, map_update_elem);
+ err = err ?: map_update_elem(&attr.map_update_elem, uattr);
break;
case BPF_MAP_DELETE_ELEM:
- err = map_delete_elem(&attr);
+ err = CHECK_ATTR_TAIL(&attr, map_delete_elem);
+ err = err ?: map_delete_elem(&attr.map_delete_elem);
break;
case BPF_MAP_GET_NEXT_KEY:
- err = map_get_next_key(&attr);
+ err = CHECK_ATTR_TAIL(&attr, map_get_next_key);
+ err = err ?: map_get_next_key(&attr.map_get_next_key);
break;
case BPF_MAP_FREEZE:
err = map_freeze(&attr);
--
2.30.2
next prev parent reply other threads:[~2021-10-14 14:35 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-10-14 14:34 [RFC 0/9] uapi/bpf.h for robots Lorenz Bauer
2021-10-14 14:34 ` [RFC 1/9] bpf: name enums used from userspace Lorenz Bauer
2021-10-14 14:34 ` [RFC 2/9] bpf: various constants Lorenz Bauer
2021-10-14 14:43 ` Greg KH
2021-10-14 14:47 ` Lorenz Bauer
2021-10-14 14:56 ` Greg KH
2021-10-14 14:34 ` [RFC 3/9] bpf: move up __bpf_md_ptr Lorenz Bauer
2021-10-14 14:34 ` [RFC 4/9] bpf: name __u64 member of __bpf_md_ptr Lorenz Bauer
2021-10-14 14:34 ` [RFC 5/9] bpf: enum bpf_map_create_attr Lorenz Bauer
2021-10-14 14:34 ` [RFC 5/9] bpf: introduce CHECK_ATTR_TAIL Lorenz Bauer
2021-10-14 14:34 ` Lorenz Bauer [this message]
2021-10-20 17:13 ` [RFC 6/9] bpf: split map modification structs Alexei Starovoitov
2021-10-14 14:34 ` [RFC 6/9] bpf: struct bpf_map_create_attr Lorenz Bauer
2021-10-14 14:34 ` [RFC 7/9] bpf: split get_id and fd_by_id in bpf_attr Lorenz Bauer
2021-10-20 17:15 ` Alexei Starovoitov
2021-10-21 15:59 ` Lorenz Bauer
2021-10-27 18:20 ` Alexei Starovoitov
2021-10-29 14:01 ` Lorenz Bauer
2021-10-14 14:34 ` [RFC 7/9] bpf: split map modification structs Lorenz Bauer
2021-10-14 14:34 ` [RFC 8/9] selftests: sync bpf.h Lorenz Bauer
2021-10-14 14:34 ` [RFC 9/9] libbpf: use new-style syscall args Lorenz Bauer
2021-10-20 17:19 ` Alexei Starovoitov
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20211014143436.54470-8-lmb@cloudflare.com \
--to=lmb@cloudflare.com \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=kernel-team@cloudflare.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).