Skip to content

Commit 9ee0203

Browse files
committed
Issue python#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.
1 parent 4569cd5 commit 9ee0203

File tree

2 files changed

+15
-5
lines changed

2 files changed

+15
-5
lines changed

Misc/NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ Core and Builtins
3535
Library
3636
-------
3737

38+
- Issue #18135: Fix a possible integer overflow in ssl.SSLSocket.write()
39+
and in ssl.SSLContext.load_cert_chain() for strings and passwords longer than
40+
2 gigabytes.
41+
3842
- Issue #18248: Fix libffi build on AIX.
3943

4044
- Issue #18259: Declare sethostname in socketmodule.c for AIX

Modules/_ssl.c

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1284,8 +1284,9 @@ static PyObject *PySSL_SSLwrite(PySSLSocket *self, PyObject *args)
12841284
goto error;
12851285
}
12861286
do {
1287+
len = (int)Py_MIN(buf.len, INT_MAX);
12871288
PySSL_BEGIN_ALLOW_THREADS
1288-
len = SSL_write(self->ssl, buf.buf, buf.len);
1289+
len = SSL_write(self->ssl, buf.buf, len);
12891290
err = SSL_get_error(self->ssl, len);
12901291
PySSL_END_ALLOW_THREADS
12911292
if (PyErr_CheckSignals()) {
@@ -1576,7 +1577,7 @@ PySSL_tls_unique_cb(PySSLSocket *self)
15761577
{
15771578
PyObject *retval = NULL;
15781579
char buf[PySSL_CB_MAXLEN];
1579-
int len;
1580+
size_t len;
15801581

15811582
if (SSL_session_reused(self->ssl) ^ !self->socket_type) {
15821583
/* if session is resumed XOR we are the client */
@@ -1588,7 +1589,6 @@ PySSL_tls_unique_cb(PySSLSocket *self)
15881589
}
15891590

15901591
/* It cannot be negative in current OpenSSL version as of July 2011 */
1591-
assert(len >= 0);
15921592
if (len == 0)
15931593
Py_RETURN_NONE;
15941594

@@ -1915,7 +1915,7 @@ typedef struct {
19151915
PyThreadState *thread_state;
19161916
PyObject *callable;
19171917
char *password;
1918-
Py_ssize_t size;
1918+
int size;
19191919
int error;
19201920
} _PySSLPasswordInfo;
19211921

@@ -1949,6 +1949,12 @@ _pwinfo_set(_PySSLPasswordInfo *pw_info, PyObject* password,
19491949
goto error;
19501950
}
19511951

1952+
if (size > (Py_ssize_t)INT_MAX) {
1953+
PyErr_Format(PyExc_ValueError,
1954+
"password cannot be longer than %d bytes", INT_MAX);
1955+
goto error;
1956+
}
1957+
19521958
free(pw_info->password);
19531959
pw_info->password = malloc(size);
19541960
if (!pw_info->password) {
@@ -1957,7 +1963,7 @@ _pwinfo_set(_PySSLPasswordInfo *pw_info, PyObject* password,
19571963
goto error;
19581964
}
19591965
memcpy(pw_info->password, data, size);
1960-
pw_info->size = size;
1966+
pw_info->size = (int)size;
19611967

19621968
Py_XDECREF(password_bytes);
19631969
return 1;

0 commit comments

Comments
 (0)