-
Notifications
You must be signed in to change notification settings - Fork 10.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[ASAN] Adjust asan instrumented GlobalVariable size to not include redzone #66666
base: main
Are you sure you want to change the base?
Conversation
462b35a
to
9f01af0
Compare
9f01af0
to
3ca9d8c
Compare
Clang codegen seems to add the SanitizerMetadata for globals, but when asan pass is run, some globals seems to have lost that. So I'm checking in asan pass if globals hasSanitizerMetadata() and if not present, adding one, with NoAddress set to false. |
@@ -2445,6 +2445,11 @@ bool ModuleAddressSanitizer::InstrumentGlobals(IRBuilder<> &IRB, Module &M, | |||
// zero so we can copy the metadata over as is. | |||
NewGlobal->copyMetadata(G, 0); | |||
|
|||
// Set sanitizer metadata for newly created global, | |||
// if it doesn't have it. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we comment here that this may be a workaround for metadata lost between front end and this instrumentation pass?
@@ -2445,6 +2445,11 @@ bool ModuleAddressSanitizer::InstrumentGlobals(IRBuilder<> &IRB, Module &M, | |||
// zero so we can copy the metadata over as is. | |||
NewGlobal->copyMetadata(G, 0); | |||
|
|||
// Set sanitizer metadata for newly created global, | |||
// if it doesn't have it. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Clang codegen seems to add the SanitizerMetadata for globals, but when asan pass is run, some globals seems to have lost that. So I'm checking in asan pass if globals hasSanitizerMetadata() and if not present, adding one, with NoAddress set to false.
This is used in AsmPrinter, to identify the asan instrumented globals with padded redzones.
Sorry if I'm asking a naive question, but doesn't changing .size for the globals remove the redzone space that is needed? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
memtag test is not for Asan,
This change looks suspicious. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, clang/test/CodeGen/memtag-globals-asm.cpp
is for MTE Globals, not ASan - and the sizes of the GVs should be multiple-of-16 bytes: https://github.com/ARM-software/abi-aa/blob/main/memtagabielf64/memtagabielf64.rst#compilation
What problem are you trying to solve here?
ASAN pass identifies the global variables that needs to be instrumented and replaces them with new globals with size equal to actual size + redzone size. To identify such instrumented global variables, added SanitizerMetadata to the new global, which will have NoAddress set to false(which implies asan instrumented global). At asm printer stage, such gloabal would be identified and actual value without redzone size would be emitted. This change was done under assumption that any target would only want the actual size of global in the elf and not the padded size. AMDGPU needs this change. Please let me know if it causes issue with other targets? |
Under MTE globals (not asan, but the test you're changing in memtag-globals-asm.cpp), there are no redzones - the round-to-16-byte size is what we want to be in the ELF. Copying the sanitizer metadata over seems fine, but reusing Also, to the premise, why is ANDGPU unhappy about having the sizeof(GV) == global+redzone in the ELF? |
The reason this is a problem is that AMD language runtimes provide queries for the size of device global symbols, and functions to copy data to and from device global variables. The runtime gets the needed information form the ELF symbol table. This approach works fine when the ELF size reflects the actual size of the variable. But when it reflects the instrumented size of the variable then it causes problems, e.g. reading from the poisoned redzone. In general it doesn't seem like instrumentation should have such an effect. |
@hctim, |
@hctim,
Please let me know if any of these approaches work here? |
My gut feeling is that it's a really bad idea to have a global variable whose symtab size differs from the underlying GV size. So I tested against lld, gold, and ld, and they all seem to end up with
I suspect this could break relinkers and various other things. It doesn't seem clear to me why amdgpu has problems with copying the extra redzone padding. We may also actually use the redzone for metadata and would expect that it would be consistent. |
@hctim any implementation will have a problem when copying the redzone padding. That is simply because the redzone is poisoned (hence the name). Any access to a poisoned location will be reported and the application terminated. That is how ASAN works. |
My assumption is that you have some driver code or preloaded DSO that effectively implements Can you just make your driver not be asan-ified (either by not building it with This seems like a more appropriate thing than making |
@hctim as far as I'm concerned, the symbol is already not the right size. The right size of a global variable of type float is 4, not 32. And disabling ASAN checking in the copy mechanism would reduce the usefulness of the address sanitizer. But I take your point about linker optimizations. We are looking at alternatives. |
Add SanitizerMetadata to instrumented GlobalVariables if not present. This is used by AsmPrinter to identify the globals which are instrumented and only emit the actual size without the redzones.