Skip to content

Commit 531b87d

Browse files
mykyta5Alexei Starovoitov
authored andcommitted
bpf: widen dynptr size/offset to 64 bit
Dynptr currently caps size and offset at 24 bits, which isn’t sufficient for file-backed use cases; even 32 bits can be limiting. Refactor dynptr helpers/kfuncs to use 64-bit size and offset, ensuring consistency across the APIs. This change does not affect internals of xdp, skb or other dynptrs, which continue to behave as before. Also it does not break binary compatibility. The widening enables large-file access support via dynptr, implemented in the next patches. Signed-off-by: Mykyta Yatsenko <[email protected]> Acked-by: Eduard Zingerman <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Alexei Starovoitov <[email protected]>
1 parent a61a257 commit 531b87d

File tree

7 files changed

+86
-86
lines changed

7 files changed

+86
-86
lines changed

include/linux/bpf.h

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1387,19 +1387,19 @@ enum bpf_dynptr_type {
13871387
BPF_DYNPTR_TYPE_SKB_META,
13881388
};
13891389

1390-
int bpf_dynptr_check_size(u32 size);
1391-
u32 __bpf_dynptr_size(const struct bpf_dynptr_kern *ptr);
1392-
const void *__bpf_dynptr_data(const struct bpf_dynptr_kern *ptr, u32 len);
1393-
void *__bpf_dynptr_data_rw(const struct bpf_dynptr_kern *ptr, u32 len);
1390+
int bpf_dynptr_check_size(u64 size);
1391+
u64 __bpf_dynptr_size(const struct bpf_dynptr_kern *ptr);
1392+
const void *__bpf_dynptr_data(const struct bpf_dynptr_kern *ptr, u64 len);
1393+
void *__bpf_dynptr_data_rw(const struct bpf_dynptr_kern *ptr, u64 len);
13941394
bool __bpf_dynptr_is_rdonly(const struct bpf_dynptr_kern *ptr);
1395-
int __bpf_dynptr_write(const struct bpf_dynptr_kern *dst, u32 offset,
1396-
void *src, u32 len, u64 flags);
1397-
void *bpf_dynptr_slice_rdwr(const struct bpf_dynptr *p, u32 offset,
1398-
void *buffer__opt, u32 buffer__szk);
1395+
int __bpf_dynptr_write(const struct bpf_dynptr_kern *dst, u64 offset,
1396+
void *src, u64 len, u64 flags);
1397+
void *bpf_dynptr_slice_rdwr(const struct bpf_dynptr *p, u64 offset,
1398+
void *buffer__opt, u64 buffer__szk);
13991399

1400-
static inline int bpf_dynptr_check_off_len(const struct bpf_dynptr_kern *ptr, u32 offset, u32 len)
1400+
static inline int bpf_dynptr_check_off_len(const struct bpf_dynptr_kern *ptr, u64 offset, u64 len)
14011401
{
1402-
u32 size = __bpf_dynptr_size(ptr);
1402+
u64 size = __bpf_dynptr_size(ptr);
14031403

14041404
if (len > size || offset > size - len)
14051405
return -E2BIG;

include/uapi/linux/bpf.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5618,7 +5618,7 @@ union bpf_attr {
56185618
* Return
56195619
* *sk* if casting is valid, or **NULL** otherwise.
56205620
*
5621-
* long bpf_dynptr_from_mem(void *data, u32 size, u64 flags, struct bpf_dynptr *ptr)
5621+
* long bpf_dynptr_from_mem(void *data, u64 size, u64 flags, struct bpf_dynptr *ptr)
56225622
* Description
56235623
* Get a dynptr to local memory *data*.
56245624
*
@@ -5661,7 +5661,7 @@ union bpf_attr {
56615661
* Return
56625662
* Nothing. Always succeeds.
56635663
*
5664-
* long bpf_dynptr_read(void *dst, u32 len, const struct bpf_dynptr *src, u32 offset, u64 flags)
5664+
* long bpf_dynptr_read(void *dst, u64 len, const struct bpf_dynptr *src, u64 offset, u64 flags)
56655665
* Description
56665666
* Read *len* bytes from *src* into *dst*, starting from *offset*
56675667
* into *src*.
@@ -5671,7 +5671,7 @@ union bpf_attr {
56715671
* of *src*'s data, -EINVAL if *src* is an invalid dynptr or if
56725672
* *flags* is not 0.
56735673
*
5674-
* long bpf_dynptr_write(const struct bpf_dynptr *dst, u32 offset, void *src, u32 len, u64 flags)
5674+
* long bpf_dynptr_write(const struct bpf_dynptr *dst, u64 offset, void *src, u64 len, u64 flags)
56755675
* Description
56765676
* Write *len* bytes from *src* into *dst*, starting from *offset*
56775677
* into *dst*.
@@ -5692,7 +5692,7 @@ union bpf_attr {
56925692
* is a read-only dynptr or if *flags* is not correct. For skb-type dynptrs,
56935693
* other errors correspond to errors returned by **bpf_skb_store_bytes**\ ().
56945694
*
5695-
* void *bpf_dynptr_data(const struct bpf_dynptr *ptr, u32 offset, u32 len)
5695+
* void *bpf_dynptr_data(const struct bpf_dynptr *ptr, u64 offset, u64 len)
56965696
* Description
56975697
* Get a pointer to the underlying dynptr data.
56985698
*

kernel/bpf/helpers.c

Lines changed: 33 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1684,19 +1684,19 @@ static enum bpf_dynptr_type bpf_dynptr_get_type(const struct bpf_dynptr_kern *pt
16841684
return (ptr->size & ~(DYNPTR_RDONLY_BIT)) >> DYNPTR_TYPE_SHIFT;
16851685
}
16861686

1687-
u32 __bpf_dynptr_size(const struct bpf_dynptr_kern *ptr)
1687+
u64 __bpf_dynptr_size(const struct bpf_dynptr_kern *ptr)
16881688
{
16891689
return ptr->size & DYNPTR_SIZE_MASK;
16901690
}
16911691

1692-
static void bpf_dynptr_set_size(struct bpf_dynptr_kern *ptr, u32 new_size)
1692+
static void bpf_dynptr_set_size(struct bpf_dynptr_kern *ptr, u64 new_size)
16931693
{
16941694
u32 metadata = ptr->size & ~DYNPTR_SIZE_MASK;
16951695

1696-
ptr->size = new_size | metadata;
1696+
ptr->size = (u32)new_size | metadata;
16971697
}
16981698

1699-
int bpf_dynptr_check_size(u32 size)
1699+
int bpf_dynptr_check_size(u64 size)
17001700
{
17011701
return size > DYNPTR_MAX_SIZE ? -E2BIG : 0;
17021702
}
@@ -1715,7 +1715,7 @@ void bpf_dynptr_set_null(struct bpf_dynptr_kern *ptr)
17151715
memset(ptr, 0, sizeof(*ptr));
17161716
}
17171717

1718-
BPF_CALL_4(bpf_dynptr_from_mem, void *, data, u32, size, u64, flags, struct bpf_dynptr_kern *, ptr)
1718+
BPF_CALL_4(bpf_dynptr_from_mem, void *, data, u64, size, u64, flags, struct bpf_dynptr_kern *, ptr)
17191719
{
17201720
int err;
17211721

@@ -1750,8 +1750,8 @@ static const struct bpf_func_proto bpf_dynptr_from_mem_proto = {
17501750
.arg4_type = ARG_PTR_TO_DYNPTR | DYNPTR_TYPE_LOCAL | MEM_UNINIT | MEM_WRITE,
17511751
};
17521752

1753-
static int __bpf_dynptr_read(void *dst, u32 len, const struct bpf_dynptr_kern *src,
1754-
u32 offset, u64 flags)
1753+
static int __bpf_dynptr_read(void *dst, u64 len, const struct bpf_dynptr_kern *src,
1754+
u64 offset, u64 flags)
17551755
{
17561756
enum bpf_dynptr_type type;
17571757
int err;
@@ -1787,8 +1787,8 @@ static int __bpf_dynptr_read(void *dst, u32 len, const struct bpf_dynptr_kern *s
17871787
}
17881788
}
17891789

1790-
BPF_CALL_5(bpf_dynptr_read, void *, dst, u32, len, const struct bpf_dynptr_kern *, src,
1791-
u32, offset, u64, flags)
1790+
BPF_CALL_5(bpf_dynptr_read, void *, dst, u64, len, const struct bpf_dynptr_kern *, src,
1791+
u64, offset, u64, flags)
17921792
{
17931793
return __bpf_dynptr_read(dst, len, src, offset, flags);
17941794
}
@@ -1804,8 +1804,8 @@ static const struct bpf_func_proto bpf_dynptr_read_proto = {
18041804
.arg5_type = ARG_ANYTHING,
18051805
};
18061806

1807-
int __bpf_dynptr_write(const struct bpf_dynptr_kern *dst, u32 offset, void *src,
1808-
u32 len, u64 flags)
1807+
int __bpf_dynptr_write(const struct bpf_dynptr_kern *dst, u64 offset, void *src,
1808+
u64 len, u64 flags)
18091809
{
18101810
enum bpf_dynptr_type type;
18111811
int err;
@@ -1848,8 +1848,8 @@ int __bpf_dynptr_write(const struct bpf_dynptr_kern *dst, u32 offset, void *src,
18481848
}
18491849
}
18501850

1851-
BPF_CALL_5(bpf_dynptr_write, const struct bpf_dynptr_kern *, dst, u32, offset, void *, src,
1852-
u32, len, u64, flags)
1851+
BPF_CALL_5(bpf_dynptr_write, const struct bpf_dynptr_kern *, dst, u64, offset, void *, src,
1852+
u64, len, u64, flags)
18531853
{
18541854
return __bpf_dynptr_write(dst, offset, src, len, flags);
18551855
}
@@ -1865,7 +1865,7 @@ static const struct bpf_func_proto bpf_dynptr_write_proto = {
18651865
.arg5_type = ARG_ANYTHING,
18661866
};
18671867

1868-
BPF_CALL_3(bpf_dynptr_data, const struct bpf_dynptr_kern *, ptr, u32, offset, u32, len)
1868+
BPF_CALL_3(bpf_dynptr_data, const struct bpf_dynptr_kern *, ptr, u64, offset, u64, len)
18691869
{
18701870
enum bpf_dynptr_type type;
18711871
int err;
@@ -2680,12 +2680,12 @@ __bpf_kfunc struct task_struct *bpf_task_from_vpid(s32 vpid)
26802680
* provided buffer, with its contents containing the data, if unable to obtain
26812681
* direct pointer)
26822682
*/
2683-
__bpf_kfunc void *bpf_dynptr_slice(const struct bpf_dynptr *p, u32 offset,
2684-
void *buffer__opt, u32 buffer__szk)
2683+
__bpf_kfunc void *bpf_dynptr_slice(const struct bpf_dynptr *p, u64 offset,
2684+
void *buffer__opt, u64 buffer__szk)
26852685
{
26862686
const struct bpf_dynptr_kern *ptr = (struct bpf_dynptr_kern *)p;
26872687
enum bpf_dynptr_type type;
2688-
u32 len = buffer__szk;
2688+
u64 len = buffer__szk;
26892689
int err;
26902690

26912691
if (!ptr->data)
@@ -2767,8 +2767,8 @@ __bpf_kfunc void *bpf_dynptr_slice(const struct bpf_dynptr *p, u32 offset,
27672767
* provided buffer, with its contents containing the data, if unable to obtain
27682768
* direct pointer)
27692769
*/
2770-
__bpf_kfunc void *bpf_dynptr_slice_rdwr(const struct bpf_dynptr *p, u32 offset,
2771-
void *buffer__opt, u32 buffer__szk)
2770+
__bpf_kfunc void *bpf_dynptr_slice_rdwr(const struct bpf_dynptr *p, u64 offset,
2771+
void *buffer__opt, u64 buffer__szk)
27722772
{
27732773
const struct bpf_dynptr_kern *ptr = (struct bpf_dynptr_kern *)p;
27742774

@@ -2800,10 +2800,10 @@ __bpf_kfunc void *bpf_dynptr_slice_rdwr(const struct bpf_dynptr *p, u32 offset,
28002800
return bpf_dynptr_slice(p, offset, buffer__opt, buffer__szk);
28012801
}
28022802

2803-
__bpf_kfunc int bpf_dynptr_adjust(const struct bpf_dynptr *p, u32 start, u32 end)
2803+
__bpf_kfunc int bpf_dynptr_adjust(const struct bpf_dynptr *p, u64 start, u64 end)
28042804
{
28052805
struct bpf_dynptr_kern *ptr = (struct bpf_dynptr_kern *)p;
2806-
u32 size;
2806+
u64 size;
28072807

28082808
if (!ptr->data || start > end)
28092809
return -EINVAL;
@@ -2836,7 +2836,7 @@ __bpf_kfunc bool bpf_dynptr_is_rdonly(const struct bpf_dynptr *p)
28362836
return __bpf_dynptr_is_rdonly(ptr);
28372837
}
28382838

2839-
__bpf_kfunc __u32 bpf_dynptr_size(const struct bpf_dynptr *p)
2839+
__bpf_kfunc u64 bpf_dynptr_size(const struct bpf_dynptr *p)
28402840
{
28412841
struct bpf_dynptr_kern *ptr = (struct bpf_dynptr_kern *)p;
28422842

@@ -2873,14 +2873,14 @@ __bpf_kfunc int bpf_dynptr_clone(const struct bpf_dynptr *p,
28732873
* Copies data from source dynptr to destination dynptr.
28742874
* Returns 0 on success; negative error, otherwise.
28752875
*/
2876-
__bpf_kfunc int bpf_dynptr_copy(struct bpf_dynptr *dst_ptr, u32 dst_off,
2877-
struct bpf_dynptr *src_ptr, u32 src_off, u32 size)
2876+
__bpf_kfunc int bpf_dynptr_copy(struct bpf_dynptr *dst_ptr, u64 dst_off,
2877+
struct bpf_dynptr *src_ptr, u64 src_off, u64 size)
28782878
{
28792879
struct bpf_dynptr_kern *dst = (struct bpf_dynptr_kern *)dst_ptr;
28802880
struct bpf_dynptr_kern *src = (struct bpf_dynptr_kern *)src_ptr;
28812881
void *src_slice, *dst_slice;
28822882
char buf[256];
2883-
u32 off;
2883+
u64 off;
28842884

28852885
src_slice = bpf_dynptr_slice(src_ptr, src_off, NULL, size);
28862886
dst_slice = bpf_dynptr_slice_rdwr(dst_ptr, dst_off, NULL, size);
@@ -2902,7 +2902,7 @@ __bpf_kfunc int bpf_dynptr_copy(struct bpf_dynptr *dst_ptr, u32 dst_off,
29022902

29032903
off = 0;
29042904
while (off < size) {
2905-
u32 chunk_sz = min_t(u32, sizeof(buf), size - off);
2905+
u64 chunk_sz = min_t(u64, sizeof(buf), size - off);
29062906
int err;
29072907

29082908
err = __bpf_dynptr_read(buf, chunk_sz, src, src_off + off, 0);
@@ -2928,10 +2928,10 @@ __bpf_kfunc int bpf_dynptr_copy(struct bpf_dynptr *dst_ptr, u32 dst_off,
29282928
* at @offset with the constant byte @val.
29292929
* Returns 0 on success; negative error, otherwise.
29302930
*/
2931-
__bpf_kfunc int bpf_dynptr_memset(struct bpf_dynptr *p, u32 offset, u32 size, u8 val)
2932-
{
2931+
__bpf_kfunc int bpf_dynptr_memset(struct bpf_dynptr *p, u64 offset, u64 size, u8 val)
2932+
{
29332933
struct bpf_dynptr_kern *ptr = (struct bpf_dynptr_kern *)p;
2934-
u32 chunk_sz, write_off;
2934+
u64 chunk_sz, write_off;
29352935
char buf[256];
29362936
void* slice;
29372937
int err;
@@ -2950,11 +2950,11 @@ __bpf_kfunc int bpf_dynptr_copy(struct bpf_dynptr *dst_ptr, u32 dst_off,
29502950
return err;
29512951

29522952
/* Non-linear data under the dynptr, write from a local buffer */
2953-
chunk_sz = min_t(u32, sizeof(buf), size);
2953+
chunk_sz = min_t(u64, sizeof(buf), size);
29542954
memset(buf, val, chunk_sz);
29552955

29562956
for (write_off = 0; write_off < size; write_off += chunk_sz) {
2957-
chunk_sz = min_t(u32, sizeof(buf), size - write_off);
2957+
chunk_sz = min_t(u64, sizeof(buf), size - write_off);
29582958
err = __bpf_dynptr_write(ptr, offset + write_off, buf, chunk_sz, 0);
29592959
if (err)
29602960
return err;
@@ -4469,7 +4469,7 @@ late_initcall(kfunc_init);
44694469
/* Get a pointer to dynptr data up to len bytes for read only access. If
44704470
* the dynptr doesn't have continuous data up to len bytes, return NULL.
44714471
*/
4472-
const void *__bpf_dynptr_data(const struct bpf_dynptr_kern *ptr, u32 len)
4472+
const void *__bpf_dynptr_data(const struct bpf_dynptr_kern *ptr, u64 len)
44734473
{
44744474
const struct bpf_dynptr *p = (struct bpf_dynptr *)ptr;
44754475

@@ -4480,7 +4480,7 @@ const void *__bpf_dynptr_data(const struct bpf_dynptr_kern *ptr, u32 len)
44804480
* the dynptr doesn't have continuous data up to len bytes, or the dynptr
44814481
* is read only, return NULL.
44824482
*/
4483-
void *__bpf_dynptr_data_rw(const struct bpf_dynptr_kern *ptr, u32 len)
4483+
void *__bpf_dynptr_data_rw(const struct bpf_dynptr_kern *ptr, u64 len)
44844484
{
44854485
if (__bpf_dynptr_is_rdonly(ptr))
44864486
return NULL;

0 commit comments

Comments
 (0)