Issue with relocations while trying to tag global variables with HWASAN

37 views
Skip to first unread message

Alexey Baturo

unread,
Aug 25, 2022, 5:03:57 PM8/25/22
to RISC-V SW Dev, jrt...@jrtc27.com, kito....@sifive.com, i...@maskray.me
Hi all,

I've been recently working on upstreaming HWASAN LLVM support for RISC-V.
Brief description how HWASAN works: the idea behind HWASAN is similar to a regular ASAN, but in this case tag is stored in top 8 bits of the pointer, which is checked upon memory access with instrumented code. I.e. 0x2300000012341234 is a valid tagged pointer value with 0x23 as tag.

Current HWASAN implementation for RISC-V mostly works except for tagging global variables: the existing code models and relocation sequences doesn't allow such address to be constructed. So such cases would fail during linking.

I could propose a solution for this problem which is almost identical to the one used in AArch64. The following things have to be done:
- Add non-checking variants of R_RISCV_HI20 and R_RISCV_PCREL_HI20 relocations
- Add new relocation which could set top 8 bits of global address the same way R_AARCH64_MOVW_PREL_G3 does
- Switch to new relocation sequence if HWASAN tagging globals option is enabled

I'd like to hear your opinions on this suggestion. Or maybe someone could suggest better ways of dealing with this issue.
I could prototype the suggested changes for llvm/lld, but as far as I can tell, introducing new relocations/updating psABI might be a tricky thing. So I'd like to start the discussion first.

Folks in cc: sorry for explicitly putting you in cc, but I believe you could bring some insights to this discussion.

Thanks

Palmer Dabbelt

unread,
Aug 25, 2022, 6:58:08 PM8/25/22
to baturo...@gmail.com, sw-...@groups.riscv.org, jrt...@jrtc27.com, kito....@sifive.com, i...@maskray.me
On Thu, 25 Aug 2022 14:03:56 PDT (-0700), baturo...@gmail.com wrote:
> Hi all,
>
> I've been recently working on upstreaming HWASAN LLVM support for RISC-V.
> Brief description how HWASAN works: the idea behind HWASAN is similar to a
> regular ASAN, but in this case tag is stored in top 8 bits of the pointer,
> which is checked upon memory access with instrumented code. I.e.
> 0x2300000012341234 is a valid tagged pointer value with 0x23 as tag.
>
> Current HWASAN implementation for RISC-V mostly works except for tagging
> global variables: the existing code models and relocation sequences doesn't
> allow such address to be constructed. So such cases would fail during
> linking.
>
> I could propose a solution for this problem which is almost identical to
> the one used in AArch64. The following things have to be done:
> - Add non-checking variants of R_RISCV_HI20 and R_RISCV_PCREL_HI20
> relocations
> - Add new relocation which could set top 8 bits of global address the same
> way R_AARCH64_MOVW_PREL_G3 does
> - Switch to new relocation sequence if HWASAN tagging globals option is
> enabled
>
> I'd like to hear your opinions on this suggestion. Or maybe someone could
> suggest better ways of dealing with this issue.

I'm not super familiar with arm64 or hwasan, but from looking at their
psABI I think we're missing the instructions that would be required to
efficiently implement these addressing sequences: we'd need a addi/shift
pair to set the high bits, and then another add to mix in the low bits.
It's essentially the same problem we have for the inline large code
model, with the fix being to move to load-indirect addressing.

Alexey Baturo

unread,
Aug 27, 2022, 3:20:32 PM8/27/22
to Jessica Clarke, Palmer Dabbelt, sw-...@groups.riscv.org, kito....@sifive.com, i...@maskray.me
>with the fix being to move to load-indirect addressing.
Do you know if there's an existing mechanism?

>just load via the GOT instead.
I could reuse existing subtarget features infra and emit GOT sequence instead of pcrel one for global vars.

However, this approach wouldn't work with the no-pic option passed: I don't think that's an issue, at least for now, while there are no actual users for hwasan.
I wonder if this situation should be explicitly checked and error raised or just let it fail during linking time?

Thanks

пт, 26 авг. 2022 г. в 02:01, Jessica Clarke <jrt...@jrtc27.com>:
On 25 Aug 2022, at 23:58, Palmer Dabbelt <pal...@dabbelt.com> wrote:
>
> On Thu, 25 Aug 2022 14:03:56 PDT (-0700), baturo...@gmail.com wrote:
>> Hi all,
>>
>> I've been recently working on upstreaming HWASAN LLVM support for RISC-V.
>> Brief description how HWASAN works: the idea behind HWASAN is similar to a
>> regular ASAN, but in this case tag is stored in top 8 bits of the pointer,
>> which is checked upon memory access with instrumented code. I.e.
>> 0x2300000012341234 is a valid tagged pointer value with 0x23 as tag.
>>
>> Current HWASAN implementation for RISC-V mostly works except for tagging
>> global variables: the existing code models and relocation sequences doesn't
>> allow such address to be constructed. So such cases would fail during
>> linking.
>>
>> I could propose a solution for this problem which is almost identical to
>> the one used in AArch64. The following things have to be done:
>> - Add non-checking variants of R_RISCV_HI20 and R_RISCV_PCREL_HI20
>> relocations
>> - Add new relocation which could set top 8 bits of global address the same
>> way R_AARCH64_MOVW_PREL_G3 does
>> - Switch to new relocation sequence if HWASAN tagging globals option is
>> enabled
>>
>> I'd like to hear your opinions on this suggestion. Or maybe someone could
>> suggest better ways of dealing with this issue.
>
> I'm not super familiar with arm64 or hwasan, but from looking at their psABI I think we're missing the instructions that would be required to efficiently implement these addressing sequences: we'd need a addi/shift pair to set the high bits, and then another add to mix in the low bits.  It's essentially the same problem we have for the inline large code model, with the fix being to move to load-indirect addressing.

That would be my initial intuition, just load via the GOT instead.

Jess
Reply all
Reply to author
Forward
0 new messages