From: Catalin Marinas <catalin.marinas@arm.com>
To: Vincenzo Frascino <vincenzo.frascino@arm.com>
Cc: Andrey Konovalov <andreyknvl@google.com>,
LKML <linux-kernel@vger.kernel.org>,
kasan-dev <kasan-dev@googlegroups.com>,
Leon Romanovsky <leonro@mellanox.com>,
Alexander Potapenko <glider@google.com>,
Dmitry Vyukov <dvyukov@google.com>,
Andrey Ryabinin <aryabinin@virtuozzo.com>,
Linux ARM <linux-arm-kernel@lists.infradead.org>
Subject: Re: [PATCH] kasan: Add explicit preconditions to kasan_report()
Date: Wed, 20 Jan 2021 17:55:09 +0000 [thread overview]
Message-ID: <20210120175509.GA17952@gaia> (raw)
In-Reply-To: <6525b31a-9258-a5d1-9188-5bce68af573c@arm.com>
On Wed, Jan 20, 2021 at 04:16:02PM +0000, Vincenzo Frascino wrote:
> On 1/20/21 4:04 PM, Catalin Marinas wrote:
> > On Tue, Jan 19, 2021 at 08:35:49PM +0000, Vincenzo Frascino wrote:
> >> On 1/19/21 6:52 PM, Catalin Marinas wrote:
> >>> On Tue, Jan 19, 2021 at 07:27:43PM +0100, Andrey Konovalov wrote:
> >>>> On Tue, Jan 19, 2021 at 6:26 PM Vincenzo Frascino
> >>>> <vincenzo.frascino@arm.com> wrote:
> >>>>>
> >>>>> With the introduction of KASAN_HW_TAGS, kasan_report() dereferences
> >>>>> the address passed as a parameter.
> >>>>>
> >>>>> Add a comment to make sure that the preconditions to the function are
> >>>>> explicitly clarified.
> >>>>>
> >>>>> Note: An invalid address (e.g. NULL pointer address) passed to the
> >>>>> function when, KASAN_HW_TAGS is enabled, leads to a kernel panic.
> >>>>>
> >>>>> Cc: Andrey Ryabinin <aryabinin@virtuozzo.com>
> >>>>> Cc: Alexander Potapenko <glider@google.com>
> >>>>> Cc: Dmitry Vyukov <dvyukov@google.com>
> >>>>> Cc: Leon Romanovsky <leonro@mellanox.com>
> >>>>> Cc: Andrey Konovalov <andreyknvl@google.com>
> >>>>> Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
> >>>>> ---
> >>>>> mm/kasan/report.c | 11 +++++++++++
> >>>>> 1 file changed, 11 insertions(+)
> >>>>>
> >>>>> diff --git a/mm/kasan/report.c b/mm/kasan/report.c
> >>>>> index c0fb21797550..2485b585004d 100644
> >>>>> --- a/mm/kasan/report.c
> >>>>> +++ b/mm/kasan/report.c
> >>>>> @@ -403,6 +403,17 @@ static void __kasan_report(unsigned long addr, size_t size, bool is_write,
> >>>>> end_report(&flags);
> >>>>> }
> >>>>>
> >>>>> +/**
> >>>>> + * kasan_report - report kasan fault details
> >>>>> + * @addr: valid address of the allocation where the tag fault was detected
> >>>>> + * @size: size of the allocation where the tag fault was detected
> >>>>> + * @is_write: the instruction that caused the fault was a read or write?
> >>>>> + * @ip: pointer to the instruction that cause the fault
> >>>>> + *
> >>>>> + * Note: When CONFIG_KASAN_HW_TAGS is enabled kasan_report() dereferences
> >>>>> + * the address to access the tags, hence it must be valid at this point in
> >>>>> + * order to not cause a kernel panic.
> >>>>> + */
> >>>>
> >>>> It doesn't dereference the address, it just checks the tags, right?
> >>>>
> >>>> Ideally, kasan_report() should survive that with HW_TAGS like with the
> >>>> other modes. The reason it doesn't is probably because of a blank
> >>>> addr_has_metadata() definition for HW_TAGS in mm/kasan/kasan.h. I
> >>>> guess we should somehow check that the memory comes from page_alloc or
> >>>> kmalloc. Or otherwise make sure that it has tags. Maybe there's an arm
> >>>> instruction to check whether the memory has tags?
> >>>
> >>> There isn't an architected way to probe whether a memory location has a
> >>> VA->PA mapping. The tags are addressed by PA but you can't reach them if
> >>> you get a page fault on the VA. So we either document the kasan_report()
> >>> preconditions or, as you suggest, update addr_has_metadata() for the
> >>> HW_TAGS case. Something like:
> >>>
> >>> return is_vmalloc_addr(virt) || virt_addr_valid(virt));
> >>>
> >>
> >> This seems not working on arm64 because according to virt_addr_valid 0 is a
> >> valid virtual address, in fact:
> >>
> >> __is_lm_address(0) == true && pfn_valid(virt_to_pfn(0)) == true.
> >
> > Ah, so __is_lm_address(0) is true. Maybe we should improve this since
> > virt_to_pfn(0) doesn't make much sense.
>
> How do you propose to improve it?
Check that it's actually a kernel address starting at PAGE_OFFSET. The
current __is_lm_address() check just masks out the top 12 bits but if
they were 0, this still yields a true result. Maybe extending the
current definition as:
#define __is_lm_address(addr) ((u64)(addr) >= PAGE_OFFSET && \
((u64)(addr) & ~PAGE_OFFSET) < (PAGE_END - PAGE_OFFSET))
Which basically means:
#define __is_lm_address(addr) ((u64)(addr) >= PAGE_OFFSET && \
(u64)(addr) < PAGE_END)
I think we could write the above as:
#define __is_lm_address(addr) (((u64)(addr) ^ PAGE_OFFSET) < (PAGE_END - PAGE_OFFSET))
This way we catch any 0 bits in the top 12 (or 16 with a 48-bit VA
configuration).
--
Catalin
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
WARNING: multiple messages have this Message-ID (diff)
From: Catalin Marinas <catalin.marinas@arm.com>
To: Vincenzo Frascino <vincenzo.frascino@arm.com>
Cc: Andrey Konovalov <andreyknvl@google.com>,
LKML <linux-kernel@vger.kernel.org>,
kasan-dev <kasan-dev@googlegroups.com>,
Leon Romanovsky <leonro@mellanox.com>,
Alexander Potapenko <glider@google.com>,
Linux ARM <linux-arm-kernel@lists.infradead.org>,
Andrey Ryabinin <aryabinin@virtuozzo.com>,
Dmitry Vyukov <dvyukov@google.com>
Subject: Re: [PATCH] kasan: Add explicit preconditions to kasan_report()
Date: Wed, 20 Jan 2021 17:55:09 +0000 [thread overview]
Message-ID: <20210120175509.GA17952@gaia> (raw)
In-Reply-To: <6525b31a-9258-a5d1-9188-5bce68af573c@arm.com>
On Wed, Jan 20, 2021 at 04:16:02PM +0000, Vincenzo Frascino wrote:
> On 1/20/21 4:04 PM, Catalin Marinas wrote:
> > On Tue, Jan 19, 2021 at 08:35:49PM +0000, Vincenzo Frascino wrote:
> >> On 1/19/21 6:52 PM, Catalin Marinas wrote:
> >>> On Tue, Jan 19, 2021 at 07:27:43PM +0100, Andrey Konovalov wrote:
> >>>> On Tue, Jan 19, 2021 at 6:26 PM Vincenzo Frascino
> >>>> <vincenzo.frascino@arm.com> wrote:
> >>>>>
> >>>>> With the introduction of KASAN_HW_TAGS, kasan_report() dereferences
> >>>>> the address passed as a parameter.
> >>>>>
> >>>>> Add a comment to make sure that the preconditions to the function are
> >>>>> explicitly clarified.
> >>>>>
> >>>>> Note: An invalid address (e.g. NULL pointer address) passed to the
> >>>>> function when, KASAN_HW_TAGS is enabled, leads to a kernel panic.
> >>>>>
> >>>>> Cc: Andrey Ryabinin <aryabinin@virtuozzo.com>
> >>>>> Cc: Alexander Potapenko <glider@google.com>
> >>>>> Cc: Dmitry Vyukov <dvyukov@google.com>
> >>>>> Cc: Leon Romanovsky <leonro@mellanox.com>
> >>>>> Cc: Andrey Konovalov <andreyknvl@google.com>
> >>>>> Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
> >>>>> ---
> >>>>> mm/kasan/report.c | 11 +++++++++++
> >>>>> 1 file changed, 11 insertions(+)
> >>>>>
> >>>>> diff --git a/mm/kasan/report.c b/mm/kasan/report.c
> >>>>> index c0fb21797550..2485b585004d 100644
> >>>>> --- a/mm/kasan/report.c
> >>>>> +++ b/mm/kasan/report.c
> >>>>> @@ -403,6 +403,17 @@ static void __kasan_report(unsigned long addr, size_t size, bool is_write,
> >>>>> end_report(&flags);
> >>>>> }
> >>>>>
> >>>>> +/**
> >>>>> + * kasan_report - report kasan fault details
> >>>>> + * @addr: valid address of the allocation where the tag fault was detected
> >>>>> + * @size: size of the allocation where the tag fault was detected
> >>>>> + * @is_write: the instruction that caused the fault was a read or write?
> >>>>> + * @ip: pointer to the instruction that cause the fault
> >>>>> + *
> >>>>> + * Note: When CONFIG_KASAN_HW_TAGS is enabled kasan_report() dereferences
> >>>>> + * the address to access the tags, hence it must be valid at this point in
> >>>>> + * order to not cause a kernel panic.
> >>>>> + */
> >>>>
> >>>> It doesn't dereference the address, it just checks the tags, right?
> >>>>
> >>>> Ideally, kasan_report() should survive that with HW_TAGS like with the
> >>>> other modes. The reason it doesn't is probably because of a blank
> >>>> addr_has_metadata() definition for HW_TAGS in mm/kasan/kasan.h. I
> >>>> guess we should somehow check that the memory comes from page_alloc or
> >>>> kmalloc. Or otherwise make sure that it has tags. Maybe there's an arm
> >>>> instruction to check whether the memory has tags?
> >>>
> >>> There isn't an architected way to probe whether a memory location has a
> >>> VA->PA mapping. The tags are addressed by PA but you can't reach them if
> >>> you get a page fault on the VA. So we either document the kasan_report()
> >>> preconditions or, as you suggest, update addr_has_metadata() for the
> >>> HW_TAGS case. Something like:
> >>>
> >>> return is_vmalloc_addr(virt) || virt_addr_valid(virt));
> >>>
> >>
> >> This seems not working on arm64 because according to virt_addr_valid 0 is a
> >> valid virtual address, in fact:
> >>
> >> __is_lm_address(0) == true && pfn_valid(virt_to_pfn(0)) == true.
> >
> > Ah, so __is_lm_address(0) is true. Maybe we should improve this since
> > virt_to_pfn(0) doesn't make much sense.
>
> How do you propose to improve it?
Check that it's actually a kernel address starting at PAGE_OFFSET. The
current __is_lm_address() check just masks out the top 12 bits but if
they were 0, this still yields a true result. Maybe extending the
current definition as:
#define __is_lm_address(addr) ((u64)(addr) >= PAGE_OFFSET && \
((u64)(addr) & ~PAGE_OFFSET) < (PAGE_END - PAGE_OFFSET))
Which basically means:
#define __is_lm_address(addr) ((u64)(addr) >= PAGE_OFFSET && \
(u64)(addr) < PAGE_END)
I think we could write the above as:
#define __is_lm_address(addr) (((u64)(addr) ^ PAGE_OFFSET) < (PAGE_END - PAGE_OFFSET))
This way we catch any 0 bits in the top 12 (or 16 with a 48-bit VA
configuration).
--
Catalin
next prev parent reply other threads:[~2021-01-20 17:56 UTC|newest]
Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-01-19 17:26 [PATCH] kasan: Add explicit preconditions to kasan_report() Vincenzo Frascino
2021-01-19 17:26 ` Vincenzo Frascino
2021-01-19 18:27 ` Andrey Konovalov
2021-01-19 18:27 ` Andrey Konovalov
2021-01-19 18:52 ` Catalin Marinas
2021-01-19 18:52 ` Catalin Marinas
2021-01-19 19:00 ` Vincenzo Frascino
2021-01-19 19:00 ` Vincenzo Frascino
2021-01-19 19:02 ` Catalin Marinas
2021-01-19 19:02 ` Catalin Marinas
2021-01-19 19:07 ` Vincenzo Frascino
2021-01-19 19:07 ` Vincenzo Frascino
2021-01-19 19:33 ` Andrey Konovalov
2021-01-19 19:33 ` Andrey Konovalov
2021-01-19 20:35 ` Vincenzo Frascino
2021-01-19 20:35 ` Vincenzo Frascino
2021-01-19 20:56 ` Andrey Konovalov
2021-01-19 20:56 ` Andrey Konovalov
2021-01-21 11:34 ` Vincenzo Frascino
2021-01-21 11:34 ` Vincenzo Frascino
2021-01-21 12:27 ` Andrey Konovalov
2021-01-21 12:27 ` Andrey Konovalov
2021-01-20 16:04 ` Catalin Marinas
2021-01-20 16:04 ` Catalin Marinas
2021-01-20 16:16 ` Vincenzo Frascino
2021-01-20 16:16 ` Vincenzo Frascino
2021-01-20 17:55 ` Catalin Marinas [this message]
2021-01-20 17:55 ` Catalin Marinas
2021-01-19 18:58 ` Vincenzo Frascino
2021-01-19 18:58 ` Vincenzo Frascino
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=20210120175509.GA17952@gaia \
--to=catalin.marinas@arm.com \
--cc=andreyknvl@google.com \
--cc=aryabinin@virtuozzo.com \
--cc=dvyukov@google.com \
--cc=glider@google.com \
--cc=kasan-dev@googlegroups.com \
--cc=leonro@mellanox.com \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=vincenzo.frascino@arm.com \
/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.