Hi Dave,
On 4/22/20 7:29 PM, Dave Anderson wrote:
Hi Amit,
Two more questions below...
----- Original Message -----
>> But here's where I'm confused: when an in-kernel exception frame occurs,
and the
>> processor lays down the full register set on the stack, are both the PC and LR
(regs[30])
>> text values written on the stack as obfuscated values?
>>
>
> In arm64 case arch/arm64/include/asm/kexec.h + crash_setup_regs()
> function sets up the kernel exception frame. As can be seen PC does not
> have obfuscated (PAC) values but LR can be obfuscated.
Ok, so that's when it's setting up the registers for a kexec/kdump operation.
But what about exceptions that occur during the normal course of events, such as
when an interrupt or page fault occurs?
pc will never have obfuscated value as obfuscated value can reside
either in lr or stack.
The epilogue of function where return to lr register happens is usually
like,
ldp x29, x30, [sp], #16 // optional if x29, x30 is not corrupted
autiasp
ret
Here autiasp clears the obfuscated value then pc is set to lr with ret
address.
If autiasp fails then the lr top byte is set to some bit pattern and pc=lr
Note that KERNELPACMASK or obfuscated value starts below from top byte
and leaves the top byte as it is. Even pointer authentication backtrace
shows the PC with top byte as the corrupted bit pattern. This error bit
pattern was not properly defined in armv8.3 architecture manual so left
like this. In this case symbol search may fail here.
I am also working on armv8.6(patches floating in mailing list) where if
autiasp fails then proper pointer authentication exception is generated
so pc top byte will be without any error bit pattern and all the changes
done here should work fine.
>> ...
>>
>> When it gathers the starting hooks for non-active tasks, it does this:
>>
>> static int
>> arm64_get_stackframe(struct bt_info *bt, struct arm64_stackframe
*frame)crash_setup_regs
>> {
>> if (!fill_task_struct(bt->task))
>> return FALSE;
>>
>> frame->sp = ULONG(tt->task_struct +
OFFSET(task_struct_thread_context_sp));
>> frame->pc = ULONG(tt->task_struct +
OFFSET(task_struct_thread_context_pc));
>> frame->fp = ULONG(tt->task_struct +
OFFSET(task_struct_thread_context_fp));
>>
>> return TRUE;
>> }
>>
>> When a task is put to sleep, is the PC text address in the task's
thread_struct.cpu_context
>> obfuscated?
And again, what happens in this case?
Oh I forgot to add my reply for this.
The above reasoning may hold here too.
Cheers,
Amit
Thanks,
Dave