From 4ee7708bf6dbfaa712749f081eec1f0d122fa001 Mon Sep 17 00:00:00 2001 From: Sergio Correia Date: Mon, 1 Apr 2024 12:10:54 +0100 Subject: [PATCH 1/7] Fix potential DoS issue with p2c header Unbounded p2c headers may be used to cause an application that accept PBES algorithms to spend a lot of resources running PBKDF2 with a very high number of iterations. Limit the maximum number of iterations to to 32768. Fixes: CVE-2023-50967 Signed-off-by: Sergio Correia --- lib/openssl/pbes2.c | 9 +++++++-- tests/cve-2023-50967/cve-2023-50967.jwe | 1 + tests/cve-2023-50967/cve-2023-50967.jwk | 1 + tests/jose-jwe-dec | 5 +++++ tests/meson.build | 2 ++ 5 files changed, 16 insertions(+), 2 deletions(-) create mode 100644 tests/cve-2023-50967/cve-2023-50967.jwe create mode 100644 tests/cve-2023-50967/cve-2023-50967.jwk diff --git a/lib/openssl/pbes2.c b/lib/openssl/pbes2.c index aae40059..1b3ca309 100644 --- a/lib/openssl/pbes2.c +++ b/lib/openssl/pbes2.c @@ -25,6 +25,8 @@ #include #define NAMES "PBES2-HS256+A128KW", "PBES2-HS384+A192KW", "PBES2-HS512+A256KW" +#define P2C_MIN_ITERATIONS 1000 +#define P2C_MAX_ITERATIONS 32768 static json_t * pbkdf2(const char *alg, jose_cfg_t *cfg, const json_t *jwk, int iter, @@ -193,7 +195,7 @@ alg_wrap_wrp(const jose_hook_alg_t *alg, jose_cfg_t *cfg, json_t *jwe, json_auto_t *hdr = NULL; const char *aes = NULL; json_t *h = NULL; - int p2c = 10000; + int p2c = P2C_MAX_ITERATIONS; size_t stl = 0; if (!json_object_get(cek, "k") && !jose_jwk_gen(cfg, cek)) @@ -226,7 +228,7 @@ alg_wrap_wrp(const jose_hook_alg_t *alg, jose_cfg_t *cfg, json_t *jwe, json_object_set_new(h, "p2c", json_integer(p2c)) < 0) return false; - if (p2c < 1000) + if (p2c < P2C_MIN_ITERATIONS || p2c > P2C_MAX_ITERATIONS) return false; if (json_object_set_new(h, "p2s", jose_b64_enc(st, stl)) == -1) @@ -268,6 +270,9 @@ alg_wrap_unw(const jose_hook_alg_t *alg, jose_cfg_t *cfg, const json_t *jwe, if (json_unpack(hdr, "{s:I}", "p2c", &p2c) == -1) return false; + if (p2c > P2C_MAX_ITERATIONS) + return false; + stl = jose_b64_dec(json_object_get(hdr, "p2s"), NULL, 0); if (stl < 8 || stl > sizeof(st)) return false; diff --git a/tests/cve-2023-50967/cve-2023-50967.jwe b/tests/cve-2023-50967/cve-2023-50967.jwe new file mode 100644 index 00000000..70bfc42e --- /dev/null +++ b/tests/cve-2023-50967/cve-2023-50967.jwe @@ -0,0 +1 @@ +{"ciphertext":"aaPb-JYGACs-loPwJkZewg","encrypted_key":"P1h8q8wLVxqYsZUuw6iEQTzgXVZHCsu8Eik-oqbE4AJGIDto3gb3SA","header":{"alg":"PBES2-HS256+A128KW","p2c":1000000000,"p2s":"qUQQWWkyyIqculSiC93mlg"},"iv":"Clg3JX9oNl_ck3sLSGrlgg","protected":"eyJlbmMiOiJBMTI4Q0JDLUhTMjU2In0","tag":"i7vga9tJkwRswFd7HlyD_A"} diff --git a/tests/cve-2023-50967/cve-2023-50967.jwk b/tests/cve-2023-50967/cve-2023-50967.jwk new file mode 100644 index 00000000..d7fb1beb --- /dev/null +++ b/tests/cve-2023-50967/cve-2023-50967.jwk @@ -0,0 +1 @@ +{"alg":"PBES2-HS256+A128KW","k":"VHBLJ4-PmnqELoKbQoXuRA","key_ops":["wrapKey","unwrapKey"],"kty":"oct"} diff --git a/tests/jose-jwe-dec b/tests/jose-jwe-dec index 7a0c3bfb..e02d12e0 100755 --- a/tests/jose-jwe-dec +++ b/tests/jose-jwe-dec @@ -53,3 +53,8 @@ test "`jose jwe dec -i $prfx.12.jweg -k $prfx.12.jwk`" = "`cat $prfx.12.pt`" test "`jose jwe dec -i $prfx.13.jweg -k $prfx.13.1.jwk`" = "`cat $prfx.13.pt`" test "`jose jwe dec -i $prfx.13.jweg -k $prfx.13.2.jwk`" = "`cat $prfx.13.pt`" test "`jose jwe dec -i $prfx.13.jweg -k $prfx.13.3.jwk`" = "`cat $prfx.13.pt`" + +# CVE-2023-50967 - test originally from https://github.com/P3ngu1nW/CVE_Request/blob/main/latch-jose.md +# This test is expected to fail quickly on patched systems. +prfx="${CVE_2023_50967}/cve-2023-50967" +! test "$(jose jwe dec -i $prfx.jwe -k $prfx.jwk)" diff --git a/tests/meson.build b/tests/meson.build index 37b910a8..1de53a13 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -31,6 +31,8 @@ progs = [ e = environment() e.prepend('PATH', meson.current_build_dir() + '/../cmd', separator: ':') e.set('VECTORS', meson.current_source_dir() + '/vectors') +e.set('CVE_2023_50967', meson.current_source_dir() + '/cve-2023-50967') + foreach p: progs exe = executable(p, p + '.c', dependencies: libjose_dep) From 76ec70ba4875a6ab6ad83b295e3da94685bbacb8 Mon Sep 17 00:00:00 2001 From: Sergio Arroutbi Date: Wed, 3 Apr 2024 14:52:22 +0200 Subject: [PATCH 2/7] Release v13 (#156) Resolves: #155 Signed-off-by: Sergio Arroutbi --- meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meson.build b/meson.build index b3308689..4877cb21 100644 --- a/meson.build +++ b/meson.build @@ -1,5 +1,5 @@ project('jose', 'c', license: 'APL2', - version: '12', + version: '13', default_options: [ 'c_std=gnu99', 'prefix=/usr', From efb5cfa74edbdaf13f356d3da4bb46a8dca65320 Mon Sep 17 00:00:00 2001 From: Sergio Arroutbi Date: Fri, 17 May 2024 10:54:06 +0200 Subject: [PATCH 3/7] Avoid potential DoS with high decompression chunks (#157) Signed-off-by: Sergio Arroutbi --- lib/hooks.h | 2 ++ lib/zlib/deflate.c | 3 +++ tests/alg_comp.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 72 insertions(+) diff --git a/lib/hooks.h b/lib/hooks.h index d4cd5f93..4208c254 100644 --- a/lib/hooks.h +++ b/lib/hooks.h @@ -20,6 +20,8 @@ #include #include +#define MAX_COMPRESSED_SIZE (256*1024) + typedef enum { JOSE_HOOK_JWK_KIND_NONE = 0, JOSE_HOOK_JWK_KIND_TYPE, diff --git a/lib/zlib/deflate.c b/lib/zlib/deflate.c index 07eca0c9..04ded33e 100644 --- a/lib/zlib/deflate.c +++ b/lib/zlib/deflate.c @@ -113,6 +113,9 @@ def_free(jose_io_t *io) static bool inf_feed(jose_io_t *io, const void *in, size_t len) { + if (len > MAX_COMPRESSED_SIZE) { + return false; + } return feed(io, in, len, inflate); } diff --git a/tests/alg_comp.c b/tests/alg_comp.c index fcd305c1..753566ba 100644 --- a/tests/alg_comp.c +++ b/tests/alg_comp.c @@ -19,6 +19,10 @@ #include #include #include +#include + +static int g_high_compression_tested = 0; +static int g_low_compression_tested = 0; const struct { const char *alg; @@ -41,6 +45,62 @@ const struct { {} }; +const uint32_t long_string_tests[] = { + 2000, 200000, 10000000, 0 +}; + +static uint8_t* get_random_string(uint32_t length) +{ + assert(length); + uint8_t* c = (uint8_t*)malloc(length*sizeof(uint8_t)); + for (uint32_t i=0; icomp.def(a, NULL, b); + assert(z); + + assert(z->feed(z, str, inputlen)); + assert(z->done(z)); + + /* Test decompression now */ + c = jose_io_malloc(NULL, &buf2, &clen); + assert(b); + z = a->comp.inf(a, NULL, c); + assert(z); + + /* If length>MAX_COMPRESSED_SIZE, it must fail due to high decompression size */ + if(blen > MAX_COMPRESSED_SIZE) { + assert(!z->feed(z, buf1, blen)); + g_high_compression_tested = 1; + } else { + assert(z->feed(z, buf1, blen)); + g_low_compression_tested = 1; + /* Compare the final output with the original input. */ + assert(clen == inputlen); + assert(memcmp(buf2, str, inputlen) == 0); + } + assert(z->done(z)); + free(str); +} + static void test(const jose_hook_alg_t *a, bool iter, const uint8_t *i, size_t il) @@ -119,5 +179,12 @@ main(int argc, char *argv[]) tst_inf, sizeof(tst_inf)); } + for (size_t i = 0; long_string_tests[i]; i++) { + test_long_string(long_string_tests[i]); + } + + assert(1 == g_high_compression_tested); + assert(1 == g_low_compression_tested); + return EXIT_SUCCESS; } From be761d281699c8c542598d01d9b762d941ffe385 Mon Sep 17 00:00:00 2001 From: Sergio Correia Date: Wed, 22 May 2024 10:10:24 +0100 Subject: [PATCH 4/7] jwe: fix the case when we have "zip" in the protected header (#161) When we have "zip" in the protected header, e.g.: "zip": "DEF", we should compress the payload before the encryption. However, as it stands, we are doing the compression after the encryption, which results in the jose_jwe_enc* functions producing JWEs that we are unable to decrypt afterwards. For the "zip" case, we do the compression now before the encryption, to fix this behavior. Also add some tests to exercise these scenarios, both using the jose_jwe_enc*/jose_jwe_dec* functions, as well as the command line utilities jose jwe enc / jose jwe dec. Signed-off-by: Sergio Correia --- lib/jwe.c | 26 +++--------- lib/misc.c | 58 +++++++++++++++++++++++++ lib/misc.h | 6 +++ lib/openssl/aescbch.c | 9 +++- lib/openssl/aesgcm.c | 10 ++++- tests/alg_comp.c | 1 + tests/api_jwe.c | 99 +++++++++++++++++++++++++++++++++++++++++-- tests/jose-jwe-enc | 9 ++++ 8 files changed, 192 insertions(+), 26 deletions(-) diff --git a/lib/jwe.c b/lib/jwe.c index 516245bd..55b43330 100644 --- a/lib/jwe.c +++ b/lib/jwe.c @@ -275,14 +275,8 @@ jose_jwe_enc_cek_io(jose_cfg_t *cfg, json_t *jwe, const json_t *cek, jose_io_t *next) { const jose_hook_alg_t *alg = NULL; - jose_io_auto_t *zip = NULL; - json_auto_t *prt = NULL; const char *h = NULL; const char *k = NULL; - const char *z = NULL; - - prt = jose_b64_dec_load(json_object_get(jwe, "protected")); - (void) json_unpack(prt, "{s:s}", "zip", &z); if (json_unpack(jwe, "{s?{s?s}}", "unprotected", "enc", &h) < 0) return NULL; @@ -336,19 +330,7 @@ jose_jwe_enc_cek_io(jose_cfg_t *cfg, json_t *jwe, const json_t *cek, if (!encode_protected(jwe)) return NULL; - if (z) { - const jose_hook_alg_t *a = NULL; - - a = jose_hook_alg_find(JOSE_HOOK_ALG_KIND_COMP, z); - if (!a) - return NULL; - - zip = a->comp.def(a, cfg, next); - if (!zip) - return NULL; - } - - return alg->encr.enc(alg, cfg, jwe, cek, zip ? zip : next); + return alg->encr.enc(alg, cfg, jwe, cek, next); } void * @@ -463,6 +445,12 @@ jose_jwe_dec_cek(jose_cfg_t *cfg, const json_t *jwe, const json_t *cek, o = jose_io_malloc(cfg, &pt, ptl); d = jose_jwe_dec_cek_io(cfg, jwe, cek, o); i = jose_b64_dec_io(d); + + /* Here we make sure the ciphertext is not larger than our + * compression limit. */ + if (zip_in_protected_header((json_t*)jwe) && ctl > MAX_COMPRESSED_SIZE) + return false; + if (!o || !d || !i || !i->feed(i, ct, ctl) || !i->done(i)) return NULL; diff --git a/lib/misc.c b/lib/misc.c index 465cd0d0..1015ce46 100644 --- a/lib/misc.c +++ b/lib/misc.c @@ -18,6 +18,7 @@ #include "misc.h" #include #include +#include "hooks.h" bool encode_protected(json_t *obj) @@ -42,6 +43,63 @@ zero(void *mem, size_t len) memset(mem, 0, len); } + +bool +handle_zip_enc(json_t *json, const void *in, size_t len, void **data, size_t *datalen) +{ + json_t *prt = NULL; + char *z = NULL; + const jose_hook_alg_t *a = NULL; + jose_io_auto_t *zip = NULL; + jose_io_auto_t *zipdata = NULL; + + prt = json_object_get(json, "protected"); + if (prt && json_is_string(prt)) + prt = jose_b64_dec_load(prt); + + /* Check if we have "zip" in the protected header. */ + if (json_unpack(prt, "{s:s}", "zip", &z) == -1) { + /* No zip. */ + *data = (void*)in; + *datalen = len; + return true; + } + + /* OK, we have "zip", so we should compress the payload before + * the encryption takes place. */ + a = jose_hook_alg_find(JOSE_HOOK_ALG_KIND_COMP, z); + if (!a) + return false; + + zipdata = jose_io_malloc(NULL, data, datalen); + if (!zipdata) + return false; + + zip = a->comp.def(a, NULL, zipdata); + if (!zip || !zip->feed(zip, in, len) || !zip->done(zip)) + return false; + + return true; +} + +bool +zip_in_protected_header(json_t *json) +{ + json_t *prt = NULL; + char *z = NULL; + + prt = json_object_get(json, "protected"); + if (prt && json_is_string(prt)) + prt = jose_b64_dec_load(prt); + + /* Check if we have "zip" in the protected header. */ + if (json_unpack(prt, "{s:s}", "zip", &z) == -1) + return false; + + /* We have "zip", but let's validate the alg also. */ + return jose_hook_alg_find(JOSE_HOOK_ALG_KIND_COMP, z) != NULL; +} + static void __attribute__((constructor)) constructor(void) { diff --git a/lib/misc.h b/lib/misc.h index d479d53f..18e7710a 100644 --- a/lib/misc.h +++ b/lib/misc.h @@ -30,3 +30,9 @@ encode_protected(json_t *obj); void zero(void *mem, size_t len); + +bool +handle_zip_enc(json_t *jwe, const void *in, size_t len, void **data, size_t *data_len); + +bool +zip_in_protected_header(json_t *jwe); diff --git a/lib/openssl/aescbch.c b/lib/openssl/aescbch.c index c8d5e605..00bd2ae1 100644 --- a/lib/openssl/aescbch.c +++ b/lib/openssl/aescbch.c @@ -18,6 +18,7 @@ #include "misc.h" #include #include "../hooks.h" +#include "../misc.h" #include #include @@ -155,9 +156,13 @@ enc_feed(jose_io_t *io, const void *in, size_t len) io_t *i = containerof(io, io_t, io); uint8_t ct[EVP_CIPHER_CTX_block_size(i->cctx) + 1]; - const uint8_t *pt = in; + uint8_t *pt = NULL; + size_t ptlen = 0; - for (size_t j = 0; j < len; j++) { + if (!handle_zip_enc(i->json, in, len, (void**)&pt, &ptlen)) + return false; + + for (size_t j = 0; j < ptlen; j++) { int l = 0; if (EVP_EncryptUpdate(i->cctx, ct, &l, &pt[j], 1) <= 0) diff --git a/lib/openssl/aesgcm.c b/lib/openssl/aesgcm.c index b4f55f2d..d3ab65cc 100644 --- a/lib/openssl/aesgcm.c +++ b/lib/openssl/aesgcm.c @@ -18,6 +18,7 @@ #include "misc.h" #include #include "../hooks.h" +#include "../misc.h" #include @@ -103,10 +104,15 @@ static bool enc_feed(jose_io_t *io, const void *in, size_t len) { io_t *i = containerof(io, io_t, io); - const uint8_t *pt = in; int l = 0; - for (size_t j = 0; j < len; j++) { + uint8_t *pt = NULL; + size_t ptlen = 0; + + if (!handle_zip_enc(i->json, in, len, (void**)&pt, &ptlen)) + return false; + + for (size_t j = 0; j < ptlen; j++) { uint8_t ct[EVP_CIPHER_CTX_block_size(i->cctx) + 1]; if (EVP_EncryptUpdate(i->cctx, ct, &l, &pt[j], 1) <= 0) diff --git a/tests/alg_comp.c b/tests/alg_comp.c index 753566ba..33dc32e6 100644 --- a/tests/alg_comp.c +++ b/tests/alg_comp.c @@ -53,6 +53,7 @@ static uint8_t* get_random_string(uint32_t length) { assert(length); uint8_t* c = (uint8_t*)malloc(length*sizeof(uint8_t)); + assert(c); for (uint32_t i=0; i #include +#include "../lib/hooks.h" /* for MAX_COMPRESSED_SIZE */ + static bool -dec(json_t *jwe, json_t *jwk) +dec_cmp(json_t *jwe, json_t *jwk, const char* expected_data, size_t expected_len) { bool ret = false; char *pt = NULL; @@ -30,10 +32,10 @@ dec(json_t *jwe, json_t *jwk) if (!pt) goto error; - if (ptl != 4) + if (ptl != expected_len) goto error; - if (strcmp(pt, "foo") != 0) + if (strcmp(pt, expected_data) != 0) goto error; ret = true; @@ -43,12 +45,40 @@ dec(json_t *jwe, json_t *jwk) return ret; } +static bool +dec(json_t *jwe, json_t *jwk) +{ + return dec_cmp(jwe, jwk, "foo", 4); +} + +struct zip_test_data_t { + char* data; + size_t datalen; + bool expected; +}; + +static char* +make_data(size_t len) +{ + assert(len > 0); + + char *data = malloc(len); + assert(data); + + for (size_t i = 0; i < len; i++) { + data[i] = 'A' + (random() % 26); + } + data[len-1] = '\0'; + return data; +} + int main(int argc, char *argv[]) { json_auto_t *jwke = json_pack("{s:s}", "alg", "ECDH-ES+A128KW"); json_auto_t *jwkr = json_pack("{s:s}", "alg", "RSA1_5"); json_auto_t *jwko = json_pack("{s:s}", "alg", "A128KW"); + json_auto_t *jwkz = json_pack("{s:s, s:i}", "kty", "oct", "bytes", 16); json_auto_t *set0 = json_pack("{s:[O,O]}", "keys", jwke, jwko); json_auto_t *set1 = json_pack("{s:[O,O]}", "keys", jwkr, jwko); json_auto_t *set2 = json_pack("{s:[O,O]}", "keys", jwke, jwkr); @@ -57,6 +87,7 @@ main(int argc, char *argv[]) assert(jose_jwk_gen(NULL, jwke)); assert(jose_jwk_gen(NULL, jwkr)); assert(jose_jwk_gen(NULL, jwko)); + assert(jose_jwk_gen(NULL, jwkz)); json_decref(jwe); assert((jwe = json_object())); @@ -98,5 +129,67 @@ main(int argc, char *argv[]) assert(dec(jwe, set1)); assert(dec(jwe, set2)); + + json_decref(jwe); + assert((jwe = json_pack("{s:{s:s,s:s,s:s,s:s}}", "protected", "alg", "A128KW", "enc", "A128GCM", "typ", "JWE", "zip", "DEF"))); + assert(jose_jwe_enc(NULL, jwe, NULL, jwkz, "foo", 4)); + assert(dec(jwe, jwkz)); + assert(!dec(jwe, jwkr)); + assert(!dec(jwe, jwko)); + assert(!dec(jwe, set0)); + assert(!dec(jwe, set1)); + assert(!dec(jwe, set2)); + + /* Some tests with "zip": "DEF" */ + struct zip_test_data_t zip[] = { + { + .data = make_data(5), + .datalen = 5, + .expected = true, + }, + { + .data = make_data(50), + .datalen = 50, + .expected = true, + }, + { + .data = make_data(1000), + .datalen = 1000, + .expected = true, + }, + { + .data = make_data(10000000), + .datalen = 10000000, + .expected = false, /* compressed len will be ~8000000+ + * (i.e. > MAX_COMPRESSED_SIZE) + */ + }, + { + .data = make_data(50000), + .datalen = 50000, + .expected = true + }, + { + + .data = NULL + } + }; + + for (size_t i = 0; zip[i].data != NULL; i++) { + json_decref(jwe); + assert((jwe = json_pack("{s:{s:s,s:s,s:s,s:s}}", "protected", "alg", "A128KW", "enc", "A128GCM", "typ", "JWE", "zip", "DEF"))); + assert(jose_jwe_enc(NULL, jwe, NULL, jwkz, zip[i].data, zip[i].datalen)); + + /* Now let's get the ciphertext compressed len. */ + char *ct = NULL; + size_t ctl = 0; + assert(json_unpack(jwe, "{s:s%}", "ciphertext", &ct, &ctl) != -1); + /* And check our expectation is correct. */ + assert(zip[i].expected == (ctl < MAX_COMPRESSED_SIZE)); + + assert(dec_cmp(jwe, jwkz, zip[i].data, zip[i].datalen) == zip[i].expected); + free(zip[i].data); + zip[i].data = NULL; + } return EXIT_SUCCESS; } diff --git a/tests/jose-jwe-enc b/tests/jose-jwe-enc index 5391fd8d..d9969ece 100755 --- a/tests/jose-jwe-enc +++ b/tests/jose-jwe-enc @@ -74,4 +74,13 @@ for msg in "hi" "this is a longer message that is more than one block"; do printf '%s' "$msg" | jose jwe enc -I- -k $jwk -o $jwe [ "`jose jwe dec -i $jwe -k $jwk -O-`" = "$msg" ] done + + # "zip": "DEF" + tmpl='{"kty":"oct","bytes":32}' + for enc in A128CBC-HS256 A192CBC-HS384 A256CBC-HS512 A128GCM A192GCM A256GCM; do + jose jwk gen -i "${tmpl}" -o "${jwk}" + zip="$(printf '{"alg":"A128KW","enc":"%s","zip":"DEF"}' "${enc}")" + printf '%s' "${msg}" | jose jwe enc -i "${zip}" -I- -k "${jwk}" -o "${jwe}" + [ "$(jose jwe dec -i "${jwe}" -k "${jwk}" -O-)" = "${msg}" ] + done done From fed2dc71994092c34c7baa1717af012454d13c56 Mon Sep 17 00:00:00 2001 From: Sergio Correia Date: Wed, 22 May 2024 10:10:38 +0100 Subject: [PATCH 5/7] openssl/oct: improve bound check for len (#162) Signed-off-by: Sergio Correia --- lib/openssl/oct.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/openssl/oct.c b/lib/openssl/oct.c index df4f0907..ef76b4ef 100644 --- a/lib/openssl/oct.c +++ b/lib/openssl/oct.c @@ -45,7 +45,7 @@ jwk_make_execute(jose_cfg_t *cfg, json_t *jwk) if (json_unpack(jwk, "{s:I}", "bytes", &len) < 0) return false; - if (len > KEYMAX) + if (len <= 0 || len > KEYMAX) return false; if (RAND_bytes(key, len) <= 0) From 3f11058762abe80144f2ae7ffd6cd4f212e0cf05 Mon Sep 17 00:00:00 2001 From: Howard Holm Date: Wed, 22 May 2024 05:14:05 -0400 Subject: [PATCH 6/7] Update meson.build (#153) Add undefined-version flag to link check for version-script to avoid false failures do to the "code" in the check being trivial --- lib/meson.build | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/lib/meson.build b/lib/meson.build index e836e885..a997ca93 100644 --- a/lib/meson.build +++ b/lib/meson.build @@ -2,8 +2,14 @@ flags = '-Wl,--version-script=' + meson.current_source_dir() + '/libjose.map' code = 'int main() { return 0; }' cc = meson.get_compiler('c') -if not cc.links(code, args: flags, name: '-Wl,--version-script=...') - flags = [ '-export-symbols-regex=^jose_.*' ] +if host_machine.system() == 'freebsd' + if not cc.links(code, args: flags + ',--undefined-version' , name: '-Wl,--version-script=...') + flags = [ '-export-symbols-regex=^jose_.*' ] + endif +else + if not cc.links(code, args: flags, name: '-Wl,--version-script=...') + flags = [ '-export-symbols-regex=^jose_.*' ] + endif endif libjose_lib = shared_library('jose', From 339ad6c836587c3e481f5df56c22c5370c7a264b Mon Sep 17 00:00:00 2001 From: Sergio Arroutbi Date: Wed, 22 May 2024 12:21:11 +0200 Subject: [PATCH 7/7] Release version v14 (#159) Resolves: #158 Signed-off-by: Sergio Arroutbi --- meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meson.build b/meson.build index 4877cb21..1581cedf 100644 --- a/meson.build +++ b/meson.build @@ -1,5 +1,5 @@ project('jose', 'c', license: 'APL2', - version: '13', + version: '14', default_options: [ 'c_std=gnu99', 'prefix=/usr',