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

___str*_chk symbol(s) not found in any library kext #1

Closed
leiless opened this issue Dec 20, 2018 · 4 comments
Closed

___str*_chk symbol(s) not found in any library kext #1

leiless opened this issue Dec 20, 2018 · 4 comments
Assignees

Comments

@leiless
Copy link
Owner

leiless commented Dec 20, 2018

Make kext output snippet:

For x86_64:
2 symbols not found in any library kext:
___strlcpy_chk
___strncpy_chk

@leiless leiless self-assigned this Dec 20, 2018
@leiless
Copy link
Owner Author

leiless commented Dec 20, 2018

macOS 10.13+ kernel added _str*_chk() for all str*() family functions(Need reconfirm), which its corresponding header located in Kernel.framework/Headers/string.h

If you encountered above compile issue, it certainly indicates that your Command Line Tools version is byond current macOS version, so there're symbol-mismatch.

FIX: please visit More Downloads for Apple Developers and download correct version of Command Line Tools matchs your macOS version


In my case, I installed the brew(which it installed a bit high version of Command Line Tools) in macOS 10.12(16G29).

Check /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/SDKSettings.plist's MACOSX_DEPLOYMENT_TARGET


see: steven-michaud/HookCase#2

@leiless leiless changed the title __str*cpy_chk symbol(s) not found in any library kext ___str*cpy_chk symbol(s) not found in any library kext Dec 20, 2018
@leiless leiless changed the title ___str*cpy_chk symbol(s) not found in any library kext ___str*_chk symbol(s) not found in any library kext Dec 20, 2018
@leiless
Copy link
Owner Author

leiless commented Dec 21, 2018

HOWTO reproduce above missing symbol bug:

  1. Install brew in macOS(16G29), as it'll install Command Line Tools automatically

  2. Clone generic_kext project

  3. Inside example/ directory, create a .c file and put some code which uses str*():

#include <string.h>
#include <libkern/libkern.h>

void foobar(const char *s)
{
	char t[1024];
	strlcpy(t, s, strlen(s) >> 1); /* Uses str*() family function */
	printf(KEXTNAME_S ": %s\n", t);
}
  1. Make the example kext, you'll something like this:
For x86_64:
    1 symbol not found in any library kext:
	___strlcpy_chk

If you put the foobar() function into example.c solely(i.e. there is only one .c source), and recompile, the missing symbol bug disappeared. which is weird :-(

There must be something wrong with multiple-file compilation...

FYI:

$ sw_vers
ProductName:	Mac OS X
ProductVersion:	10.12.6
BuildVersion:	16G29

$ clang -v
Apple LLVM version 9.0.0 (clang-900.0.39.2)
Target: x86_64-apple-darwin16.7.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin

@leiless
Copy link
Owner Author

leiless commented Dec 21, 2018

I have a faint suspicious that there are some "critical" compile/load flags missing in Makefile

@leiless
Copy link
Owner Author

leiless commented Dec 21, 2018

Final solution:

As you check Kernel.framework/string.h, you will find the following code for macOS SDK >= 10.13

#if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_13
/* older deployment target */
#elif defined(KASAN) || (defined (_FORTIFY_SOURCE) && _FORTIFY_SOURCE == 0)
/* FORTIFY_SOURCE disabled */
#else /* _chk macros */
#if __has_builtin(__builtin___memcpy_chk)
/*
 * TL;DL
 */
#endif /* _chk macros */
#ifdef __cplusplus

You'll find that the control flow goes into the #else block
and #if __has_builtin(__builtin___*_chk) yields true

Thus you can use some dirty wordaround to dismiss __builtin___*_chk

Solutions:

  1. Add -D_FORTIFY_SOURCE=0 to Makefile CPPFLAGS

  2. Add -DKASAN to Makefile CPPFLAGS. FYI, KASAN stands for Kernel Address SANitizer

  3. [BAD] Add -D__MAC_OS_X_VERSION_MIN_REQUIRED=XXXXXX to Makefile CPPFLAGS
    For example, in my case, macOS 10.12.6(16G29), it's 101206
    see: <Kernel.framework/Availability.h>


Solution 3 is not applicable, the macro __MAC_OS_X_VERSION_MIN_REQUIRED is use by Kernel.framework internally

In file included from /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks/Kernel.framework/Headers/Availability.h:202:
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks/Kernel.framework/Headers/AvailabilityInternal.h:27141:13: warning: 
      '__MAC_OS_X_VERSION_MIN_REQUIRED' macro redefined [-Wmacro-redefined]
    #define __MAC_OS_X_VERSION_MIN_REQUIRED __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__
            ^
<command line>:7:9: note: previous definition is here
#define __MAC_OS_X_VERSION_MIN_REQUIRED 101206
        ^
1 warning generated.

see:
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks/Kernel.framework/Versions/A/Headers

leiless added a commit that referenced this issue Dec 22, 2018
@leiless leiless closed this as completed Dec 24, 2018
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

1 participant