mirror of
https://github.com/python/cpython.git
synced 2025-08-01 07:33:08 +00:00
- 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().
This commit is contained in:
parent
a528dc507c
commit
de1a8b720a
3 changed files with 63 additions and 11 deletions
|
@ -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):
|
||||||
|
|
||||||
# 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.
|
|
||||||
tempsock = socket.socket()
|
|
||||||
tempsock.bind(("0.0.0.0", 0))
|
|
||||||
(host, port) = tempsock.getsockname()
|
|
||||||
tempsock.close()
|
|
||||||
del tempsock
|
|
||||||
|
|
||||||
|
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.bind((bind_address, 0))
|
||||||
|
host, port = tempsock.getsockname()
|
||||||
|
tempsock.close()
|
||||||
|
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):
|
||||||
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
|
||||||
- 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,
|
||||||
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,
|
||||||
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,
|
||||||
"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.");
|
||||||
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;
|
return NULL;
|
||||||
|
if (port < 0 || port > 0xffff) {
|
||||||
|
PyErr_SetString(
|
||||||
|
PyExc_OverflowError,
|
||||||
|
"getservbyport: port must be 0-65535.");
|
||||||
|
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");
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue