diff options
author | Joel Sing <jsing@cvs.openbsd.org> | 2014-06-22 14:41:11 +0000 |
---|---|---|
committer | Joel Sing <jsing@cvs.openbsd.org> | 2014-06-22 14:41:11 +0000 |
commit | dbc7cf1becfdcb28934e6b4bac8d643be688149e (patch) | |
tree | 21c080e561e515c7cbe039ff82e747e4af64fbdd /lib | |
parent | 836de2e2b1e2401b5e5e2569278a18a3bf159680 (diff) |
In BIO_get_port(), use strol() with appropriate range checks rather than
an atoi() followed by an unsigned short cast. This stops things like "-1"
and "66536" from being considered to be "valid" port numbers.
ok beck@ deraadt@
Diffstat (limited to 'lib')
-rw-r--r-- | lib/libcrypto/bio/b_sock.c | 78 | ||||
-rw-r--r-- | lib/libcrypto/bio/bio.h | 3 | ||||
-rw-r--r-- | lib/libcrypto/bio/bio_err.c | 3 |
3 files changed, 50 insertions, 34 deletions
diff --git a/lib/libcrypto/bio/b_sock.c b/lib/libcrypto/bio/b_sock.c index 69be7861f03..ddd2abb625c 100644 --- a/lib/libcrypto/bio/b_sock.c +++ b/lib/libcrypto/bio/b_sock.c @@ -1,4 +1,4 @@ -/* $OpenBSD: b_sock.c,v 1.38 2014/06/12 15:49:28 deraadt Exp $ */ +/* $OpenBSD: b_sock.c,v 1.39 2014/06/22 14:41:10 jsing Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -138,42 +138,56 @@ err: int BIO_get_port(const char *str, unsigned short *port_ptr) { - int i; struct servent *s; + long port; + char *ep; if (str == NULL) { - BIOerr(BIO_F_BIO_GET_PORT, BIO_R_NO_PORT_DEFINED); + BIOerr(BIO_F_BIO_GET_PORT, BIO_R_NO_PORT_SPECIFIED); return (0); } - i = atoi(str); - if (i != 0) - *port_ptr = (unsigned short)i; - else { - CRYPTO_w_lock(CRYPTO_LOCK_GETSERVBYNAME); - s = getservbyname(str, "tcp"); - if (s != NULL) - *port_ptr = ntohs((unsigned short)s->s_port); - CRYPTO_w_unlock(CRYPTO_LOCK_GETSERVBYNAME); - if (s == NULL) { - if (strcmp(str, "http") == 0) - *port_ptr = 80; - else if (strcmp(str, "telnet") == 0) - *port_ptr = 23; - else if (strcmp(str, "socks") == 0) - *port_ptr = 1080; - else if (strcmp(str, "https") == 0) - *port_ptr = 443; - else if (strcmp(str, "ssl") == 0) - *port_ptr = 443; - else if (strcmp(str, "ftp") == 0) - *port_ptr = 21; - else if (strcmp(str, "gopher") == 0) - *port_ptr = 70; - else { - SYSerr(SYS_F_GETSERVBYNAME, errno); - ERR_asprintf_error_data("service='%s'", str); - return (0); - } + + errno = 0; + port = strtol(str, &ep, 10); + if (str[0] != '\0' && *ep == '\0') { + if (errno == ERANGE && (port == LONG_MAX || port == LONG_MIN)) { + BIOerr(BIO_F_BIO_GET_PORT, BIO_R_INVALID_PORT_NUMBER); + return (0); + } + if (port < 0 || port > 65535) { + BIOerr(BIO_F_BIO_GET_PORT, BIO_R_INVALID_PORT_NUMBER); + return (0); + } + + *port_ptr = (unsigned short)port; + return (1); + } + + CRYPTO_w_lock(CRYPTO_LOCK_GETSERVBYNAME); + s = getservbyname(str, "tcp"); + if (s != NULL) + *port_ptr = ntohs((unsigned short)s->s_port); + CRYPTO_w_unlock(CRYPTO_LOCK_GETSERVBYNAME); + + if (s == NULL) { + if (strcmp(str, "http") == 0) + *port_ptr = 80; + else if (strcmp(str, "telnet") == 0) + *port_ptr = 23; + else if (strcmp(str, "socks") == 0) + *port_ptr = 1080; + else if (strcmp(str, "https") == 0) + *port_ptr = 443; + else if (strcmp(str, "ssl") == 0) + *port_ptr = 443; + else if (strcmp(str, "ftp") == 0) + *port_ptr = 21; + else if (strcmp(str, "gopher") == 0) + *port_ptr = 70; + else { + SYSerr(SYS_F_GETSERVBYNAME, errno); + ERR_asprintf_error_data("service='%s'", str); + return (0); } } return (1); diff --git a/lib/libcrypto/bio/bio.h b/lib/libcrypto/bio/bio.h index 2ec6119aaa9..cc5ef618b5d 100644 --- a/lib/libcrypto/bio/bio.h +++ b/lib/libcrypto/bio/bio.h @@ -1,4 +1,4 @@ -/* $OpenBSD: bio.h,v 1.23 2014/06/12 15:49:28 deraadt Exp $ */ +/* $OpenBSD: bio.h,v 1.24 2014/06/22 14:41:10 jsing Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -802,6 +802,7 @@ void ERR_load_BIO_strings(void); #define BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET 107 #define BIO_R_INVALID_ARGUMENT 125 #define BIO_R_INVALID_IP_ADDRESS 108 +#define BIO_R_INVALID_PORT_NUMBER 129 #define BIO_R_IN_USE 123 #define BIO_R_KEEPALIVE 109 #define BIO_R_NBIO_CONNECT_ERROR 110 diff --git a/lib/libcrypto/bio/bio_err.c b/lib/libcrypto/bio/bio_err.c index e6bf958b6e9..8307c1099fe 100644 --- a/lib/libcrypto/bio/bio_err.c +++ b/lib/libcrypto/bio/bio_err.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bio_err.c,v 1.14 2014/06/12 15:49:28 deraadt Exp $ */ +/* $OpenBSD: bio_err.c,v 1.15 2014/06/22 14:41:10 jsing Exp $ */ /* ==================================================================== * Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved. * @@ -118,6 +118,7 @@ static ERR_STRING_DATA BIO_str_reasons[] = { {ERR_REASON(BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET), "gethostbyname addr is not af inet"}, {ERR_REASON(BIO_R_INVALID_ARGUMENT) , "invalid argument"}, {ERR_REASON(BIO_R_INVALID_IP_ADDRESS) , "invalid ip address"}, + {ERR_REASON(BIO_R_INVALID_PORT_NUMBER) , "invalid port number"}, {ERR_REASON(BIO_R_IN_USE) , "in use"}, {ERR_REASON(BIO_R_KEEPALIVE) , "keepalive"}, {ERR_REASON(BIO_R_NBIO_CONNECT_ERROR) , "nbio connect error"}, |