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

Compiling C program with zig cc with FORTIFY_SOURCE enabled leads to linking issue when building against < 2.38 glibc version #21252

Closed
FedeDP opened this issue Aug 30, 2024 · 3 comments · Fixed by #21253
Labels
bug Observed behavior contradicts documented or intended behavior
Milestone

Comments

@FedeDP
Copy link
Contributor

FedeDP commented Aug 30, 2024

Zig Version

0.13.0

Steps to Reproduce and Observed Behavior

Source file:

#include <string.h>
int main(void) { 
  char s[10]; strlcpy(s, "foo", sizeof(s)); 
  return 0; 
}

zig cc test.c -o test -D_FORTIFY_SOURCE=2 -D_GNU_SOURCE -O2 leads to OK compilation (using glibc 2.38).

Targeting instead eg: glibc 2.17 leads to issue:

zig cc -target x86_64-linux-gnu.2.17 test.c -o test -D_FORTIFY_SOURCE=2 -D_GNU_SOURCE -O2
ld.lld: error: undefined symbol: __strlcpy_chk
>>> referenced by string_fortified.h:156 (zig/zig-linux-x86_64-0.13.0/lib/libc/include/generic-glibc/bits/string_fortified.h:156)
>>>               test.lto.o:(main)
>>> did you mean: __strncpy_chk
>>> defined in: /home/federico/.cache/zig/o/6d6ed7dfa74bdd6b9de1e0f01ec3621d/libc.so.6

But the strlcpy symbol is actually found (it complains that strlcpy calls __strncpy_chk that is not defined).

This is hitting us because, as many projects, we have a cmake check around strlcpy, like:

include(CheckSymbolExists)
check_symbol_exists(strlcpy "string.h" HAVE_STRLCPY)

and this is failing when building against glibc 2.17, of course; follows that our own internal strlcpy implementation gets compiled, but <string.h> header still exposes the strlcpy prototype, leading to a redefinition error.
Relevant bits:

  • <string.h>:
#if __GNUC_PREREQ (3,4)
# if __USE_FORTIFY_LEVEL > 0 && defined __fortify_function
/* Functions with security checks.  */
#  include <bits/string_fortified.h>
# endif
#endif
  • <bits/string_fortified.h>
extern size_t __strlcpy_chk (char *__dest, const char *__src, size_t __n,
			     size_t __destlen) __THROW;
extern size_t __REDIRECT_NTH (__strlcpy_alias,
			      (char *__dest, const char *__src, size_t __n),
			      strlcpy);

__fortify_function size_t
__NTH (strlcpy (char *__restrict __dest, const char *__restrict __src,
		size_t __n))
{
  if (__glibc_objsize (__dest) != (size_t) -1
      && (!__builtin_constant_p (__n > __glibc_objsize (__dest))
	  || __n > __glibc_objsize (__dest)))
    return __strlcpy_chk (__dest, __src, __n, __glibc_objsize (__dest));
  return __strlcpy_alias (__dest, __src, __n);
}

My (super wild) guess is that the declaration in string_fortified.h must still be surrounded by the

#if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 38) || __GLIBC__ > 2

check.

Indeed, patching <bits/string_fortified.h> adding the surrounding guard, properly gives the expected error:

zig cc -target x86_64-linux-gnu.2.17 test.c -o test -D_FORTIFY_SOURCE=2 -O2 -D_GNU_SOURCE
test.c:3:15: error: call to undeclared library function 'strlcpy' with type 'unsigned long (char *, const char *, unsigned long)'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
    3 |   char s[10]; strlcpy(s, "foo", sizeof(s)); 
      |               ^
test.c:3:15: note: include the header <string.h> or explicitly provide a declaration for 'strlcpy'
1 error generated.

since strlcpy was added to glibc 2.38.

Expected Behavior

I'd expect that no strlcpy / strlcat prototype is included via <string.h> on glibc <2.38 versions, since they were not existing, even with _FORTIFY_SOURCE enabled.

@FedeDP FedeDP added the bug Observed behavior contradicts documented or intended behavior label Aug 30, 2024
@alexrp
Copy link
Member

alexrp commented Aug 30, 2024

My (super wild) guess is that the declaration in string_fortified.h must still be surrounded by the

That sounds right to me.

@FedeDP
Copy link
Contributor Author

FedeDP commented Aug 30, 2024

I can make a PR for that, if you agree ;)

@FedeDP
Copy link
Contributor Author

FedeDP commented Aug 30, 2024

Done; hopefully my commit message is good enough, otherwise i can amend.

@Vexu Vexu added this to the 0.14.0 milestone Aug 30, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Observed behavior contradicts documented or intended behavior
Projects
None yet
3 participants