diff options
| author | Jakub Kicinski <kuba@kernel.org> | 2022-02-23 06:44:06 +0300 |
|---|---|---|
| committer | Jakub Kicinski <kuba@kernel.org> | 2022-02-23 06:44:07 +0300 |
| commit | fa4fad40d5959373e3c6046d30344fc4f586bb20 (patch) | |
| tree | 8706a31bfa3847b1d4eb34a20bca12e1dc9ca5d7 /include/linux | |
| parent | 0ebea8f9b81cc02bbef2ec720a4c19e841c03217 (diff) | |
| parent | 2b88cba55883eaafbc9b7cbff0b2c7cdba71ed01 (diff) | |
| download | linux-fa4fad40d5959373e3c6046d30344fc4f586bb20.tar.xz | |
Merge branch 'tcp-take-care-of-another-syzbot-issue'
Eric Dumazet says:
====================
tcp: take care of another syzbot issue
This is a minor issue: It took months for syzbot to find a C repro,
and even with it, I had to spend a lot of time to understand KFENCE
was a prereq. With the default kfence 500ms interval, I had to be
very patient to trigger the kernel warning and perform my analysis.
This series targets net-next tree, because I added a new generic helper
in the first patch, then fixed the issue in the second one.
They can be backported once proven solid.
====================
Link: https://lore.kernel.org/r/20220222032113.4005821-1-eric.dumazet@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'include/linux')
| -rw-r--r-- | include/linux/skbuff.h | 28 |
1 files changed, 19 insertions, 9 deletions
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index a3e90efe6586..31be38078918 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -1536,6 +1536,11 @@ static inline unsigned int skb_end_offset(const struct sk_buff *skb) { return skb->end; } + +static inline void skb_set_end_offset(struct sk_buff *skb, unsigned int offset) +{ + skb->end = offset; +} #else static inline unsigned char *skb_end_pointer(const struct sk_buff *skb) { @@ -1546,6 +1551,11 @@ static inline unsigned int skb_end_offset(const struct sk_buff *skb) { return skb->end - skb->head; } + +static inline void skb_set_end_offset(struct sk_buff *skb, unsigned int offset) +{ + skb->end = skb->head + offset; +} #endif /* Internal */ @@ -1785,19 +1795,19 @@ static inline int skb_unclone(struct sk_buff *skb, gfp_t pri) return 0; } -/* This variant of skb_unclone() makes sure skb->truesize is not changed */ +/* This variant of skb_unclone() makes sure skb->truesize + * and skb_end_offset() are not changed, whenever a new skb->head is needed. + * + * Indeed there is no guarantee that ksize(kmalloc(X)) == ksize(kmalloc(X)) + * when various debugging features are in place. + */ +int __skb_unclone_keeptruesize(struct sk_buff *skb, gfp_t pri); static inline int skb_unclone_keeptruesize(struct sk_buff *skb, gfp_t pri) { might_sleep_if(gfpflags_allow_blocking(pri)); - if (skb_cloned(skb)) { - unsigned int save = skb->truesize; - int res; - - res = pskb_expand_head(skb, 0, 0, pri); - skb->truesize = save; - return res; - } + if (skb_cloned(skb)) + return __skb_unclone_keeptruesize(skb, pri); return 0; } |
