diff options
author | miod <> | 2014-04-23 20:59:36 +0000 |
---|---|---|
committer | miod <> | 2014-04-23 20:59:36 +0000 |
commit | 2200007b52bd1fa0d16b0f986bb90e51ec5fcf01 (patch) | |
tree | 1096190589e0961bf69454ee8670bf22d4a20a41 | |
parent | a874a9e945512d316a64779e37a6b661549ae60d (diff) | |
download | openbsd-2200007b52bd1fa0d16b0f986bb90e51ec5fcf01.tar.gz openbsd-2200007b52bd1fa0d16b0f986bb90e51ec5fcf01.tar.bz2 openbsd-2200007b52bd1fa0d16b0f986bb90e51ec5fcf01.zip |
The usual idiom to cope with systems not defining socklen_t is to add a
#define socklen_t int
somewhere (or a typedef, whatever gives you an integer type of the size
your system expects as the 3rd argument of accept(2), really).
OpenSSL here is a bit more creative by using an union of an int and a size_t,
and extra code if sizeof(int) != sizeof(size_t) in order to recover the
proper size. With a comment mentioning that this has no chance to work on
a platform with a stack growing up and accept() returning an int, fortunately
this seems to work on HP-UX.
Switch to the light side of the force and declare and use socklen_t variables,
period. If your system does not define socklen_t, consider bringing it back
to your vendor for a refund.
ok matthew@ tedu@
-rw-r--r-- | src/lib/libcrypto/bio/b_sock.c | 40 | ||||
-rw-r--r-- | src/lib/libcrypto/bio/bss_dgram.c | 17 | ||||
-rw-r--r-- | src/lib/libssl/src/crypto/bio/b_sock.c | 40 | ||||
-rw-r--r-- | src/lib/libssl/src/crypto/bio/bss_dgram.c | 17 |
4 files changed, 16 insertions, 98 deletions
diff --git a/src/lib/libcrypto/bio/b_sock.c b/src/lib/libcrypto/bio/b_sock.c index e5f42398df..05eb362cc6 100644 --- a/src/lib/libcrypto/bio/b_sock.c +++ b/src/lib/libcrypto/bio/b_sock.c | |||
@@ -452,31 +452,7 @@ BIO_accept(int sock, char **addr) | |||
452 | char *p, *tmp; | 452 | char *p, *tmp; |
453 | 453 | ||
454 | struct { | 454 | struct { |
455 | /* | 455 | socklen_t len; |
456 | * As for following union. Trouble is that there are platforms | ||
457 | * that have socklen_t and there are platforms that don't, on | ||
458 | * some platforms socklen_t is int and on some size_t. So what | ||
459 | * one can do? One can cook #ifdef spaghetti, which is nothing | ||
460 | * but masochistic. Or one can do union between int and size_t. | ||
461 | * One naturally does it primarily for 64-bit platforms where | ||
462 | * sizeof(int) != sizeof(size_t). But would it work? Note that | ||
463 | * if size_t member is initialized to 0, then later int member | ||
464 | * assignment naturally does the job on little-endian platforms | ||
465 | * regardless accept's expectations! What about big-endians? | ||
466 | * If accept expects int*, then it works, and if size_t*, then | ||
467 | * length value would appear as unreasonably large. But this | ||
468 | * won't prevent it from filling in the address structure. The | ||
469 | * trouble of course would be if accept returns more data than | ||
470 | * actual buffer can accomodate and overwrite stack... That's | ||
471 | * where early OPENSSL_assert comes into picture. Besides, the | ||
472 | * only 64-bit big-endian platform found so far that expects | ||
473 | * size_t* is HP-UX, where stack grows towards higher address. | ||
474 | * <appro> | ||
475 | */ | ||
476 | union { | ||
477 | size_t s; | ||
478 | int i; | ||
479 | } len; | ||
480 | union { | 456 | union { |
481 | struct sockaddr sa; | 457 | struct sockaddr sa; |
482 | struct sockaddr_in sa_in; | 458 | struct sockaddr_in sa_in; |
@@ -484,15 +460,9 @@ BIO_accept(int sock, char **addr) | |||
484 | } from; | 460 | } from; |
485 | } sa; | 461 | } sa; |
486 | 462 | ||
487 | sa.len.s = 0; | 463 | sa.len = sizeof(sa.from); |
488 | sa.len.i = sizeof(sa.from); | ||
489 | memset(&sa.from, 0, sizeof(sa.from)); | 464 | memset(&sa.from, 0, sizeof(sa.from)); |
490 | ret = accept(sock, &sa.from.sa, (void *)&sa.len); | 465 | ret = accept(sock, &sa.from.sa, &sa.len); |
491 | if (sizeof(sa.len.i) != sizeof(sa.len.s) && sa.len.i == 0) { | ||
492 | OPENSSL_assert(sa.len.s <= sizeof(sa.from)); | ||
493 | sa.len.i = (int)sa.len.s; | ||
494 | /* use sa.len.i from this point */ | ||
495 | } | ||
496 | if (ret == -1) { | 466 | if (ret == -1) { |
497 | if (BIO_sock_should_retry(ret)) | 467 | if (BIO_sock_should_retry(ret)) |
498 | return -2; | 468 | return -2; |
@@ -511,7 +481,7 @@ BIO_accept(int sock, char **addr) | |||
511 | static union { | 481 | static union { |
512 | void *p; | 482 | void *p; |
513 | int (*f)(const struct sockaddr *, | 483 | int (*f)(const struct sockaddr *, |
514 | size_t/*socklen_t*/, char *, size_t, | 484 | socklen_t, char *, size_t, |
515 | char *, size_t, int); | 485 | char *, size_t, int); |
516 | } p_getnameinfo = {NULL}; | 486 | } p_getnameinfo = {NULL}; |
517 | /* 2nd argument to getnameinfo is specified to | 487 | /* 2nd argument to getnameinfo is specified to |
@@ -527,7 +497,7 @@ BIO_accept(int sock, char **addr) | |||
527 | if (p_getnameinfo.p == (void *) - 1) | 497 | if (p_getnameinfo.p == (void *) - 1) |
528 | break; | 498 | break; |
529 | 499 | ||
530 | if ((*p_getnameinfo.f)(&sa.from.sa, sa.len.i, h, sizeof(h), | 500 | if ((*p_getnameinfo.f)(&sa.from.sa, sa.len, h, sizeof(h), |
531 | s, sizeof(s), NI_NUMERICHOST|NI_NUMERICSERV)) | 501 | s, sizeof(s), NI_NUMERICHOST|NI_NUMERICSERV)) |
532 | break; | 502 | break; |
533 | nl = strlen(h) + strlen(s) + 2; | 503 | nl = strlen(h) + strlen(s) + 2; |
diff --git a/src/lib/libcrypto/bio/bss_dgram.c b/src/lib/libcrypto/bio/bss_dgram.c index a3b5bb6574..ab269aeba3 100644 --- a/src/lib/libcrypto/bio/bss_dgram.c +++ b/src/lib/libcrypto/bio/bss_dgram.c | |||
@@ -331,13 +331,7 @@ dgram_read(BIO *b, char *out, int outl) | |||
331 | bio_dgram_data *data = (bio_dgram_data *)b->ptr; | 331 | bio_dgram_data *data = (bio_dgram_data *)b->ptr; |
332 | 332 | ||
333 | struct { | 333 | struct { |
334 | /* | 334 | socklen_t len; |
335 | * See commentary in b_sock.c. <appro> | ||
336 | */ | ||
337 | union { | ||
338 | size_t s; | ||
339 | int i; | ||
340 | } len; | ||
341 | union { | 335 | union { |
342 | struct sockaddr sa; | 336 | struct sockaddr sa; |
343 | struct sockaddr_in sa_in; | 337 | struct sockaddr_in sa_in; |
@@ -345,18 +339,13 @@ dgram_read(BIO *b, char *out, int outl) | |||
345 | } peer; | 339 | } peer; |
346 | } sa; | 340 | } sa; |
347 | 341 | ||
348 | sa.len.s = 0; | 342 | sa.len = sizeof(sa.peer); |
349 | sa.len.i = sizeof(sa.peer); | ||
350 | 343 | ||
351 | if (out != NULL) { | 344 | if (out != NULL) { |
352 | errno = 0; | 345 | errno = 0; |
353 | memset(&sa.peer, 0x00, sizeof(sa.peer)); | 346 | memset(&sa.peer, 0x00, sizeof(sa.peer)); |
354 | dgram_adjust_rcv_timeout(b); | 347 | dgram_adjust_rcv_timeout(b); |
355 | ret = recvfrom(b->num, out, outl, 0, &sa.peer.sa,(void *)&sa.len); | 348 | ret = recvfrom(b->num, out, outl, 0, &sa.peer.sa, &sa.len); |
356 | if (sizeof(sa.len.i) != sizeof(sa.len.s) && sa.len.i == 0) { | ||
357 | OPENSSL_assert(sa.len.s <= sizeof(sa.peer)); | ||
358 | sa.len.i = (int)sa.len.s; | ||
359 | } | ||
360 | 349 | ||
361 | if (! data->connected && ret >= 0) | 350 | if (! data->connected && ret >= 0) |
362 | BIO_ctrl(b, BIO_CTRL_DGRAM_SET_PEER, 0, &sa.peer); | 351 | BIO_ctrl(b, BIO_CTRL_DGRAM_SET_PEER, 0, &sa.peer); |
diff --git a/src/lib/libssl/src/crypto/bio/b_sock.c b/src/lib/libssl/src/crypto/bio/b_sock.c index e5f42398df..05eb362cc6 100644 --- a/src/lib/libssl/src/crypto/bio/b_sock.c +++ b/src/lib/libssl/src/crypto/bio/b_sock.c | |||
@@ -452,31 +452,7 @@ BIO_accept(int sock, char **addr) | |||
452 | char *p, *tmp; | 452 | char *p, *tmp; |
453 | 453 | ||
454 | struct { | 454 | struct { |
455 | /* | 455 | socklen_t len; |
456 | * As for following union. Trouble is that there are platforms | ||
457 | * that have socklen_t and there are platforms that don't, on | ||
458 | * some platforms socklen_t is int and on some size_t. So what | ||
459 | * one can do? One can cook #ifdef spaghetti, which is nothing | ||
460 | * but masochistic. Or one can do union between int and size_t. | ||
461 | * One naturally does it primarily for 64-bit platforms where | ||
462 | * sizeof(int) != sizeof(size_t). But would it work? Note that | ||
463 | * if size_t member is initialized to 0, then later int member | ||
464 | * assignment naturally does the job on little-endian platforms | ||
465 | * regardless accept's expectations! What about big-endians? | ||
466 | * If accept expects int*, then it works, and if size_t*, then | ||
467 | * length value would appear as unreasonably large. But this | ||
468 | * won't prevent it from filling in the address structure. The | ||
469 | * trouble of course would be if accept returns more data than | ||
470 | * actual buffer can accomodate and overwrite stack... That's | ||
471 | * where early OPENSSL_assert comes into picture. Besides, the | ||
472 | * only 64-bit big-endian platform found so far that expects | ||
473 | * size_t* is HP-UX, where stack grows towards higher address. | ||
474 | * <appro> | ||
475 | */ | ||
476 | union { | ||
477 | size_t s; | ||
478 | int i; | ||
479 | } len; | ||
480 | union { | 456 | union { |
481 | struct sockaddr sa; | 457 | struct sockaddr sa; |
482 | struct sockaddr_in sa_in; | 458 | struct sockaddr_in sa_in; |
@@ -484,15 +460,9 @@ BIO_accept(int sock, char **addr) | |||
484 | } from; | 460 | } from; |
485 | } sa; | 461 | } sa; |
486 | 462 | ||
487 | sa.len.s = 0; | 463 | sa.len = sizeof(sa.from); |
488 | sa.len.i = sizeof(sa.from); | ||
489 | memset(&sa.from, 0, sizeof(sa.from)); | 464 | memset(&sa.from, 0, sizeof(sa.from)); |
490 | ret = accept(sock, &sa.from.sa, (void *)&sa.len); | 465 | ret = accept(sock, &sa.from.sa, &sa.len); |
491 | if (sizeof(sa.len.i) != sizeof(sa.len.s) && sa.len.i == 0) { | ||
492 | OPENSSL_assert(sa.len.s <= sizeof(sa.from)); | ||
493 | sa.len.i = (int)sa.len.s; | ||
494 | /* use sa.len.i from this point */ | ||
495 | } | ||
496 | if (ret == -1) { | 466 | if (ret == -1) { |
497 | if (BIO_sock_should_retry(ret)) | 467 | if (BIO_sock_should_retry(ret)) |
498 | return -2; | 468 | return -2; |
@@ -511,7 +481,7 @@ BIO_accept(int sock, char **addr) | |||
511 | static union { | 481 | static union { |
512 | void *p; | 482 | void *p; |
513 | int (*f)(const struct sockaddr *, | 483 | int (*f)(const struct sockaddr *, |
514 | size_t/*socklen_t*/, char *, size_t, | 484 | socklen_t, char *, size_t, |
515 | char *, size_t, int); | 485 | char *, size_t, int); |
516 | } p_getnameinfo = {NULL}; | 486 | } p_getnameinfo = {NULL}; |
517 | /* 2nd argument to getnameinfo is specified to | 487 | /* 2nd argument to getnameinfo is specified to |
@@ -527,7 +497,7 @@ BIO_accept(int sock, char **addr) | |||
527 | if (p_getnameinfo.p == (void *) - 1) | 497 | if (p_getnameinfo.p == (void *) - 1) |
528 | break; | 498 | break; |
529 | 499 | ||
530 | if ((*p_getnameinfo.f)(&sa.from.sa, sa.len.i, h, sizeof(h), | 500 | if ((*p_getnameinfo.f)(&sa.from.sa, sa.len, h, sizeof(h), |
531 | s, sizeof(s), NI_NUMERICHOST|NI_NUMERICSERV)) | 501 | s, sizeof(s), NI_NUMERICHOST|NI_NUMERICSERV)) |
532 | break; | 502 | break; |
533 | nl = strlen(h) + strlen(s) + 2; | 503 | nl = strlen(h) + strlen(s) + 2; |
diff --git a/src/lib/libssl/src/crypto/bio/bss_dgram.c b/src/lib/libssl/src/crypto/bio/bss_dgram.c index a3b5bb6574..ab269aeba3 100644 --- a/src/lib/libssl/src/crypto/bio/bss_dgram.c +++ b/src/lib/libssl/src/crypto/bio/bss_dgram.c | |||
@@ -331,13 +331,7 @@ dgram_read(BIO *b, char *out, int outl) | |||
331 | bio_dgram_data *data = (bio_dgram_data *)b->ptr; | 331 | bio_dgram_data *data = (bio_dgram_data *)b->ptr; |
332 | 332 | ||
333 | struct { | 333 | struct { |
334 | /* | 334 | socklen_t len; |
335 | * See commentary in b_sock.c. <appro> | ||
336 | */ | ||
337 | union { | ||
338 | size_t s; | ||
339 | int i; | ||
340 | } len; | ||
341 | union { | 335 | union { |
342 | struct sockaddr sa; | 336 | struct sockaddr sa; |
343 | struct sockaddr_in sa_in; | 337 | struct sockaddr_in sa_in; |
@@ -345,18 +339,13 @@ dgram_read(BIO *b, char *out, int outl) | |||
345 | } peer; | 339 | } peer; |
346 | } sa; | 340 | } sa; |
347 | 341 | ||
348 | sa.len.s = 0; | 342 | sa.len = sizeof(sa.peer); |
349 | sa.len.i = sizeof(sa.peer); | ||
350 | 343 | ||
351 | if (out != NULL) { | 344 | if (out != NULL) { |
352 | errno = 0; | 345 | errno = 0; |
353 | memset(&sa.peer, 0x00, sizeof(sa.peer)); | 346 | memset(&sa.peer, 0x00, sizeof(sa.peer)); |
354 | dgram_adjust_rcv_timeout(b); | 347 | dgram_adjust_rcv_timeout(b); |
355 | ret = recvfrom(b->num, out, outl, 0, &sa.peer.sa,(void *)&sa.len); | 348 | ret = recvfrom(b->num, out, outl, 0, &sa.peer.sa, &sa.len); |
356 | if (sizeof(sa.len.i) != sizeof(sa.len.s) && sa.len.i == 0) { | ||
357 | OPENSSL_assert(sa.len.s <= sizeof(sa.peer)); | ||
358 | sa.len.i = (int)sa.len.s; | ||
359 | } | ||
360 | 349 | ||
361 | if (! data->connected && ret >= 0) | 350 | if (! data->connected && ret >= 0) |
362 | BIO_ctrl(b, BIO_CTRL_DGRAM_SET_PEER, 0, &sa.peer); | 351 | BIO_ctrl(b, BIO_CTRL_DGRAM_SET_PEER, 0, &sa.peer); |