Skip to content
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

Crash on macOS (EXC_BAD_ACCESS (Code Signature Invalid)) #1309

Closed
pwardle opened this issue Jun 17, 2020 · 1 comment
Closed

Crash on macOS (EXC_BAD_ACCESS (Code Signature Invalid)) #1309

pwardle opened this issue Jun 17, 2020 · 1 comment

Comments

@pwardle
Copy link

pwardle commented Jun 17, 2020

tl;dr macOS may forcefully terminate a process when scanning a file, due to code signing issues of the file. To fix, mmap should be called with MAP_RESILIENT_CODESIGN

In filemap.c, function yr_filemap_map_fd a file to scan is mapped in via mmap:

pmapped_file->data = (const uint8_t*) mmap(
        0,
        pmapped_file->size,
        PROT_READ,
        MAP_PRIVATE,
        pmapped_file->file,
        offset);

For reasons yet to be understood, occasional when scanning certain mach-O binaries, macOS decides that the code-signature of this readonly (PROT_READ) mapping of the file should be validated, before the bytes in the mapping can be read (scanned). In this situation, if the file being scanned doesn't have a valid signature, when the scanner then attempts to read the mapped bytes, macOS freaks and kills the process with EXC_BAD_ACCESS (Code Signature Invalid).

I was able to reproduce this locally in the following (external) proof of concept, that simply maps a file (in the same manner as Yara), then attempts to read said bytes:

//note: path is the path to file to scan
//         size is the size of the file to scan
int fd = open(path, O_RDONLY);
void* bytes = mmap(0, size, PROT_READ, MAP_PRIVATE, fd, 0);
printf("bytes at %p: %x\n\n", bytes, *(unsigned int*)bytes);

When run compiled (with the hardened-runtime enabled) certain files cause macOS to terminate the process, when the bytes in the mapping are accessed (i.e. *(unsigned int*)bytes):

$ ./poc ~/Downloads/test
Killed: 9

Exception Type:        EXC_BAD_ACCESS (Code Signature Invalid)
Exception Codes:       0x0000000000000032, 0x000000010e688000
Exception Note:        EXC_CORPSE_NOTIFY

Termination Reason:    Namespace CODESIGNING, Code 0x2

Note, only the scanning (more specifically the mapping of) certain files will trigger this behavior.
One such file is the mas binary (https://github.com/mas-cli/mas).

Clearly, it seems silly for macOS to validate the code-signature of read-only mappings. As such a bug report will be filed with Apple as well.

Reversing Apple's private Yara library (/System/Library/PrivateFrameworks/yara.framework/yara) reveals they call mmap with the (macOS-specific) MAP_RESILIENT_CODESIGN flag. Adding this flag to our PoC, instructs macOS to ignore code-signing "failures", and ensures scanning can commence as expected (i.e. no crash!).

void* bytes = mmap(0, size, PROT_READ, MAP_PRIVATE|MAP_RESILIENT_CODESIGN, fd, 0);

As such, it is suggested that this flag is added to (macOS-builds) of Yara :)

Related: "LLVM: Adopt mmap flags that allow mmap'ed memory to be less crash prone."

@plusvic
Copy link
Member

plusvic commented Jun 18, 2020

Interesting stuff, and a very complete bug report!

tarterp pushed a commit to mandiant/yara that referenced this issue Mar 31, 2022
… MacOS.

These flags prevent crashes while reading from memory-mapped files in MacOS. MAP_RESILIENT_MEDIA prevents crashes while reading from a file in removable media that becomes unavailable, while MAP_RESILIENT_CODESIGN prevents crashes when reading binaries whose digital signature is invalid.

Closes VirusTotal#1309
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants