summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorJoel Sing <jsing@cvs.openbsd.org>2014-06-22 14:41:11 +0000
committerJoel Sing <jsing@cvs.openbsd.org>2014-06-22 14:41:11 +0000
commitdbc7cf1becfdcb28934e6b4bac8d643be688149e (patch)
tree21c080e561e515c7cbe039ff82e747e4af64fbdd /lib
parent836de2e2b1e2401b5e5e2569278a18a3bf159680 (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.c78
-rw-r--r--lib/libcrypto/bio/bio.h3
-rw-r--r--lib/libcrypto/bio/bio_err.c3
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"},