[PATCH v2 6/8] arm64: Import latest memcpy()/memmove() implementation
Robin Murphy
robin.murphy at arm.com
Fri Sep 10 04:42:16 PDT 2021
On 2021-09-10 01:35, Peter Collingbourne wrote:
> Hi Robin,
>
> (apologies for breaking the threading, I wasn't subscribed to
> linux-arm-kernel when you sent this)
>
> It looks like this patch breaks the KASAN unit tests when running in
> HW tags mode. You can construct a config that reproduces the problem
> with something like:
>
> make O=out defconfig
> scripts/config --file out/.config -e CONFIG_KUNIT -e CONFIG_KASAN -e
> CONFIG_KASAN_HW_TAGS -e CONFIG_KASAN_KUNIT_TEST
> yes '' | make O=out syncconfig
>
> With that the "kmalloc_memmove_invalid_size" test fails and causes the
> kernel panic below.
>
> What appears to be going on is that whereas the old memcpy
> implementation ends up returning early after not copying very much
> data if supplied a "negative" size as a side effect of using
> conditional branches that implement signed comparisons (e.g. b.ge on
> line 75), the new implementation does not exit early and attempts to
> copy a large amount of data backwards 4 bytes (after having disabled
> MTE early on as a result of a tag mismatch) until it hits a read-only
> page and causes a panic.
If the test depends on the implementation of memmove() being buggy, it's
clearly not a very good test :/
> I'm not sure what the correct fix should be. It seems that at least
> when KASAN is enabled we should be able to catch these invalid memcpys
> somehow, print an error report and ideally abort the entire operation.
> But we should do so without causing a performance impact in the usual
> case.
Not sure I follow - the top of the log below clearly shows that KASASN
*is* detecting and reporting a bad access. The fact that code intended
to deliberately corrupt memory goes on to corrupt memory doesn't seem
particularly surprising to me. A bug exists (intentionally or otherwise)
which led to that invalid access being attempted, and KASAN can't
magically change that.
Robin.
>
> Peter
>
> [ 7.726311] ==================================================================
> [ 7.726817] BUG: KASAN: invalid-access in __memcpy+0x1a0/0x230
> [ 7.727310] Read at addr f8ff000002650ef2 by task kunit_try_catch/117
> [ 7.727828] Pointer tag: [f8], memory tag: [fe]
> [ 7.728209]
> [ 7.728419] CPU: 0 PID: 117 Comm: kunit_try_catch Tainted: G B
> 5.14.0-rc3-00011-g7a062ce31807-dirty #1
> [ 7.729186] Hardware name: linux,dummy-virt (DT)
> [ 7.729568] Call trace:
> [ 7.729817] dump_backtrace+0x0/0x1cc
> [ 7.730191] show_stack+0x18/0x24
> [ 7.730543] dump_stack_lvl+0x64/0x7c
> [ 7.730917] print_address_description+0x7c/0x1e0
> [ 7.731336] __kasan_report+0x228/0x30c
> [ 7.731718] kasan_report+0x44/0x70
> [ 7.732076] __do_kernel_fault+0xbc/0x248
> [ 7.732464] do_tag_check_fault+0x38/0xfc
> [ 7.732862] do_mem_abort+0x40/0xb4
> [ 7.733223] el1_abort+0x40/0x60
> [ 7.733568] el1h_64_sync_handler+0x5c/0x98
> [ 7.733964] el1h_64_sync+0x78/0x7c
> [ 7.734327] __memcpy+0x1a0/0x230
> [ 7.734684] kunit_try_run_case+0x48/0x108
> [ 7.735073] kunit_generic_run_threadfn_adapter+0x20/0x2c
> [ 7.735536] kthread+0x170/0x330
> [ 7.735888] ret_from_fork+0x10/0x18
> [ 7.736264]
> [ 7.736462] Allocated by task 116:
> [ 7.736780] ____kasan_kmalloc+0x108/0x130
> [ 7.737163] __kasan_kmalloc+0x10/0x1c
> [ 7.737527] kthread+0x6c/0x330
> [ 7.737861] ret_from_fork+0x10/0x18
> [ 7.738217]
> [ 7.738413] Freed by task 115:
> [ 7.738713] kasan_set_track+0x3c/0x74
> [ 7.739080] kasan_set_free_info+0x20/0x2c
> [ 7.739461] ____kasan_slab_free+0x214/0x218
> [ 7.739847] __kasan_slab_free+0x14/0x24
> [ 7.740223] kfree+0x140/0x3bc
> [ 7.740553] free_kthread_struct+0x28/0x4c
> [ 7.740935] __put_task_struct+0x138/0x1b8
> [ 7.741326] delayed_put_task_struct+0x4c/0x88
> [ 7.741728] rcu_do_batch+0x130/0x3ec
> [ 7.742092] rcu_core+0x1f0/0x344
> [ 7.742446] rcu_core_si+0x10/0x1c
> [ 7.742796] __do_softirq+0xd8/0x260
> [ 7.743152]
> [ 7.743348] The buggy address belongs to the object at ffff000002650e00
> [ 7.743348] which belongs to the cache kmalloc-128 of size 128
> [ 7.744152] The buggy address is located 114 bytes to the right of
> [ 7.744152] 128-byte region [ffff000002650e00, ffff000002650e80)
> [ 7.744971] The buggy address belongs to the page:
> [ 7.745345] page:fffffc0000099400 refcount:1 mapcount:0
> mapping:0000000000000000 index:0x0 pfn:0x42650
> [ 7.746004] flags:
> 0x3fffc0000000200(slab|node=0|zone=0|lastcpupid=0xffff|kasantag=0x0)
> [ 7.746680] raw: 03fffc0000000200 0000000000000000 0000000100000001
> fdff000002401200
> [ 7.747276] raw: 0000000000000000 0000000080100010 00000001ffffffff
> 0000000000000000
> [ 7.747775] page dumped because: kasan: bad access detected
> [ 7.748190]
> [ 7.748383] Memory state around the buggy address:
> [ 7.748767] ffff000002650c00: f8 f8 fe fe fe fe fe fe fe fe fe fe
> fe fe fe fe
> [ 7.749303] ffff000002650d00: f8 f8 f8 f8 f8 f8 f8 fe fe fe fe fe
> fe fe fe fe
> [ 7.749831] >ffff000002650e00: fa fa fa fa fa fa fa fe fe fe fe fe
> fe fe fe fe
> [ 7.750345] ^
> [ 7.750853] ffff000002650f00: f8 f8 f8 f8 fe fe fe fe fe fe fe fe
> fe fe fe fe
> [ 7.751388] ffff000002651000: fc fc fc fc fc fc fc fc fe fb fb fb
> fb fb fb fb
> [ 7.751914] ==================================================================
> [ 7.754424] Unable to handle kernel write to read-only memory at
> virtual address f8ff000002573ff0
> [ 7.760818] Mem abort info:
> [ 7.761074] ESR = 0x9600004f
> [ 7.761392] EC = 0x25: DABT (current EL), IL = 32 bits
> [ 7.761819] SET = 0, FnV = 0
> [ 7.762086] EA = 0, S1PTW = 0
> [ 7.762374] FSC = 0x0f: level 3 permission fault
> [ 7.763350] Data abort info:
> [ 7.763600] ISV = 0, ISS = 0x0000004f
> [ 7.763954] CM = 0, WnR = 1
> [ 7.764282] swapper pgtable: 4k pages, 48-bit VAs, pgdp=000000004193c000
> [ 7.764760] [f8ff000002573ff0] pgd=180000005fff7003,
> p4d=180000005fff7003, pud=180000005fff6003, pmd=180000005ffed003,
> pte=0060000042573f87
> [ 7.766996] Internal error: Oops: 9600004f [#1] PREEMPT SMP
> [ 7.767561] Modules linked in:
> [ 7.768138] CPU: 0 PID: 117 Comm: kunit_try_catch Tainted: G B
> 5.14.0-rc3-00011-g7a062ce31807-dirty #1
> [ 7.768948] Hardware name: linux,dummy-virt (DT)
> [ 7.769444] pstate: a0400005 (NzCv daif +PAN -UAO -TCO BTYPE=--)
> [ 7.769987] pc : __memcpy+0x1e8/0x230
> [ 7.771029] lr : kmalloc_memmove_invalid_size+0x148/0x1cc
> [ 7.771457] sp : ffff80001023bd60
> [ 7.771740] x29: ffff80001023bdb0 x28: 0000000000000000 x27: f8ff000002650d40
> [ 7.772450] x26: f3ff000002d64600 x25: ffffc63e374bdf48 x24: ffffc63e3901c50c
> [ 7.773109] x23: 000001e700000001 x22: ffffc63e3905f000 x21: ffffc63e38587294
> [ 7.773768] x20: ffff80001000bb70 x19: f8ff000002650f00 x18: ffffffffffffffff
> [ 7.774422] x17: 0000000000000000 x16: 0000000000000118 x15: 0000000000000004
> [ 7.775067] x14: 000000000000000e x13: 42573f83d4202000 x12: d4202000d4202000
> [ 7.775722] x11: d4202000d4202000 x10: d4202000d4202000 x9 : d4202000d4202000
> [ 7.776397] x8 : d4202000d4202000 x7 : d4202000d4202000 x6 : d4202000d4202000
> [ 7.777040] x5 : f8ff000002574030 x4 : f8ff000002573ff4 x3 : 0000000000000000
> [ 7.777687] x2 : fffffffffff230b0 x1 : f8ff000002650f04 x0 : f8ff000002650f00
> [ 7.778441] Call trace:
> [ 7.778714] __memcpy+0x1e8/0x230
> [ 7.779064] kunit_try_run_case+0x48/0x108
> [ 7.779409] kunit_generic_run_threadfn_adapter+0x20/0x2c
> [ 7.779818] kthread+0x170/0x330
> [ 7.780125] ret_from_fork+0x10/0x18
> [ 7.780771] Code: a93e24a8 a97e2488 a93d2caa a97d2c8a (a9bc34ac)
> [ 7.781490] ---[ end trace e570c3a10375543e ]---
> [ 7.783261] Unable to handle kernel paging request at virtual
> address 00650d50f8fefff8
> [ 7.783766] Mem abort info:
> [ 7.784002] ESR = 0x96000004
> [ 7.784255] EC = 0x25: DABT (current EL), IL = 32 bits
> [ 7.784637] SET = 0, FnV = 0
> [ 7.784892] EA = 0, S1PTW = 0
> [ 7.785150] FSC = 0x04: level 0 translation fault
> [ 7.785495] Data abort info:
> [ 7.785724] ISV = 0, ISS = 0x00000004
> [ 7.786013] CM = 0, WnR = 0
> [ 7.786268] [00650d50f8fefff8] address between user and kernel address ranges
> [ 7.786743] Internal error: Oops: 96000004 [#2] PREEMPT SMP
> [ 7.787122] Modules linked in:
> [ 7.787423] CPU: 0 PID: 117 Comm: kunit_try_catch Tainted: G B D
> 5.14.0-rc3-00011-g7a062ce31807-dirty #1
> [ 7.788099] Hardware name: linux,dummy-virt (DT)
> [ 7.788419] pstate: 004000c5 (nzcv daIF +PAN -UAO -TCO BTYPE=--)
> [ 7.788855] pc : swake_up_locked+0x1c/0x48
> [ 7.789197] lr : complete+0x44/0x64
> [ 7.789508] sp : ffff80001023b910
> [ 7.789773] x29: ffff80001023b910 x28: f3ff000002d64600 x27: f3ff000002d64600
> [ 7.790425] x26: f3ff000002d64600 x25: ffffc63e374bdf48 x24: ffffc63e374efbf8
> [ 7.791069] x23: ffff80001023baa4 x22: 0000000000000000 x21: 0000000000000000
> [ 7.791733] x20: f8ff000002650d40 x19: 02650d50f8ff0000 x18: ffffffffffffffff
> [ 7.792380] x17: 0000000000000000 x16: 0000000000000118 x15: 0000000000000004
> [ 7.793031] x14: 0000000000000fff x13: ffffc63e38d4aa08 x12: 0000000000000003
> [ 7.793683] x11: 0000000000000000 x10: 0000000000000002 x9 : 0000000000000000
> [ 7.794341] x8 : 0000000000000001 x7 : 205d303934313837 x6 : 372e37202020205b
> [ 7.794977] x5 : ffffc63e39041f58 x4 : 0000000000000001 x3 : 0000000000000000
> [ 7.795622] x2 : 0000000000000001 x1 : 0000000000000000 x0 : f8ff000002650d50
> [ 7.796272] Call trace:
> [ 7.796503] swake_up_locked+0x1c/0x48
> [ 7.796836] complete+0x44/0x64
> [ 7.797133] mm_release+0xd4/0xec
> [ 7.797437] exit_mm_release+0x28/0x38
> [ 7.797775] exit_mm+0x3c/0x214
> [ 7.798074] do_exit+0x180/0x778
> [ 7.798379] die+0x2ac/0x2b0
> [ 7.798669] __do_kernel_fault+0x1bc/0x248
> [ 7.799020] do_page_fault+0x4c/0x3c4
> [ 7.799343] do_mem_abort+0x40/0xb4
> [ 7.799661] el1_abort+0x40/0x60
> [ 7.799968] el1h_64_sync_handler+0x5c/0x98
> [ 7.800318] el1h_64_sync+0x78/0x7c
> [ 7.800639] __memcpy+0x1e8/0x230
> [ 7.800948] kunit_try_run_case+0x48/0x108
> [ 7.801297] kunit_generic_run_threadfn_adapter+0x20/0x2c
> [ 7.801697] kthread+0x170/0x330
> [ 7.801993] ret_from_fork+0x10/0x18
> [ 7.802383] Code: 910003fd f8408c13 eb00027f 54000100 (f85f8260)
> [ 7.802810] ---[ end trace e570c3a10375543f ]---
> [ 7.803154] note: kunit_try_catch[117] exited with preempt_count 2
> [ 7.803596] Fixing recursive fault but reboot is needed!
> [ 10.659826] Unable to handle kernel paging request at virtual
> address ffff39c2e762363e
> [ 10.661382] Mem abort info:
> [ 10.662059] ESR = 0x96000004
> [ 10.662795] EC = 0x25: DABT (current EL), IL = 32 bits
> [ 10.663887] SET = 0, FnV = 0
> [ 10.664634] EA = 0, S1PTW = 0
> [ 10.665390] FSC = 0x04: level 0 translation fault
> [ 10.666379] Data abort info:
> [ 10.667043] ISV = 0, ISS = 0x00000004
> [ 10.667879] CM = 0, WnR = 0
> [ 10.668605] swapper pgtable: 4k pages, 48-bit VAs, pgdp=000000004193c000
> [ 10.669507] [ffff39c2e762363e] pgd=0000000000000000, p4d=0000000000000000
> [ 10.670636] Internal error: Oops: 96000004 [#3] PREEMPT SMP
> [ 10.671425] Modules linked in:
> [ 10.671998] CPU: 0 PID: 0 Comm: swapper/0 Tainted: G B D
> 5.14.0-rc3-00011-g7a062ce31807-dirty #1
> [ 10.673281] Hardware name: linux,dummy-virt (DT)
> [ 10.673958] pstate: 604000c5 (nZCv daIF +PAN -UAO -TCO BTYPE=--)
> [ 10.674844] pc : __queue_work+0x1f4/0x408
> [ 10.675536] lr : __queue_work+0x38/0x408
> [ 10.676205] sp : ffff800010003d80
> [ 10.676739] x29: ffff800010003d80 x28: ffff39c2e762363e x27: dead000000000122
> [ 10.678061] x26: 0000000000000000 x25: ffffc63e38d1d768 x24: 000000007fffffff
> [ 10.679392] x23: ffffc63e388a9638 x22: 0000000000000014 x21: 0000000000000100
> [ 10.680286] x20: f9ff0000025f8c00 x19: f8ff000002fcc5b0 x18: 0000000000000000
> [ 10.681183] x17: 0000000000000000 x16: 0000000000000001 x15: 0000000000000000
> [ 10.682071] x14: 0000000000200000 x13: f8ff000002fcc588 x12: ffff00001fecd258
> [ 10.682959] x11: ffffffffc0000040 x10: ffffc63e3889f000 x9 : ffff39c1e7627000
> [ 10.683867] x8 : 000000007fffffff x7 : 00001e8480000000 x6 : 0000000000000000
> [ 10.684763] x5 : 0000000000000000 x4 : 0000000000000000 x3 : 0000000000000069
> [ 10.685642] x2 : f8ff000002fcc5b0 x1 : f9ff0000025f8c00 x0 : ffffc63e3901c250
> [ 10.686511] Call trace:
> [ 10.686832] __queue_work+0x1f4/0x408
> [ 10.687287] queue_work_on+0x54/0x8c
> [ 10.687736] blk_rq_timed_out_timer+0x20/0x2c
> [ 10.688225] __run_timers+0x1d8/0x2fc
> [ 10.688682] run_timer_softirq+0x24/0x48
> [ 10.689154] __do_softirq+0xd8/0x260
> [ 10.689592] __irq_exit_rcu+0xf4/0xf8
> [ 10.689954] irq_exit+0x10/0x20
> [ 10.690265] handle_domain_irq+0x60/0x88
> [ 10.690609] gic_handle_irq+0x68/0xe0
> [ 10.690944] call_on_irq_stack+0x2c/0x54
> [ 10.691284] el1_interrupt+0x60/0xa4
> [ 10.691633] el1h_64_irq_handler+0x18/0x24
> [ 10.691994] el1h_64_irq+0x78/0x7c
> [ 10.692316] arch_cpu_idle+0x18/0x28
> [ 10.692651] cpuidle_idle_call+0x70/0x250
> [ 10.693011] do_idle+0xb0/0xfc
> [ 10.693317] cpu_startup_entry+0x24/0x28
> [ 10.693662] rest_init+0xe4/0xf4
> [ 10.693976] arch_call_rest_init+0x10/0x1c
> [ 10.694343] start_kernel+0x328/0x43c
> [ 10.694679] __primary_switched+0xc0/0xc8
> [ 10.695101] Code: eb14013f 54000280 aa1b03e0 9439f6fb (f9400380)
> [ 10.695897] ---[ end trace e570c3a103755440 ]---
> [ 10.696360] Kernel panic - not syncing: Oops: Fatal exception in interrupt
> [ 10.697132] Kernel Offset: 0x463e27000000 from 0xffff800010000000
> [ 10.697565] PHYS_OFFSET: 0x40000000
> [ 10.697857] CPU features: 0x000003d9,4d330c5f
> [ 10.698416] Memory Limit: none
> [ 10.698918] ---[ end Kernel panic - not syncing: Oops: Fatal
> exception in interrupt ]---
>
More information about the linux-arm-kernel
mailing list