Uploaded image for project: 'ZooKeeper'
  1. ZooKeeper
  2. ZOOKEEPER-1906

zkpython: invalid data in GetData for empty node

    Details

    • Type: Bug
    • Status: Resolved
    • Priority: Major
    • Resolution: Fixed
    • Affects Version/s: 3.4.6, 3.5.0
    • Fix Version/s: 3.4.7, 3.5.0
    • Component/s: contrib-bindings
    • Labels:
      None
    • Environment:

      FreeBSD

      Description

      In python if we ask zookeeper.get (which translates into pyzoo_get) for empty node we can get trash in result on Python level. Issue is pretty tricky. It goes like this:

      • python C extension allocates buffer with malloc buffer = malloc(sizeof(char)*buffer_len); and calls zoo_wget providing both buffer and buffer_len.
      • deserialize_GetDataResponse deserializes empty buffer and sets buffer_len to -1 and zoo_wget returns.
      • python C extension calls Py_BuildValue( "(s#,N)", buffer,buffer_len ... with buffer_len set to -1.
      • Py_BuildValue calls do_mkvalue to build python string which falls back to strlen(str) in case string length (buffer_len < 0) - that's our case.
      • usually strlen returns 0, because e.g. linux uses magic zero filled page as result of mmap (which is being copied upon page fault, i.e. when you want to write to it)
      • everything works!

      But on FreeBSD (not always) we can get random data in malloc result and this trash will be exposed to the user.

      Not sure about the right way to fix this, but something like

      Index: src/contrib/zkpython/src/c/zookeeper.c
      ===================================================================
      --- src/contrib/zkpython/src/c/zookeeper.c	(revision 1583238)
      +++ src/contrib/zkpython/src/c/zookeeper.c	(working copy)
      @@ -1223,7 +1223,7 @@
         }
       
         PyObject *stat_dict = build_stat( &stat );
      -  PyObject *ret = Py_BuildValue( "(s#,N)", buffer,buffer_len, stat_dict );
      +  PyObject *ret = Py_BuildValue( "(s#,N)", buffer,buffer_len < 0 ? 0 : buffer_len, stat_dict );
         free(buffer);
       
         return ret;
      

      should do the trick

        Attachments

          Activity

            People

            • Assignee:
              nekto0n Nikita Vetoshkin
              Reporter:
              nekto0n Nikita Vetoshkin
            • Votes:
              0 Vote for this issue
              Watchers:
              4 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: