"Funny" issue with strlcpy in kernel extension at build time

Let's say that a kernel extension Xcode project is set to build with a target deployment of 10.9 and is built using Xcode 10.x on macOS Mojave.


Let's say that in the project there is a header and a source that does this:


somefile.h


#include <sys/types.h>


#include <sys/kern_control.h>


extern void doSomething(void);


somefile.c


#include "file.h"


#include <libkern/libkern.h>


void doSomething(void)

{

struct kern_ctl_reg tKernelControlStruct;


strlcpy(tKernelControlStruct.ctl_name,"inc.acme.coyote.evil", MAX_KCTL_NAME);

}


o At build time strlcpy is replaced by __builtin___strlcpy_chk. Which is not the expected outcome. Which causes issues on 10.9 since the *_strlcpy_chk symbol does not exist.


o In the string.h header of the Kernel framework, strlcpy is supposed to be replaced when the min OS required is 10.13.


From what I'm observing the __MAC_OS_X_VERSION_MIN_REQUIRED macro is not defined. Shouldn't it be?


Question:


How do you make sure it is defined?

Replies

That is weird. The first thing I’d do

#undef
the macro to confirm that it is the macro that’s causing the problem. After that, I’d check why the deployment target check is resolving incorrectly.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

There are 2 cases:


- in some cases, strlcpy is colored as a macro by Xcode source editor and, when you jump to its definition, you are seeing the macro switching strlcpy for the strlcyp_chk version.

- in other cases, strlcpy is colored as a function and when you jump to its definition, you are seing the function prototype.


I tried to check with the preprocessor whether the __MAC_OS_X_VERSION_MIN_REQUIRED macro was defined before the call to strlcpy, it is with the correct value 1090.


I tried including the availibility macros just in case. No success.


I had a few moments where I thought I had found the origin of the issue but this only solved the issue in specific cases without any sound logic:


- removing #include <string.h> solved the issue for some files (I thought this was pointing to the userland API but it was correctly pointing to the Kernel framework API and I later found out that libkern.h includes string.h).

- making sure that #include "file.h" is before #include <libkern/libkern.h> solved the issues for other files. (I thought this was working because the macro was correctly defined for project files and not for SDK files).

It looks like that adding #include <Availability.h> before #include <string.h> solves the issue and this makes sense.


I checked the 10.11 SDK and the Macros to replace strlcpy are missing.


So I would tend to believe there is an issue in the Kernel framework headers in the 10.14 and 10.15 SDKs (maybe the 10.13 one too) as string.h should directly or indirectly include Availability.h so that the __MAC_OS_X_VERSION_MIN_REQUIRED gets defined from the __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ which is correctly defined from what I'm seeing in the preprocess output.