lists.openwall.net | lists / announce owl-users owl-dev john-users john-dev passwdqc-users yescrypt popa3d-users / oss-security kernel-hardening musl sabotage tlsify passwords / crypt-dev xvendor / Bugtraq Full-Disclosure linux-kernel linux-netdev linux-ext4 linux-hardening PHC | |
Open Source and information security mailing list archives
| ||
|
Date: Sun, 16 Aug 2020 15:15:15 +0800 From: Coly Li <colyli@...e.de> To: linux-block@...r.kernel.org, linux-nvme@...ts.infradead.org Cc: netdev@...r.kernel.org, stable@...r.kernel.org, linux-kernel@...r.kernel.org, Coly Li <colyli@...e.de>, Chaitanya Kulkarni <chaitanya.kulkarni@....com>, Christoph Hellwig <hch@....de>, Hannes Reinecke <hare@...e.de>, Jan Kara <jack@...e.com>, Jens Axboe <axboe@...nel.dk>, Mikhail Skorzhinskii <mskorzhinskiy@...arflare.com>, Philipp Reisner <philipp.reisner@...bit.com>, Sagi Grimberg <sagi@...mberg.me>, Vlastimil Babka <vbabka@...e.com> Subject: [PATCH v5 1/3] net: introduce helper sendpage_ok() in include/linux/net.h The original problem was from nvme-over-tcp code, who mistakenly uses kernel_sendpage() to send pages allocated by __get_free_pages() without __GFP_COMP flag. Such pages don't have refcount (page_count is 0) on tail pages, sending them by kernel_sendpage() may trigger a kernel panic from a corrupted kernel heap, because these pages are incorrectly freed in network stack as page_count 0 pages. This patch introduces a helper sendpage_ok(), it returns true if the checking page, - is not slab page: PageSlab(page) is false. - has page refcount: page_count(page) is not zero All drivers who want to send page to remote end by kernel_sendpage() may use this helper to check whether the page is OK. If the helper does not return true, the driver should try other non sendpage method (e.g. sock_no_sendpage()) to handle the page. Signed-off-by: Coly Li <colyli@...e.de> Cc: Chaitanya Kulkarni <chaitanya.kulkarni@....com> Cc: Christoph Hellwig <hch@....de> Cc: Hannes Reinecke <hare@...e.de> Cc: Jan Kara <jack@...e.com> Cc: Jens Axboe <axboe@...nel.dk> Cc: Mikhail Skorzhinskii <mskorzhinskiy@...arflare.com> Cc: Philipp Reisner <philipp.reisner@...bit.com> Cc: Sagi Grimberg <sagi@...mberg.me> Cc: Vlastimil Babka <vbabka@...e.com> Cc: stable@...r.kernel.org --- Changelog: v5, include linux/mm.h in include/linux/net.h v4, change sendpage_ok() as an inline helper, and post it as separate patch. v3, introduce a more common sendpage_ok() v2, fix typo in patch subject v1, the initial version. include/linux/net.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/include/linux/net.h b/include/linux/net.h index d48ff1180879..a807fad31958 100644 --- a/include/linux/net.h +++ b/include/linux/net.h @@ -21,6 +21,7 @@ #include <linux/rcupdate.h> #include <linux/once.h> #include <linux/fs.h> +#include <linux/mm.h> #include <linux/sockptr.h> #include <uapi/linux/net.h> @@ -286,6 +287,21 @@ do { \ #define net_get_random_once_wait(buf, nbytes) \ get_random_once_wait((buf), (nbytes)) +/* + * E.g. XFS meta- & log-data is in slab pages, or bcache meta + * data pages, or other high order pages allocated by + * __get_free_pages() without __GFP_COMP, which have a page_count + * of 0 and/or have PageSlab() set. We cannot use send_page for + * those, as that does get_page(); put_page(); and would cause + * either a VM_BUG directly, or __page_cache_release a page that + * would actually still be referenced by someone, leading to some + * obscure delayed Oops somewhere else. + */ +static inline bool sendpage_ok(struct page *page) +{ + return (!PageSlab(page) && page_count(page) >= 1); +} + int kernel_sendmsg(struct socket *sock, struct msghdr *msg, struct kvec *vec, size_t num, size_t len); int kernel_sendmsg_locked(struct sock *sk, struct msghdr *msg, -- 2.26.2
Powered by blists - more mailing lists