Commit f70b884a authored by Stéphane Wirtel's avatar Stéphane Wirtel Committed by Victor Stinner

bpo-36337: socket.send()/sendall() use Py_ssize_t (GH-12397)

Fix buffer overflow in send() and sendall() methods of socket.socket
for data larger than 2 GiB.
parent 869652b4
Fix buffer overflow in :meth:`~socket.socket.send` and
:meth:`~socket.socket.sendall` methods of :func:`socket.socket` for data larger
than 2 GiB.
...@@ -625,16 +625,16 @@ set_gaierror(int error) ...@@ -625,16 +625,16 @@ set_gaierror(int error)
#ifdef __VMS #ifdef __VMS
/* Function to send in segments */ /* Function to send in segments */
static int static Py_ssize_t
sendsegmented(int sock_fd, char *buf, int len, int flags) sendsegmented(int sock_fd, char *buf, Py_ssize_t len, int flags)
{ {
int n = 0; int n = 0;
int remaining = len; Py_ssize_t remaining = len;
while (remaining > 0) { while (remaining > 0) {
unsigned int segment; unsigned int segment;
segment = (remaining >= SEGMENT_SIZE ? SEGMENT_SIZE : remaining); segment = ((size_t)remaining >= SEGMENT_SIZE ? SEGMENT_SIZE : (unsigned int) remaining);
n = send(sock_fd, buf, segment, flags); n = send(sock_fd, buf, segment, flags);
if (n < 0) { if (n < 0) {
return n; return n;
...@@ -2797,7 +2797,8 @@ static PyObject * ...@@ -2797,7 +2797,8 @@ static PyObject *
sock_send(PySocketSockObject *s, PyObject *args) sock_send(PySocketSockObject *s, PyObject *args)
{ {
char *buf; char *buf;
int len, n = -1, flags = 0, timeout; int flags = 0, timeout;
Py_ssize_t len, n = -1;
Py_buffer pbuf; Py_buffer pbuf;
if (!PyArg_ParseTuple(args, "s*|i:send", &pbuf, &flags)) if (!PyArg_ParseTuple(args, "s*|i:send", &pbuf, &flags))
...@@ -2813,12 +2814,18 @@ sock_send(PySocketSockObject *s, PyObject *args) ...@@ -2813,12 +2814,18 @@ sock_send(PySocketSockObject *s, PyObject *args)
BEGIN_SELECT_LOOP(s) BEGIN_SELECT_LOOP(s)
Py_BEGIN_ALLOW_THREADS Py_BEGIN_ALLOW_THREADS
timeout = internal_select_ex(s, 1, interval); timeout = internal_select_ex(s, 1, interval);
if (!timeout) if (!timeout) {
#ifdef __VMS #ifdef __VMS
n = sendsegmented(s->sock_fd, buf, len, flags); n = sendsegmented(s->sock_fd, buf, len, flags);
#elif defined(MS_WINDOWS)
if (len > INT_MAX) {
len = INT_MAX;
}
n = send(s->sock_fd, buf, (int)len, flags);
#else #else
n = send(s->sock_fd, buf, len, flags); n = send(s->sock_fd, buf, len, flags);
#endif #endif
}
Py_END_ALLOW_THREADS Py_END_ALLOW_THREADS
if (timeout == 1) { if (timeout == 1) {
PyBuffer_Release(&pbuf); PyBuffer_Release(&pbuf);
...@@ -2830,7 +2837,7 @@ sock_send(PySocketSockObject *s, PyObject *args) ...@@ -2830,7 +2837,7 @@ sock_send(PySocketSockObject *s, PyObject *args)
PyBuffer_Release(&pbuf); PyBuffer_Release(&pbuf);
if (n < 0) if (n < 0)
return s->errorhandler(); return s->errorhandler();
return PyInt_FromLong((long)n); return PyInt_FromSsize_t(n);
} }
PyDoc_STRVAR(send_doc, PyDoc_STRVAR(send_doc,
...@@ -2847,7 +2854,8 @@ static PyObject * ...@@ -2847,7 +2854,8 @@ static PyObject *
sock_sendall(PySocketSockObject *s, PyObject *args) sock_sendall(PySocketSockObject *s, PyObject *args)
{ {
char *buf; char *buf;
int len, n = -1, flags = 0, timeout, saved_errno; int flags = 0, timeout, saved_errno;
Py_ssize_t len, n = -1;
Py_buffer pbuf; Py_buffer pbuf;
if (!PyArg_ParseTuple(args, "s*|i:sendall", &pbuf, &flags)) if (!PyArg_ParseTuple(args, "s*|i:sendall", &pbuf, &flags))
...@@ -2868,6 +2876,11 @@ sock_sendall(PySocketSockObject *s, PyObject *args) ...@@ -2868,6 +2876,11 @@ sock_sendall(PySocketSockObject *s, PyObject *args)
if (!timeout) { if (!timeout) {
#ifdef __VMS #ifdef __VMS
n = sendsegmented(s->sock_fd, buf, len, flags); n = sendsegmented(s->sock_fd, buf, len, flags);
#elif defined(MS_WINDOWS)
if (len > INT_MAX) {
len = INT_MAX;
}
n = send(s->sock_fd, buf, (int)len, flags);
#else #else
n = send(s->sock_fd, buf, len, flags); n = send(s->sock_fd, buf, len, flags);
#endif #endif
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment