From: Kees Cook <keescook@chromium.org>
To: "Matthew Wilcox (Oracle)" <willy@infradead.org>
Cc: linux-mm@kvack.org, Thomas Gleixner <tglx@linutronix.de>
Subject: Re: [PATCH 1/3] mm/usercopy: Check kmap addresses properly
Date: Tue, 5 Oct 2021 14:23:09 -0700 [thread overview]
Message-ID: <202110051422.3E52FBDE18@keescook> (raw)
In-Reply-To: <20211004224224.4137992-2-willy@infradead.org>
On Mon, Oct 04, 2021 at 11:42:21PM +0100, Matthew Wilcox (Oracle) wrote:
> If you are copying to an address in the kmap region, you may not copy
> across a page boundary, no matter what the size of the underlying
> allocation. You can't kmap() a slab page because slab pages always
> come from low memory.
>
> Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
> ---
> arch/x86/include/asm/highmem.h | 1 +
> include/linux/highmem-internal.h | 10 ++++++++++
> mm/usercopy.c | 15 +++++++++------
> 3 files changed, 20 insertions(+), 6 deletions(-)
>
> diff --git a/arch/x86/include/asm/highmem.h b/arch/x86/include/asm/highmem.h
> index 032e020853aa..731ee7cc40a5 100644
> --- a/arch/x86/include/asm/highmem.h
> +++ b/arch/x86/include/asm/highmem.h
> @@ -26,6 +26,7 @@
> #include <asm/tlbflush.h>
> #include <asm/paravirt.h>
> #include <asm/fixmap.h>
> +#include <asm/pgtable_areas.h>
>
> /* declarations for highmem.c */
> extern unsigned long highstart_pfn, highend_pfn;
> diff --git a/include/linux/highmem-internal.h b/include/linux/highmem-internal.h
> index 4aa1031d3e4c..97d6dc836749 100644
> --- a/include/linux/highmem-internal.h
> +++ b/include/linux/highmem-internal.h
> @@ -143,6 +143,11 @@ static inline void totalhigh_pages_add(long count)
> atomic_long_add(count, &_totalhigh_pages);
> }
>
> +static inline bool is_kmap_addr(const void *x)
> +{
> + unsigned long addr = (unsigned long)x;
> + return addr >= PKMAP_ADDR(0) && addr < PKMAP_ADDR(LAST_PKMAP);
> +}
> #else /* CONFIG_HIGHMEM */
>
> static inline struct page *kmap_to_page(void *addr)
> @@ -223,6 +228,11 @@ static inline void __kunmap_atomic(void *addr)
> static inline unsigned int nr_free_highpages(void) { return 0; }
> static inline unsigned long totalhigh_pages(void) { return 0UL; }
>
> +static inline bool is_kmap_addr(const void *x)
> +{
> + return false;
> +}
> +
> #endif /* CONFIG_HIGHMEM */
>
> /*
> diff --git a/mm/usercopy.c b/mm/usercopy.c
> index b3de3c4eefba..ac95b22fbbce 100644
> --- a/mm/usercopy.c
> +++ b/mm/usercopy.c
> @@ -228,12 +228,15 @@ static inline void check_heap_object(const void *ptr, unsigned long n,
> if (!virt_addr_valid(ptr))
> return;
>
> - /*
> - * When CONFIG_HIGHMEM=y, kmap_to_page() will give either the
> - * highmem page or fallback to virt_to_page(). The following
> - * is effectively a highmem-aware virt_to_head_page().
> - */
> - page = compound_head(kmap_to_page((void *)ptr));
> + if (is_kmap_addr(ptr)) {
> + unsigned long page_end = (unsigned long)ptr | (PAGE_SIZE - 1);
> +
> + if ((unsigned long)ptr + n - 1 > page_end)
> + usercopy_abort("kmap", NULL, to_user, 0, n);
It's likely not worth getting an offset here, but "0" above could be
something like "ptr - PKMAP_ADDR(0)".
Either way:
Acked-by: Kees Cook <keescook@chromium.org>
Thanks!
-Kees
> + return;
> + }
> +
> + page = virt_to_head_page(ptr);
>
> if (PageSlab(page)) {
> /* Check slab allocator for flags and size. */
> --
> 2.32.0
>
--
Kees Cook
next prev parent reply other threads:[~2021-10-05 21:23 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-10-04 22:42 [PATCH 0/3] Assorted improvements to usercopy Matthew Wilcox (Oracle)
2021-10-04 22:42 ` [PATCH 1/3] mm/usercopy: Check kmap addresses properly Matthew Wilcox (Oracle)
2021-10-05 21:23 ` Kees Cook [this message]
2021-10-05 21:43 ` Matthew Wilcox
2021-10-05 21:54 ` Kees Cook
2021-10-04 22:42 ` [PATCH 2/3] mm/usercopy: Detect vmalloc overruns Matthew Wilcox (Oracle)
2021-10-05 21:25 ` Kees Cook
2021-10-06 1:26 ` Matthew Wilcox
2021-10-06 3:02 ` Kees Cook
2021-10-04 22:42 ` [PATCH 3/3] mm/usercopy: Detect compound page overruns Matthew Wilcox (Oracle)
2021-10-05 21:26 ` Kees Cook
2021-10-05 22:12 ` Matthew Wilcox
2021-10-05 22:55 ` Kees Cook
2021-10-05 21:27 ` [PATCH 0/3] Assorted improvements to usercopy Kees Cook
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=202110051422.3E52FBDE18@keescook \
--to=keescook@chromium.org \
--cc=linux-mm@kvack.org \
--cc=tglx@linutronix.de \
--cc=willy@infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.