This is an archive of the discontinued LLVM Phabricator instance.

[compiler-rt][scudo] Check for failing prctl call
ClosedPublic

Authored by leonardchan on Sep 30 2021, 3:30 PM.

Details

Summary

A bunch of MTE tests like ./ScudoUnitTest-aarch64-Test/MemtagTest.StoreTags can fail on aarch64-linux if the kernel doesn't support TBI. It looks like the call to prctl(PR_GET_TAGGED_ADDR_CTRL, 0, 0, 0, 0) can return -1, which casted to an unsigned int and masked will return a value not equal to PR_MTE_TCF_NONE, meaning systemDetectsMemoryTagFaultsTestOnly can return an incorrect value.

This updates the check to account for a failing prctl call.

Diff Detail

Event Timeline

leonardchan created this revision.Sep 30 2021, 3:30 PM
leonardchan requested review of this revision.Sep 30 2021, 3:30 PM
Herald added a project: Restricted Project. · View Herald TranscriptSep 30 2021, 3:30 PM
Herald added a subscriber: Restricted Project. · View Herald Transcript
pcc added a comment.Sep 30 2021, 4:08 PM

Please remember to upload patches with context: https://llvm.org/docs/Phabricator.html#requesting-a-review-via-the-web-interface

The tests in MemtagTests are meant to be skipped if the hardware doesn't support MTE (see the top of MemtagTest::SetUp()). Is that not working for you?

I don't think you should normally need to be defining SCUDO_DISABLE_TBI because it's controlled by the operating system, and all arm64 Linux systems that we normally care about support TBI. I figured that you were maybe trying to run these tests on Fuchsia, but then I noticed that memtag_test.cpp is wrapped in an #if SCUDO_LINUX, so I'm not sure why you're running into an issue. Are you trying to run these tests on arm64 non-Android Linux? Maybe the GTEST_SKIP() isn't working correctly for you for some reason?

compiler-rt/lib/scudo/standalone/memtag.h
21

Can we change this to:

#if (__clang_major__ >= 12 && defined(__aarch64__) && SCUDO_LINUX && !defined(SCUDO_DISABLE_TBI)) || defined(SCUDO_FUZZ)

and remove the #if on line 26 instead? (This is orthogonal to your issue though.)

Please remember to upload patches with context: https://llvm.org/docs/Phabricator.html#requesting-a-review-via-the-web-interface

The tests in MemtagTests are meant to be skipped if the hardware doesn't support MTE (see the top of MemtagTest::SetUp()). Is that not working for you?

I don't think you should normally need to be defining SCUDO_DISABLE_TBI because it's controlled by the operating system, and all arm64 Linux systems that we normally care about support TBI. I figured that you were maybe trying to run these tests on Fuchsia, but then I noticed that memtag_test.cpp is wrapped in an #if SCUDO_LINUX, so I'm not sure why you're running into an issue. Are you trying to run these tests on arm64 non-Android Linux? Maybe the GTEST_SKIP() isn't working correctly for you for some reason?

I'm attempting to run host-linux runtimes tests. We weren't running them before and this is the first time we're trying it. We just happen to run into these test failures when turning them on before. But I think I found out the underlying issue: prctl(PR_GET_TAGGED_ADDR_CTRL, 0, 0, 0, 0) (in systemDetectsMemoryTagFaultsTestOnly) can return -1 if TBI isn't supported according to https://man7.org/linux/man-pages/man2/prctl.2.html, and this seems to be the case for us. The -1 is cast to an unsigned long and masked, then systemDetectsMemoryTagFaultsTestOnly ends up returning true when comparing a non-zero value after masking. I think the proper fix might be to just account for the -1 result. I'll update the patch later.

pcc added a comment.Sep 30 2021, 6:06 PM

Please remember to upload patches with context: https://llvm.org/docs/Phabricator.html#requesting-a-review-via-the-web-interface

The tests in MemtagTests are meant to be skipped if the hardware doesn't support MTE (see the top of MemtagTest::SetUp()). Is that not working for you?

I don't think you should normally need to be defining SCUDO_DISABLE_TBI because it's controlled by the operating system, and all arm64 Linux systems that we normally care about support TBI. I figured that you were maybe trying to run these tests on Fuchsia, but then I noticed that memtag_test.cpp is wrapped in an #if SCUDO_LINUX, so I'm not sure why you're running into an issue. Are you trying to run these tests on arm64 non-Android Linux? Maybe the GTEST_SKIP() isn't working correctly for you for some reason?

I'm attempting to run host-linux runtimes tests. We weren't running them before and this is the first time we're trying it. We just happen to run into these test failures when turning them on before. But I think I found out the underlying issue: prctl(PR_GET_TAGGED_ADDR_CTRL, 0, 0, 0, 0) (in systemDetectsMemoryTagFaultsTestOnly) can return -1 if TBI isn't supported according to https://man7.org/linux/man-pages/man2/prctl.2.html, and this seems to be the case for us. The -1 is cast to an unsigned long and masked, then systemDetectsMemoryTagFaultsTestOnly ends up returning true when comparing a non-zero value after masking. I think the proper fix might be to just account for the -1 result. I'll update the patch later.

Ah, that could explain it. I don't think the issue is that TBI isn't supported (it's always been supported on Linux going back to 2013 or so), it's that the tagged address ABI isn't supported in your kernel. The support for the tagged address ABI was first introduced in kernel version 5.4, but it was backported quite far back on Android , so I guess we never noticed this issue because we never ran the tests on a machine that didn't have them backported. Checking for the -1 return value seems like the right fix to me, thanks.

leonardchan retitled this revision from [compiler-rt][scudo] Move !defined(SCUDO_DISABLE_TBI) check to [compiler-rt][scudo] Check for failing prctl call.
leonardchan edited the summary of this revision. (Show Details)
leonardchan added inline comments.Oct 4 2021, 11:15 AM
compiler-rt/lib/scudo/standalone/memtag.h
21

Made D111080 for this.

pcc accepted this revision.Oct 4 2021, 12:00 PM

LGTM

s/TBI/the tagged address ABI/ in the commit message.

This revision is now accepted and ready to land.Oct 4 2021, 12:00 PM
This revision was automatically updated to reflect the committed changes.