mirror of
https://github.com/torvalds/linux.git
synced 2024-11-26 06:02:05 +00:00
net: switch to storing KCOV handle directly in sk_buff
It turns out that usage of skb extensions can cause memory leaks. Ido Schimmel reported: "[...] there are instances that blindly overwrite 'skb->extensions' by invoking skb_copy_header() after __alloc_skb()." Therefore, give up on using skb extensions for KCOV handle, and instead directly store kcov_handle in sk_buff. Fixes:6370cc3bbd
("net: add kcov handle to skb extensions") Fixes:85ce50d337
("net: kcov: don't select SKB_EXTENSIONS when there is no NET") Fixes:97f53a08cb
("net: linux/skbuff.h: combine SKB_EXTENSIONS + KCOV handling") Link: https://lore.kernel.org/linux-wireless/20201121160941.GA485907@shredder.lan/ Reported-by: Ido Schimmel <idosch@idosch.org> Signed-off-by: Marco Elver <elver@google.com> Link: https://lore.kernel.org/r/20201125224840.2014773-1-elver@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
0fca55ed98
commit
fa69ee5aa4
@ -701,6 +701,7 @@ typedef unsigned char *sk_buff_data_t;
|
||||
* @transport_header: Transport layer header
|
||||
* @network_header: Network layer header
|
||||
* @mac_header: Link layer header
|
||||
* @kcov_handle: KCOV remote handle for remote coverage collection
|
||||
* @tail: Tail pointer
|
||||
* @end: End pointer
|
||||
* @head: Head of buffer
|
||||
@ -904,6 +905,10 @@ struct sk_buff {
|
||||
__u16 network_header;
|
||||
__u16 mac_header;
|
||||
|
||||
#ifdef CONFIG_KCOV
|
||||
u64 kcov_handle;
|
||||
#endif
|
||||
|
||||
/* private: */
|
||||
__u32 headers_end[0];
|
||||
/* public: */
|
||||
@ -4150,9 +4155,6 @@ enum skb_ext_id {
|
||||
#endif
|
||||
#if IS_ENABLED(CONFIG_MPTCP)
|
||||
SKB_EXT_MPTCP,
|
||||
#endif
|
||||
#if IS_ENABLED(CONFIG_KCOV)
|
||||
SKB_EXT_KCOV_HANDLE,
|
||||
#endif
|
||||
SKB_EXT_NUM, /* must be last */
|
||||
};
|
||||
@ -4608,35 +4610,22 @@ static inline void skb_reset_redirect(struct sk_buff *skb)
|
||||
#endif
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_KCOV) && IS_ENABLED(CONFIG_SKB_EXTENSIONS)
|
||||
static inline void skb_set_kcov_handle(struct sk_buff *skb,
|
||||
const u64 kcov_handle)
|
||||
{
|
||||
/* Do not allocate skb extensions only to set kcov_handle to zero
|
||||
* (as it is zero by default). However, if the extensions are
|
||||
* already allocated, update kcov_handle anyway since
|
||||
* skb_set_kcov_handle can be called to zero a previously set
|
||||
* value.
|
||||
*/
|
||||
if (skb_has_extensions(skb) || kcov_handle) {
|
||||
u64 *kcov_handle_ptr = skb_ext_add(skb, SKB_EXT_KCOV_HANDLE);
|
||||
|
||||
if (kcov_handle_ptr)
|
||||
*kcov_handle_ptr = kcov_handle;
|
||||
}
|
||||
#ifdef CONFIG_KCOV
|
||||
skb->kcov_handle = kcov_handle;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline u64 skb_get_kcov_handle(struct sk_buff *skb)
|
||||
{
|
||||
u64 *kcov_handle = skb_ext_find(skb, SKB_EXT_KCOV_HANDLE);
|
||||
|
||||
return kcov_handle ? *kcov_handle : 0;
|
||||
}
|
||||
#ifdef CONFIG_KCOV
|
||||
return skb->kcov_handle;
|
||||
#else
|
||||
static inline void skb_set_kcov_handle(struct sk_buff *skb,
|
||||
const u64 kcov_handle) { }
|
||||
static inline u64 skb_get_kcov_handle(struct sk_buff *skb) { return 0; }
|
||||
#endif /* CONFIG_KCOV && CONFIG_SKB_EXTENSIONS */
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
#endif /* _LINUX_SKBUFF_H */
|
||||
|
@ -1879,7 +1879,6 @@ config KCOV
|
||||
depends on CC_HAS_SANCOV_TRACE_PC || GCC_PLUGINS
|
||||
select DEBUG_FS
|
||||
select GCC_PLUGIN_SANCOV if !CC_HAS_SANCOV_TRACE_PC
|
||||
select SKB_EXTENSIONS if NET
|
||||
help
|
||||
KCOV exposes kernel code coverage information in a form suitable
|
||||
for coverage-guided fuzzing (randomized testing).
|
||||
|
@ -4210,9 +4210,6 @@ static const u8 skb_ext_type_len[] = {
|
||||
#if IS_ENABLED(CONFIG_MPTCP)
|
||||
[SKB_EXT_MPTCP] = SKB_EXT_CHUNKSIZEOF(struct mptcp_ext),
|
||||
#endif
|
||||
#if IS_ENABLED(CONFIG_KCOV)
|
||||
[SKB_EXT_KCOV_HANDLE] = SKB_EXT_CHUNKSIZEOF(u64),
|
||||
#endif
|
||||
};
|
||||
|
||||
static __always_inline unsigned int skb_ext_total_length(void)
|
||||
@ -4229,9 +4226,6 @@ static __always_inline unsigned int skb_ext_total_length(void)
|
||||
#endif
|
||||
#if IS_ENABLED(CONFIG_MPTCP)
|
||||
skb_ext_type_len[SKB_EXT_MPTCP] +
|
||||
#endif
|
||||
#if IS_ENABLED(CONFIG_KCOV)
|
||||
skb_ext_type_len[SKB_EXT_KCOV_HANDLE] +
|
||||
#endif
|
||||
0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user