Re: [PATCH] libselinux: fix Python binding for security_load_policy()

Stephen Smalley <[email protected]> Fri, 24 Jul 2026 10:22:52 -0400
Newsgroups org.kernel.vger.selinux
Message-ID <CAEjxPJ7ZwBQ7A1-2qr-FB2pWKJdu45O7vyx+jvGtQ4jCFP==xQ@mail.gmail.com>
On Tue, Jul 21, 2026 at 1:16 PM Stephen Smalley
<[email protected]> wrote:
>
> Commit 9639f5d ("Add decent constants for python for return of
> getenforce call") also added a global typemap that forces every void *
> parameter to NULL from Python. This was intended to auto-supply NULL
> for the opaque auditdata parameter of avc_has_perm(), avc_audit(), and
> selinux_check_access(), but also matched the void *data parameter of
> security_load_policy(), forcing it to NULL and preventing its
> use. Restrict the auto-NULL typemap to only the auditdata parameters
> and provide a typemap for security_load_policy that supports passing
> any bytes-like object (bytes, bytearray, mmap) that can be handled.
>
> Fixes: https://github.com/SELinuxProject/selinux/issues/354
> Signed-off-by: Stephen Smalley <[email protected]>

Merged.

> ---
>  libselinux/src/selinuxswig_python.i | 25 +++++++++++++++++++++++--
>  1 file changed, 23 insertions(+), 2 deletions(-)
>
> diff --git a/libselinux/src/selinuxswig_python.i b/libselinux/src/selinuxswig_python.i
> index 03ed296d..c8c08a40 100644
> --- a/libselinux/src/selinuxswig_python.i
> +++ b/libselinux/src/selinuxswig_python.i
> @@ -88,9 +88,30 @@ def install(src, dest):
>    $1 = &temp;
>  }
>
> -%typemap(in, numinputs=0) void *(char *temp=NULL) {
> -       $1 = temp;
> +/*
> + * Auto-supply NULL for the opaque auditdata parameter on avc_has_perm(),
> + * avc_audit(), and selinux_check_access(); it is not usable from Python.
> + * Restricted by parameter name so that it does not swallow other void * args.
> + */
> +%typemap(in, numinputs=0) void *auditdata {
> +       $1 = NULL;
> +}
> +
> +/*
> + * security_load_policy(const void *data, size_t len) accept any
> + * object exposing the buffer protocol (bytes, bytearray, mmap, ...)
> + * as a single Python argument.
> + */
> +%typemap(in) (const void *data, size_t len)(Py_buffer view) {
> +       view.obj = NULL;
> +       if (PyObject_GetBuffer($input, &view, PyBUF_SIMPLE) < 0)
> +               SWIG_fail;
> +       $1 = view.buf;
> +       $2 = (size_t)view.len;
>  }
> +%typemap(freearg) (const void *data, size_t len) {
> +       PyBuffer_Release(&view$argnum);
> + }
>
>  /* Makes security_compute_user() return a Python list of contexts */
>  %typemap(argout) (char ***con) {
> --
> 2.55.0
>