A few places where SLUB accesses object's data or metadata were missed in
a previous patch. This leads to false positives with hardware tag-based
KASAN when bulk allocations are used with init_on_alloc/free.
Fix the false-positives by resetting pointer tags during these accesses.
Link: https://linux-review.googlesource.com/id/I50dd32838a666e173fe06c3c5c766f2c36aae901
Fixes: aa1ef4d7b3f67 ("kasan, mm: reset tags when accessing metadata")
Reported-by: Dmitry Vyukov <dvyukov@google.com>
Signed-off-by: Andrey Konovalov <redacted>
---
mm/slub.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
As of the "arm64: expose FAR_EL1 tag bits in siginfo" patch, the address
that is passed to report_tag_fault has pointer tags in the format of 0x0X,
while KASAN uses 0xFX format (note the difference in the top 4 bits).
Fix up the pointer tag before calling kasan_report.
Link: https://linux-review.googlesource.com/id/I9ced973866036d8679e8f4ae325de547eb969649
Fixes: dceec3ff7807 ("arm64: expose FAR_EL1 tag bits in siginfo")
Fixes: 4291e9ee6189 ("kasan, arm64: print report from tag fault handler")
Signed-off-by: Andrey Konovalov <redacted>
---
arch/arm64/mm/fault.c | 2 ++
1 file changed, 2 insertions(+)
@@ -304,6 +304,8 @@ static void report_tag_fault(unsigned long addr, unsigned int esr,{boolis_write=((esr&ESR_ELx_WNR)>>ESR_ELx_WNR_SHIFT)!=0;+/* The format of KASAN tags is 0xF<x>. */+addr|=(0xF0UL<<MTE_TAG_SHIFT);/**SASbitsaren'tsetforallfaultsreportedinEL1,sowecan't*findoutaccesssize.
--
2.30.0.284.gd98b1dd5eaa7-goog
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
On Wed, Jan 13, 2021 at 05:03:30PM +0100, Andrey Konovalov wrote:
quoted hunk
As of the "arm64: expose FAR_EL1 tag bits in siginfo" patch, the address
that is passed to report_tag_fault has pointer tags in the format of 0x0X,
while KASAN uses 0xFX format (note the difference in the top 4 bits).
Fix up the pointer tag before calling kasan_report.
Link: https://linux-review.googlesource.com/id/I9ced973866036d8679e8f4ae325de547eb969649
Fixes: dceec3ff7807 ("arm64: expose FAR_EL1 tag bits in siginfo")
Fixes: 4291e9ee6189 ("kasan, arm64: print report from tag fault handler")
Signed-off-by: Andrey Konovalov <redacted>
---
arch/arm64/mm/fault.c | 2 ++
1 file changed, 2 insertions(+)
@@ -304,6 +304,8 @@ static void report_tag_fault(unsigned long addr, unsigned int esr,{boolis_write=((esr&ESR_ELx_WNR)>>ESR_ELx_WNR_SHIFT)!=0;+/* The format of KASAN tags is 0xF<x>. */+addr|=(0xF0UL<<MTE_TAG_SHIFT);
Ah, I see, that top 4 bits are zeroed by do_tag_check_fault(). When this
was added, the only tag faults were generated for user addresses.
Anyway, I'd rather fix it in there based on bit 55, something like (only
compile-tested):
@@ -709,10 +709,11 @@ static int do_tag_check_fault(unsigned long far, unsigned int esr,structpt_regs*regs){/*-*Thearchitecturespecifiesthatbits63:60ofFAR_EL1areUNKNOWNfortag-*checkfaults.Maskthemoutnowsothatuserspacedoesn'tseethem.+*Thearchitecturespecifiesthatbits63:60ofFAR_EL1areUNKNOWN+*fortagcheckfaults.Setthemtothecorrespondingbitsinthe+*untaggedaddress.*/-far&=(1UL<<60)-1;+far=(untagged_addr(far)&~MTE_TAG_MASK)|(far&MTE_TAG_MASK);do_bad_area(far,esr,regs);return0;}
--
Catalin
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
A few places where SLUB accesses object's data or metadata were missed in
a previous patch. This leads to false positives with hardware tag-based
KASAN when bulk allocations are used with init_on_alloc/free.
Fix the false-positives by resetting pointer tags during these accesses.
Link: https://linux-review.googlesource.com/id/I50dd32838a666e173fe06c3c5c766f2c36aae901
Fixes: aa1ef4d7b3f67 ("kasan, mm: reset tags when accessing metadata")
Reported-by: Dmitry Vyukov <dvyukov@google.com>
Signed-off-by: Andrey Konovalov <redacted>
On Wed, Jan 13, 2021 at 6:25 PM Vlastimil Babka [off-list ref] wrote:
On 1/13/21 5:03 PM, Andrey Konovalov wrote:
quoted
A few places where SLUB accesses object's data or metadata were missed in
a previous patch. This leads to false positives with hardware tag-based
KASAN when bulk allocations are used with init_on_alloc/free.
Fix the false-positives by resetting pointer tags during these accesses.
Link: https://linux-review.googlesource.com/id/I50dd32838a666e173fe06c3c5c766f2c36aae901
Fixes: aa1ef4d7b3f67 ("kasan, mm: reset tags when accessing metadata")
Reported-by: Dmitry Vyukov <dvyukov@google.com>
Signed-off-by: Andrey Konovalov <redacted>
And in that case the reset was unnecessary, right. (commit log only mentions
adding missing resets).
The reset has been moved into maybe_wipe_obj_freeptr(). I'll mention
it in the changelog in v2.
Thanks!
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
On Wed, Jan 13, 2021 at 5:54 PM Catalin Marinas [off-list ref] wrote:
quoted hunk
On Wed, Jan 13, 2021 at 05:03:30PM +0100, Andrey Konovalov wrote:
quoted
As of the "arm64: expose FAR_EL1 tag bits in siginfo" patch, the address
that is passed to report_tag_fault has pointer tags in the format of 0x0X,
while KASAN uses 0xFX format (note the difference in the top 4 bits).
Fix up the pointer tag before calling kasan_report.
Link: https://linux-review.googlesource.com/id/I9ced973866036d8679e8f4ae325de547eb969649
Fixes: dceec3ff7807 ("arm64: expose FAR_EL1 tag bits in siginfo")
Fixes: 4291e9ee6189 ("kasan, arm64: print report from tag fault handler")
Signed-off-by: Andrey Konovalov <redacted>
---
arch/arm64/mm/fault.c | 2 ++
1 file changed, 2 insertions(+)
@@ -304,6 +304,8 @@ static void report_tag_fault(unsigned long addr, unsigned int esr,{boolis_write=((esr&ESR_ELx_WNR)>>ESR_ELx_WNR_SHIFT)!=0;+/* The format of KASAN tags is 0xF<x>. */+addr|=(0xF0UL<<MTE_TAG_SHIFT);
Ah, I see, that top 4 bits are zeroed by do_tag_check_fault(). When this
was added, the only tag faults were generated for user addresses.
Anyway, I'd rather fix it in there based on bit 55, something like (only
compile-tested):
@@ -709,10 +709,11 @@ static int do_tag_check_fault(unsigned long far, unsigned int esr,structpt_regs*regs){/*-*Thearchitecturespecifiesthatbits63:60ofFAR_EL1areUNKNOWNfortag-*checkfaults.Maskthemoutnowsothatuserspacedoesn'tseethem.+*Thearchitecturespecifiesthatbits63:60ofFAR_EL1areUNKNOWN+*fortagcheckfaults.Setthemtothecorrespondingbitsinthe+*untaggedaddress.*/-far&=(1UL<<60)-1;+far=(untagged_addr(far)&~MTE_TAG_MASK)|(far&MTE_TAG_MASK);do_bad_area(far,esr,regs);return0;}
On Fri, Jan 15, 2021 at 02:12:24PM +0100, Andrey Konovalov wrote:
On Wed, Jan 13, 2021 at 5:54 PM Catalin Marinas [off-list ref] wrote:
quoted
On Wed, Jan 13, 2021 at 05:03:30PM +0100, Andrey Konovalov wrote:
quoted
As of the "arm64: expose FAR_EL1 tag bits in siginfo" patch, the address
that is passed to report_tag_fault has pointer tags in the format of 0x0X,
while KASAN uses 0xFX format (note the difference in the top 4 bits).
Fix up the pointer tag before calling kasan_report.
Link: https://linux-review.googlesource.com/id/I9ced973866036d8679e8f4ae325de547eb969649
Fixes: dceec3ff7807 ("arm64: expose FAR_EL1 tag bits in siginfo")
Fixes: 4291e9ee6189 ("kasan, arm64: print report from tag fault handler")
Signed-off-by: Andrey Konovalov <redacted>
---
arch/arm64/mm/fault.c | 2 ++
1 file changed, 2 insertions(+)
@@ -304,6 +304,8 @@ static void report_tag_fault(unsigned long addr, unsigned int esr,{boolis_write=((esr&ESR_ELx_WNR)>>ESR_ELx_WNR_SHIFT)!=0;+/* The format of KASAN tags is 0xF<x>. */+addr|=(0xF0UL<<MTE_TAG_SHIFT);
Ah, I see, that top 4 bits are zeroed by do_tag_check_fault(). When this
was added, the only tag faults were generated for user addresses.
Anyway, I'd rather fix it in there based on bit 55, something like (only
compile-tested):
@@ -709,10 +709,11 @@ static int do_tag_check_fault(unsigned long far, unsigned int esr,structpt_regs*regs){/*-*Thearchitecturespecifiesthatbits63:60ofFAR_EL1areUNKNOWNfortag-*checkfaults.Maskthemoutnowsothatuserspacedoesn'tseethem.+*Thearchitecturespecifiesthatbits63:60ofFAR_EL1areUNKNOWN+*fortagcheckfaults.Setthemtothecorrespondingbitsinthe+*untaggedaddress.*/-far&=(1UL<<60)-1;+far=(untagged_addr(far)&~MTE_TAG_MASK)|(far&MTE_TAG_MASK);do_bad_area(far,esr,regs);return0;}
Sounds good, will do in v3, thanks!
I wonder if this one gives the same result (so please check):
far = u64_replace_bits(untagged_addr(far), far, MTE_TAG_MASK);
(defined in linux/bitfield.h)
--
Catalin
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
On Fri, Jan 15, 2021 at 4:07 PM Catalin Marinas [off-list ref] wrote:
On Fri, Jan 15, 2021 at 02:12:24PM +0100, Andrey Konovalov wrote:
quoted
On Wed, Jan 13, 2021 at 5:54 PM Catalin Marinas [off-list ref] wrote:
quoted
On Wed, Jan 13, 2021 at 05:03:30PM +0100, Andrey Konovalov wrote:
quoted
As of the "arm64: expose FAR_EL1 tag bits in siginfo" patch, the address
that is passed to report_tag_fault has pointer tags in the format of 0x0X,
while KASAN uses 0xFX format (note the difference in the top 4 bits).
Fix up the pointer tag before calling kasan_report.
Link: https://linux-review.googlesource.com/id/I9ced973866036d8679e8f4ae325de547eb969649
Fixes: dceec3ff7807 ("arm64: expose FAR_EL1 tag bits in siginfo")
Fixes: 4291e9ee6189 ("kasan, arm64: print report from tag fault handler")
Signed-off-by: Andrey Konovalov <redacted>
---
arch/arm64/mm/fault.c | 2 ++
1 file changed, 2 insertions(+)
@@ -304,6 +304,8 @@ static void report_tag_fault(unsigned long addr, unsigned int esr,{boolis_write=((esr&ESR_ELx_WNR)>>ESR_ELx_WNR_SHIFT)!=0;+/* The format of KASAN tags is 0xF<x>. */+addr|=(0xF0UL<<MTE_TAG_SHIFT);
Ah, I see, that top 4 bits are zeroed by do_tag_check_fault(). When this
was added, the only tag faults were generated for user addresses.
Anyway, I'd rather fix it in there based on bit 55, something like (only
compile-tested):
@@ -709,10 +709,11 @@ static int do_tag_check_fault(unsigned long far, unsigned int esr,structpt_regs*regs){/*-*Thearchitecturespecifiesthatbits63:60ofFAR_EL1areUNKNOWNfortag-*checkfaults.Maskthemoutnowsothatuserspacedoesn'tseethem.+*Thearchitecturespecifiesthatbits63:60ofFAR_EL1areUNKNOWN+*fortagcheckfaults.Setthemtothecorrespondingbitsinthe+*untaggedaddress.*/-far&=(1UL<<60)-1;+far=(untagged_addr(far)&~MTE_TAG_MASK)|(far&MTE_TAG_MASK);do_bad_area(far,esr,regs);return0;}
Sounds good, will do in v3, thanks!
I wonder if this one gives the same result (so please check):
far = u64_replace_bits(untagged_addr(far), far, MTE_TAG_MASK);
(defined in linux/bitfield.h)
No, it zeroes out the tag. Not sure why. I took a brief look at the
implementation and didn't get how it's supposed to work - too much bit
trickery.
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
On Wed, Jan 13, 2021 at 5:54 PM Catalin Marinas [off-list ref] wrote:
quoted hunk
On Wed, Jan 13, 2021 at 05:03:30PM +0100, Andrey Konovalov wrote:
quoted
As of the "arm64: expose FAR_EL1 tag bits in siginfo" patch, the address
that is passed to report_tag_fault has pointer tags in the format of 0x0X,
while KASAN uses 0xFX format (note the difference in the top 4 bits).
Fix up the pointer tag before calling kasan_report.
Link: https://linux-review.googlesource.com/id/I9ced973866036d8679e8f4ae325de547eb969649
Fixes: dceec3ff7807 ("arm64: expose FAR_EL1 tag bits in siginfo")
Fixes: 4291e9ee6189 ("kasan, arm64: print report from tag fault handler")
Signed-off-by: Andrey Konovalov <redacted>
---
arch/arm64/mm/fault.c | 2 ++
1 file changed, 2 insertions(+)
@@ -304,6 +304,8 @@ static void report_tag_fault(unsigned long addr, unsigned int esr,{boolis_write=((esr&ESR_ELx_WNR)>>ESR_ELx_WNR_SHIFT)!=0;+/* The format of KASAN tags is 0xF<x>. */+addr|=(0xF0UL<<MTE_TAG_SHIFT);
Ah, I see, that top 4 bits are zeroed by do_tag_check_fault(). When this
was added, the only tag faults were generated for user addresses.
Anyway, I'd rather fix it in there based on bit 55, something like (only
compile-tested):
@@ -709,10 +709,11 @@ static int do_tag_check_fault(unsigned long far, unsigned int esr,structpt_regs*regs){/*-*Thearchitecturespecifiesthatbits63:60ofFAR_EL1areUNKNOWNfortag-*checkfaults.Maskthemoutnowsothatuserspacedoesn'tseethem.+*Thearchitecturespecifiesthatbits63:60ofFAR_EL1areUNKNOWN+*fortagcheckfaults.Setthemtothecorrespondingbitsinthe+*untaggedaddress.*/-far&=(1UL<<60)-1;+far=(untagged_addr(far)&~MTE_TAG_MASK)|(far&MTE_TAG_MASK);do_bad_area(far,esr,regs);return0;}
BTW, we can do "untagged_addr(far) | (far & MTE_TAG_MASK)" here, as
untagged_addr() doesn't change kernel pointers.
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
On Fri, Jan 15, 2021 at 05:30:40PM +0100, Andrey Konovalov wrote:
On Wed, Jan 13, 2021 at 5:54 PM Catalin Marinas [off-list ref] wrote:
quoted
On Wed, Jan 13, 2021 at 05:03:30PM +0100, Andrey Konovalov wrote:
quoted
As of the "arm64: expose FAR_EL1 tag bits in siginfo" patch, the address
that is passed to report_tag_fault has pointer tags in the format of 0x0X,
while KASAN uses 0xFX format (note the difference in the top 4 bits).
Fix up the pointer tag before calling kasan_report.
Link: https://linux-review.googlesource.com/id/I9ced973866036d8679e8f4ae325de547eb969649
Fixes: dceec3ff7807 ("arm64: expose FAR_EL1 tag bits in siginfo")
Fixes: 4291e9ee6189 ("kasan, arm64: print report from tag fault handler")
Signed-off-by: Andrey Konovalov <redacted>
---
arch/arm64/mm/fault.c | 2 ++
1 file changed, 2 insertions(+)
@@ -304,6 +304,8 @@ static void report_tag_fault(unsigned long addr, unsigned int esr,{boolis_write=((esr&ESR_ELx_WNR)>>ESR_ELx_WNR_SHIFT)!=0;+/* The format of KASAN tags is 0xF<x>. */+addr|=(0xF0UL<<MTE_TAG_SHIFT);
Ah, I see, that top 4 bits are zeroed by do_tag_check_fault(). When this
was added, the only tag faults were generated for user addresses.
Anyway, I'd rather fix it in there based on bit 55, something like (only
compile-tested):
@@ -709,10 +709,11 @@ static int do_tag_check_fault(unsigned long far, unsigned int esr,structpt_regs*regs){/*-*Thearchitecturespecifiesthatbits63:60ofFAR_EL1areUNKNOWNfortag-*checkfaults.Maskthemoutnowsothatuserspacedoesn'tseethem.+*Thearchitecturespecifiesthatbits63:60ofFAR_EL1areUNKNOWN+*fortagcheckfaults.Setthemtothecorrespondingbitsinthe+*untaggedaddress.*/-far&=(1UL<<60)-1;+far=(untagged_addr(far)&~MTE_TAG_MASK)|(far&MTE_TAG_MASK);do_bad_area(far,esr,regs);return0;}
BTW, we can do "untagged_addr(far) | (far & MTE_TAG_MASK)" here, as
untagged_addr() doesn't change kernel pointers.
untagged_addr() does change tagged kernel pointers, it sign-extends from
bit 55. So the top byte becomes 0xff and you can no longer or the tag
bits in.
--
Catalin
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
On Fri, Jan 15, 2021 at 5:56 PM Catalin Marinas [off-list ref] wrote:
On Fri, Jan 15, 2021 at 05:30:40PM +0100, Andrey Konovalov wrote:
quoted
On Wed, Jan 13, 2021 at 5:54 PM Catalin Marinas [off-list ref] wrote:
quoted
On Wed, Jan 13, 2021 at 05:03:30PM +0100, Andrey Konovalov wrote:
quoted
As of the "arm64: expose FAR_EL1 tag bits in siginfo" patch, the address
that is passed to report_tag_fault has pointer tags in the format of 0x0X,
while KASAN uses 0xFX format (note the difference in the top 4 bits).
Fix up the pointer tag before calling kasan_report.
Link: https://linux-review.googlesource.com/id/I9ced973866036d8679e8f4ae325de547eb969649
Fixes: dceec3ff7807 ("arm64: expose FAR_EL1 tag bits in siginfo")
Fixes: 4291e9ee6189 ("kasan, arm64: print report from tag fault handler")
Signed-off-by: Andrey Konovalov <redacted>
---
arch/arm64/mm/fault.c | 2 ++
1 file changed, 2 insertions(+)
@@ -304,6 +304,8 @@ static void report_tag_fault(unsigned long addr, unsigned int esr,{boolis_write=((esr&ESR_ELx_WNR)>>ESR_ELx_WNR_SHIFT)!=0;+/* The format of KASAN tags is 0xF<x>. */+addr|=(0xF0UL<<MTE_TAG_SHIFT);
Ah, I see, that top 4 bits are zeroed by do_tag_check_fault(). When this
was added, the only tag faults were generated for user addresses.
Anyway, I'd rather fix it in there based on bit 55, something like (only
compile-tested):
@@ -709,10 +709,11 @@ static int do_tag_check_fault(unsigned long far, unsigned int esr,structpt_regs*regs){/*-*Thearchitecturespecifiesthatbits63:60ofFAR_EL1areUNKNOWNfortag-*checkfaults.Maskthemoutnowsothatuserspacedoesn'tseethem.+*Thearchitecturespecifiesthatbits63:60ofFAR_EL1areUNKNOWN+*fortagcheckfaults.Setthemtothecorrespondingbitsinthe+*untaggedaddress.*/-far&=(1UL<<60)-1;+far=(untagged_addr(far)&~MTE_TAG_MASK)|(far&MTE_TAG_MASK);do_bad_area(far,esr,regs);return0;}
BTW, we can do "untagged_addr(far) | (far & MTE_TAG_MASK)" here, as
untagged_addr() doesn't change kernel pointers.
untagged_addr() does change tagged kernel pointers, it sign-extends from
bit 55. So the top byte becomes 0xff and you can no longer or the tag
bits in.
That's __untagged_addr(), untagged_addr() keeps the bits for kernel
pointers as of 597399d0cb91.
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
On Fri, Jan 15, 2021 at 06:00:36PM +0100, Andrey Konovalov wrote:
On Fri, Jan 15, 2021 at 5:56 PM Catalin Marinas [off-list ref] wrote:
quoted
On Fri, Jan 15, 2021 at 05:30:40PM +0100, Andrey Konovalov wrote:
quoted
On Wed, Jan 13, 2021 at 5:54 PM Catalin Marinas [off-list ref] wrote:
quoted
On Wed, Jan 13, 2021 at 05:03:30PM +0100, Andrey Konovalov wrote:
quoted
As of the "arm64: expose FAR_EL1 tag bits in siginfo" patch, the address
that is passed to report_tag_fault has pointer tags in the format of 0x0X,
while KASAN uses 0xFX format (note the difference in the top 4 bits).
Fix up the pointer tag before calling kasan_report.
Link: https://linux-review.googlesource.com/id/I9ced973866036d8679e8f4ae325de547eb969649
Fixes: dceec3ff7807 ("arm64: expose FAR_EL1 tag bits in siginfo")
Fixes: 4291e9ee6189 ("kasan, arm64: print report from tag fault handler")
Signed-off-by: Andrey Konovalov <redacted>
---
arch/arm64/mm/fault.c | 2 ++
1 file changed, 2 insertions(+)
@@ -304,6 +304,8 @@ static void report_tag_fault(unsigned long addr, unsigned int esr,{boolis_write=((esr&ESR_ELx_WNR)>>ESR_ELx_WNR_SHIFT)!=0;+/* The format of KASAN tags is 0xF<x>. */+addr|=(0xF0UL<<MTE_TAG_SHIFT);
Ah, I see, that top 4 bits are zeroed by do_tag_check_fault(). When this
was added, the only tag faults were generated for user addresses.
Anyway, I'd rather fix it in there based on bit 55, something like (only
compile-tested):
@@ -709,10 +709,11 @@ static int do_tag_check_fault(unsigned long far, unsigned int esr,structpt_regs*regs){/*-*Thearchitecturespecifiesthatbits63:60ofFAR_EL1areUNKNOWNfortag-*checkfaults.Maskthemoutnowsothatuserspacedoesn'tseethem.+*Thearchitecturespecifiesthatbits63:60ofFAR_EL1areUNKNOWN+*fortagcheckfaults.Setthemtothecorrespondingbitsinthe+*untaggedaddress.*/-far&=(1UL<<60)-1;+far=(untagged_addr(far)&~MTE_TAG_MASK)|(far&MTE_TAG_MASK);do_bad_area(far,esr,regs);return0;}
BTW, we can do "untagged_addr(far) | (far & MTE_TAG_MASK)" here, as
untagged_addr() doesn't change kernel pointers.
untagged_addr() does change tagged kernel pointers, it sign-extends from
bit 55. So the top byte becomes 0xff and you can no longer or the tag
bits in.
That's __untagged_addr(), untagged_addr() keeps the bits for kernel
pointers as of 597399d0cb91.
Ah, you are right. In this case I think we should use __untagged_addr()
above. Even if the tag check fault happened on a kernel address, bits
63:60 are still unknown.
--
Catalin
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
On Fri, Jan 15, 2021 at 6:06 PM Catalin Marinas [off-list ref] wrote:
On Fri, Jan 15, 2021 at 06:00:36PM +0100, Andrey Konovalov wrote:
quoted
On Fri, Jan 15, 2021 at 5:56 PM Catalin Marinas [off-list ref] wrote:
quoted
On Fri, Jan 15, 2021 at 05:30:40PM +0100, Andrey Konovalov wrote:
quoted
On Wed, Jan 13, 2021 at 5:54 PM Catalin Marinas [off-list ref] wrote:
quoted
On Wed, Jan 13, 2021 at 05:03:30PM +0100, Andrey Konovalov wrote:
quoted
As of the "arm64: expose FAR_EL1 tag bits in siginfo" patch, the address
that is passed to report_tag_fault has pointer tags in the format of 0x0X,
while KASAN uses 0xFX format (note the difference in the top 4 bits).
Fix up the pointer tag before calling kasan_report.
Link: https://linux-review.googlesource.com/id/I9ced973866036d8679e8f4ae325de547eb969649
Fixes: dceec3ff7807 ("arm64: expose FAR_EL1 tag bits in siginfo")
Fixes: 4291e9ee6189 ("kasan, arm64: print report from tag fault handler")
Signed-off-by: Andrey Konovalov <redacted>
---
arch/arm64/mm/fault.c | 2 ++
1 file changed, 2 insertions(+)
@@ -304,6 +304,8 @@ static void report_tag_fault(unsigned long addr, unsigned int esr,{boolis_write=((esr&ESR_ELx_WNR)>>ESR_ELx_WNR_SHIFT)!=0;+/* The format of KASAN tags is 0xF<x>. */+addr|=(0xF0UL<<MTE_TAG_SHIFT);
Ah, I see, that top 4 bits are zeroed by do_tag_check_fault(). When this
was added, the only tag faults were generated for user addresses.
Anyway, I'd rather fix it in there based on bit 55, something like (only
compile-tested):
@@ -709,10 +709,11 @@ static int do_tag_check_fault(unsigned long far, unsigned int esr,structpt_regs*regs){/*-*Thearchitecturespecifiesthatbits63:60ofFAR_EL1areUNKNOWNfortag-*checkfaults.Maskthemoutnowsothatuserspacedoesn'tseethem.+*Thearchitecturespecifiesthatbits63:60ofFAR_EL1areUNKNOWN+*fortagcheckfaults.Setthemtothecorrespondingbitsinthe+*untaggedaddress.*/-far&=(1UL<<60)-1;+far=(untagged_addr(far)&~MTE_TAG_MASK)|(far&MTE_TAG_MASK);do_bad_area(far,esr,regs);return0;}
BTW, we can do "untagged_addr(far) | (far & MTE_TAG_MASK)" here, as
untagged_addr() doesn't change kernel pointers.
untagged_addr() does change tagged kernel pointers, it sign-extends from
bit 55. So the top byte becomes 0xff and you can no longer or the tag
bits in.
That's __untagged_addr(), untagged_addr() keeps the bits for kernel
pointers as of 597399d0cb91.
Ah, you are right. In this case I think we should use __untagged_addr()
above. Even if the tag check fault happened on a kernel address, bits
63:60 are still unknown.
Yeah, I keep forgetting about [__]untagged_addr() too. Maybe we need
better names? Like untagged_addr() and untagged_addr_ttbr0()?
Anyway, I'll do the explicit calculation with __untagged_addr() in the
next version.
Thanks!
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel