Skip to content

Commit 027d976

Browse files
authored
dlopen(NULL) returns NULL on static linked executable (#215)
1 parent fa108de commit 027d976

File tree

2 files changed

+115
-33
lines changed

2 files changed

+115
-33
lines changed

.github/workflows/ci.yml

Lines changed: 49 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ on:
66
- 'main'
77

88
env:
9-
BUILDER_VERSION: v0.9.72
9+
BUILDER_VERSION: v0.9.79
1010
BUILDER_SOURCE: releases
1111
BUILDER_HOST: https://d19elf31gohf1l.cloudfront.net
1212
PACKAGE_NAME: aws-c-cal
@@ -136,7 +136,7 @@ jobs:
136136
linux-openssl3-static:
137137
runs-on: ubuntu-24.04 # latest
138138
steps:
139-
- uses: aws-actions/configure-aws-credentials@v4
139+
- uses: aws-actions/configure-aws-credentials@v4
140140
with:
141141
role-to-assume: ${{ env.CRT_CI_ROLE }}
142142
aws-region: ${{ env.AWS_DEFAULT_REGION }}
@@ -149,7 +149,7 @@ jobs:
149149
linux-openssl-shared:
150150
runs-on: ubuntu-24.04 # latest
151151
steps:
152-
- uses: aws-actions/configure-aws-credentials@v4
152+
- uses: aws-actions/configure-aws-credentials@v4
153153
with:
154154
role-to-assume: ${{ env.CRT_CI_ROLE }}
155155
aws-region: ${{ env.AWS_DEFAULT_REGION }}
@@ -171,20 +171,51 @@ jobs:
171171
linux-aws-lc-fips:
172172
runs-on: ubuntu-24.04 # latest
173173
steps:
174-
- uses: aws-actions/configure-aws-credentials@v4
174+
- uses: aws-actions/configure-aws-credentials@v4
175175
with:
176176
role-to-assume: ${{ env.CRT_CI_ROLE }}
177177
aws-region: ${{ env.AWS_DEFAULT_REGION }}
178178
# We can't use the `uses: docker://image` version yet, GitHub lacks authentication for actions -> packages
179179
- name: Build ${{ env.PACKAGE_NAME }}
180180
run: |
181181
python -c "from urllib.request import urlretrieve; urlretrieve('${{ env.BUILDER_HOST }}/${{ env.BUILDER_SOURCE }}/${{ env.BUILDER_VERSION }}/builder.pyz?run=${{ env.RUN }}', 'builder.pyz')"
182-
AWS_TEST_FIPS=1 python builder.pyz build -p ${{ env.PACKAGE_NAME }} --variant=aws-lc-fips --cmake-extra=-DFIPS=ON --cmake-extra=-DPERL_EXECUTABLE=perl --cmake-extra=-DGO_EXECUTABLE=go --cmake-extra=-DCMAKE_POLICY_VERSION_MINIMUM=3.5
182+
AWS_TEST_FIPS=1 python builder.pyz build -p ${{ env.PACKAGE_NAME }} --variant=aws-lc-fips --cmake-extra=-DFIPS=ON --cmake-extra=-DPERL_EXECUTABLE=perl --cmake-extra=-DGO_EXECUTABLE=go --cmake-extra=-DCMAKE_POLICY_VERSION_MINIMUM=3.5
183+
184+
linux-musl:
185+
runs-on: ${{ matrix.architecture == 'arm' && 'ubuntu-24.04-arm' || 'ubuntu-24.04' }}
186+
strategy:
187+
matrix:
188+
include:
189+
# x64 builds
190+
- architecture: x64
191+
image: alpine-3.16-x64
192+
static: false
193+
- architecture: x64
194+
image: alpine-3.16-x64
195+
static: true
196+
# arm builds
197+
- architecture: arm
198+
image: alpine-3.16-arm64
199+
static: false
200+
- architecture: arm
201+
image: alpine-3.16-arm64
202+
static: true
203+
steps:
204+
- uses: aws-actions/configure-aws-credentials@v4
205+
with:
206+
role-to-assume: ${{ env.CRT_CI_ROLE }}
207+
aws-region: ${{ env.AWS_DEFAULT_REGION }}
208+
role-duration-seconds: 3600
209+
- name: Build ${{ env.PACKAGE_NAME }} ${{ matrix.static && '(static)' || '' }}
210+
run: |
211+
aws s3 cp s3://aws-crt-test-stuff/ci/${{ env.BUILDER_VERSION }}/linux-container-ci.sh ./linux-container-ci.sh && chmod a+x ./linux-container-ci.sh
212+
./linux-container-ci.sh ${{ env.BUILDER_VERSION }} aws-crt-${{ matrix.image }} build -p ${{ env.PACKAGE_NAME }} ${{ matrix.static && '--cmake-extra=-DCMAKE_C_FLAGS="-static"' || '' }}
213+
183214
184215
windows:
185216
runs-on: windows-2022 # latest
186217
steps:
187-
- uses: aws-actions/configure-aws-credentials@v4
218+
- uses: aws-actions/configure-aws-credentials@v4
188219
with:
189220
role-to-assume: ${{ env.CRT_CI_ROLE }}
190221
aws-region: ${{ env.AWS_DEFAULT_REGION }}
@@ -197,7 +228,7 @@ jobs:
197228
runs-on: windows-2022 # latest
198229
steps:
199230
- uses: ilammy/setup-nasm@v1
200-
- uses: aws-actions/configure-aws-credentials@v4
231+
- uses: aws-actions/configure-aws-credentials@v4
201232
with:
202233
role-to-assume: ${{ env.CRT_CI_ROLE }}
203234
aws-region: ${{ env.AWS_DEFAULT_REGION }}
@@ -209,7 +240,7 @@ jobs:
209240
windows-debug:
210241
runs-on: windows-2022 # latest
211242
steps:
212-
- uses: aws-actions/configure-aws-credentials@v4
243+
- uses: aws-actions/configure-aws-credentials@v4
213244
with:
214245
role-to-assume: ${{ env.CRT_CI_ROLE }}
215246
aws-region: ${{ env.AWS_DEFAULT_REGION }}
@@ -224,7 +255,7 @@ jobs:
224255
matrix:
225256
arch: [x86, x64]
226257
steps:
227-
- uses: aws-actions/configure-aws-credentials@v4
258+
- uses: aws-actions/configure-aws-credentials@v4
228259
with:
229260
role-to-assume: ${{ env.CRT_CI_ROLE }}
230261
aws-region: ${{ env.AWS_DEFAULT_REGION }}
@@ -236,7 +267,7 @@ jobs:
236267
windows-shared-libs:
237268
runs-on: windows-2022 # latest
238269
steps:
239-
- uses: aws-actions/configure-aws-credentials@v4
270+
- uses: aws-actions/configure-aws-credentials@v4
240271
with:
241272
role-to-assume: ${{ env.CRT_CI_ROLE }}
242273
aws-region: ${{ env.AWS_DEFAULT_REGION }}
@@ -248,7 +279,7 @@ jobs:
248279
windows-app-verifier:
249280
runs-on: windows-2022 # latest
250281
steps:
251-
- uses: aws-actions/configure-aws-credentials@v4
282+
- uses: aws-actions/configure-aws-credentials@v4
252283
with:
253284
role-to-assume: ${{ env.CRT_CI_ROLE }}
254285
aws-region: ${{ env.AWS_DEFAULT_REGION }}
@@ -267,7 +298,7 @@ jobs:
267298
name: ${{ matrix.image == 'macos-14' && 'macos' || 'macos-x64' }}
268299
runs-on: ${{ matrix.image }}
269300
steps:
270-
- uses: aws-actions/configure-aws-credentials@v4
301+
- uses: aws-actions/configure-aws-credentials@v4
271302
with:
272303
role-to-assume: ${{ env.CRT_CI_ROLE }}
273304
aws-region: ${{ env.AWS_DEFAULT_REGION }}
@@ -284,7 +315,7 @@ jobs:
284315
name: ${{ matrix.image == 'macos-14' && 'macos' || 'macos-x64' }} with lc ed25519
285316
runs-on: ${{ matrix.image }}
286317
steps:
287-
- uses: aws-actions/configure-aws-credentials@v4
318+
- uses: aws-actions/configure-aws-credentials@v4
288319
with:
289320
role-to-assume: ${{ env.CRT_CI_ROLE }}
290321
aws-region: ${{ env.AWS_DEFAULT_REGION }}
@@ -297,7 +328,7 @@ jobs:
297328
macos-min-deployment-target:
298329
runs-on: macos-14 # latest
299330
steps:
300-
- uses: aws-actions/configure-aws-credentials@v4
331+
- uses: aws-actions/configure-aws-credentials@v4
301332
with:
302333
role-to-assume: ${{ env.CRT_CI_ROLE }}
303334
aws-region: ${{ env.AWS_DEFAULT_REGION }}
@@ -310,7 +341,7 @@ jobs:
310341
freebsd:
311342
runs-on: ubuntu-24.04 # latest
312343
steps:
313-
- uses: aws-actions/configure-aws-credentials@v4
344+
- uses: aws-actions/configure-aws-credentials@v4
314345
with:
315346
role-to-assume: ${{ env.CRT_CI_ROLE }}
316347
aws-region: ${{ env.AWS_DEFAULT_REGION }}
@@ -331,7 +362,7 @@ jobs:
331362
openbsd:
332363
runs-on: ubuntu-24.04 # latest
333364
steps:
334-
- uses: aws-actions/configure-aws-credentials@v4
365+
- uses: aws-actions/configure-aws-credentials@v4
335366
with:
336367
role-to-assume: ${{ env.CRT_CI_ROLE }}
337368
aws-region: ${{ env.AWS_DEFAULT_REGION }}
@@ -354,7 +385,7 @@ jobs:
354385
downstream:
355386
runs-on: ubuntu-24.04 # latest
356387
steps:
357-
- uses: aws-actions/configure-aws-credentials@v4
388+
- uses: aws-actions/configure-aws-credentials@v4
358389
with:
359390
role-to-assume: ${{ env.CRT_CI_ROLE }}
360391
aws-region: ${{ env.AWS_DEFAULT_REGION }}
@@ -367,7 +398,7 @@ jobs:
367398
byo-crypto:
368399
runs-on: ubuntu-24.04 # latest
369400
steps:
370-
- uses: aws-actions/configure-aws-credentials@v4
401+
- uses: aws-actions/configure-aws-credentials@v4
371402
with:
372403
role-to-assume: ${{ env.CRT_CI_ROLE }}
373404
aws-region: ${{ env.AWS_DEFAULT_REGION }}

source/unix/openssl_platform_init.c

Lines changed: 66 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,32 @@ static struct aws_allocator *s_libcrypto_allocator = NULL;
3838
* and avoid dead-stripping
3939
*/
4040
#if defined(OPENSSL_IS_AWSLC) || defined(OPENSSL_IS_BORINGSSL)
41+
/* TODO:the weak refs is not GUARANTEED to avoid linker to strip the symbol.
42+
Build on musl with openssl 1.1.1w, those those was referenced, but still stripped from libcrypto during linking.
43+
Logs was:
44+
```
45+
/ # gcc -static -Wl,--trace-symbol=HMAC_CTX_new,-v -o test test.c -I $HOME/opt/aws/include -L $HOME/opt/aws/lib
46+
-laws-c-cal -laws-c-common /usr/lib/libcrypto.a -fno-lto collect2 version 11.2.1 20220219
47+
/usr/lib/gcc/x86_64-alpine-linux-musl/11.2.1/../../../../x86_64-alpine-linux-musl/bin/ld --hash-style=gnu -m
48+
elf_x86_64 --as-needed -static -z now -o test /usr/lib/gcc/x86_64-alpine-linux-musl/11.2.1/../../../../lib/crt1.o
49+
/usr/lib/gcc/x86_64-alpine-linux-musl/11.2.1/../../../../lib/crti.o
50+
/usr/lib/gcc/x86_64-alpine-linux-musl/11.2.1/crtbeginT.o -L/root/opt/aws/lib
51+
-L/usr/lib/gcc/x86_64-alpine-linux-musl/11.2.1
52+
-L/usr/lib/gcc/x86_64-alpine-linux-musl/11.2.1/../../../../x86_64-alpine-linux-musl/lib/../lib
53+
-L/usr/lib/gcc/x86_64-alpine-linux-musl/11.2.1/../../../../lib -L/lib/../lib -L/usr/lib/../lib
54+
-L/usr/lib/gcc/x86_64-alpine-linux-musl/11.2.1/../../../../x86_64-alpine-linux-musl/lib
55+
-L/usr/lib/gcc/x86_64-alpine-linux-musl/11.2.1/../../.. --trace-symbol=HMAC_CTX_new -v /tmp/ccBcKMkh.o -laws-c-cal
56+
-laws-c-common /usr/lib/libcrypto.a -lssp_nonshared --start-group -lgcc -lgcc_eh -lc --end-group
57+
/usr/lib/gcc/x86_64-alpine-linux-musl/11.2.1/crtend.o
58+
/usr/lib/gcc/x86_64-alpine-linux-musl/11.2.1/../../../../lib/crtn.o
59+
60+
GNU ld (GNU Binutils) 2.38
61+
/usr/lib/gcc/x86_64-alpine-linux-musl/11.2.1/../../../../x86_64-alpine-linux-musl/bin/ld:
62+
/root/opt/aws/lib/libaws-c-cal.a(openssl_platform_init.c.o): reference to HMAC_CTX_new
63+
```
64+
We don't really understand what strips the symbols, but aws-lc is a workaround.
65+
And, --require-defined=HMAC_CTX_new is another workaround to force the linker to keep the symbol.
66+
*/
4167
extern HMAC_CTX *HMAC_CTX_new(void) __attribute__((weak, used));
4268
extern void HMAC_CTX_free(HMAC_CTX *) __attribute__((weak, used));
4369
extern void HMAC_CTX_init(HMAC_CTX *) __attribute__((weak, used));
@@ -140,8 +166,12 @@ bool s_resolve_hmac_102(void *module) {
140166
/* were symbols bound by static linking? */
141167
bool has_102_symbols = init_fn && clean_up_fn && update_fn && final_fn && init_ex_fn;
142168
if (has_102_symbols) {
143-
AWS_LOGF_DEBUG(AWS_LS_CAL_LIBCRYPTO_RESOLVE, "found static libcrypto 1.0.2 HMAC symbols");
169+
AWS_LOGF_DEBUG(AWS_LS_CAL_LIBCRYPTO_RESOLVE, "found weak ref libcrypto 1.0.2 HMAC symbols");
144170
} else {
171+
if (!module) {
172+
AWS_LOGF_DEBUG(AWS_LS_CAL_LIBCRYPTO_RESOLVE, "No loaded libcrypto 1.0.2 HMAC symbols found");
173+
return false;
174+
}
145175
/* If symbols aren't already found, try to find the requested version */
146176
*(void **)(&init_fn) = dlsym(module, "HMAC_CTX_init");
147177
*(void **)(&clean_up_fn) = dlsym(module, "HMAC_CTX_cleanup");
@@ -180,8 +210,12 @@ bool s_resolve_hmac_111(void *module) {
180210
bool has_111_symbols = new_fn && free_fn && update_fn && final_fn && init_ex_fn;
181211

182212
if (has_111_symbols) {
183-
AWS_LOGF_DEBUG(AWS_LS_CAL_LIBCRYPTO_RESOLVE, "found static libcrypto 1.1.1 HMAC symbols");
213+
AWS_LOGF_DEBUG(AWS_LS_CAL_LIBCRYPTO_RESOLVE, "found weak ref libcrypto 1.1.1 HMAC symbols");
184214
} else {
215+
if (!module) {
216+
AWS_LOGF_DEBUG(AWS_LS_CAL_LIBCRYPTO_RESOLVE, "No loaded libcrypto 1.1.1 HMAC symbols found");
217+
return false;
218+
}
185219
*(void **)(&new_fn) = dlsym(module, "HMAC_CTX_new");
186220
*(void **)(&free_fn) = dlsym(module, "HMAC_CTX_free");
187221
*(void **)(&update_fn) = dlsym(module, "HMAC_Update");
@@ -225,8 +259,12 @@ bool s_resolve_hmac_lc(void *module) {
225259
/* when built as a shared lib, and multiple versions of libcrypto are possibly
226260
* available (e.g. brazil), select AWS-LC by default for consistency */
227261
if (has_awslc_symbols) {
228-
AWS_LOGF_DEBUG(AWS_LS_CAL_LIBCRYPTO_RESOLVE, "found static aws-lc HMAC symbols");
262+
AWS_LOGF_DEBUG(AWS_LS_CAL_LIBCRYPTO_RESOLVE, "found weak ref aws-lc HMAC symbols");
229263
} else {
264+
if (!module) {
265+
AWS_LOGF_DEBUG(AWS_LS_CAL_LIBCRYPTO_RESOLVE, "No loaded aws-lc HMAC symbols found");
266+
return false;
267+
}
230268
*(void **)(&new_fn) = dlsym(module, "HMAC_CTX_new");
231269
*(void **)(&free_fn) = dlsym(module, "HMAC_CTX_free");
232270
*(void **)(&update_fn) = dlsym(module, "HMAC_Update");
@@ -266,8 +304,12 @@ bool s_resolve_hmac_boringssl(void *module) {
266304
bool has_bssl_symbols = new_fn && free_fn && update_fn && final_fn && init_ex_fn;
267305

268306
if (has_bssl_symbols) {
269-
AWS_LOGF_DEBUG(AWS_LS_CAL_LIBCRYPTO_RESOLVE, "found static boringssl HMAC symbols");
307+
AWS_LOGF_DEBUG(AWS_LS_CAL_LIBCRYPTO_RESOLVE, "found weak ref boringssl HMAC symbols");
270308
} else {
309+
if (!module) {
310+
AWS_LOGF_DEBUG(AWS_LS_CAL_LIBCRYPTO_RESOLVE, "No loaded boringssl HMAC symbols found");
311+
return false;
312+
}
271313
*(void **)(&new_fn) = dlsym(module, "HMAC_CTX_new");
272314
*(void **)(&free_fn) = dlsym(module, "HMAC_CTX_free");
273315
*(void **)(&update_fn) = dlsym(module, "HMAC_Update");
@@ -352,8 +394,12 @@ bool s_resolve_md_102(void *module) {
352394
bool has_102_symbols = md_create_fn && md_destroy_fn && md_init_ex_fn && md_update_fn && md_final_ex_fn;
353395

354396
if (has_102_symbols) {
355-
AWS_LOGF_DEBUG(AWS_LS_CAL_LIBCRYPTO_RESOLVE, "found static libcrypto 1.0.2 EVP_MD symbols");
397+
AWS_LOGF_DEBUG(AWS_LS_CAL_LIBCRYPTO_RESOLVE, "found weak ref libcrypto 1.0.2 EVP_MD symbols");
356398
} else {
399+
if (!module) {
400+
AWS_LOGF_DEBUG(AWS_LS_CAL_LIBCRYPTO_RESOLVE, "No loaded libcrypto 1.0.2 EVP_MD symbols found");
401+
return false;
402+
}
357403
*(void **)(&md_create_fn) = dlsym(module, "EVP_MD_CTX_create");
358404
*(void **)(&md_destroy_fn) = dlsym(module, "EVP_MD_CTX_destroy");
359405
*(void **)(&md_init_ex_fn) = dlsym(module, "EVP_DigestInit_ex");
@@ -387,8 +433,12 @@ bool s_resolve_md_111(void *module) {
387433

388434
bool has_111_symbols = md_new_fn && md_free_fn && md_init_ex_fn && md_update_fn && md_final_ex_fn;
389435
if (has_111_symbols) {
390-
AWS_LOGF_DEBUG(AWS_LS_CAL_LIBCRYPTO_RESOLVE, "found static libcrypto 1.1.1 EVP_MD symbols");
436+
AWS_LOGF_DEBUG(AWS_LS_CAL_LIBCRYPTO_RESOLVE, "found weak ref libcrypto 1.1.1 EVP_MD symbols");
391437
} else {
438+
if (!module) {
439+
AWS_LOGF_DEBUG(AWS_LS_CAL_LIBCRYPTO_RESOLVE, "No loaded libcrypto 1.1.1 EVP_MD symbols found");
440+
return false;
441+
}
392442
*(void **)(&md_new_fn) = dlsym(module, "EVP_MD_CTX_new");
393443
*(void **)(&md_free_fn) = dlsym(module, "EVP_MD_CTX_free");
394444
*(void **)(&md_init_ex_fn) = dlsym(module, "EVP_DigestInit_ex");
@@ -426,8 +476,12 @@ bool s_resolve_md_lc(void *module) {
426476
md_new_fn && md_create_fn && md_free_fn && md_destroy_fn && md_init_ex_fn && md_update_fn && md_final_ex_fn;
427477

428478
if (has_awslc_symbols) {
429-
AWS_LOGF_DEBUG(AWS_LS_CAL_LIBCRYPTO_RESOLVE, "found static aws-lc libcrypto 1.1.1 EVP_MD symbols");
479+
AWS_LOGF_DEBUG(AWS_LS_CAL_LIBCRYPTO_RESOLVE, "found weak ref aws-lc libcrypto 1.1.1 EVP_MD symbols");
430480
} else {
481+
if (!module) {
482+
AWS_LOGF_DEBUG(AWS_LS_CAL_LIBCRYPTO_RESOLVE, "No loaded aws-lc libcrypto 1.1.1 EVP_MD symbols found");
483+
return false;
484+
}
431485
*(void **)(&md_new_fn) = dlsym(module, "EVP_MD_CTX_new");
432486
*(void **)(&md_free_fn) = dlsym(module, "EVP_MD_CTX_free");
433487
*(void **)(&md_init_ex_fn) = dlsym(module, "EVP_DigestInit_ex");
@@ -643,28 +697,25 @@ static void s_validate_libcrypto_linkage(void) {
643697
static enum aws_libcrypto_version s_resolve_libcrypto(void) {
644698
/* Try to auto-resolve against what's linked in/process space */
645699
AWS_LOGF_DEBUG(AWS_LS_CAL_LIBCRYPTO_RESOLVE, "searching process and loaded modules");
646-
void *process = dlopen(NULL, RTLD_NOW);
647-
AWS_FATAL_ASSERT(process && "Unable to load symbols from process space");
648-
enum aws_libcrypto_version result = s_resolve_libcrypto_symbols(AWS_LIBCRYPTO_LC, process);
700+
enum aws_libcrypto_version result = s_resolve_libcrypto_symbols(AWS_LIBCRYPTO_LC, NULL);
649701
if (result == AWS_LIBCRYPTO_NONE) {
650702
AWS_LOGF_DEBUG(AWS_LS_CAL_LIBCRYPTO_RESOLVE, "did not find aws-lc symbols linked");
651-
result = s_resolve_libcrypto_symbols(AWS_LIBCRYPTO_BORINGSSL, process);
703+
result = s_resolve_libcrypto_symbols(AWS_LIBCRYPTO_BORINGSSL, NULL);
652704
}
653705
if (result == AWS_LIBCRYPTO_NONE) {
654706
AWS_LOGF_DEBUG(AWS_LS_CAL_LIBCRYPTO_RESOLVE, "did not find boringssl symbols linked");
655-
result = s_resolve_libcrypto_symbols(AWS_LIBCRYPTO_1_1_1, process);
707+
result = s_resolve_libcrypto_symbols(AWS_LIBCRYPTO_1_1_1, NULL);
656708
}
657709
if (result == AWS_LIBCRYPTO_NONE) {
658710
AWS_LOGF_DEBUG(AWS_LS_CAL_LIBCRYPTO_RESOLVE, "did not find libcrypto 1.1.1 symbols linked");
659-
result = s_resolve_libcrypto_symbols(AWS_LIBCRYPTO_1_0_2, process);
711+
result = s_resolve_libcrypto_symbols(AWS_LIBCRYPTO_1_0_2, NULL);
660712
}
661-
dlclose(process);
662713

663714
if (result == AWS_LIBCRYPTO_NONE) {
664715
AWS_LOGF_DEBUG(AWS_LS_CAL_LIBCRYPTO_RESOLVE, "did not find libcrypto 1.0.2 symbols linked");
665716
AWS_LOGF_DEBUG(
666717
AWS_LS_CAL_LIBCRYPTO_RESOLVE,
667-
"libcrypto symbols were not statically linked, searching for shared libraries");
718+
"libcrypto symbols were not linked, searching for shared libraries and loading it");
668719
result = s_resolve_libcrypto_sharedlib();
669720
}
670721

0 commit comments

Comments
 (0)