]> granicus.if.org Git - python/commitdiff
- Issue #5104: The socket module now raises OverflowError when 16-bit port and
authorGregory P. Smith <greg@mad-scientist.com>
Sat, 31 Jan 2009 22:57:30 +0000 (22:57 +0000)
committerGregory P. Smith <greg@mad-scientist.com>
Sat, 31 Jan 2009 22:57:30 +0000 (22:57 +0000)
  protocol numbers are supplied outside the allowed 0-65536 range on bind()
  and getservbyport().

Lib/test/test_socket.py
Misc/NEWS
Modules/socketmodule.c

index 2980889e9392bc8ef96ba7493db2c0bbcc4652ec..66664b44ed5bd481d38d3c9139370929db093679 100644 (file)
@@ -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
index bce220754c1dbb73b60fd7e2142f15f64fb6b820..c403b61ae495c44d5dc53a4bfe373148dacb0ddb 100644 (file)
--- 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
 -----------
 
index c1e3cfe175d82d3e041df46abf5e614a49b96710..fc85bcc894a9f358025aa4fbbfcfeff0292a5151 100644 (file)
@@ -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");