Skip to content

Commit 2c38549

Browse files
jsitnickiKernel Patches Daemon
authored andcommitted
bpf: Unclone skb head on bpf_dynptr_write to skb metadata
Currently bpf_dynptr_from_skb_meta() marks the dynptr as read-only when the skb is cloned, preventing writes to metadata. Remove this restriction and unclone the skb head on bpf_dynptr_write() to metadata, now that the metadata is preserved during uncloning. This makes metadata dynptr consistent with skb dynptr, allowing writes regardless of whether the skb is cloned. Signed-off-by: Jakub Sitnicki <[email protected]>
1 parent 9a4c8d7 commit 2c38549

File tree

3 files changed

+23
-10
lines changed

3 files changed

+23
-10
lines changed

include/linux/filter.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1781,6 +1781,8 @@ int __bpf_xdp_store_bytes(struct xdp_buff *xdp, u32 offset, void *buf, u32 len);
17811781
void *bpf_xdp_pointer(struct xdp_buff *xdp, u32 offset, u32 len);
17821782
void bpf_xdp_copy_buf(struct xdp_buff *xdp, unsigned long off,
17831783
void *buf, unsigned long len, bool flush);
1784+
int __bpf_skb_meta_store_bytes(struct sk_buff *skb, u32 offset,
1785+
const void *from, u32 len, u64 flags);
17841786
void *bpf_skb_meta_pointer(struct sk_buff *skb, u32 offset);
17851787
#else /* CONFIG_NET */
17861788
static inline int __bpf_skb_load_bytes(const struct sk_buff *skb, u32 offset,
@@ -1817,6 +1819,13 @@ static inline void bpf_xdp_copy_buf(struct xdp_buff *xdp, unsigned long off, voi
18171819
{
18181820
}
18191821

1822+
static inline int __bpf_skb_meta_store_bytes(struct sk_buff *skb, u32 offset,
1823+
const void *from, u32 len,
1824+
u64 flags)
1825+
{
1826+
return -EOPNOTSUPP;
1827+
}
1828+
18201829
static inline void *bpf_skb_meta_pointer(struct sk_buff *skb, u32 offset)
18211830
{
18221831
return ERR_PTR(-EOPNOTSUPP);

kernel/bpf/helpers.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1890,10 +1890,8 @@ int __bpf_dynptr_write(const struct bpf_dynptr_kern *dst, u64 offset, void *src,
18901890
return -EINVAL;
18911891
return __bpf_xdp_store_bytes(dst->data, dst->offset + offset, src, len);
18921892
case BPF_DYNPTR_TYPE_SKB_META:
1893-
if (flags)
1894-
return -EINVAL;
1895-
memmove(bpf_skb_meta_pointer(dst->data, dst->offset + offset), src, len);
1896-
return 0;
1893+
return __bpf_skb_meta_store_bytes(dst->data, dst->offset + offset, src,
1894+
len, flags);
18971895
default:
18981896
WARN_ONCE(true, "bpf_dynptr_write: unknown dynptr type %d\n", type);
18991897
return -EFAULT;

net/core/filter.c

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12022,6 +12022,18 @@ void *bpf_skb_meta_pointer(struct sk_buff *skb, u32 offset)
1202212022
return skb_metadata_end(skb) - skb_metadata_len(skb) + offset;
1202312023
}
1202412024

12025+
int __bpf_skb_meta_store_bytes(struct sk_buff *skb, u32 offset,
12026+
const void *from, u32 len, u64 flags)
12027+
{
12028+
if (unlikely(flags))
12029+
return -EINVAL;
12030+
if (unlikely(bpf_try_make_writable(skb, 0)))
12031+
return -EFAULT;
12032+
12033+
memmove(bpf_skb_meta_pointer(skb, offset), from, len);
12034+
return 0;
12035+
}
12036+
1202512037
__bpf_kfunc_start_defs();
1202612038
__bpf_kfunc int bpf_dynptr_from_skb(struct __sk_buff *s, u64 flags,
1202712039
struct bpf_dynptr *ptr__uninit)
@@ -12049,9 +12061,6 @@ __bpf_kfunc int bpf_dynptr_from_skb(struct __sk_buff *s, u64 flags,
1204912061
* XDP context with bpf_xdp_adjust_meta(). Serves as an alternative to
1205012062
* &__sk_buff->data_meta.
1205112063
*
12052-
* If passed @skb_ is a clone which shares the data with the original, the
12053-
* dynptr will be read-only. This limitation may be lifted in the future.
12054-
*
1205512064
* Return:
1205612065
* * %0 - dynptr ready to use
1205712066
* * %-EINVAL - invalid flags, dynptr set to null
@@ -12069,9 +12078,6 @@ __bpf_kfunc int bpf_dynptr_from_skb_meta(struct __sk_buff *skb_, u64 flags,
1206912078

1207012079
bpf_dynptr_init(ptr, skb, BPF_DYNPTR_TYPE_SKB_META, 0, skb_metadata_len(skb));
1207112080

12072-
if (skb_cloned(skb))
12073-
bpf_dynptr_set_rdonly(ptr);
12074-
1207512081
return 0;
1207612082
}
1207712083

0 commit comments

Comments
 (0)