summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGregory P. Smith <greg@mad-scientist.com>2009-01-31 22:57:30 (GMT)
committerGregory P. Smith <greg@mad-scientist.com>2009-01-31 22:57:30 (GMT)
commitde1a8b720a8cc5a6dab5e293d322a43d7ecb5c69 (patch)
treede48d40fe9b7261a43d44005f0eda3512268db37
parenta528dc507caab7b549ec7b6a8f84c2a76dd6c1c7 (diff)
downloadcpython-de1a8b720a8cc5a6dab5e293d322a43d7ecb5c69.zip
cpython-de1a8b720a8cc5a6dab5e293d322a43d7ecb5c69.tar.gz
cpython-de1a8b720a8cc5a6dab5e293d322a43d7ecb5c69.tar.bz2
- 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().
-rw-r--r--Lib/test/test_socket.py36
-rw-r--r--Misc/NEWS4
-rw-r--r--Modules/socketmodule.c30
3 files changed, 61 insertions, 9 deletions
diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py
index 2980889..66664b4 100644
--- a/Lib/test/test_socket.py
+++ b/Lib/test/test_socket.py
@@ -356,6 +356,9 @@ class GeneralModuleTests(unittest.TestCase):
eq(socket.getservbyport(port, 'tcp'), service)
if udpport is not None:
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):
# Testing default timeout
@@ -456,15 +459,23 @@ class GeneralModuleTests(unittest.TestCase):
# XXX The following don't test module-level functionality...
- def testSockName(self):
- # Testing getsockname(). Use a temporary socket to elicit an unused
- # ephemeral port that we can use later in the test.
+ def _get_unused_port(self, bind_address='0.0.0.0'):
+ """Use a temporary socket to elicit an unused ephemeral port.
+
+ 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(("0.0.0.0", 0))
- (host, port) = tempsock.getsockname()
+ tempsock.bind((bind_address, 0))
+ host, port = tempsock.getsockname()
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.bind(("0.0.0.0", port))
name = sock.getsockname()
@@ -504,6 +515,19 @@ class GeneralModuleTests(unittest.TestCase):
self.assertEqual(sock.proto, 0)
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):
if os.name != "nt":
return
diff --git a/Misc/NEWS b/Misc/NEWS
index bce2207..c403b61 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -383,6 +383,10 @@ Library
- Issue #4861: ctypes.util.find_library(): Robustify. Fix library detection on
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
-----------
diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c
index c1e3cfe..fc85bcc 100644
--- a/Modules/socketmodule.c
+++ b/Modules/socketmodule.c
@@ -1259,6 +1259,12 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args,
PyMem_Free(host);
if (result < 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_port = htons((short)port);
*len_ret = sizeof *addr;
@@ -1291,6 +1297,12 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args,
PyMem_Free(host);
if (result < 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_port = htons((short)port);
addr->sin6_flowinfo = flowinfo;
@@ -1417,6 +1429,12 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args,
"Hardware address must be 8 bytes or less");
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->sll_family = AF_PACKET;
addr->sll_protocol = htons((short)protoNumber);
@@ -3446,13 +3464,19 @@ otherwise any protocol will match.");
static PyObject *
socket_getservbyport(PyObject *self, PyObject *args)
{
- unsigned short port;
+ int port;
char *proto=NULL;
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;
+ }
Py_BEGIN_ALLOW_THREADS
- sp = getservbyport(htons(port), proto);
+ sp = getservbyport(htons((short)port), proto);
Py_END_ALLOW_THREADS
if (sp == NULL) {
PyErr_SetString(socket_error, "port/proto not found");