diff options
author | jsing <> | 2014-06-22 14:41:10 +0000 |
---|---|---|
committer | jsing <> | 2014-06-22 14:41:10 +0000 |
commit | 0e48583e384b473bddadeed479e2ac76911814bc (patch) | |
tree | a48d59c793ed018ac1b68d77e5b9dc0708d3bc84 | |
parent | fc342088a9e9234b5e22294af9d7a3b490705097 (diff) | |
download | openbsd-0e48583e384b473bddadeed479e2ac76911814bc.tar.gz openbsd-0e48583e384b473bddadeed479e2ac76911814bc.tar.bz2 openbsd-0e48583e384b473bddadeed479e2ac76911814bc.zip |
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@
-rw-r--r-- | src/lib/libcrypto/bio/b_sock.c | 78 | ||||
-rw-r--r-- | src/lib/libcrypto/bio/bio.h | 3 | ||||
-rw-r--r-- | src/lib/libcrypto/bio/bio_err.c | 3 | ||||
-rw-r--r-- | src/lib/libssl/src/crypto/bio/b_sock.c | 78 | ||||
-rw-r--r-- | src/lib/libssl/src/crypto/bio/bio.h | 3 | ||||
-rw-r--r-- | src/lib/libssl/src/crypto/bio/bio_err.c | 3 |
6 files changed, 100 insertions, 68 deletions
diff --git a/src/lib/libcrypto/bio/b_sock.c b/src/lib/libcrypto/bio/b_sock.c index 69be7861f0..ddd2abb625 100644 --- a/src/lib/libcrypto/bio/b_sock.c +++ b/src/lib/libcrypto/bio/b_sock.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: b_sock.c,v 1.38 2014/06/12 15:49:28 deraadt Exp $ */ | 1 | /* $OpenBSD: b_sock.c,v 1.39 2014/06/22 14:41:10 jsing Exp $ */ |
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
3 | * All rights reserved. | 3 | * All rights reserved. |
4 | * | 4 | * |
@@ -138,42 +138,56 @@ err: | |||
138 | int | 138 | int |
139 | BIO_get_port(const char *str, unsigned short *port_ptr) | 139 | BIO_get_port(const char *str, unsigned short *port_ptr) |
140 | { | 140 | { |
141 | int i; | ||
142 | struct servent *s; | 141 | struct servent *s; |
142 | long port; | ||
143 | char *ep; | ||
143 | 144 | ||
144 | if (str == NULL) { | 145 | if (str == NULL) { |
145 | BIOerr(BIO_F_BIO_GET_PORT, BIO_R_NO_PORT_DEFINED); | 146 | BIOerr(BIO_F_BIO_GET_PORT, BIO_R_NO_PORT_SPECIFIED); |
146 | return (0); | 147 | return (0); |
147 | } | 148 | } |
148 | i = atoi(str); | 149 | |
149 | if (i != 0) | 150 | errno = 0; |
150 | *port_ptr = (unsigned short)i; | 151 | port = strtol(str, &ep, 10); |
151 | else { | 152 | if (str[0] != '\0' && *ep == '\0') { |
152 | CRYPTO_w_lock(CRYPTO_LOCK_GETSERVBYNAME); | 153 | if (errno == ERANGE && (port == LONG_MAX || port == LONG_MIN)) { |
153 | s = getservbyname(str, "tcp"); | 154 | BIOerr(BIO_F_BIO_GET_PORT, BIO_R_INVALID_PORT_NUMBER); |
154 | if (s != NULL) | 155 | return (0); |
155 | *port_ptr = ntohs((unsigned short)s->s_port); | 156 | } |
156 | CRYPTO_w_unlock(CRYPTO_LOCK_GETSERVBYNAME); | 157 | if (port < 0 || port > 65535) { |
157 | if (s == NULL) { | 158 | BIOerr(BIO_F_BIO_GET_PORT, BIO_R_INVALID_PORT_NUMBER); |
158 | if (strcmp(str, "http") == 0) | 159 | return (0); |
159 | *port_ptr = 80; | 160 | } |
160 | else if (strcmp(str, "telnet") == 0) | 161 | |
161 | *port_ptr = 23; | 162 | *port_ptr = (unsigned short)port; |
162 | else if (strcmp(str, "socks") == 0) | 163 | return (1); |
163 | *port_ptr = 1080; | 164 | } |
164 | else if (strcmp(str, "https") == 0) | 165 | |
165 | *port_ptr = 443; | 166 | CRYPTO_w_lock(CRYPTO_LOCK_GETSERVBYNAME); |
166 | else if (strcmp(str, "ssl") == 0) | 167 | s = getservbyname(str, "tcp"); |
167 | *port_ptr = 443; | 168 | if (s != NULL) |
168 | else if (strcmp(str, "ftp") == 0) | 169 | *port_ptr = ntohs((unsigned short)s->s_port); |
169 | *port_ptr = 21; | 170 | CRYPTO_w_unlock(CRYPTO_LOCK_GETSERVBYNAME); |
170 | else if (strcmp(str, "gopher") == 0) | 171 | |
171 | *port_ptr = 70; | 172 | if (s == NULL) { |
172 | else { | 173 | if (strcmp(str, "http") == 0) |
173 | SYSerr(SYS_F_GETSERVBYNAME, errno); | 174 | *port_ptr = 80; |
174 | ERR_asprintf_error_data("service='%s'", str); | 175 | else if (strcmp(str, "telnet") == 0) |
175 | return (0); | 176 | *port_ptr = 23; |
176 | } | 177 | else if (strcmp(str, "socks") == 0) |
178 | *port_ptr = 1080; | ||
179 | else if (strcmp(str, "https") == 0) | ||
180 | *port_ptr = 443; | ||
181 | else if (strcmp(str, "ssl") == 0) | ||
182 | *port_ptr = 443; | ||
183 | else if (strcmp(str, "ftp") == 0) | ||
184 | *port_ptr = 21; | ||
185 | else if (strcmp(str, "gopher") == 0) | ||
186 | *port_ptr = 70; | ||
187 | else { | ||
188 | SYSerr(SYS_F_GETSERVBYNAME, errno); | ||
189 | ERR_asprintf_error_data("service='%s'", str); | ||
190 | return (0); | ||
177 | } | 191 | } |
178 | } | 192 | } |
179 | return (1); | 193 | return (1); |
diff --git a/src/lib/libcrypto/bio/bio.h b/src/lib/libcrypto/bio/bio.h index 2ec6119aaa..cc5ef618b5 100644 --- a/src/lib/libcrypto/bio/bio.h +++ b/src/lib/libcrypto/bio/bio.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: bio.h,v 1.23 2014/06/12 15:49:28 deraadt Exp $ */ | 1 | /* $OpenBSD: bio.h,v 1.24 2014/06/22 14:41:10 jsing Exp $ */ |
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
3 | * All rights reserved. | 3 | * All rights reserved. |
4 | * | 4 | * |
@@ -802,6 +802,7 @@ void ERR_load_BIO_strings(void); | |||
802 | #define BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET 107 | 802 | #define BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET 107 |
803 | #define BIO_R_INVALID_ARGUMENT 125 | 803 | #define BIO_R_INVALID_ARGUMENT 125 |
804 | #define BIO_R_INVALID_IP_ADDRESS 108 | 804 | #define BIO_R_INVALID_IP_ADDRESS 108 |
805 | #define BIO_R_INVALID_PORT_NUMBER 129 | ||
805 | #define BIO_R_IN_USE 123 | 806 | #define BIO_R_IN_USE 123 |
806 | #define BIO_R_KEEPALIVE 109 | 807 | #define BIO_R_KEEPALIVE 109 |
807 | #define BIO_R_NBIO_CONNECT_ERROR 110 | 808 | #define BIO_R_NBIO_CONNECT_ERROR 110 |
diff --git a/src/lib/libcrypto/bio/bio_err.c b/src/lib/libcrypto/bio/bio_err.c index e6bf958b6e..8307c1099f 100644 --- a/src/lib/libcrypto/bio/bio_err.c +++ b/src/lib/libcrypto/bio/bio_err.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: bio_err.c,v 1.14 2014/06/12 15:49:28 deraadt Exp $ */ | 1 | /* $OpenBSD: bio_err.c,v 1.15 2014/06/22 14:41:10 jsing Exp $ */ |
2 | /* ==================================================================== | 2 | /* ==================================================================== |
3 | * Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved. | 3 | * Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved. |
4 | * | 4 | * |
@@ -118,6 +118,7 @@ static ERR_STRING_DATA BIO_str_reasons[] = { | |||
118 | {ERR_REASON(BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET), "gethostbyname addr is not af inet"}, | 118 | {ERR_REASON(BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET), "gethostbyname addr is not af inet"}, |
119 | {ERR_REASON(BIO_R_INVALID_ARGUMENT) , "invalid argument"}, | 119 | {ERR_REASON(BIO_R_INVALID_ARGUMENT) , "invalid argument"}, |
120 | {ERR_REASON(BIO_R_INVALID_IP_ADDRESS) , "invalid ip address"}, | 120 | {ERR_REASON(BIO_R_INVALID_IP_ADDRESS) , "invalid ip address"}, |
121 | {ERR_REASON(BIO_R_INVALID_PORT_NUMBER) , "invalid port number"}, | ||
121 | {ERR_REASON(BIO_R_IN_USE) , "in use"}, | 122 | {ERR_REASON(BIO_R_IN_USE) , "in use"}, |
122 | {ERR_REASON(BIO_R_KEEPALIVE) , "keepalive"}, | 123 | {ERR_REASON(BIO_R_KEEPALIVE) , "keepalive"}, |
123 | {ERR_REASON(BIO_R_NBIO_CONNECT_ERROR) , "nbio connect error"}, | 124 | {ERR_REASON(BIO_R_NBIO_CONNECT_ERROR) , "nbio connect error"}, |
diff --git a/src/lib/libssl/src/crypto/bio/b_sock.c b/src/lib/libssl/src/crypto/bio/b_sock.c index 69be7861f0..ddd2abb625 100644 --- a/src/lib/libssl/src/crypto/bio/b_sock.c +++ b/src/lib/libssl/src/crypto/bio/b_sock.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: b_sock.c,v 1.38 2014/06/12 15:49:28 deraadt Exp $ */ | 1 | /* $OpenBSD: b_sock.c,v 1.39 2014/06/22 14:41:10 jsing Exp $ */ |
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
3 | * All rights reserved. | 3 | * All rights reserved. |
4 | * | 4 | * |
@@ -138,42 +138,56 @@ err: | |||
138 | int | 138 | int |
139 | BIO_get_port(const char *str, unsigned short *port_ptr) | 139 | BIO_get_port(const char *str, unsigned short *port_ptr) |
140 | { | 140 | { |
141 | int i; | ||
142 | struct servent *s; | 141 | struct servent *s; |
142 | long port; | ||
143 | char *ep; | ||
143 | 144 | ||
144 | if (str == NULL) { | 145 | if (str == NULL) { |
145 | BIOerr(BIO_F_BIO_GET_PORT, BIO_R_NO_PORT_DEFINED); | 146 | BIOerr(BIO_F_BIO_GET_PORT, BIO_R_NO_PORT_SPECIFIED); |
146 | return (0); | 147 | return (0); |
147 | } | 148 | } |
148 | i = atoi(str); | 149 | |
149 | if (i != 0) | 150 | errno = 0; |
150 | *port_ptr = (unsigned short)i; | 151 | port = strtol(str, &ep, 10); |
151 | else { | 152 | if (str[0] != '\0' && *ep == '\0') { |
152 | CRYPTO_w_lock(CRYPTO_LOCK_GETSERVBYNAME); | 153 | if (errno == ERANGE && (port == LONG_MAX || port == LONG_MIN)) { |
153 | s = getservbyname(str, "tcp"); | 154 | BIOerr(BIO_F_BIO_GET_PORT, BIO_R_INVALID_PORT_NUMBER); |
154 | if (s != NULL) | 155 | return (0); |
155 | *port_ptr = ntohs((unsigned short)s->s_port); | 156 | } |
156 | CRYPTO_w_unlock(CRYPTO_LOCK_GETSERVBYNAME); | 157 | if (port < 0 || port > 65535) { |
157 | if (s == NULL) { | 158 | BIOerr(BIO_F_BIO_GET_PORT, BIO_R_INVALID_PORT_NUMBER); |
158 | if (strcmp(str, "http") == 0) | 159 | return (0); |
159 | *port_ptr = 80; | 160 | } |
160 | else if (strcmp(str, "telnet") == 0) | 161 | |
161 | *port_ptr = 23; | 162 | *port_ptr = (unsigned short)port; |
162 | else if (strcmp(str, "socks") == 0) | 163 | return (1); |
163 | *port_ptr = 1080; | 164 | } |
164 | else if (strcmp(str, "https") == 0) | 165 | |
165 | *port_ptr = 443; | 166 | CRYPTO_w_lock(CRYPTO_LOCK_GETSERVBYNAME); |
166 | else if (strcmp(str, "ssl") == 0) | 167 | s = getservbyname(str, "tcp"); |
167 | *port_ptr = 443; | 168 | if (s != NULL) |
168 | else if (strcmp(str, "ftp") == 0) | 169 | *port_ptr = ntohs((unsigned short)s->s_port); |
169 | *port_ptr = 21; | 170 | CRYPTO_w_unlock(CRYPTO_LOCK_GETSERVBYNAME); |
170 | else if (strcmp(str, "gopher") == 0) | 171 | |
171 | *port_ptr = 70; | 172 | if (s == NULL) { |
172 | else { | 173 | if (strcmp(str, "http") == 0) |
173 | SYSerr(SYS_F_GETSERVBYNAME, errno); | 174 | *port_ptr = 80; |
174 | ERR_asprintf_error_data("service='%s'", str); | 175 | else if (strcmp(str, "telnet") == 0) |
175 | return (0); | 176 | *port_ptr = 23; |
176 | } | 177 | else if (strcmp(str, "socks") == 0) |
178 | *port_ptr = 1080; | ||
179 | else if (strcmp(str, "https") == 0) | ||
180 | *port_ptr = 443; | ||
181 | else if (strcmp(str, "ssl") == 0) | ||
182 | *port_ptr = 443; | ||
183 | else if (strcmp(str, "ftp") == 0) | ||
184 | *port_ptr = 21; | ||
185 | else if (strcmp(str, "gopher") == 0) | ||
186 | *port_ptr = 70; | ||
187 | else { | ||
188 | SYSerr(SYS_F_GETSERVBYNAME, errno); | ||
189 | ERR_asprintf_error_data("service='%s'", str); | ||
190 | return (0); | ||
177 | } | 191 | } |
178 | } | 192 | } |
179 | return (1); | 193 | return (1); |
diff --git a/src/lib/libssl/src/crypto/bio/bio.h b/src/lib/libssl/src/crypto/bio/bio.h index 2ec6119aaa..cc5ef618b5 100644 --- a/src/lib/libssl/src/crypto/bio/bio.h +++ b/src/lib/libssl/src/crypto/bio/bio.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: bio.h,v 1.23 2014/06/12 15:49:28 deraadt Exp $ */ | 1 | /* $OpenBSD: bio.h,v 1.24 2014/06/22 14:41:10 jsing Exp $ */ |
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
3 | * All rights reserved. | 3 | * All rights reserved. |
4 | * | 4 | * |
@@ -802,6 +802,7 @@ void ERR_load_BIO_strings(void); | |||
802 | #define BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET 107 | 802 | #define BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET 107 |
803 | #define BIO_R_INVALID_ARGUMENT 125 | 803 | #define BIO_R_INVALID_ARGUMENT 125 |
804 | #define BIO_R_INVALID_IP_ADDRESS 108 | 804 | #define BIO_R_INVALID_IP_ADDRESS 108 |
805 | #define BIO_R_INVALID_PORT_NUMBER 129 | ||
805 | #define BIO_R_IN_USE 123 | 806 | #define BIO_R_IN_USE 123 |
806 | #define BIO_R_KEEPALIVE 109 | 807 | #define BIO_R_KEEPALIVE 109 |
807 | #define BIO_R_NBIO_CONNECT_ERROR 110 | 808 | #define BIO_R_NBIO_CONNECT_ERROR 110 |
diff --git a/src/lib/libssl/src/crypto/bio/bio_err.c b/src/lib/libssl/src/crypto/bio/bio_err.c index e6bf958b6e..8307c1099f 100644 --- a/src/lib/libssl/src/crypto/bio/bio_err.c +++ b/src/lib/libssl/src/crypto/bio/bio_err.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: bio_err.c,v 1.14 2014/06/12 15:49:28 deraadt Exp $ */ | 1 | /* $OpenBSD: bio_err.c,v 1.15 2014/06/22 14:41:10 jsing Exp $ */ |
2 | /* ==================================================================== | 2 | /* ==================================================================== |
3 | * Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved. | 3 | * Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved. |
4 | * | 4 | * |
@@ -118,6 +118,7 @@ static ERR_STRING_DATA BIO_str_reasons[] = { | |||
118 | {ERR_REASON(BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET), "gethostbyname addr is not af inet"}, | 118 | {ERR_REASON(BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET), "gethostbyname addr is not af inet"}, |
119 | {ERR_REASON(BIO_R_INVALID_ARGUMENT) , "invalid argument"}, | 119 | {ERR_REASON(BIO_R_INVALID_ARGUMENT) , "invalid argument"}, |
120 | {ERR_REASON(BIO_R_INVALID_IP_ADDRESS) , "invalid ip address"}, | 120 | {ERR_REASON(BIO_R_INVALID_IP_ADDRESS) , "invalid ip address"}, |
121 | {ERR_REASON(BIO_R_INVALID_PORT_NUMBER) , "invalid port number"}, | ||
121 | {ERR_REASON(BIO_R_IN_USE) , "in use"}, | 122 | {ERR_REASON(BIO_R_IN_USE) , "in use"}, |
122 | {ERR_REASON(BIO_R_KEEPALIVE) , "keepalive"}, | 123 | {ERR_REASON(BIO_R_KEEPALIVE) , "keepalive"}, |
123 | {ERR_REASON(BIO_R_NBIO_CONNECT_ERROR) , "nbio connect error"}, | 124 | {ERR_REASON(BIO_R_NBIO_CONNECT_ERROR) , "nbio connect error"}, |