diff options
| author | Peter Marko <peter.marko@siemens.com> | 2023-06-22 19:39:13 +0200 |
|---|---|---|
| committer | Armin Kuster <akuster808@gmail.com> | 2023-06-23 07:44:53 -0400 |
| commit | 06a732d7bdf59765a7704a06d78da95ad1fb89b7 (patch) | |
| tree | 20aa391ac984be0de05687a30bed34db07eb2169 | |
| parent | a82d92c8a6525da01524bf8f4a60bf6b35dcbb3d (diff) | |
| download | meta-openembedded-06a732d7bdf59765a7704a06d78da95ad1fb89b7.tar.gz | |
c-ares: backport patch for CVE-2023-31147
Backported from https://github.com/c-ares/c-ares/commit/823df3b989e59465d17b0a2eb1239a5fc048b4e5
Signed-off-by: Peter Marko <peter.marko@siemens.com>
Signed-off-by: Armin Kuster <akuster808@gmail.com>
| -rw-r--r-- | meta-oe/recipes-support/c-ares/c-ares/CVE-2023-31147.patch | 717 | ||||
| -rw-r--r-- | meta-oe/recipes-support/c-ares/c-ares_1.18.1.bb | 1 |
2 files changed, 718 insertions, 0 deletions
diff --git a/meta-oe/recipes-support/c-ares/c-ares/CVE-2023-31147.patch b/meta-oe/recipes-support/c-ares/c-ares/CVE-2023-31147.patch new file mode 100644 index 0000000000..bbd6aa0aec --- /dev/null +++ b/meta-oe/recipes-support/c-ares/c-ares/CVE-2023-31147.patch | |||
| @@ -0,0 +1,717 @@ | |||
| 1 | From c543406f44fa070ea101d4d4b173c2c88af0c2a5 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Brad House <brad@brad-house.com> | ||
| 3 | Date: Mon, 22 May 2023 06:51:06 -0400 | ||
| 4 | Subject: [PATCH] Merge pull request from GHSA-8r8p-23f3-64c2 | ||
| 5 | |||
| 6 | * segment random number generation into own file | ||
| 7 | |||
| 8 | * abstract random code to make it more modular so we can have multiple backends | ||
| 9 | |||
| 10 | * rand: add support for arc4random_buf() and also direct CARES_RANDOM_FILE reading | ||
| 11 | |||
| 12 | * autotools: fix detection of arc4random_buf | ||
| 13 | |||
| 14 | * rework initial rc4 seed for PRNG as last fallback | ||
| 15 | |||
| 16 | * rc4: more proper implementation, simplified for clarity | ||
| 17 | |||
| 18 | * clarifications | ||
| 19 | |||
| 20 | CVE: CVE-2023-31147 | ||
| 21 | Upstream-Status: Backport [https://github.com/c-ares/c-ares/commit/823df3b989e59465d17b0a2eb1239a5fc048b4e5] | ||
| 22 | |||
| 23 | Signed-off-by: Peter Marko <peter.marko@siemens.com> | ||
| 24 | --- | ||
| 25 | CMakeLists.txt | 2 + | ||
| 26 | configure.ac | 1 + | ||
| 27 | m4/cares-functions.m4 | 85 +++++++++++ | ||
| 28 | src/lib/Makefile.inc | 1 + | ||
| 29 | src/lib/ares_config.h.cmake | 3 + | ||
| 30 | src/lib/ares_destroy.c | 3 + | ||
| 31 | src/lib/ares_init.c | 82 ++--------- | ||
| 32 | src/lib/ares_private.h | 19 ++- | ||
| 33 | src/lib/ares_query.c | 36 +---- | ||
| 34 | src/lib/ares_rand.c | 274 ++++++++++++++++++++++++++++++++++++ | ||
| 35 | 10 files changed, 387 insertions(+), 119 deletions(-) | ||
| 36 | create mode 100644 src/lib/ares_rand.c | ||
| 37 | |||
| 38 | diff --git a/CMakeLists.txt b/CMakeLists.txt | ||
| 39 | index 194485a..1fb9af5 100644 | ||
| 40 | --- a/CMakeLists.txt | ||
| 41 | +++ b/CMakeLists.txt | ||
| 42 | @@ -386,6 +386,8 @@ CHECK_SYMBOL_EXISTS (strncasecmp "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_STRNCAS | ||
| 43 | CHECK_SYMBOL_EXISTS (strncmpi "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_STRNCMPI) | ||
| 44 | CHECK_SYMBOL_EXISTS (strnicmp "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_STRNICMP) | ||
| 45 | CHECK_SYMBOL_EXISTS (writev "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_WRITEV) | ||
| 46 | +CHECK_SYMBOL_EXISTS (arc4random_buf "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_ARC4RANDOM_BUF) | ||
| 47 | + | ||
| 48 | |||
| 49 | # On Android, the system headers may define __system_property_get(), but excluded | ||
| 50 | # from libc. We need to perform a link test instead of a header/symbol test. | ||
| 51 | diff --git a/configure.ac b/configure.ac | ||
| 52 | index 1d0fb5c..9a76369 100644 | ||
| 53 | --- a/configure.ac | ||
| 54 | +++ b/configure.ac | ||
| 55 | @@ -683,6 +683,7 @@ CARES_CHECK_FUNC_STRNCASECMP | ||
| 56 | CARES_CHECK_FUNC_STRNCMPI | ||
| 57 | CARES_CHECK_FUNC_STRNICMP | ||
| 58 | CARES_CHECK_FUNC_WRITEV | ||
| 59 | +CARES_CHECK_FUNC_ARC4RANDOM_BUF | ||
| 60 | |||
| 61 | |||
| 62 | dnl check for AF_INET6 | ||
| 63 | diff --git a/m4/cares-functions.m4 b/m4/cares-functions.m4 | ||
| 64 | index 0f3992c..d4f4f99 100644 | ||
| 65 | --- a/m4/cares-functions.m4 | ||
| 66 | +++ b/m4/cares-functions.m4 | ||
| 67 | @@ -3753,3 +3753,88 @@ AC_DEFUN([CARES_CHECK_FUNC_WRITEV], [ | ||
| 68 | ac_cv_func_writev="no" | ||
| 69 | fi | ||
| 70 | ]) | ||
| 71 | + | ||
| 72 | +dnl CARES_CHECK_FUNC_ARC4RANDOM_BUF | ||
| 73 | +dnl ------------------------------------------------- | ||
| 74 | +dnl Verify if arc4random_buf is available, prototyped, and | ||
| 75 | +dnl can be compiled. If all of these are true, and | ||
| 76 | +dnl usage has not been previously disallowed with | ||
| 77 | +dnl shell variable cares_disallow_arc4random_buf, then | ||
| 78 | +dnl HAVE_ARC4RANDOM_BUF will be defined. | ||
| 79 | + | ||
| 80 | +AC_DEFUN([CARES_CHECK_FUNC_ARC4RANDOM_BUF], [ | ||
| 81 | + AC_REQUIRE([CARES_INCLUDES_STDLIB])dnl | ||
| 82 | + # | ||
| 83 | + tst_links_arc4random_buf="unknown" | ||
| 84 | + tst_proto_arc4random_buf="unknown" | ||
| 85 | + tst_compi_arc4random_buf="unknown" | ||
| 86 | + tst_allow_arc4random_buf="unknown" | ||
| 87 | + # | ||
| 88 | + AC_MSG_CHECKING([if arc4random_buf can be linked]) | ||
| 89 | + AC_LINK_IFELSE([ | ||
| 90 | + AC_LANG_FUNC_LINK_TRY([arc4random_buf]) | ||
| 91 | + ],[ | ||
| 92 | + AC_MSG_RESULT([yes]) | ||
| 93 | + tst_links_arc4random_buf="yes" | ||
| 94 | + ],[ | ||
| 95 | + AC_MSG_RESULT([no]) | ||
| 96 | + tst_links_arc4random_buf="no" | ||
| 97 | + ]) | ||
| 98 | + # | ||
| 99 | + if test "$tst_links_arc4random_buf" = "yes"; then | ||
| 100 | + AC_MSG_CHECKING([if arc4random_buf is prototyped]) | ||
| 101 | + AC_EGREP_CPP([arc4random_buf],[ | ||
| 102 | + $cares_includes_stdlib | ||
| 103 | + ],[ | ||
| 104 | + AC_MSG_RESULT([yes]) | ||
| 105 | + tst_proto_arc4random_buf="yes" | ||
| 106 | + ],[ | ||
| 107 | + AC_MSG_RESULT([no]) | ||
| 108 | + tst_proto_arc4random_buf="no" | ||
| 109 | + ]) | ||
| 110 | + fi | ||
| 111 | + # | ||
| 112 | + if test "$tst_proto_arc4random_buf" = "yes"; then | ||
| 113 | + AC_MSG_CHECKING([if arc4random_buf is compilable]) | ||
| 114 | + AC_COMPILE_IFELSE([ | ||
| 115 | + AC_LANG_PROGRAM([[ | ||
| 116 | + $cares_includes_stdlib | ||
| 117 | + ]],[[ | ||
| 118 | + arc4random_buf(NULL, 0); | ||
| 119 | + return 1; | ||
| 120 | + ]]) | ||
| 121 | + ],[ | ||
| 122 | + AC_MSG_RESULT([yes]) | ||
| 123 | + tst_compi_arc4random_buf="yes" | ||
| 124 | + ],[ | ||
| 125 | + AC_MSG_RESULT([no]) | ||
| 126 | + tst_compi_arc4random_buf="no" | ||
| 127 | + ]) | ||
| 128 | + fi | ||
| 129 | + # | ||
| 130 | + if test "$tst_compi_arc4random_buf" = "yes"; then | ||
| 131 | + AC_MSG_CHECKING([if arc4random_buf usage allowed]) | ||
| 132 | + if test "x$cares_disallow_arc4random_buf" != "xyes"; then | ||
| 133 | + AC_MSG_RESULT([yes]) | ||
| 134 | + tst_allow_arc4random_buf="yes" | ||
| 135 | + else | ||
| 136 | + AC_MSG_RESULT([no]) | ||
| 137 | + tst_allow_arc4random_buf="no" | ||
| 138 | + fi | ||
| 139 | + fi | ||
| 140 | + # | ||
| 141 | + AC_MSG_CHECKING([if arc4random_buf might be used]) | ||
| 142 | + if test "$tst_links_arc4random_buf" = "yes" && | ||
| 143 | + test "$tst_proto_arc4random_buf" = "yes" && | ||
| 144 | + test "$tst_compi_arc4random_buf" = "yes" && | ||
| 145 | + test "$tst_allow_arc4random_buf" = "yes"; then | ||
| 146 | + AC_MSG_RESULT([yes]) | ||
| 147 | + AC_DEFINE_UNQUOTED(HAVE_ARC4RANDOM_BUF, 1, | ||
| 148 | + [Define to 1 if you have the arc4random_buf function.]) | ||
| 149 | + ac_cv_func_arc4random_buf="yes" | ||
| 150 | + else | ||
| 151 | + AC_MSG_RESULT([no]) | ||
| 152 | + ac_cv_func_arc4random_buf="no" | ||
| 153 | + fi | ||
| 154 | +]) | ||
| 155 | + | ||
| 156 | diff --git a/src/lib/Makefile.inc b/src/lib/Makefile.inc | ||
| 157 | index a3b060c..72a7673 100644 | ||
| 158 | --- a/src/lib/Makefile.inc | ||
| 159 | +++ b/src/lib/Makefile.inc | ||
| 160 | @@ -45,6 +45,7 @@ CSOURCES = ares__addrinfo2hostent.c \ | ||
| 161 | ares_platform.c \ | ||
| 162 | ares_process.c \ | ||
| 163 | ares_query.c \ | ||
| 164 | + ares_rand.c \ | ||
| 165 | ares_search.c \ | ||
| 166 | ares_send.c \ | ||
| 167 | ares_strcasecmp.c \ | ||
| 168 | diff --git a/src/lib/ares_config.h.cmake b/src/lib/ares_config.h.cmake | ||
| 169 | index fddb785..798820a 100644 | ||
| 170 | --- a/src/lib/ares_config.h.cmake | ||
| 171 | +++ b/src/lib/ares_config.h.cmake | ||
| 172 | @@ -346,6 +346,9 @@ | ||
| 173 | /* Define to 1 if you need the memory.h header file even with stdlib.h */ | ||
| 174 | #cmakedefine NEED_MEMORY_H | ||
| 175 | |||
| 176 | +/* Define if have arc4random_buf() */ | ||
| 177 | +#cmakedefine HAVE_ARC4RANDOM_BUF | ||
| 178 | + | ||
| 179 | /* a suitable file/device to read random data from */ | ||
| 180 | #cmakedefine CARES_RANDOM_FILE "@CARES_RANDOM_FILE@" | ||
| 181 | |||
| 182 | diff --git a/src/lib/ares_destroy.c b/src/lib/ares_destroy.c | ||
| 183 | index fed2009..0447af4 100644 | ||
| 184 | --- a/src/lib/ares_destroy.c | ||
| 185 | +++ b/src/lib/ares_destroy.c | ||
| 186 | @@ -90,6 +90,9 @@ void ares_destroy(ares_channel channel) | ||
| 187 | if (channel->resolvconf_path) | ||
| 188 | ares_free(channel->resolvconf_path); | ||
| 189 | |||
| 190 | + if (channel->rand_state) | ||
| 191 | + ares__destroy_rand_state(channel->rand_state); | ||
| 192 | + | ||
| 193 | ares_free(channel); | ||
| 194 | } | ||
| 195 | |||
| 196 | diff --git a/src/lib/ares_init.c b/src/lib/ares_init.c | ||
| 197 | index de5d86c..2607ed6 100644 | ||
| 198 | --- a/src/lib/ares_init.c | ||
| 199 | +++ b/src/lib/ares_init.c | ||
| 200 | @@ -72,7 +72,6 @@ static int config_nameserver(struct server_state **servers, int *nservers, | ||
| 201 | static int set_search(ares_channel channel, const char *str); | ||
| 202 | static int set_options(ares_channel channel, const char *str); | ||
| 203 | static const char *try_option(const char *p, const char *q, const char *opt); | ||
| 204 | -static int init_id_key(rc4_key* key,int key_data_len); | ||
| 205 | |||
| 206 | static int config_sortlist(struct apattern **sortlist, int *nsort, | ||
| 207 | const char *str); | ||
| 208 | @@ -149,6 +148,7 @@ int ares_init_options(ares_channel *channelptr, struct ares_options *options, | ||
| 209 | channel->sock_funcs = NULL; | ||
| 210 | channel->sock_func_cb_data = NULL; | ||
| 211 | channel->resolvconf_path = NULL; | ||
| 212 | + channel->rand_state = NULL; | ||
| 213 | |||
| 214 | channel->last_server = 0; | ||
| 215 | channel->last_timeout_processed = (time_t)now.tv_sec; | ||
| 216 | @@ -202,9 +202,13 @@ int ares_init_options(ares_channel *channelptr, struct ares_options *options, | ||
| 217 | /* Generate random key */ | ||
| 218 | |||
| 219 | if (status == ARES_SUCCESS) { | ||
| 220 | - status = init_id_key(&channel->id_key, ARES_ID_KEY_LEN); | ||
| 221 | + channel->rand_state = ares__init_rand_state(); | ||
| 222 | + if (channel->rand_state == NULL) { | ||
| 223 | + status = ARES_ENOMEM; | ||
| 224 | + } | ||
| 225 | + | ||
| 226 | if (status == ARES_SUCCESS) | ||
| 227 | - channel->next_id = ares__generate_new_id(&channel->id_key); | ||
| 228 | + channel->next_id = ares__generate_new_id(channel->rand_state); | ||
| 229 | else | ||
| 230 | DEBUGF(fprintf(stderr, "Error: init_id_key failed: %s\n", | ||
| 231 | ares_strerror(status))); | ||
| 232 | @@ -224,6 +228,8 @@ done: | ||
| 233 | ares_free(channel->lookups); | ||
| 234 | if(channel->resolvconf_path) | ||
| 235 | ares_free(channel->resolvconf_path); | ||
| 236 | + if (channel->rand_state) | ||
| 237 | + ares__destroy_rand_state(channel->rand_state); | ||
| 238 | ares_free(channel); | ||
| 239 | return status; | ||
| 240 | } | ||
| 241 | @@ -2495,76 +2501,6 @@ static int sortlist_alloc(struct apattern **sortlist, int *nsort, | ||
| 242 | return 1; | ||
| 243 | } | ||
| 244 | |||
| 245 | -/* initialize an rc4 key. If possible a cryptographically secure random key | ||
| 246 | - is generated using a suitable function (for example win32's RtlGenRandom as | ||
| 247 | - described in | ||
| 248 | - http://blogs.msdn.com/michael_howard/archive/2005/01/14/353379.aspx | ||
| 249 | - otherwise the code defaults to cross-platform albeit less secure mechanism | ||
| 250 | - using rand | ||
| 251 | -*/ | ||
| 252 | -static void randomize_key(unsigned char* key,int key_data_len) | ||
| 253 | -{ | ||
| 254 | - int randomized = 0; | ||
| 255 | - int counter=0; | ||
| 256 | -#ifdef WIN32 | ||
| 257 | - BOOLEAN res; | ||
| 258 | - if (ares_fpSystemFunction036) | ||
| 259 | - { | ||
| 260 | - res = (*ares_fpSystemFunction036) (key, key_data_len); | ||
| 261 | - if (res) | ||
| 262 | - randomized = 1; | ||
| 263 | - } | ||
| 264 | -#else /* !WIN32 */ | ||
| 265 | -#ifdef CARES_RANDOM_FILE | ||
| 266 | - FILE *f = fopen(CARES_RANDOM_FILE, "rb"); | ||
| 267 | - if(f) { | ||
| 268 | - setvbuf(f, NULL, _IONBF, 0); | ||
| 269 | - counter = aresx_uztosi(fread(key, 1, key_data_len, f)); | ||
| 270 | - fclose(f); | ||
| 271 | - } | ||
| 272 | -#endif | ||
| 273 | -#endif /* WIN32 */ | ||
| 274 | - | ||
| 275 | - if (!randomized) { | ||
| 276 | - for (;counter<key_data_len;counter++) | ||
| 277 | - key[counter]=(unsigned char)(rand() % 256); /* LCOV_EXCL_LINE */ | ||
| 278 | - } | ||
| 279 | -} | ||
| 280 | - | ||
| 281 | -static int init_id_key(rc4_key* key,int key_data_len) | ||
| 282 | -{ | ||
| 283 | - unsigned char index1; | ||
| 284 | - unsigned char index2; | ||
| 285 | - unsigned char* state; | ||
| 286 | - short counter; | ||
| 287 | - unsigned char *key_data_ptr = 0; | ||
| 288 | - | ||
| 289 | - key_data_ptr = ares_malloc(key_data_len); | ||
| 290 | - if (!key_data_ptr) | ||
| 291 | - return ARES_ENOMEM; | ||
| 292 | - memset(key_data_ptr, 0, key_data_len); | ||
| 293 | - | ||
| 294 | - state = &key->state[0]; | ||
| 295 | - for(counter = 0; counter < 256; counter++) | ||
| 296 | - /* unnecessary AND but it keeps some compilers happier */ | ||
| 297 | - state[counter] = (unsigned char)(counter & 0xff); | ||
| 298 | - randomize_key(key->state,key_data_len); | ||
| 299 | - key->x = 0; | ||
| 300 | - key->y = 0; | ||
| 301 | - index1 = 0; | ||
| 302 | - index2 = 0; | ||
| 303 | - for(counter = 0; counter < 256; counter++) | ||
| 304 | - { | ||
| 305 | - index2 = (unsigned char)((key_data_ptr[index1] + state[counter] + | ||
| 306 | - index2) % 256); | ||
| 307 | - ARES_SWAP_BYTE(&state[counter], &state[index2]); | ||
| 308 | - | ||
| 309 | - index1 = (unsigned char)((index1 + 1) % key_data_len); | ||
| 310 | - } | ||
| 311 | - ares_free(key_data_ptr); | ||
| 312 | - return ARES_SUCCESS; | ||
| 313 | -} | ||
| 314 | - | ||
| 315 | void ares_set_local_ip4(ares_channel channel, unsigned int local_ip) | ||
| 316 | { | ||
| 317 | channel->local_ip4 = local_ip; | ||
| 318 | diff --git a/src/lib/ares_private.h b/src/lib/ares_private.h | ||
| 319 | index 60d69e0..518b5c3 100644 | ||
| 320 | --- a/src/lib/ares_private.h | ||
| 321 | +++ b/src/lib/ares_private.h | ||
| 322 | @@ -101,8 +101,6 @@ W32_FUNC const char *_w32_GetHostsFile (void); | ||
| 323 | |||
| 324 | #endif | ||
| 325 | |||
| 326 | -#define ARES_ID_KEY_LEN 31 | ||
| 327 | - | ||
| 328 | #include "ares_ipv6.h" | ||
| 329 | #include "ares_llist.h" | ||
| 330 | |||
| 331 | @@ -262,12 +260,8 @@ struct apattern { | ||
| 332 | unsigned short type; | ||
| 333 | }; | ||
| 334 | |||
| 335 | -typedef struct rc4_key | ||
| 336 | -{ | ||
| 337 | - unsigned char state[256]; | ||
| 338 | - unsigned char x; | ||
| 339 | - unsigned char y; | ||
| 340 | -} rc4_key; | ||
| 341 | +struct ares_rand_state; | ||
| 342 | +typedef struct ares_rand_state ares_rand_state; | ||
| 343 | |||
| 344 | struct ares_channeldata { | ||
| 345 | /* Configuration data */ | ||
| 346 | @@ -302,8 +296,8 @@ struct ares_channeldata { | ||
| 347 | |||
| 348 | /* ID to use for next query */ | ||
| 349 | unsigned short next_id; | ||
| 350 | - /* key to use when generating new ids */ | ||
| 351 | - rc4_key id_key; | ||
| 352 | + /* random state to use when generating new ids */ | ||
| 353 | + ares_rand_state *rand_state; | ||
| 354 | |||
| 355 | /* Generation number to use for the next TCP socket open/close */ | ||
| 356 | int tcp_connection_generation; | ||
| 357 | @@ -359,7 +353,10 @@ void ares__close_sockets(ares_channel channel, struct server_state *server); | ||
| 358 | int ares__get_hostent(FILE *fp, int family, struct hostent **host); | ||
| 359 | int ares__read_line(FILE *fp, char **buf, size_t *bufsize); | ||
| 360 | void ares__free_query(struct query *query); | ||
| 361 | -unsigned short ares__generate_new_id(rc4_key* key); | ||
| 362 | + | ||
| 363 | +ares_rand_state *ares__init_rand_state(void); | ||
| 364 | +void ares__destroy_rand_state(ares_rand_state *state); | ||
| 365 | +unsigned short ares__generate_new_id(ares_rand_state *state); | ||
| 366 | struct timeval ares__tvnow(void); | ||
| 367 | int ares__expand_name_validated(const unsigned char *encoded, | ||
| 368 | const unsigned char *abuf, | ||
| 369 | diff --git a/src/lib/ares_query.c b/src/lib/ares_query.c | ||
| 370 | index 508274d..42323be 100644 | ||
| 371 | --- a/src/lib/ares_query.c | ||
| 372 | +++ b/src/lib/ares_query.c | ||
| 373 | @@ -33,32 +33,6 @@ struct qquery { | ||
| 374 | |||
| 375 | static void qcallback(void *arg, int status, int timeouts, unsigned char *abuf, int alen); | ||
| 376 | |||
| 377 | -static void rc4(rc4_key* key, unsigned char *buffer_ptr, int buffer_len) | ||
| 378 | -{ | ||
| 379 | - unsigned char x; | ||
| 380 | - unsigned char y; | ||
| 381 | - unsigned char* state; | ||
| 382 | - unsigned char xorIndex; | ||
| 383 | - int counter; | ||
| 384 | - | ||
| 385 | - x = key->x; | ||
| 386 | - y = key->y; | ||
| 387 | - | ||
| 388 | - state = &key->state[0]; | ||
| 389 | - for(counter = 0; counter < buffer_len; counter ++) | ||
| 390 | - { | ||
| 391 | - x = (unsigned char)((x + 1) % 256); | ||
| 392 | - y = (unsigned char)((state[x] + y) % 256); | ||
| 393 | - ARES_SWAP_BYTE(&state[x], &state[y]); | ||
| 394 | - | ||
| 395 | - xorIndex = (unsigned char)((state[x] + state[y]) % 256); | ||
| 396 | - | ||
| 397 | - buffer_ptr[counter] = (unsigned char)(buffer_ptr[counter]^state[xorIndex]); | ||
| 398 | - } | ||
| 399 | - key->x = x; | ||
| 400 | - key->y = y; | ||
| 401 | -} | ||
| 402 | - | ||
| 403 | static struct query* find_query_by_id(ares_channel channel, unsigned short id) | ||
| 404 | { | ||
| 405 | unsigned short qid; | ||
| 406 | @@ -78,7 +52,6 @@ static struct query* find_query_by_id(ares_channel channel, unsigned short id) | ||
| 407 | return NULL; | ||
| 408 | } | ||
| 409 | |||
| 410 | - | ||
| 411 | /* a unique query id is generated using an rc4 key. Since the id may already | ||
| 412 | be used by a running query (as infrequent as it may be), a lookup is | ||
| 413 | performed per id generation. In practice this search should happen only | ||
| 414 | @@ -89,19 +62,12 @@ static unsigned short generate_unique_id(ares_channel channel) | ||
| 415 | unsigned short id; | ||
| 416 | |||
| 417 | do { | ||
| 418 | - id = ares__generate_new_id(&channel->id_key); | ||
| 419 | + id = ares__generate_new_id(channel->rand_state); | ||
| 420 | } while (find_query_by_id(channel, id)); | ||
| 421 | |||
| 422 | return (unsigned short)id; | ||
| 423 | } | ||
| 424 | |||
| 425 | -unsigned short ares__generate_new_id(rc4_key* key) | ||
| 426 | -{ | ||
| 427 | - unsigned short r=0; | ||
| 428 | - rc4(key, (unsigned char *)&r, sizeof(r)); | ||
| 429 | - return r; | ||
| 430 | -} | ||
| 431 | - | ||
| 432 | void ares_query(ares_channel channel, const char *name, int dnsclass, | ||
| 433 | int type, ares_callback callback, void *arg) | ||
| 434 | { | ||
| 435 | diff --git a/src/lib/ares_rand.c b/src/lib/ares_rand.c | ||
| 436 | new file mode 100644 | ||
| 437 | index 0000000..a564bc2 | ||
| 438 | --- /dev/null | ||
| 439 | +++ b/src/lib/ares_rand.c | ||
| 440 | @@ -0,0 +1,274 @@ | ||
| 441 | +/* Copyright 1998 by the Massachusetts Institute of Technology. | ||
| 442 | + * Copyright (C) 2007-2013 by Daniel Stenberg | ||
| 443 | + * | ||
| 444 | + * Permission to use, copy, modify, and distribute this | ||
| 445 | + * software and its documentation for any purpose and without | ||
| 446 | + * fee is hereby granted, provided that the above copyright | ||
| 447 | + * notice appear in all copies and that both that copyright | ||
| 448 | + * notice and this permission notice appear in supporting | ||
| 449 | + * documentation, and that the name of M.I.T. not be used in | ||
| 450 | + * advertising or publicity pertaining to distribution of the | ||
| 451 | + * software without specific, written prior permission. | ||
| 452 | + * M.I.T. makes no representations about the suitability of | ||
| 453 | + * this software for any purpose. It is provided "as is" | ||
| 454 | + * without express or implied warranty. | ||
| 455 | + */ | ||
| 456 | + | ||
| 457 | +#include "ares_setup.h" | ||
| 458 | +#include "ares.h" | ||
| 459 | +#include "ares_private.h" | ||
| 460 | +#include "ares_nowarn.h" | ||
| 461 | +#include <stdlib.h> | ||
| 462 | + | ||
| 463 | +typedef enum { | ||
| 464 | + ARES_RAND_OS = 1, /* OS-provided such as RtlGenRandom or arc4random */ | ||
| 465 | + ARES_RAND_FILE = 2, /* OS file-backed random number generator */ | ||
| 466 | + ARES_RAND_RC4 = 3 /* Internal RC4 based PRNG */ | ||
| 467 | +} ares_rand_backend; | ||
| 468 | + | ||
| 469 | +typedef struct ares_rand_rc4 | ||
| 470 | +{ | ||
| 471 | + unsigned char S[256]; | ||
| 472 | + size_t i; | ||
| 473 | + size_t j; | ||
| 474 | +} ares_rand_rc4; | ||
| 475 | + | ||
| 476 | +struct ares_rand_state | ||
| 477 | +{ | ||
| 478 | + ares_rand_backend type; | ||
| 479 | + union { | ||
| 480 | + FILE *rand_file; | ||
| 481 | + ares_rand_rc4 rc4; | ||
| 482 | + } state; | ||
| 483 | +}; | ||
| 484 | + | ||
| 485 | + | ||
| 486 | +/* Define RtlGenRandom = SystemFunction036. This is in advapi32.dll. There is | ||
| 487 | + * no need to dynamically load this, other software used widely does not. | ||
| 488 | + * http://blogs.msdn.com/michael_howard/archive/2005/01/14/353379.aspx | ||
| 489 | + * https://docs.microsoft.com/en-us/windows/win32/api/ntsecapi/nf-ntsecapi-rtlgenrandom | ||
| 490 | + */ | ||
| 491 | +#ifdef _WIN32 | ||
| 492 | +BOOLEAN WINAPI SystemFunction036(PVOID RandomBuffer, ULONG RandomBufferLength); | ||
| 493 | +# ifndef RtlGenRandom | ||
| 494 | +# define RtlGenRandom(a,b) SystemFunction036(a,b) | ||
| 495 | +# endif | ||
| 496 | +#endif | ||
| 497 | + | ||
| 498 | + | ||
| 499 | +#define ARES_RC4_KEY_LEN 32 /* 256 bits */ | ||
| 500 | + | ||
| 501 | +static unsigned int ares_u32_from_ptr(void *addr) | ||
| 502 | +{ | ||
| 503 | + if (sizeof(void *) == 8) { | ||
| 504 | + return (unsigned int)((((size_t)addr >> 32) & 0xFFFFFFFF) | ((size_t)addr & 0xFFFFFFFF)); | ||
| 505 | + } | ||
| 506 | + return (unsigned int)((size_t)addr & 0xFFFFFFFF); | ||
| 507 | +} | ||
| 508 | + | ||
| 509 | + | ||
| 510 | +/* initialize an rc4 key as the last possible fallback. */ | ||
| 511 | +static void ares_rc4_generate_key(ares_rand_rc4 *rc4_state, unsigned char *key, size_t key_len) | ||
| 512 | +{ | ||
| 513 | + size_t i; | ||
| 514 | + size_t len = 0; | ||
| 515 | + unsigned int data; | ||
| 516 | + struct timeval tv; | ||
| 517 | + | ||
| 518 | + if (key_len != ARES_RC4_KEY_LEN) | ||
| 519 | + return; | ||
| 520 | + | ||
| 521 | + /* Randomness is hard to come by. Maybe the system randomizes heap and stack addresses. | ||
| 522 | + * Maybe the current timestamp give us some randomness. | ||
| 523 | + * Use rc4_state (heap), &i (stack), and ares__tvnow() | ||
| 524 | + */ | ||
| 525 | + data = ares_u32_from_ptr(rc4_state); | ||
| 526 | + memcpy(key + len, &data, sizeof(data)); | ||
| 527 | + len += sizeof(data); | ||
| 528 | + | ||
| 529 | + data = ares_u32_from_ptr(&i); | ||
| 530 | + memcpy(key + len, &data, sizeof(data)); | ||
| 531 | + len += sizeof(data); | ||
| 532 | + | ||
| 533 | + tv = ares__tvnow(); | ||
| 534 | + data = (unsigned int)((tv.tv_sec | tv.tv_usec) & 0xFFFFFFFF); | ||
| 535 | + memcpy(key + len, &data, sizeof(data)); | ||
| 536 | + len += sizeof(data); | ||
| 537 | + | ||
| 538 | + srand(ares_u32_from_ptr(rc4_state) | ares_u32_from_ptr(&i) | (unsigned int)((tv.tv_sec | tv.tv_usec) & 0xFFFFFFFF)); | ||
| 539 | + | ||
| 540 | + for (i=len; i<key_len; i++) { | ||
| 541 | + key[i]=(unsigned char)(rand() % 256); /* LCOV_EXCL_LINE */ | ||
| 542 | + } | ||
| 543 | +} | ||
| 544 | + | ||
| 545 | + | ||
| 546 | +static void ares_rc4_init(ares_rand_rc4 *rc4_state) | ||
| 547 | +{ | ||
| 548 | + unsigned char key[ARES_RC4_KEY_LEN]; | ||
| 549 | + size_t i; | ||
| 550 | + size_t j; | ||
| 551 | + | ||
| 552 | + ares_rc4_generate_key(rc4_state, key, sizeof(key)); | ||
| 553 | + | ||
| 554 | + for (i = 0; i < sizeof(rc4_state->S); i++) { | ||
| 555 | + rc4_state->S[i] = i & 0xFF; | ||
| 556 | + } | ||
| 557 | + | ||
| 558 | + for(i = 0, j = 0; i < 256; i++) { | ||
| 559 | + j = (j + rc4_state->S[i] + key[i % sizeof(key)]) % 256; | ||
| 560 | + ARES_SWAP_BYTE(&rc4_state->S[i], &rc4_state->S[j]); | ||
| 561 | + } | ||
| 562 | + | ||
| 563 | + rc4_state->i = 0; | ||
| 564 | + rc4_state->j = 0; | ||
| 565 | +} | ||
| 566 | + | ||
| 567 | +/* Just outputs the key schedule, no need to XOR with any data since we have none */ | ||
| 568 | +static void ares_rc4_prng(ares_rand_rc4 *rc4_state, unsigned char *buf, int len) | ||
| 569 | +{ | ||
| 570 | + unsigned char *S = rc4_state->S; | ||
| 571 | + size_t i = rc4_state->i; | ||
| 572 | + size_t j = rc4_state->j; | ||
| 573 | + size_t cnt; | ||
| 574 | + | ||
| 575 | + for (cnt=0; cnt<len; cnt++) { | ||
| 576 | + i = (i + 1) % 256; | ||
| 577 | + j = (j + S[i]) % 256; | ||
| 578 | + | ||
| 579 | + ARES_SWAP_BYTE(&S[i], &S[j]); | ||
| 580 | + buf[cnt] = S[(S[i] + S[j]) % 256]; | ||
| 581 | + } | ||
| 582 | + | ||
| 583 | + rc4_state->i = i; | ||
| 584 | + rc4_state->j = j; | ||
| 585 | +} | ||
| 586 | + | ||
| 587 | + | ||
| 588 | +static int ares__init_rand_engine(ares_rand_state *state) | ||
| 589 | +{ | ||
| 590 | + memset(state, 0, sizeof(*state)); | ||
| 591 | + | ||
| 592 | +#if defined(HAVE_ARC4RANDOM_BUF) || defined(_WIN32) | ||
| 593 | + state->type = ARES_RAND_OS; | ||
| 594 | + return 1; | ||
| 595 | +#elif defined(CARES_RANDOM_FILE) | ||
| 596 | + state->type = ARES_RAND_FILE; | ||
| 597 | + state->state.rand_file = fopen(CARES_RANDOM_FILE, "rb"); | ||
| 598 | + if (state->state.rand_file) { | ||
| 599 | + setvbuf(state->state.rand_file, NULL, _IONBF, 0); | ||
| 600 | + return 1; | ||
| 601 | + } | ||
| 602 | + /* Fall-Thru on failure to RC4 */ | ||
| 603 | +#endif | ||
| 604 | + | ||
| 605 | + state->type = ARES_RAND_RC4; | ||
| 606 | + ares_rc4_init(&state->state.rc4); | ||
| 607 | + | ||
| 608 | + /* Currently cannot fail */ | ||
| 609 | + return 1; | ||
| 610 | +} | ||
| 611 | + | ||
| 612 | + | ||
| 613 | +ares_rand_state *ares__init_rand_state() | ||
| 614 | +{ | ||
| 615 | + ares_rand_state *state = NULL; | ||
| 616 | + | ||
| 617 | + state = ares_malloc(sizeof(*state)); | ||
| 618 | + if (!state) | ||
| 619 | + return NULL; | ||
| 620 | + | ||
| 621 | + if (!ares__init_rand_engine(state)) { | ||
| 622 | + ares_free(state); | ||
| 623 | + return NULL; | ||
| 624 | + } | ||
| 625 | + | ||
| 626 | + return state; | ||
| 627 | +} | ||
| 628 | + | ||
| 629 | + | ||
| 630 | +static void ares__clear_rand_state(ares_rand_state *state) | ||
| 631 | +{ | ||
| 632 | + if (!state) | ||
| 633 | + return; | ||
| 634 | + | ||
| 635 | + switch (state->type) { | ||
| 636 | + case ARES_RAND_OS: | ||
| 637 | + break; | ||
| 638 | + case ARES_RAND_FILE: | ||
| 639 | + fclose(state->state.rand_file); | ||
| 640 | + break; | ||
| 641 | + case ARES_RAND_RC4: | ||
| 642 | + break; | ||
| 643 | + } | ||
| 644 | +} | ||
| 645 | + | ||
| 646 | + | ||
| 647 | +static void ares__reinit_rand(ares_rand_state *state) | ||
| 648 | +{ | ||
| 649 | + ares__clear_rand_state(state); | ||
| 650 | + ares__init_rand_engine(state); | ||
| 651 | +} | ||
| 652 | + | ||
| 653 | + | ||
| 654 | +void ares__destroy_rand_state(ares_rand_state *state) | ||
| 655 | +{ | ||
| 656 | + if (!state) | ||
| 657 | + return; | ||
| 658 | + | ||
| 659 | + ares__clear_rand_state(state); | ||
| 660 | + ares_free(state); | ||
| 661 | +} | ||
| 662 | + | ||
| 663 | + | ||
| 664 | +static void ares__rand_bytes(ares_rand_state *state, unsigned char *buf, size_t len) | ||
| 665 | +{ | ||
| 666 | + | ||
| 667 | + while (1) { | ||
| 668 | + size_t rv; | ||
| 669 | + size_t bytes_read = 0; | ||
| 670 | + | ||
| 671 | + switch (state->type) { | ||
| 672 | + case ARES_RAND_OS: | ||
| 673 | +#ifdef _WIN32 | ||
| 674 | + RtlGenRandom(buf, len); | ||
| 675 | + return; | ||
| 676 | +#elif defined(HAVE_ARC4RANDOM_BUF) | ||
| 677 | + arc4random_buf(buf, len); | ||
| 678 | + return; | ||
| 679 | +#else | ||
| 680 | + /* Shouldn't be possible to be here */ | ||
| 681 | + break; | ||
| 682 | +#endif | ||
| 683 | + | ||
| 684 | + case ARES_RAND_FILE: | ||
| 685 | + while (1) { | ||
| 686 | + size_t rv = fread(buf + bytes_read, 1, len - bytes_read, state->state.rand_file); | ||
| 687 | + if (rv == 0) | ||
| 688 | + break; /* critical error, will reinit rand state */ | ||
| 689 | + | ||
| 690 | + bytes_read += rv; | ||
| 691 | + if (bytes_read == len) | ||
| 692 | + return; | ||
| 693 | + } | ||
| 694 | + break; | ||
| 695 | + | ||
| 696 | + case ARES_RAND_RC4: | ||
| 697 | + ares_rc4_prng(&state->state.rc4, buf, len); | ||
| 698 | + return; | ||
| 699 | + } | ||
| 700 | + | ||
| 701 | + /* If we didn't return before we got here, that means we had a critical rand | ||
| 702 | + * failure and need to reinitialized */ | ||
| 703 | + ares__reinit_rand(state); | ||
| 704 | + } | ||
| 705 | +} | ||
| 706 | + | ||
| 707 | +unsigned short ares__generate_new_id(ares_rand_state *state) | ||
| 708 | +{ | ||
| 709 | + unsigned short r=0; | ||
| 710 | + | ||
| 711 | + ares__rand_bytes(state, (unsigned char *)&r, sizeof(r)); | ||
| 712 | + return r; | ||
| 713 | +} | ||
| 714 | + | ||
| 715 | -- | ||
| 716 | 2.30.2 | ||
| 717 | |||
diff --git a/meta-oe/recipes-support/c-ares/c-ares_1.18.1.bb b/meta-oe/recipes-support/c-ares/c-ares_1.18.1.bb index fef33cd083..b6cdd801e5 100644 --- a/meta-oe/recipes-support/c-ares/c-ares_1.18.1.bb +++ b/meta-oe/recipes-support/c-ares/c-ares_1.18.1.bb | |||
| @@ -9,6 +9,7 @@ SRC_URI = "git://github.com/c-ares/c-ares.git;branch=main;protocol=https \ | |||
| 9 | file://CVE-2022-4904.patch \ | 9 | file://CVE-2022-4904.patch \ |
| 10 | file://CVE-2023-31130.patch \ | 10 | file://CVE-2023-31130.patch \ |
| 11 | file://CVE-2023-32067.patch \ | 11 | file://CVE-2023-32067.patch \ |
| 12 | file://CVE-2023-31147.patch \ | ||
| 12 | " | 13 | " |
| 13 | SRCREV = "2aa086f822aad5017a6f2061ef656f237a62d0ed" | 14 | SRCREV = "2aa086f822aad5017a6f2061ef656f237a62d0ed" |
| 14 | 15 | ||
