summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormiod <>2014-04-23 20:59:36 +0000
committermiod <>2014-04-23 20:59:36 +0000
commit2200007b52bd1fa0d16b0f986bb90e51ec5fcf01 (patch)
tree1096190589e0961bf69454ee8670bf22d4a20a41
parenta874a9e945512d316a64779e37a6b661549ae60d (diff)
downloadopenbsd-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.c40
-rw-r--r--src/lib/libcrypto/bio/bss_dgram.c17
-rw-r--r--src/lib/libssl/src/crypto/bio/b_sock.c40
-rw-r--r--src/lib/libssl/src/crypto/bio/bss_dgram.c17
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);