-
Notifications
You must be signed in to change notification settings - Fork 265
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
Can we prefix compat symbols to avoid symbol clashes in static links? #928
Comments
I wonder if we can do something like this in the various compat headers: #ifndef HAVE_ARC4RANDOM
#define arc4random _libressl_arc4random
uint32_t arc4random(void);
#endif This way we don't need to litter the main source code with prefixes and the symbols should no longer leak out of the libraries, even with static linking. |
autotools unexpectedly detects `arc4random` because it is also looking into dependency libs. One dependency, LibreSSL, happens to publish an `arc4random` function (via its shared lib before v3.7, also via static lib as of v3.8.2). When trying to use this function in `lib/rand.c`, its protoype is missing. To fix that, curl included a prototype, but that used a C99 type without including `stdint.h`, causing: ``` ../../lib/rand.c:37:1: error: unknown type name 'uint32_t' 37 | uint32_t arc4random(void); | ^ 1 error generated. ``` This patch improves this by dropping the local prototype and instead limiting `arc4random` use for non-OpenSSL builds. OpenSSL builds provide their own random source anyway. The better fix would be to teach autotools to not link dependency libs while detecting `arc4random`. LibreSSL publishing a non-namespaced `arc4random` tracked here: libressl/portable#928 Regression from 755ddbe curl#10672 Fixes curl#12257 Closes #xxxxx
autotools unexpectedly detects `arc4random` because it is also looking into dependency libs. One dependency, LibreSSL, happens to publish an `arc4random` function (via its shared lib before v3.7, also via static lib as of v3.8.2). When trying to use this function in `lib/rand.c`, its protoype is missing. To fix that, curl included a prototype, but that used a C99 type without including `stdint.h`, causing: ``` ../../lib/rand.c:37:1: error: unknown type name 'uint32_t' 37 | uint32_t arc4random(void); | ^ 1 error generated. ``` This patch improves this by dropping the local prototype and instead limiting `arc4random` use for non-OpenSSL builds. OpenSSL builds provide their own random source anyway. The better fix would be to teach autotools to not link dependency libs while detecting `arc4random`. LibreSSL publishing a non-namespaced `arc4random` tracked here: libressl/portable#928 Regression from 755ddbe #10672 Reviewed-by: Daniel Stenberg Fixes #12257 Closes #12274
Is it really only the arc4random that becomes a problem here now that some systems have it? |
On Fri, Nov 10, 2023 at 06:11:19AM -0800, Bob Beck wrote:
Is it really only the arc4random that becomes a problem here now that some systems have it?
All compat symbols are a problem. And there may be internal symbols that
could also potentially clash.
|
Another non-prefixed symbol,
The workaround for that is to suppress detection with
https://github.com/curl/curl-for-win/actions/runs/7159857921/job/19493576239#step:3:3226
https://github.com/curl/curl-for-win/actions/runs/7159857921/job/19493576239#step:3:5300 |
The point of this issue is that all compat symbols should be prefixed. The problem is that the Windows API needs to be dealt with by someone familiar with it. I sent @busterb what I have. It will happen at some point. Regarding 2, for strtonum, a stanza like for strsep should be added to I'm not sure what to make of the first and the third problem. Both seem unrelated to this issue? |
I believe all these are related to re-using existing symbol names. It isn't Windows-specific either. In case of This can only be fixed by building without In summary, in case of [1]: check_function_exists(strtonum HAVE_STRTONUM)
if(HAVE_STRTONUM)
add_definitions(-DHAVE_STRTONUM)
endif()
|
I understand that your problem isn't Windows-specific. What I'm saying is that the reason this issue isn't moving forward is Windows-specific. Otherwise I think we conflate two independent issues:
|
If it helps, here's what I currently have for the prefixing: diff --git a/include/compat/stdio.h b/include/compat/stdio.h
index d5725c9..4ddd63a 100644
--- a/include/compat/stdio.h
+++ b/include/compat/stdio.h
@@ -20,7 +20,9 @@
#ifndef HAVE_ASPRINTF
#include <stdarg.h>
+#define vasprintf libressl_vasprintf
int vasprintf(char **str, const char *fmt, va_list ap);
+#define asprintf libressl_asprintf
int asprintf(char **str, const char *fmt, ...);
#endif
diff --git a/include/compat/stdlib.h b/include/compat/stdlib.h
index 2eaea24..76dc07c 100644
--- a/include/compat/stdlib.h
+++ b/include/compat/stdlib.h
@@ -20,26 +20,36 @@
#include <stdint.h>
#ifndef HAVE_ARC4RANDOM_BUF
+#define arc4random libressl_arc4random
uint32_t arc4random(void);
+#define arc4random_buf libressl_arc4random_buf
void arc4random_buf(void *_buf, size_t n);
+#define arc4random_uniform libressl_arc4random_uniform
uint32_t arc4random_uniform(uint32_t upper_bound);
#endif
#ifndef HAVE_FREEZERO
+#define freezero libressl_freezero
void freezero(void *ptr, size_t sz);
#endif
#ifndef HAVE_GETPROGNAME
+#define getprogname libressl_getprogname
const char * getprogname(void);
#endif
+#ifndef HAVE_REALLOCARRAY
+#define reallocarray libressl_reallocarray
void *reallocarray(void *, size_t, size_t);
+#endif
#ifndef HAVE_RECALLOCARRAY
+#define recallocarray libressl_recallocarray
void *recallocarray(void *, size_t, size_t, size_t);
#endif
#ifndef HAVE_STRTONUM
+#define strtonum libressl_strtonum
long long strtonum(const char *nptr, long long minval,
long long maxval, const char **errstr);
#endif
diff --git a/include/compat/string.h b/include/compat/string.h
index 4bf7519..7e0245a 100644
--- a/include/compat/string.h
+++ b/include/compat/string.h
@@ -27,43 +27,54 @@
#endif
#ifndef HAVE_STRCASECMP
+#define strcasecmp libressl_strcasecmp
int strcasecmp(const char *s1, const char *s2);
+#define strncasecmp libressl_strncasecmp
int strncasecmp(const char *s1, const char *s2, size_t len);
#endif
#ifndef HAVE_STRLCPY
+#define strlcpy libressl_strlcpy
size_t strlcpy(char *dst, const char *src, size_t siz);
#endif
#ifndef HAVE_STRLCAT
+#define strlcat libressl_strlcat
size_t strlcat(char *dst, const char *src, size_t siz);
#endif
#ifndef HAVE_STRNDUP
+#define strndup libressl_strndup
char * strndup(const char *str, size_t maxlen);
/* the only user of strnlen is strndup, so only build it if needed */
#ifndef HAVE_STRNLEN
+#define strnlen libressl_strnlen
size_t strnlen(const char *str, size_t maxlen);
#endif
#endif
#ifndef HAVE_STRSEP
+#define strsep libressl_strsep
char *strsep(char **stringp, const char *delim);
#endif
#ifndef HAVE_EXPLICIT_BZERO
+#define explicit_bzero libressl_explicit_bzero
void explicit_bzero(void *, size_t);
#endif
#ifndef HAVE_TIMINGSAFE_BCMP
+#define timingsafe_bcmp libressl_timingsafe_bcmp
int timingsafe_bcmp(const void *b1, const void *b2, size_t n);
#endif
#ifndef HAVE_TIMINGSAFE_MEMCMP
+#define timingsafe_memcmp libressl_timingsafe_memcmp
int timingsafe_memcmp(const void *b1, const void *b2, size_t len);
#endif
#ifndef HAVE_MEMMEM
+#define memmem libressl_memmem
void * memmem(const void *big, size_t big_len, const void *little,
size_t little_len);
#endif |
Got it, though I'm missing which Windows API-issue is holding this back?
|
@botovq Thanks for that! It should fix all the problems around this. This macOS test run confirms it fixing the warnings and symbol leak: Compared to this: If this can make it to the next release, we might also address the CMake detection --- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -234,6 +234,11 @@ if(HAVE_STRSEP)
add_definitions(-DHAVE_STRSEP)
endif()
+check_function_exists(strtonum HAVE_STRTONUM)
+if(HAVE_STRTONUM)
+ add_definitions(-DHAVE_STRTONUM)
+endif()
+
check_function_exists(timegm HAVE_TIMEGM)
if(HAVE_TIMEGM)
add_definitions(-DHAVE_TIMEGM) |
See libressl#928. This isn't a full fix, but should remove much of the friction already.
Notice that just like in autotools, this detection also doesn't take into account the targeted OS version. Meaning it detects `strtonum` even if targeting a macOS older than release v11 Big Sur (which introduced this), if the SDK declares it. Ref: libressl#928 (comment) Ref: libressl#928 (comment) Prerequisite: libressl#928 (comment)
Notice that just like in autotools, this detection also doesn't take into account the targeted OS version. Meaning it detects `strtonum` even if targeting e.g. macOS older than release v11 Big Sur (which introduced this funcitions), if the SDK declares it. Wrong detection will either cause a binary broken on older macOS and/or trigger compiler warnings. Ref: libressl#928 (comment) Ref: libressl#928 (comment) Prerequisite: libressl#928 (comment)
@vszakats many thanks for your help. #961 can be merged once it's approved by a member of the project, and then we can merge #963, too. The remaining symbols can be taken care of later.
It's not a specific API, but it will have to be done by someone familiar enough with Windows to understand the complications in the compat layer. It is very foreign to me. |
Thanks @botovq! Looking forward for these. In the meantime if you have any specific pointer about Windows-specific compat layer complications, I'd be glad reading into it. |
The first thing to untangle probably is |
|
See libressl#928. This isn't a full fix, but should remove much of the friction already.
Notice that just like in autotools, this detection also doesn't take into account the targeted OS version. Meaning it detects `strtonum` even if targeting e.g. macOS older than release v11 Big Sur (which introduced this funcitions), if the SDK declares it. Wrong detection will either cause a binary broken on older macOS and/or trigger compiler warnings. Ref: libressl#928 (comment) Ref: libressl#928 (comment) Prerequisite: libressl#928 (comment)
Notice that just like in autotools, this detection also doesn't take into account the targeted OS version. Meaning it detects `strtonum` even if targeting e.g. macOS older than release v11 Big Sur (which introduced this funcitions), if the SDK declares it. Wrong detection will either cause a binary broken on older macOS and/or trigger compiler warnings. Ref: libressl#928 (comment) Ref: libressl#928 (comment) Prerequisite: libressl#928 (comment)
While we no longer export the compat symbols from the dynamic libraries, there is still an issue with static linking, see e.g., curl/curl#12257
Can we leverage a trick like the one used in the hidden directories to prefix these symbols transparently?
The text was updated successfully, but these errors were encountered: