]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
pygensec: Don't modify Python bytes objects
authorJoseph Sutton <josephsutton@catalyst.net.nz>
Mon, 19 Jul 2021 22:48:41 +0000 (10:48 +1200)
committerAndrew Bartlett <abartlet@samba.org>
Wed, 18 Aug 2021 22:28:33 +0000 (22:28 +0000)
gensec_update() and gensec_unwrap() can both modify their input buffers
(for example, during the inplace RRC operation on GSSAPI tokens).
However, buffers obtained from Python bytes objects must not be modified
in any way. Create a copy of the input buffer so the original isn't
modified.

Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
source4/auth/gensec/gensec_gssapi.c
source4/auth/gensec/pygensec.c

index 9adc477a15cbf2de651ef154bc41102feb73ceeb..e33c78462e21515a3b7d21e353afa0f52b87788f 100644 (file)
@@ -1168,6 +1168,10 @@ static NTSTATUS gensec_gssapi_unwrap(struct gensec_security *gensec_security,
                }
        }
        
+       /*
+        * FIXME: input_message_buffer is marked const, but gss_unwrap() may
+        * modify it (see calls to rrc_rotate() in _gssapi_unwrap_cfx()).
+        */
        maj_stat = gss_unwrap(&min_stat, 
                              gensec_gssapi_state->gssapi_context, 
                              &input_token,
index f1f845a4663d5be2def2266232bc6abc9ac882e5..dd63fa58348fa0807615fea4b7ccda6eb9ccf5d3 100644 (file)
@@ -468,6 +468,9 @@ static PyObject *py_gensec_update(PyObject *self, PyObject *args)
        PyObject *py_bytes, *result, *py_in;
        struct gensec_security *security = pytalloc_get_type(self, struct gensec_security);
        PyObject *finished_processing;
+       char *data = NULL;
+       Py_ssize_t len;
+       int err;
 
        if (!PyArg_ParseTuple(args, "O", &py_in))
                return NULL;
@@ -477,14 +480,21 @@ static PyObject *py_gensec_update(PyObject *self, PyObject *args)
                return PyErr_NoMemory();
        }
 
-       if (!PyBytes_Check(py_in)) {
+       err = PyBytes_AsStringAndSize(py_in, &data, &len);
+       if (err) {
                talloc_free(mem_ctx);
-               PyErr_Format(PyExc_TypeError, "bytes expected");
                return NULL;
        }
 
-       in.data = (uint8_t *)PyBytes_AsString(py_in);
-       in.length = PyBytes_Size(py_in);
+       /*
+        * Make a copy of the input buffer, as gensec_update may modify its
+        * input argument.
+        */
+       in = data_blob_talloc(mem_ctx, data, len);
+       if (!in.data) {
+               talloc_free(mem_ctx);
+               return PyErr_NoMemory();
+       }
 
        status = gensec_update(security, mem_ctx, in, &out);
 
@@ -556,6 +566,9 @@ static PyObject *py_gensec_unwrap(PyObject *self, PyObject *args)
        DATA_BLOB in, out;
        PyObject *ret, *py_in;
        struct gensec_security *security = pytalloc_get_type(self, struct gensec_security);
+       char *data = NULL;
+       Py_ssize_t len;
+       int err;
 
        if (!PyArg_ParseTuple(args, "O", &py_in))
                return NULL;
@@ -565,14 +578,21 @@ static PyObject *py_gensec_unwrap(PyObject *self, PyObject *args)
                return PyErr_NoMemory();
        }
 
-       if (!PyBytes_Check(py_in)) {
+       err = PyBytes_AsStringAndSize(py_in, &data, &len);
+       if (err) {
                talloc_free(mem_ctx);
-               PyErr_Format(PyExc_TypeError, "bytes expected");
                return NULL;
        }
 
-       in.data = (uint8_t *)PyBytes_AsString(py_in);
-       in.length = PyBytes_Size(py_in);
+       /*
+        * Make a copy of the input buffer, as gensec_unwrap may modify its
+        * input argument.
+        */
+       in = data_blob_talloc(mem_ctx, data, len);
+       if (!in.data) {
+               talloc_free(mem_ctx);
+               return PyErr_NoMemory();
+       }
 
        status = gensec_unwrap(security, mem_ctx, &in, &out);