Kaydet (Commit) de1a8b72 authored tarafından Gregory P. Smith's avatar Gregory P. Smith

- Issue #5104: The socket module now raises OverflowError when 16-bit port and

  protocol numbers are supplied outside the allowed 0-65536 range on bind()
  and getservbyport().
üst a528dc50
...@@ -356,6 +356,9 @@ class GeneralModuleTests(unittest.TestCase): ...@@ -356,6 +356,9 @@ class GeneralModuleTests(unittest.TestCase):
eq(socket.getservbyport(port, 'tcp'), service) eq(socket.getservbyport(port, 'tcp'), service)
if udpport is not None: if udpport is not None:
eq(socket.getservbyport(udpport, 'udp'), service) eq(socket.getservbyport(udpport, 'udp'), service)
# Make sure getservbyport does not accept out of range ports.
self.assertRaises(OverflowError, socket.getservbyport, -1)
self.assertRaises(OverflowError, socket.getservbyport, 65536)
def testDefaultTimeout(self): def testDefaultTimeout(self):
# Testing default timeout # Testing default timeout
...@@ -456,15 +459,23 @@ class GeneralModuleTests(unittest.TestCase): ...@@ -456,15 +459,23 @@ class GeneralModuleTests(unittest.TestCase):
# XXX The following don't test module-level functionality... # XXX The following don't test module-level functionality...
def testSockName(self): def _get_unused_port(self, bind_address='0.0.0.0'):
# Testing getsockname(). Use a temporary socket to elicit an unused """Use a temporary socket to elicit an unused ephemeral port.
# ephemeral port that we can use later in the test.
Args:
bind_address: Hostname or IP address to search for a port on.
Returns: A most likely to be unused port.
"""
tempsock = socket.socket() tempsock = socket.socket()
tempsock.bind(("0.0.0.0", 0)) tempsock.bind((bind_address, 0))
(host, port) = tempsock.getsockname() host, port = tempsock.getsockname()
tempsock.close() tempsock.close()
del tempsock return port
def testSockName(self):
# Testing getsockname()
port = self._get_unused_port()
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(("0.0.0.0", port)) sock.bind(("0.0.0.0", port))
name = sock.getsockname() name = sock.getsockname()
...@@ -504,6 +515,19 @@ class GeneralModuleTests(unittest.TestCase): ...@@ -504,6 +515,19 @@ class GeneralModuleTests(unittest.TestCase):
self.assertEqual(sock.proto, 0) self.assertEqual(sock.proto, 0)
sock.close() sock.close()
def test_getsockaddrarg(self):
host = '0.0.0.0'
port = self._get_unused_port(bind_address=host)
big_port = port + 65536
neg_port = port - 65536
sock = socket.socket()
try:
self.assertRaises(OverflowError, sock.bind, (host, big_port))
self.assertRaises(OverflowError, sock.bind, (host, neg_port))
sock.bind((host, port))
finally:
sock.close()
def test_sock_ioctl(self): def test_sock_ioctl(self):
if os.name != "nt": if os.name != "nt":
return return
......
...@@ -383,6 +383,10 @@ Library ...@@ -383,6 +383,10 @@ Library
- Issue #4861: ctypes.util.find_library(): Robustify. Fix library detection on - Issue #4861: ctypes.util.find_library(): Robustify. Fix library detection on
biarch systems. Try to rely on ldconfig only, without using objdump and gcc. biarch systems. Try to rely on ldconfig only, without using objdump and gcc.
- Issue #5104: The socket module now raises OverflowError when 16-bit port and
protocol numbers are supplied outside the allowed 0-65536 range on bind()
and getservbyport().
Tools/Demos Tools/Demos
----------- -----------
......
...@@ -1259,6 +1259,12 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, ...@@ -1259,6 +1259,12 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args,
PyMem_Free(host); PyMem_Free(host);
if (result < 0) if (result < 0)
return 0; return 0;
if (port < 0 || port > 0xffff) {
PyErr_SetString(
PyExc_OverflowError,
"getsockaddrarg: port must be 0-65535.");
return 0;
}
addr->sin_family = AF_INET; addr->sin_family = AF_INET;
addr->sin_port = htons((short)port); addr->sin_port = htons((short)port);
*len_ret = sizeof *addr; *len_ret = sizeof *addr;
...@@ -1291,6 +1297,12 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, ...@@ -1291,6 +1297,12 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args,
PyMem_Free(host); PyMem_Free(host);
if (result < 0) if (result < 0)
return 0; return 0;
if (port < 0 || port > 0xffff) {
PyErr_SetString(
PyExc_OverflowError,
"getsockaddrarg: port must be 0-65535.");
return 0;
}
addr->sin6_family = s->sock_family; addr->sin6_family = s->sock_family;
addr->sin6_port = htons((short)port); addr->sin6_port = htons((short)port);
addr->sin6_flowinfo = flowinfo; addr->sin6_flowinfo = flowinfo;
...@@ -1417,6 +1429,12 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, ...@@ -1417,6 +1429,12 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args,
"Hardware address must be 8 bytes or less"); "Hardware address must be 8 bytes or less");
return 0; return 0;
} }
if (protoNumber < 0 || protoNumber > 0xffff) {
PyErr_SetString(
PyExc_OverflowError,
"getsockaddrarg: protoNumber must be 0-65535.");
return 0;
}
addr = (struct sockaddr_ll*)addr_ret; addr = (struct sockaddr_ll*)addr_ret;
addr->sll_family = AF_PACKET; addr->sll_family = AF_PACKET;
addr->sll_protocol = htons((short)protoNumber); addr->sll_protocol = htons((short)protoNumber);
...@@ -3446,13 +3464,19 @@ otherwise any protocol will match."); ...@@ -3446,13 +3464,19 @@ otherwise any protocol will match.");
static PyObject * static PyObject *
socket_getservbyport(PyObject *self, PyObject *args) socket_getservbyport(PyObject *self, PyObject *args)
{ {
unsigned short port; int port;
char *proto=NULL; char *proto=NULL;
struct servent *sp; struct servent *sp;
if (!PyArg_ParseTuple(args, "H|s:getservbyport", &port, &proto)) if (!PyArg_ParseTuple(args, "i|s:getservbyport", &port, &proto))
return NULL;
if (port < 0 || port > 0xffff) {
PyErr_SetString(
PyExc_OverflowError,
"getservbyport: port must be 0-65535.");
return NULL; return NULL;
}
Py_BEGIN_ALLOW_THREADS Py_BEGIN_ALLOW_THREADS
sp = getservbyport(htons(port), proto); sp = getservbyport(htons((short)port), proto);
Py_END_ALLOW_THREADS Py_END_ALLOW_THREADS
if (sp == NULL) { if (sp == NULL) {
PyErr_SetString(socket_error, "port/proto not found"); PyErr_SetString(socket_error, "port/proto not found");
......
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