Hi Pingfan,
On Mon, Apr 26, 2021 at 8:06 PM piliu <piliu(a)redhat.com> wrote:
On 4/26/21 7:17 PM, piliu wrote:
>
> Hi Vinayak,
>
> On 3/30/21 9:52 PM, Vinayak Menon wrote:
>> With CONFIG_KASAN_HW_TAGS enabled kvaddr can be tagged
>> and this results in readmem, vtop etc. fail like below.
Sorry for the limited knowledge of this field. I have more question
during the reviewing.
-1.is this reproducible with SW TAGS?
-2. HW TAGS aims for malloc, while here I see the handling LR, PC.
It seems that they are more related to "Pointer Authentication"
I have not tried with SW tags. CONFIG_KASAN_HW_TAGS can be found here
in kernel
The MTE based kasan is used for tagging malloc too. With
CONFIG_KASAN_HW_TAGS it is used to tag kernel memory, replacing the
regular kasan.
Thanks,
Pingfan
>>
>> "
>> please wait... (gathering kmem slab cache data)
>> crash: invalid kernel virtual address: f0ffff878000201c type:
>> "kmem_cache objsize/object_size"
>> crash: get_active_set: no tasks found?
>> please wait... (gathering task table data)
>> crash: invalid kernel virtual address: f1ffff87f51e3530 type:
>> "xa_node shift"
>> "
>>
>> Make the mask introduced for pointer authentication generic
>> and use it in vtop and kvaddr validation.
>>
>> Signed-off-by: Vinayak Menon <vinayakm.list(a)gmail.com>
>> ---
>> arm64.c | 50 +++++++++++++++++++++++++++++++-------------------
>> defs.h | 2 +-
>> 2 files changed, 32 insertions(+), 20 deletions(-)
>>
>> diff --git a/arm64.c b/arm64.c
>> index 5b59972..bb41cbb 100644
>> --- a/arm64.c
>> +++ b/arm64.c
>> @@ -85,7 +85,8 @@ static int arm64_get_kvaddr_ranges(struct
>> vaddr_range *);
>> static void arm64_get_crash_notes(void);
>> static void arm64_calc_VA_BITS(void);
>> static int arm64_is_uvaddr(ulong, struct task_context *);
>> -static void arm64_calc_KERNELPACMASK(void);
>> +static int arm64_is_kvaddr(ulong);
>> +static void arm64_calc_KERNELTAGMASK(void);
>> /*
>> @@ -215,7 +216,7 @@ arm64_init(int when)
>> machdep->pagemask = ~((ulonglong)machdep->pageoffset);
>> arm64_calc_VA_BITS();
>> - arm64_calc_KERNELPACMASK();
>> + arm64_calc_KERNELTAGMASK();
>> ms = machdep->machspec;
>> if (ms->VA_BITS_ACTUAL) {
>> ms->page_offset = ARM64_PAGE_OFFSET_ACTUAL;
>> @@ -228,7 +229,7 @@ arm64_init(int when)
>> machdep->kvbase = ARM64_VA_START;
>> ms->userspace_top = ARM64_USERSPACE_TOP;
>> }
>> - machdep->is_kvaddr = generic_is_kvaddr;
>> + machdep->is_kvaddr = arm64_is_kvaddr;
>> machdep->kvtop = arm64_kvtop;
>> if (machdep->flags & NEW_VMEMMAP) {
>> struct syment *sp;
>> @@ -477,7 +478,7 @@ arm64_init(int when)
>> case LOG_ONLY:
>> machdep->machspec = &arm64_machine_specific;
>> arm64_calc_VA_BITS();
>> - arm64_calc_KERNELPACMASK();
>> + arm64_calc_KERNELTAGMASK();
>> arm64_calc_phys_offset();
>> machdep->machspec->page_offset = ARM64_PAGE_OFFSET;
>> arm64_calc_physvirt_offset();
>> @@ -608,7 +609,7 @@ arm64_dump_machdep_table(ulong arg)
>> fprintf(fp, " dis_filter: arm64_dis_filter()\n");
>> fprintf(fp, " cmd_mach: arm64_cmd_mach()\n");
>> fprintf(fp, " get_smp_cpus: arm64_get_smp_cpus()\n");
>> - fprintf(fp, " is_kvaddr: generic_is_kvaddr()\n");
>> + fprintf(fp, " is_kvaddr: arm64_is_kvaddr()\n");
>> fprintf(fp, " is_uvaddr: arm64_is_uvaddr()\n");
>> fprintf(fp, " value_to_symbol:
>> generic_machdep_value_to_symbol()\n");
>> fprintf(fp, " init_kernel_pgd: arm64_init_kernel_pgd\n");
>> @@ -668,9 +669,9 @@ arm64_dump_machdep_table(ulong arg)
>> fprintf(fp, "%ld\n", ms->VA_BITS_ACTUAL);
>> else
>> fprintf(fp, "(unused)\n");
>> - fprintf(fp, "CONFIG_ARM64_KERNELPACMASK: ");
>> - if (ms->CONFIG_ARM64_KERNELPACMASK)
>> - fprintf(fp, "%lx\n", ms->CONFIG_ARM64_KERNELPACMASK);
>> + fprintf(fp, "CONFIG_ARM64_KERNELTAGMASK: ");
>> + if (ms->CONFIG_ARM64_KERNELTAGMASK)
>> + fprintf(fp, "%lx\n", ms->CONFIG_ARM64_KERNELTAGMASK);
>> else
>> fprintf(fp, "(unused)\n");
>> fprintf(fp, " userspace_top: %016lx\n",
ms->userspace_top);
>> @@ -1208,6 +1209,9 @@ arm64_kvtop(struct task_context *tc, ulong
>> kvaddr, physaddr_t *paddr, int verbos
>> if (!IS_KVADDR(kvaddr))
>> return FALSE;
>> + if (kvaddr & (1UL << 63))
>> + kvaddr |= machdep->machspec->CONFIG_ARM64_KERNELTAGMASK;
>> +
>> if (!vt->vmalloc_start) {
>> *paddr = VTOP(kvaddr);
>> return TRUE;
>> @@ -1828,7 +1832,7 @@ arm64_is_kernel_exception_frame(struct bt_info
>> *bt, ulong stkptr)
>> if (INSTACK(regs->sp, bt) && INSTACK(regs->regs[29], bt)
&&
>> !(regs->pstate & (0xffffffff00000000ULL | PSR_MODE32_BIT))
&&
>> is_kernel_text(regs->pc) &&
>> - is_kernel_text(regs->regs[30] |
>> ms->CONFIG_ARM64_KERNELPACMASK)) {
>> + is_kernel_text(regs->regs[30] |
>> ms->CONFIG_ARM64_KERNELTAGMASK)) {
>> switch (regs->pstate & PSR_MODE_MASK)
>> {
>> case PSR_MODE_EL1t:
>> @@ -2198,8 +2202,8 @@ arm64_unwind_frame(struct bt_info *bt, struct
>> arm64_stackframe *frame)
>> frame->sp = fp + 0x10;
>> frame->fp = GET_STACK_ULONG(fp);
>> frame->pc = GET_STACK_ULONG(fp + 8);
>> - if (is_kernel_text(frame->pc | ms->CONFIG_ARM64_KERNELPACMASK))
>> - frame->pc |= ms->CONFIG_ARM64_KERNELPACMASK;
>> + if (is_kernel_text(frame->pc | ms->CONFIG_ARM64_KERNELTAGMASK))
>> + frame->pc |= ms->CONFIG_ARM64_KERNELTAGMASK;
>> if ((frame->fp == 0) && (frame->pc == 0))
>> return FALSE;
>> @@ -2869,8 +2873,8 @@ arm64_print_text_symbols(struct bt_info *bt,
>> struct arm64_stackframe *frame, FIL
>> for (i = (start - bt->stackbase)/sizeof(ulong); i <
>> LONGS_PER_STACK; i++) {
>> up = (ulong *)(&bt->stackbuf[i*sizeof(ulong)]);
>> val = *up;
>> - if (is_kernel_text(val | ms->CONFIG_ARM64_KERNELPACMASK)) {
>> - val |= ms->CONFIG_ARM64_KERNELPACMASK;
>> + if (is_kernel_text(val | ms->CONFIG_ARM64_KERNELTAGMASK)) {
>> + val |= ms->CONFIG_ARM64_KERNELTAGMASK;
>> name = closest_symbol(val);
>> fprintf(ofp, " %s[%s] %s at %lx",
>> bt->flags & BT_ERROR_MASK ?
>> @@ -3205,8 +3209,8 @@ arm64_print_exception_frame(struct bt_info *bt,
>> ulong pt_regs, int mode, FILE *o
>> rows = 4;
>> } else {
>> LR = regs->regs[30];
>> - if (is_kernel_text (LR | ms->CONFIG_ARM64_KERNELPACMASK))
>> - LR |= ms->CONFIG_ARM64_KERNELPACMASK;
>> + if (is_kernel_text (LR | ms->CONFIG_ARM64_KERNELTAGMASK))
>> + LR |= ms->CONFIG_ARM64_KERNELTAGMASK;
>> SP = regs->sp;
>> top_reg = 29;
>> is_64_bit = TRUE;
>> @@ -4102,6 +4106,14 @@ arm64_calc_virtual_memory_ranges(void)
>> }
>> static int
>> +arm64_is_kvaddr(ulong addr)
>> +{
>> + if (addr & (1UL << 63))
>> + addr |= machdep->machspec->CONFIG_ARM64_KERNELTAGMASK;
>> + return generic_is_kvaddr(addr);
>> +}
>> +
>> +static int
>> arm64_is_uvaddr(ulong addr, struct task_context *tc)
>> {
>> return (addr < machdep->machspec->userspace_top);
>> @@ -4129,21 +4141,21 @@ arm64_swp_offset(ulong pte)
>> return pte;
>> }
>> -static void arm64_calc_KERNELPACMASK(void)
>> +static void arm64_calc_KERNELTAGMASK(void)
>> {
>> ulong value = 0;
>> char *string;
>> - if ((string = pc->read_vmcoreinfo("NUMBER(KERNELPACMASK)")))
{
>> + if ((string = pc->read_vmcoreinfo("NUMBER(KERNELTAGMASK)")))
{
>
> I git grep 5.12 kernel, but did not find this. Do you plan to do it in
> kernel firstly?
>
> Thanks,
> Pingfan
>> value = htol(string, QUIET, NULL);
>> free(string);
>> } else if (machdep->machspec->tag_mask) {
>> value = machdep->machspec->tag_mask;
>> }
>> - machdep->machspec->CONFIG_ARM64_KERNELPACMASK = value;
>> + machdep->machspec->CONFIG_ARM64_KERNELTAGMASK = value;
>> if (CRASHDEBUG(1))
>> - fprintf(fp, "CONFIG_ARM64_KERNELPACMASK: %lx\n", value);
>> + fprintf(fp, "CONFIG_ARM64_KERNELTAGMASK: %lx\n", value);
>> }
>> #endif /* ARM64 */
>> diff --git a/defs.h b/defs.h
>> index d406f5f..770c335 100644
>> --- a/defs.h
>> +++ b/defs.h
>> @@ -3329,7 +3329,7 @@ struct machine_specific {
>> ulong VA_BITS_ACTUAL;
>> ulong CONFIG_ARM64_VA_BITS;
>> ulong VA_START;
>> - ulong CONFIG_ARM64_KERNELPACMASK;
>> + ulong CONFIG_ARM64_KERNELTAGMASK;
>> ulong physvirt_offset;
>> ulong tag_mask;
>> };
>>
>> --
>> Crash-utility mailing list
>> Crash-utility(a)redhat.com
>>
https://listman.redhat.com/mailman/listinfo/crash-utility
>>
>
> --
> Crash-utility mailing list
> Crash-utility(a)redhat.com
>
https://listman.redhat.com/mailman/listinfo/crash-utility