Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 8cfd67c

Browse files
committed
(Merge 3.3) Issue #18135: Fix a possible integer overflow in
ssl.SSLSocket.write() and in ssl.SSLContext.load_cert_chain() for strings and passwords longer than 2 gigabytes.
2 parents 2ab07f0 + 9ee0203 commit 8cfd67c

2 files changed

Lines changed: 20 additions & 10 deletions

File tree

Misc/NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,10 @@ Core and Builtins
126126
Library
127127
-------
128128

129+
- Issue #18135: Fix a possible integer overflow in ssl.SSLSocket.write()
130+
and in ssl.SSLContext.load_cert_chain() for strings and passwords longer than
131+
2 gigabytes.
132+
129133
- Issue #11016: Add C implementation of the stat module as _stat.
130134

131135
- Issue #18248: Fix libffi build on AIX.

Modules/_ssl.c

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1172,7 +1172,7 @@ static PyObject *PySSL_selected_npn_protocol(PySSLSocket *self) {
11721172
const unsigned char *out;
11731173
unsigned int outlen;
11741174

1175-
SSL_get0_next_proto_negotiated(self->ssl,
1175+
SSL_get0_next_proto_negotiated(self->ssl,
11761176
&out, &outlen);
11771177

11781178
if (out == NULL)
@@ -1358,8 +1358,9 @@ static PyObject *PySSL_SSLwrite(PySSLSocket *self, PyObject *args)
13581358
goto error;
13591359
}
13601360
do {
1361+
len = (int)Py_MIN(buf.len, INT_MAX);
13611362
PySSL_BEGIN_ALLOW_THREADS
1362-
len = SSL_write(self->ssl, buf.buf, buf.len);
1363+
len = SSL_write(self->ssl, buf.buf, len);
13631364
err = SSL_get_error(self->ssl, len);
13641365
PySSL_END_ALLOW_THREADS
13651366
if (PyErr_CheckSignals()) {
@@ -1650,7 +1651,7 @@ PySSL_tls_unique_cb(PySSLSocket *self)
16501651
{
16511652
PyObject *retval = NULL;
16521653
char buf[PySSL_CB_MAXLEN];
1653-
int len;
1654+
size_t len;
16541655

16551656
if (SSL_session_reused(self->ssl) ^ !self->socket_type) {
16561657
/* if session is resumed XOR we are the client */
@@ -1662,7 +1663,6 @@ PySSL_tls_unique_cb(PySSLSocket *self)
16621663
}
16631664

16641665
/* It cannot be negative in current OpenSSL version as of July 2011 */
1665-
assert(len >= 0);
16661666
if (len == 0)
16671667
Py_RETURN_NONE;
16681668

@@ -1873,8 +1873,8 @@ set_ciphers(PySSLContext *self, PyObject *args)
18731873
#ifdef OPENSSL_NPN_NEGOTIATED
18741874
/* this callback gets passed to SSL_CTX_set_next_protos_advertise_cb */
18751875
static int
1876-
_advertiseNPN_cb(SSL *s,
1877-
const unsigned char **data, unsigned int *len,
1876+
_advertiseNPN_cb(SSL *s,
1877+
const unsigned char **data, unsigned int *len,
18781878
void *args)
18791879
{
18801880
PySSLContext *ssl_ctx = (PySSLContext *) args;
@@ -1891,7 +1891,7 @@ _advertiseNPN_cb(SSL *s,
18911891
}
18921892
/* this callback gets passed to SSL_CTX_set_next_proto_select_cb */
18931893
static int
1894-
_selectNPN_cb(SSL *s,
1894+
_selectNPN_cb(SSL *s,
18951895
unsigned char **out, unsigned char *outlen,
18961896
const unsigned char *server, unsigned int server_len,
18971897
void *args)
@@ -2025,7 +2025,7 @@ typedef struct {
20252025
PyThreadState *thread_state;
20262026
PyObject *callable;
20272027
char *password;
2028-
Py_ssize_t size;
2028+
int size;
20292029
int error;
20302030
} _PySSLPasswordInfo;
20312031

@@ -2059,6 +2059,12 @@ _pwinfo_set(_PySSLPasswordInfo *pw_info, PyObject* password,
20592059
goto error;
20602060
}
20612061

2062+
if (size > (Py_ssize_t)INT_MAX) {
2063+
PyErr_Format(PyExc_ValueError,
2064+
"password cannot be longer than %d bytes", INT_MAX);
2065+
goto error;
2066+
}
2067+
20622068
free(pw_info->password);
20632069
pw_info->password = malloc(size);
20642070
if (!pw_info->password) {
@@ -2067,7 +2073,7 @@ _pwinfo_set(_PySSLPasswordInfo *pw_info, PyObject* password,
20672073
goto error;
20682074
}
20692075
memcpy(pw_info->password, data, size);
2070-
pw_info->size = size;
2076+
pw_info->size = (int)size;
20712077

20722078
Py_XDECREF(password_bytes);
20732079
return 1;
@@ -3441,7 +3447,7 @@ PyInit__ssl(void)
34413447
}
34423448
if (PyModule_AddObject(m, "lib_codes_to_names", lib_codes_to_names))
34433449
return NULL;
3444-
3450+
34453451
/* OpenSSL version */
34463452
/* SSLeay() gives us the version of the library linked against,
34473453
which could be different from the headers version.

0 commit comments

Comments
 (0)