jasonmolenda wrote:

A little bit of background, I think everyone understands the basic idea of what 
Felipe is doing here & why, but I think outlining where we are could be helpful.

AArch64 processes can be run with ptrauth enabled (the "arm64e" slice, the ABI 
only officially announced as stable in this year's OS releases, and now usable 
by third parties).  Things like function pointers are signed against a private 
key in the cpu, things like the link register are signed agaInst a private key 
_and_ a discriminator of the stack pointer value on function entry.  In the 
function epilogue, $sp is restored to its original value and the link register 
is validated against the secret key and $sp.  The Darwin AArch64 processors run 
in Top Byte Ignore mode, which means metadata can be stored in the top byte 
without breaking load/store instructions.  Function addresses put PAC signing 
in the top byte, data access signing leaves the top byte user-controlled.

As an aside, we have a pass (not upstreamed) for expressions that will sign 
things like function pointers in jitted expressions.  If you do `p 
(int)qsort(start, count, elemsize, comparefunc)` in lldb, we will find the 
address of `comparefunc()` in the symbol table and pass that in to the 
expression.  But this is a function pointer that the arm64e ABI requires be PAC 
signed.  We can't sign it in lldb, the signing must execute in-process to have 
the correct keys.  So there's a static initializer pass inserted into 
expressions that signs these.  These global ABI-mandated PAC signed values 
aren't signed against a discriminator, just the internal key, so we can do it 
fine.  (you could imagine a scenario where someone might try to construct a 
64-bit representation of the argument types for a function, and use that as a 
discriminator.  but I don't know if anyone has actually done that.)

Apple also introduced Memory Integrity Enforcement in this year's releases, and 
on the new iPhones one part of MIE is the AArch64 Memory Tag Extension on the 
new iPhones.  When a process opts in to MIE and MTE, 4 bits of the top byte for 
some heap allocates are now used to store an MTE tag which validates that a 
pointer cannot access beyond its allocated range.

With swift async funclets, called asynchronously, they are passed a pointer to 
the swift async context block.  This is a heap allocated object, and so in 
process with MIE enabled on an MTE-capable device, it will have an MTE tag.  
lldb can read and write memory from the swift async context without preserving 
the MTE tag because its own target-memory accesses aren't authenticated against 
the tags.  But when we pass the swift async context address into a jitted 
expression -- so the address is being used in code running in the process -- 
now we must include the MTE tag in the value sent into the expression.

An additional wrinkle is that it seems that in the swift funclet, when built 
with PAC (arm64e), the local register value pointing to a variable in the swift 
async context will be PAC signed against a local discriminator value.  The user 
does an expression which uses this variable, but the jitted code isn't aware 
that the swift async funclet is PAC-enforcing the address of this variable, it 
just thinks it's using an address of the variable.  So we must strip the PAC 
bits, but it's an address in the heap-allocated MTE swift async context, so we 
must also retain the MTE tag in the top byte.

We considered "well, what if we just leave the PAC bits in there" -- but normal 
load/store instructions (the ones that do not check PAC signing) require that 
all non-address bits outside of the Top Byte (with TBI mode enabled) are either 
0's or 1's.  Anything else in those bit ranges results in a fault.  We can have 
arbitrary data in the top byte, but the rest of the non-address bits must be 
correct.

https://github.com/llvm/llvm-project/pull/159785
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to