Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-python-prctl for openSUSE:Factory checked in at 2022-02-17 23:40:10 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-python-prctl (Old) and /work/SRC/openSUSE:Factory/.python-python-prctl.new.1958 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-python-prctl" Thu Feb 17 23:40:10 2022 rev:5 rq:955548 version:1.8.1 Changes: -------- --- /work/SRC/openSUSE:Factory/python-python-prctl/python-python-prctl.changes 2020-10-28 10:02:25.087314175 +0100 +++ /work/SRC/openSUSE:Factory/.python-python-prctl.new.1958/python-python-prctl.changes 2022-02-17 23:41:37.151700371 +0100 @@ -1,0 +2,13 @@ +Thu Feb 17 05:33:37 UTC 2022 - Steve Kowalik <steven.kowa...@suse.com> + +- Update to 1.8.1: + * No changelog. +- Rebase all patches. +- Add patch correct-uname-comparsion.patch: + * Support Linux >= 5.10 correctly. +- Add patch check-for-python310-correctly.patch: + * Check for Python 3.10 correctly. +- Add patch skip-speculation.patch: + * Skip a test that does not work in the OBS sandbox. + +------------------------------------------------------------------- Old: ---- python-prctl-1.7.tar.gz New: ---- check-for-python310-correctly.patch correct-uname-comparsion.patch python-prctl-1.8.1.tar.gz skip-speculation.patch ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-python-prctl.spec ++++++ --- /var/tmp/diff_new_pack.wp1wNl/_old 2022-02-17 23:41:37.823700366 +0100 +++ /var/tmp/diff_new_pack.wp1wNl/_new 2022-02-17 23:41:37.827700366 +0100 @@ -1,7 +1,7 @@ # # spec file for package python-python-prctl # -# Copyright (c) 2020 SUSE LLC +# Copyright (c) 2022 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -18,7 +18,7 @@ %{?!python_module:%define python_module() python-%{**} python3-%{**}} Name: python-python-prctl -Version: 1.7 +Version: 1.8.1 Release: 0 Summary: Python(ic) interface to the linux prctl syscall License: GPL-3.0-or-later @@ -30,6 +30,9 @@ Patch2: bigendian.patch Patch3: powerpc.patch Patch4: disable_no_new_privs.patch +Patch5: correct-uname-comparsion.patch +Patch6: check-for-python310-correctly.patch +Patch7: skip-speculation.patch BuildRequires: %{python_module devel} BuildRequires: %{python_module setuptools} BuildRequires: fdupes @@ -50,8 +53,7 @@ and allows you to set the process name as seen in ps and top. %prep -%setup -q -n python-prctl-%{version} -%autopatch -p1 +%autosetup -p1 -n python-prctl-%{version} cp %{SOURCE99} . %build ++++++ COPYING ++++++ --- /var/tmp/diff_new_pack.wp1wNl/_old 2022-02-17 23:41:37.859700366 +0100 +++ /var/tmp/diff_new_pack.wp1wNl/_new 2022-02-17 23:41:37.863700366 +0100 @@ -1,5 +1,5 @@ python-prctl - A python(ic) interface to the prctl syscall -Copyright (C) 2010-2018 Dennis Kaarsemaker <den...@kaarsemaker.net> +Copyright (C) 2010-2020 Dennis Kaarsemaker <den...@kaarsemaker.net> This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by ++++++ bigendian.patch ++++++ --- /var/tmp/diff_new_pack.wp1wNl/_old 2022-02-17 23:41:37.879700366 +0100 +++ /var/tmp/diff_new_pack.wp1wNl/_new 2022-02-17 23:41:37.883700366 +0100 @@ -1,16 +1,16 @@ -Index: python-prctl-1.7/_prctlmodule.c +Index: python-prctl-1.8.1/_prctlmodule.c =================================================================== ---- python-prctl-1.7.orig/_prctlmodule.c -+++ python-prctl-1.7/_prctlmodule.c -@@ -50,6 +50,7 @@ prctl_prctl(PyObject *self, PyObject *ar - { +--- python-prctl-1.8.1.orig/_prctlmodule.c ++++ python-prctl-1.8.1/_prctlmodule.c +@@ -51,6 +51,7 @@ prctl_prctl(PyObject *self, PyObject *ar long option = 0; long arg = 0; + long arg2 = 0; + int intarg = 0; char *argstr = NULL; char name[17] = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; int result; -@@ -286,12 +287,12 @@ prctl_prctl(PyObject *self, PyObject *ar +@@ -378,12 +379,12 @@ prctl_prctl(PyObject *self, PyObject *ar #ifdef PR_GET_TID_ADDRESS case(PR_GET_TID_ADDRESS): #endif ++++++ check-for-python310-correctly.patch ++++++ Index: python-prctl-1.8.1/test_prctl.py =================================================================== --- python-prctl-1.8.1.orig/test_prctl.py +++ python-prctl-1.8.1/test_prctl.py @@ -20,7 +20,7 @@ except ImportError: pass curdir = os.path.dirname(__file__) -builddir = os.path.join(curdir, 'build', 'lib.%s-%s' % (distutils.util.get_platform(), sys.version[0:3])) +builddir = os.path.join(curdir, 'build', 'lib.%s-%s' % (distutils.util.get_platform(), '.'.join([str(x) for x in sys.version_info[:2]]))) # Always run from the builddir if not os.path.exists(builddir) or \ ++++++ correct-uname-comparsion.patch ++++++ Index: python-prctl-1.8.1/test_prctl.py =================================================================== --- python-prctl-1.8.1.orig/test_prctl.py +++ python-prctl-1.8.1/test_prctl.py @@ -245,7 +245,7 @@ class PrctlTest(unittest.TestCase): @require('mpx_enable_management') def test_mpx(self): """Test MPX enabling/disabling""" - if os.uname().release > "5.4": + if tuple(int(x) for x in os.uname().release.split('.')[:2]) > (5, 4): self.assertRaises(OSError, prctl.mpx_enable_management) self.assertRaises(OSError, prctl.mpx_disable_management) else: ++++++ disable-sandboxed-test.patch ++++++ --- /var/tmp/diff_new_pack.wp1wNl/_old 2022-02-17 23:41:37.911700365 +0100 +++ /var/tmp/diff_new_pack.wp1wNl/_new 2022-02-17 23:41:37.911700365 +0100 @@ -1,13 +1,13 @@ -Index: python-prctl-1.7/test_prctl.py +Index: python-prctl-1.8.1/test_prctl.py =================================================================== ---- python-prctl-1.7.orig/test_prctl.py -+++ python-prctl-1.7/test_prctl.py -@@ -189,6 +189,7 @@ class PrctlTest(unittest.TestCase): - self.assertNotEqual(sp.returncode, 0) - os._exit(0) +--- python-prctl-1.8.1.orig/test_prctl.py ++++ python-prctl-1.8.1/test_prctl.py +@@ -240,6 +240,7 @@ class PrctlTest(unittest.TestCase): + else: + self.assertRaises(OSError, prctl.pac_reset_keys, prctl.PAC_APIAKEY) + @unittest.skip('borked in sandbox') def test_proctitle(self): """Test setting the process title, including too long titles""" - title = "This is a test!" + with open('/proc/self/cmdline') as fd: ++++++ disable_no_new_privs.patch ++++++ --- /var/tmp/diff_new_pack.wp1wNl/_old 2022-02-17 23:41:37.923700365 +0100 +++ /var/tmp/diff_new_pack.wp1wNl/_new 2022-02-17 23:41:37.927700365 +0100 @@ -1,8 +1,8 @@ -Index: b/test_prctl.py +Index: python-prctl-1.8.1/test_prctl.py =================================================================== ---- a/test_prctl.py -+++ b/test_prctl.py -@@ -220,6 +220,7 @@ class PrctlTest(unittest.TestCase): +--- python-prctl-1.8.1.orig/test_prctl.py ++++ python-prctl-1.8.1/test_prctl.py +@@ -259,6 +259,7 @@ class PrctlTest(unittest.TestCase): self.assertEqual(prctl.get_name(), name[:15]) @require('get_no_new_privs') ++++++ memory_failure_early_kill.patch ++++++ --- /var/tmp/diff_new_pack.wp1wNl/_old 2022-02-17 23:41:37.935700365 +0100 +++ /var/tmp/diff_new_pack.wp1wNl/_new 2022-02-17 23:41:37.939700365 +0100 @@ -1,13 +1,13 @@ -Index: python-prctl-1.7/test_prctl.py +Index: python-prctl-1.8.1/test_prctl.py =================================================================== ---- python-prctl-1.7.orig/test_prctl.py -+++ python-prctl-1.7/test_prctl.py -@@ -155,6 +155,7 @@ class PrctlTest(unittest.TestCase): +--- python-prctl-1.8.1.orig/test_prctl.py ++++ python-prctl-1.8.1/test_prctl.py +@@ -182,6 +182,7 @@ class PrctlTest(unittest.TestCase): self.assertEqual(prctl.get_keepcaps(), False) @require('set_mce_kill') + @unittest.skipIf(sys.maxsize <= 2**32 or arch == 's390x', 'no such file on this architecture') def test_mce_kill(self): """Test the MCE_KILL setting""" - fd = open('/proc/sys/vm/memory_failure_early_kill') + if not os.path.exists('/proc/sys/vm/memory_failure_early_kill'): ++++++ powerpc.patch ++++++ --- /var/tmp/diff_new_pack.wp1wNl/_old 2022-02-17 23:41:37.951700365 +0100 +++ /var/tmp/diff_new_pack.wp1wNl/_new 2022-02-17 23:41:37.971700365 +0100 @@ -1,7 +1,8 @@ -diff -ur python-prctl-1.7.orig/test_prctl.py python-prctl-1.7/test_prctl.py ---- python-prctl-1.7.orig/test_prctl.py 2020-09-07 11:09:38.544700725 +0200 -+++ python-prctl-1.7/test_prctl.py 2020-09-07 12:28:11.482301401 +0200 -@@ -44,6 +44,8 @@ +Index: python-prctl-1.8.1/test_prctl.py +=================================================================== +--- python-prctl-1.8.1.orig/test_prctl.py ++++ python-prctl-1.8.1/test_prctl.py +@@ -45,6 +45,8 @@ def require(attr): class PrctlTest(unittest.TestCase): # There are architecture specific tests arch = os.uname()[4] @@ -10,7 +11,7 @@ # prctl behaviour differs when root, so you should test as root and non-root am_root = os.geteuid() == 0 -@@ -110,6 +112,7 @@ +@@ -111,6 +113,7 @@ class PrctlTest(unittest.TestCase): self.assertEqual(prctl.get_dumpable(), False) self.assertRaises(TypeError, prctl.get_dumpable, "42") @@ -18,7 +19,7 @@ def test_endian(self): """Test manipulation of the endianness setting""" if self.arch == 'powerpc': -@@ -136,13 +139,55 @@ +@@ -137,13 +140,55 @@ class PrctlTest(unittest.TestCase): self.assertRaises(OSError, prctl.get_fpemu) self.assertRaises(OSError, prctl.set_fpemu, prctl.FPEMU_SIGFPE) ++++++ python-prctl-1.7.tar.gz -> python-prctl-1.8.1.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-prctl-1.7/PKG-INFO new/python-prctl-1.8.1/PKG-INFO --- old/python-prctl-1.7/PKG-INFO 2018-01-26 22:02:53.000000000 +0100 +++ new/python-prctl-1.8.1/PKG-INFO 2020-11-02 20:30:24.616678500 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: python-prctl -Version: 1.7 +Version: 1.8.1 Summary: Python(ic) interface to the linux prctl syscall Home-page: http://github.com/seveas/python-prctl Author: Dennis Kaarsemaker diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-prctl-1.7/_prctlmodule.c new/python-prctl-1.8.1/_prctlmodule.c --- old/python-prctl-1.7/_prctlmodule.c 2018-01-26 22:02:52.000000000 +0100 +++ new/python-prctl-1.8.1/_prctlmodule.c 2020-11-02 20:30:09.000000000 +0100 @@ -1,6 +1,6 @@ /* * python-pctrl -- python interface to the prctl function - * (c)2010-2018 Dennis Kaarsemaker <den...@kaarsemaker.net> + * (c)2010-2020 Dennis Kaarsemaker <den...@kaarsemaker.net> * See COPYING for licensing details */ @@ -50,6 +50,7 @@ { long option = 0; long arg = 0; + long arg2 = 0; char *argstr = NULL; char name[17] = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; int result; @@ -59,7 +60,7 @@ * prctl possibilities. int+string is required for (and only accepted for) * PR_SET_NAME */ - if(!PyArg_ParseTuple(args, "l|l", &option, &arg)) { + if(!PyArg_ParseTuple(args, "l|ll", &option, &arg, &arg2)) { if(!PyArg_ParseTuple(args, "ls", &option, &argstr)) { return NULL; } @@ -88,6 +89,9 @@ break; #endif case(PR_SET_DUMPABLE): +#ifdef PR_SET_IO_FLUSHER + case(PR_SET_IO_FLUSHER): +#endif case(PR_SET_KEEPCAPS): /* Only 0 and 1 are allowed */ arg = arg ? 1 : 0; @@ -113,6 +117,14 @@ return NULL; } break; +#ifdef PR_SET_FP_MODE + case(PR_SET_FP_MODE): + if(arg != PR_FP_MODE_FR && arg != PR_FP_MODE_FRE) { + PyErr_SetString(PyExc_ValueError, "Unknown floating-point mode"); + return NULL; + } + break; +#endif #ifdef PR_MCE_KILL case(PR_SET_MCE_KILL): if(arg != PR_MCE_KILL_DEFAULT && arg != PR_MCE_KILL_EARLY && arg != PR_MCE_KILL_LATE) { @@ -127,6 +139,14 @@ } strncpy(name, argstr, 16); break; +#ifdef PR_PAC_RESET_KEYS + case(PR_PAC_RESET_KEYS): + if(arg & ~(PR_PAC_APIAKEY | PR_PAC_APIBKEY | PR_PAC_APDAKEY | PR_PAC_APDBKEY | PR_PAC_APGAKEY)) { + PyErr_SetString(PyExc_ValueError, "Unknown pointer authentication key"); + return NULL; + } + break; +#endif case(PR_SET_PDEATHSIG): if(arg < 0 || arg > SIGRTMAX) { PyErr_SetString(PyExc_ValueError, "Unknown signal"); @@ -155,6 +175,38 @@ } break; #endif +#ifdef PR_GET_SPECULATION_CTRL + case(PR_SET_SPECULATION_CTRL): +#ifdef PR_SPEC_INDIRECT_BRANCH + if(arg != PR_SPEC_STORE_BYPASS && arg != PR_SPEC_INDIRECT_BRANCH) { +#else + if(arg != PR_SPEC_STORE_BYPASS) { +#endif + PyErr_SetString(PyExc_ValueError, "Invalid speculation control setting"); + return NULL; + } + if(arg2 != PR_SPEC_ENABLE + && arg2 != PR_SPEC_DISABLE + && arg2 != PR_SPEC_FORCE_DISABLE +#ifdef PR_SPEC_DISABLE_NOEXEC + && arg2 != PR_SPEC_DISABLE_NOEXEC +#endif + ) { + PyErr_SetString(PyExc_ValueError, "Invalid speculation control value"); + return NULL; + } + /* Intentionally not breaking */ + case(PR_GET_SPECULATION_CTRL): +#ifdef PR_SPEC_INDIRECT_BRANCH + if(arg != PR_SPEC_STORE_BYPASS && arg != PR_SPEC_INDIRECT_BRANCH) { +#else + if(arg != PR_SPEC_STORE_BYPASS) { +#endif + PyErr_SetString(PyExc_ValueError, "Invalid speculation control setting"); + return NULL; + } + break; +#endif case(PR_SET_TIMING): if(arg != PR_TIMING_STATISTICAL && arg != PR_TIMING_TIMESTAMP) { PyErr_SetString(PyExc_ValueError, "Invalid timing constant"); @@ -199,15 +251,30 @@ case(PR_SET_ENDIAN): case(PR_SET_FPEMU): case(PR_SET_FPEXC): +#ifdef PR_SET_FP_MODE + case(PR_GET_FP_MODE): + case(PR_SET_FP_MODE): +#endif +#ifdef PR_SET_IO_FLUSHER + case(PR_GET_IO_FLUSHER): + case(PR_SET_IO_FLUSHER): +#endif case(PR_SET_KEEPCAPS): case(PR_GET_KEEPCAPS): #ifdef PR_MCE_KILL case(PR_GET_MCE_KILL): #endif +#ifdef PR_MPX_ENABLE_MANAGEMENT + case(PR_MPX_ENABLE_MANAGEMENT): + case(PR_MPX_DISABLE_MANAGEMENT): +#endif #ifdef PR_GET_NO_NEW_PRIVS case(PR_GET_NO_NEW_PRIVS): case(PR_SET_NO_NEW_PRIVS): #endif +#ifdef PR_PAC_RESET_KEYS + case(PR_PAC_RESET_KEYS): +#endif case(PR_SET_PDEATHSIG): #if defined(PR_GET_PTRACER) && (PR_GET_PTRACER != NOT_SET) case(PR_GET_PTRACER): @@ -223,6 +290,18 @@ case(PR_SET_SECUREBITS): case(PR_GET_SECUREBITS): #endif +#ifdef PR_GET_SPECULATION_CTRL + case(PR_GET_SPECULATION_CTRL): + case(PR_SET_SPECULATION_CTRL): +#endif +#ifdef PR_TASK_PERF_EVENTS_DISABLE + case(PR_TASK_PERF_EVENTS_DISABLE): + case(PR_TASK_PERF_EVENTS_ENABLE): +#endif +#ifdef PR_SET_THP_DISABLE + case(PR_GET_THP_DISABLE): + case(PR_SET_THP_DISABLE): +#endif #ifdef PR_GET_TIMERSLACK case(PR_GET_TIMERSLACK): case(PR_SET_TIMERSLACK): @@ -233,7 +312,7 @@ case(PR_SET_TSC): #endif case(PR_SET_UNALIGN): - result = prctl(option, arg, 0, 0, 0); + result = prctl(option, arg, arg2, 0, 0); if(result < 0) { PyErr_SetFromErrno(PyExc_OSError); return NULL; @@ -243,12 +322,22 @@ case(PR_CAPBSET_READ): #endif case(PR_GET_DUMPABLE): +#ifdef PR_SET_IO_FLUSHER + case(PR_GET_IO_FLUSHER): +#endif case(PR_GET_KEEPCAPS): #ifdef PR_GET_SECCOMP case(PR_GET_SECCOMP): #endif +#ifdef PR_GET_THP_DISABLE + case(PR_GET_THP_DISABLE): +#endif case(PR_GET_TIMING): return PyBool_FromLong(result); + +#ifdef PR_SET_FP_MODE + case(PR_GET_FP_MODE): +#endif #ifdef PR_MCE_KILL case(PR_GET_MCE_KILL): #endif @@ -261,6 +350,9 @@ #ifdef PR_GET_SECUREBITS case(PR_GET_SECUREBITS): #endif +#ifdef PR_GET_SPECULATION_CTRL + case(PR_GET_SPECULATION_CTRL): +#endif #ifdef PR_GET_TIMERSLACK case(PR_GET_TIMERSLACK): #endif @@ -327,9 +419,6 @@ Py_RETURN_NONE; } -/* While not part of prctl, this complements PR_SET_NAME */ -static int __real_argc = -1; -static char **__real_argv = NULL; #if PY_MAJOR_VERSION < 3 #define _Py_GetArgcArgv Py_GetArgcArgv #else @@ -366,6 +455,9 @@ char **buf = NULL , *arg0 = NULL, *ptr = 0, *limit = NULL; Py_GetArgcArgv(argc, &argv_w); + if (*argc < 1 || argv_w == NULL) { + return 0; + } buf = (char **)malloc((*argc + 1) * sizeof(char *)); buf[*argc] = NULL; @@ -405,28 +497,24 @@ prctl_set_proctitle(PyObject *self, PyObject *args) { int argc = 0; - char **argv; - int len; char *title; + static size_t len = 0; + static char **argv; + if(!PyArg_ParseTuple(args, "s", &title)) { return NULL; } - if(__real_argc > 0) { - argc = __real_argc; - argv = __real_argv; - } - else { + if(argv == NULL) { _Py_GetArgcArgv(&argc, &argv); - __real_argc = argc; - __real_argv = argv; + if(argc > 0) { + len = (size_t)(argv[argc-1]) + strlen(argv[argc-1]) - (size_t)(argv[0]); + } } - if(argc <= 0) { + if(len <= 0) { PyErr_SetString(PyExc_RuntimeError, "Failed to locate argc/argv"); return NULL; } - /* Determine up to where we can write */ - len = (size_t)(argv[argc-1]) + strlen(argv[argc-1]) - (size_t)(argv[0]); strncpy(argv[0], title, len); if(strlen(title) < len) memset(argv[0] + strlen(title), 0, len - strlen(title)); @@ -644,6 +732,9 @@ namedconstant(PR_CAPBSET_READ); namedconstant(PR_CAPBSET_DROP); #endif +#ifdef PR_SET_CHILD_SUBREAPER + namedattribute(CHILD_SUBREAPER); +#endif namedattribute(DUMPABLE); namedattribute(ENDIAN); namedconstant(PR_ENDIAN_BIG); @@ -663,6 +754,14 @@ namedconstant(PR_FP_EXC_NONRECOV); namedconstant(PR_FP_EXC_ASYNC); namedconstant(PR_FP_EXC_PRECISE); +#ifdef PR_SET_FP_MODE + namedattribute(FP_MODE); + namedconstant(PR_FP_MODE_FR); + namedconstant(PR_FP_MODE_FRE); +#endif +#ifdef PR_SET_IO_FLUSHER + namedattribute(IO_FLUSHER); +#endif namedattribute(KEEPCAPS); #ifdef PR_MCE_KILL namedattribute(MCE_KILL); @@ -670,7 +769,22 @@ namedconstant(PR_MCE_KILL_EARLY); namedconstant(PR_MCE_KILL_LATE); #endif +#ifdef PR_MPX_ENABLE_MANAGEMENT + namedconstant(PR_MPX_ENABLE_MANAGEMENT); + namedconstant(PR_MPX_DISABLE_MANAGEMENT); +#endif namedattribute(NAME); +#ifdef PR_SET_NO_NEW_PRIVS + namedattribute(NO_NEW_PRIVS); +#endif +#ifdef PR_PAC_RESET_KEYS + namedconstant(PR_PAC_RESET_KEYS); + namedconstant(PR_PAC_APIAKEY); + namedconstant(PR_PAC_APIBKEY); + namedconstant(PR_PAC_APDAKEY); + namedconstant(PR_PAC_APDBKEY); + namedconstant(PR_PAC_APGAKEY); +#endif namedattribute(PDEATHSIG); #ifdef PR_SET_PTRACER namedattribute(PTRACER); @@ -678,19 +792,36 @@ #ifdef PR_SET_PTRACER_ANY namedconstant(PR_SET_PTRACER_ANY); #endif -#ifdef PR_SET_CHILD_SUBREAPER - namedattribute(CHILD_SUBREAPER); -#endif -#ifdef PR_SET_NO_NEW_PRIVS - namedattribute(NO_NEW_PRIVS); -#endif - #ifdef PR_GET_SECCOMP namedattribute(SECCOMP); #endif #ifdef PR_GET_SECUREBITS namedattribute(SECUREBITS); #endif +#ifdef PR_SET_SPECULATION_CTRL + namedattribute(SPECULATION_CTRL); + namedconstant(PR_SPEC_STORE_BYPASS); +#ifdef PR_SPEC_INDIRECT_BRANCH + namedconstant(PR_SPEC_INDIRECT_BRANCH); +#endif + namedconstant(PR_SPEC_PRCTL); + namedconstant(PR_SPEC_ENABLE); + namedconstant(PR_SPEC_DISABLE); + namedconstant(PR_SPEC_FORCE_DISABLE); +#ifdef PR_SPEC_DISABLE_NOEXEC + namedconstant(PR_SPEC_DISABLE_NOEXEC); +#endif +#endif +#ifdef PR_TASK_PERF_EVENTS_DISABLE + namedconstant(PR_TASK_PERF_EVENTS_DISABLE); + namedconstant(PR_TASK_PERF_EVENTS_ENABLE); +#endif +#ifdef PR_SET_THP_DISABLE + namedattribute(THP_DISABLE); +#endif +#ifdef PR_GET_TID_ADDRESS + namedconstant(PR_GET_TID_ADDRESS); +#endif #ifdef PR_GET_TIMERSLACK namedattribute(TIMERSLACK); #endif @@ -705,59 +836,70 @@ namedattribute(UNALIGN); namedconstant(PR_UNALIGN_NOPRINT); namedconstant(PR_UNALIGN_SIGBUS); -#ifdef PR_GET_TID_ADDRESS - namedconstant(PR_GET_TID_ADDRESS); -#endif + /* Add the CAP_* constants too */ namedconstant(CAP_EFFECTIVE); namedconstant(CAP_PERMITTED); namedconstant(CAP_INHERITABLE); + namedconstant(CAP_AUDIT_CONTROL); +#ifdef CAP_AUDIT_READ + namedconstant(CAP_AUDIT_READ); +#endif + namedconstant(CAP_AUDIT_WRITE); +#ifdef CAP_BLOCK_SUSPEND + namedconstant(CAP_BLOCK_SUSPEND); +#endif +#ifdef CAP_BPF + namedconstant(CAP_BPF); +#endif namedconstant(CAP_CHOWN); namedconstant(CAP_DAC_OVERRIDE); namedconstant(CAP_DAC_READ_SEARCH); namedconstant(CAP_FOWNER); namedconstant(CAP_FSETID); + namedconstant(CAP_IPC_LOCK); + namedconstant(CAP_IPC_OWNER); namedconstant(CAP_KILL); - namedconstant(CAP_SETGID); - namedconstant(CAP_SETUID); - namedconstant(CAP_SETPCAP); + namedconstant(CAP_LEASE); namedconstant(CAP_LINUX_IMMUTABLE); +#ifdef CAP_MAC_OVERRIDE + namedconstant(CAP_MAC_OVERRIDE); +#endif +#ifdef CAP_MAC_ADMIN + namedconstant(CAP_MAC_ADMIN); +#endif + namedconstant(CAP_MKNOD); + namedconstant(CAP_NET_ADMIN); namedconstant(CAP_NET_BIND_SERVICE); namedconstant(CAP_NET_BROADCAST); - namedconstant(CAP_NET_ADMIN); namedconstant(CAP_NET_RAW); - namedconstant(CAP_IPC_LOCK); - namedconstant(CAP_IPC_OWNER); - namedconstant(CAP_SYS_MODULE); - namedconstant(CAP_SYS_RAWIO); - namedconstant(CAP_SYS_CHROOT); - namedconstant(CAP_SYS_PTRACE); - namedconstant(CAP_SYS_PACCT); +#ifdef CAP_PERFMON + namedconstant(CAP_PERFMON); +#endif +#ifdef CAP_SETFCAP + namedconstant(CAP_SETFCAP); +#endif + namedconstant(CAP_SETGID); + namedconstant(CAP_SETPCAP); + namedconstant(CAP_SETUID); namedconstant(CAP_SYS_ADMIN); namedconstant(CAP_SYS_BOOT); + namedconstant(CAP_SYS_CHROOT); + namedconstant(CAP_SYS_MODULE); namedconstant(CAP_SYS_NICE); + namedconstant(CAP_SYS_PACCT); + namedconstant(CAP_SYS_PTRACE); + namedconstant(CAP_SYS_RAWIO); namedconstant(CAP_SYS_RESOURCE); namedconstant(CAP_SYS_TIME); namedconstant(CAP_SYS_TTY_CONFIG); - namedconstant(CAP_MKNOD); - namedconstant(CAP_LEASE); - namedconstant(CAP_AUDIT_WRITE); - namedconstant(CAP_AUDIT_CONTROL); -#ifdef CAP_SETFCAP - namedconstant(CAP_SETFCAP); -#endif -#ifdef CAP_MAC_OVERRIDE - namedconstant(CAP_MAC_OVERRIDE); -#endif -#ifdef CAP_MAC_ADMIN - namedconstant(CAP_MAC_ADMIN); -#endif #ifdef CAP_SYSLOG namedconstant(CAP_SYSLOG); #endif #ifdef CAP_WAKE_ALARM namedconstant(CAP_WAKE_ALARM); #endif + namedconstant(CAP_LAST_CAP); /* And the securebits constants */ namedconstant(SECURE_KEEP_CAPS); namedconstant(SECURE_NO_SETUID_FIXUP); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-prctl-1.7/docs/conf.py new/python-prctl-1.8.1/docs/conf.py --- old/python-prctl-1.7/docs/conf.py 2018-01-26 22:02:52.000000000 +0100 +++ new/python-prctl-1.8.1/docs/conf.py 2020-11-02 20:30:09.000000000 +0100 @@ -38,16 +38,16 @@ # General information about the project. project = u'python-prctl' -copyright = u'2010-2018, Dennis Kaarsemaker' +copyright = u'2010-2020, Dennis Kaarsemaker' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # # The short X.Y version. -version = '1.7' +version = '1.8' # The full version, including alpha/beta/rc tags. -release = '1.7' +release = '1.8.1' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-prctl-1.7/docs/index.rst new/python-prctl-1.8.1/docs/index.rst --- old/python-prctl-1.7/docs/index.rst 2018-01-26 22:02:52.000000000 +0100 +++ new/python-prctl-1.8.1/docs/index.rst 2020-11-02 20:30:09.000000000 +0100 @@ -137,6 +137,21 @@ Return the floating-point exception mode as a bitmap of enabled modes. See :func:`set_fpexc`. +.. function:: set_io_flusher(is_flusher) + + Put the process in :const:`IO_FLUSHER` state, which, which allows it special + treatment to make progress when allocating memory. This is used by process + involved in the block layer or filesystem i/o path, such as fuse daemons or + scsi device emulation daemons. + + This is only available in linux 5.6 and newer + +.. function:: get_io_flusher() + + Return the :const:`IO_FLUSHER` state of the process. + + This is only available in linux 5.6 and newer + .. function:: set_keepcaps(flag) Set the state of the thread's "keep capabilities" flag, which determines @@ -147,6 +162,7 @@ are cleared). This value will be reset to :const:`False` on subsequent calls to :func:`execve`. + .. function:: get_keepcaps() Return the current state of the calling thread's "keep capabilities" flag. @@ -171,6 +187,16 @@ This is only available in linux 2.6.32 and newer +.. function:: pr_mpx_enable_management() + +.. function:: pr_mpx_disable_management() + + Enable or disable intel memory protection extensions. See :manpage:`prctl(2)` + for details and limitations. + + This is only available in linux 3.19 and newer, but no longer available in + linux 5.4 and newer. + .. function:: set_name(name) Set the process name for the calling process, the name can be up to 16 bytes @@ -199,6 +225,23 @@ This is only available in linux 3.5 and newer +.. function:: pac_reset_keys(keys) + + Securely reset the thread's pointer authentication keys to fresh random + values generated by the kernel. The keys must be a logical or of any of the + keys you want to reset, or 0 to reset all keys. The available keys are + :const:`PR_PAC_APIAKEY`, :const:`PR_PAC_APIBKEY`, :const:`PR_PAC_APDAKEY`, + :const:`PR_PAC_APDBKEY` and :const:`PR_PAC_APGAKEY`. + + For more information, see the kernel source file + Documentation/arm64/pointer-authentication.rst + + This is only available in linux 5.0 and newer + + .. note:: + This function only works on arm64 systems. An :exc:`OSError` is raised + when called on other systems. + .. function:: set_proctitle(title) Set the process name for the calling process by overwriting the C-level @@ -272,6 +315,48 @@ operation is only available if the kernel is configured with :const:`CONFIG_SECCOMP` enabled. +.. function:: set_speculation_ctrl(feature, value) + + Sets the state of a speculation misfeature (:const:`SPEC_STORE_BYPASS` or + :const:`SPEC_INDIRECT_BRANCH`). The value is one of :const:`PR_SPEC_ENABLE` + to enable the feature, :const:`PR_SPEC_DISABLE` to disable it, + :const:`PR_SPEC_FORCE_DISABLE` to disable it permanently for the thread and + :const:`PR_SPEC_DISABLE_NOEXEC` to disable it until the next :func:`execve`. + + This is only available in linux 4.17 and newer + +.. function:: get_speculation_ctrl(feature) + + Returns the state of a speculation misfeature (:const:`SPEC_STORE_BYPASS` or + :const:`SPEC_INDIRECT_BRANCH`). The value is one of the values that can be + set by :func:`pr_set_speculation_ctrl`, possibly logically OR'ed with + const:`PR_SPEC_PRCTL` to indicate that the value can be controlled er thread + by that function. If all bits are 0, the CPU is not affected by the + misfeature. + + This is only available in linux 4.17 and newer + +.. function:: task_perf_events_disable() +.. function:: task_perf_events_enable() + + Disable or enable all performance counters attached to the calling process, + regardless of whether the counters were created by this process or another + process. Performance counters created by the calling process for other + processes are unaffected. + +.. function:: set_thp_disable(is_disabled) + + Disable transparent huge ages for the current process. This flag is inhereted + by child process and preserved across execve. + + This is only available in linux 3.15 and newer + +.. function:: get_thp_disable() + + Return whether transparent huge pages are disabled for the current process. + + This is only available in linux 3.15 and newer + .. function:: get_tid_address() Allows the process to obtain its own `clear_tid_address`, used when @@ -450,10 +535,24 @@ Enable and disable kernel auditing; change auditing filter rules; retrieve auditing status and filtering rules. +.. attribute:: set.audit_read + + Allow reading the audit log via a multicast netlink socket. + .. attribute:: set.audit_write Write records to kernel auditing log. +.. attribute:: set.block_suspend + + Employ features that can block system suspend (:manpage:`epoll(7)` + :const:`EPOLLWAKEUP`, :file:`/proc/sys/wake_lock`). + +.. attribute:: set.bpf + + Employ privileged BPF operations; see :manpage:`bpf(2)` and + :manpage:`bpf-helpers(7)`. + .. attribute:: set.chown Make arbitrary changes to file UIDs and GIDs (see :manpage:`chown(2)`). @@ -510,14 +609,12 @@ .. attribute:: set.mac_admin - Override Mandatory Access Control (MAC). Implemented for the Smack Linux - Security Module (LSM). + Allow MAC configuration or state changes. Implemented for the Smack LSM. .. attribute:: set.mac_override - Allow MAC configuration or state changes. Implemented for the Smack LSM. - -.. The above two were copied from the manpage, but they seem to be swapped. Hmm... + Override Mandatory Access Control (MAC). Implemented for the Smack Linux + Security Module (LSM). .. attribute:: set.mknod @@ -542,6 +639,12 @@ Use :const:`RAW` and :const:`PACKET` sockets. +.. attribute:: set.perfmon + + Employ various performance-monitoring mechanisms, including + :func:`perf_event_open` and various BPF operations that have performance + implications.. + .. attribute:: set.setgid Make arbitrary manipulations of process GIDs and supplementary GID list; @@ -579,23 +682,8 @@ .. attribute:: set.sys_admin - * Perform a range of system administration operations including: - :func:`quotactl`, func:`mount`, :func:`umount`, :func:`swapon`, - :func:`swapoff`, :func:`sethostname`, and :func:`setdomainname`. - * Perform :const:`IPC_SET` and :const:`IPC_RMID` operations on arbitrary - System V IPC objects. - * Perform operations on trusted and security Extended Attributes (see - :manpage:`attr(5)`). - * Use :func:`lookup_dcookie`. - * Use :func:`ioprio_set` to assign the :const:`IOPRIO_CLASS_RT` scheduling - class. - * Forge UID when passing socket credentials. - * Exceed :file:`/proc/sys/fs/file-max`, the system-wide limit on the number - of open files, in system calls that open files (e.g., :func:`accept`, - :func:`execve`, :func:`open`, :func:`pipe`). - * Employ :const:`CLONE_NEWNS` flag with :func:`clone` and :func:`unshare`. - * Perform :const:`KEYCTL_CHOWN` and :const:`KEYCTL_SETPERM` :func:`keyctl` - operations. + Perform a range of system administration operations, which change per kernel + version. See :manpage:`capabilities(7)` for details. .. attribute:: set.sys_boot @@ -636,19 +724,13 @@ .. attribute:: set.sys_rawio - Perform I/O port operations (:func:`iopl` and :func:`ioperm`); access - :file:`/proc/kcore`. + Perform a range of privileged i/o operations, which change per kernel + version. See :manpage:`capabilities(7)` for details. .. attribute:: set.sys_resource - * Use reserved space on ext2 file systems. - * Make :func:`ioctl` calls controlling ext3 journaling. - * Override disk quota limits. - * Increase resource limits (see :manpage:`setrlimit(2)`). - * Override :const:`RLIMIT_NPROC` resource limit. - * Raise :c:data:`msg_qbytes` limit for a System V message queue above the - limit in :file:`/proc/sys/kernel/msgmnb` (see :manpage:`msgop(2)` and - :manpage:`msgctl(2)`). + Use a set of privileged resources, which change per kernel version. See + :manpage:`capabilities(7)` for details. .. attribute:: set.sys_time diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-prctl-1.7/prctl.py new/python-prctl-1.8.1/prctl.py --- old/python-prctl-1.7/prctl.py 2018-01-26 22:02:52.000000000 +0100 +++ new/python-prctl-1.8.1/prctl.py 2020-11-02 20:30:09.000000000 +0100 @@ -1,5 +1,5 @@ # python-pctrl -- python interface to the prctl function -# (c)2010-2018 Dennis Kaarsemaker <den...@kaarsemaker.net> +# (c)2010-2020 Dennis Kaarsemaker <den...@kaarsemaker.net> # See COPYING for licensing details import _prctl # The C interface @@ -11,8 +11,12 @@ # Code generation functions def prctl_wrapper(option): - def call_prctl(arg=0): - return _prctl.prctl(option, arg) + def call_prctl(arg=None, arg2=None): + if arg == None: + return _prctl.prctl(option) + if arg2 == None: + return _prctl.prctl(option, arg) + return _prctl.prctl(option, arg, arg2) return call_prctl def capb_wrapper(cap): @@ -44,12 +48,22 @@ return property(getter, setter) # Wrap the capabilities, capability bounding set and securebits in an object -_ALL_FLAG_NAMES = ('CAP_EFFECTIVE', 'CAP_INHERITABLE', 'CAP_PERMITTED') +_ALL_FLAG_NAMES = ('CAP_EFFECTIVE', 'CAP_INHERITABLE', 'CAP_PERMITTED') _ALL_CAP_NAMES = tuple(x for x in dir(_prctl) if x.startswith('CAP_') and x not in _ALL_FLAG_NAMES) -ALL_FLAG_NAMES = list(x[4:].lower() for x in _ALL_FLAG_NAMES) -ALL_CAP_NAMES = list(x[4:].lower() for x in _ALL_CAP_NAMES) -ALL_CAPS = tuple(getattr(_prctl,x) for x in _ALL_CAP_NAMES) +ALL_FLAG_NAMES = tuple(x[4:].lower() for x in _ALL_FLAG_NAMES) +ALL_CAP_NAMES = tuple(x[4:].lower() for x in _ALL_CAP_NAMES) ALL_FLAGS = tuple(getattr(_prctl,x) for x in _ALL_FLAG_NAMES) +ALL_CAPS = tuple(getattr(_prctl,x) for x in _ALL_CAP_NAMES) + +for i in range(_prctl.CAP_LAST_CAP+1): + if i not in ALL_CAPS: + _ALL_CAP_NAMES += ("CAP_UNKNOWN_%d" % i,) +del i + +if len(_ALL_CAP_NAMES) != len(ALL_CAPS): + warnings.warn("not all known capabilities are named, this is a bug in python-prctl", RuntimeWarning) + ALL_CAP_NAMES = tuple(x[4:].lower() for x in _ALL_CAP_NAMES) + ALL_CAPS = tuple(getattr(_prctl,x) for x in _ALL_CAP_NAMES) class Capbset(object): __slots__ = ALL_CAP_NAMES @@ -69,7 +83,7 @@ capbset = Capbset() class Capset(object): - __slots__ = ALL_CAP_NAMES + ['flag'] + __slots__ = ALL_CAP_NAMES + ('flag',) def __init__(self, flag): self.flag = flag for name in _ALL_CAP_NAMES: @@ -98,8 +112,11 @@ # Copy constants from _prctl and generate the functions self = sys.modules['prctl'] + for name in dir(_prctl): - if name.startswith('PR_GET') or name.startswith('PR_SET') and name != 'PR_SET_PTRACER_ANY' or name.startswith('PR_CAPBSET'): + if name.startswith(('PR_GET', 'PR_SET', 'PR_CAPBSET', 'PR_PAC_RESET', 'PR_MPX', 'PR_TASK')) and not \ + name.startswith(('PR_SET_MM_', 'PR_SET_PTRACER_')): + # Generate a function for this option val = getattr(_prctl, name) friendly_name = name.lower()[3:] @@ -182,4 +199,4 @@ # Delete the init-only things del self, friendly_name, name, prctl_wrapper, cap_wrapper, capb_wrapper, sec_wrapper -del Capbset, Capset, Securebits, sys, val +del sys, val diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-prctl-1.7/python_prctl.egg-info/PKG-INFO new/python-prctl-1.8.1/python_prctl.egg-info/PKG-INFO --- old/python-prctl-1.7/python_prctl.egg-info/PKG-INFO 1970-01-01 01:00:00.000000000 +0100 +++ new/python-prctl-1.8.1/python_prctl.egg-info/PKG-INFO 2020-11-02 20:30:24.000000000 +0100 @@ -0,0 +1,18 @@ +Metadata-Version: 1.1 +Name: python-prctl +Version: 1.8.1 +Summary: Python(ic) interface to the linux prctl syscall +Home-page: http://github.com/seveas/python-prctl +Author: Dennis Kaarsemaker +Author-email: den...@kaarsemaker.net +License: UNKNOWN +Description: UNKNOWN +Platform: UNKNOWN +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: GNU General Public License (GPL) +Classifier: Operating System :: POSIX :: Linux +Classifier: Programming Language :: C +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3 +Classifier: Topic :: Security diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-prctl-1.7/python_prctl.egg-info/SOURCES.txt new/python-prctl-1.8.1/python_prctl.egg-info/SOURCES.txt --- old/python-prctl-1.7/python_prctl.egg-info/SOURCES.txt 1970-01-01 01:00:00.000000000 +0100 +++ new/python-prctl-1.8.1/python_prctl.egg-info/SOURCES.txt 2020-11-02 20:30:24.000000000 +0100 @@ -0,0 +1,14 @@ +MANIFEST.in +README +_prctlmodule.c +prctl.py +securebits.h +setup.py +test_prctl.py +docs/Makefile +docs/conf.py +docs/index.rst +python_prctl.egg-info/PKG-INFO +python_prctl.egg-info/SOURCES.txt +python_prctl.egg-info/dependency_links.txt +python_prctl.egg-info/top_level.txt \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-prctl-1.7/python_prctl.egg-info/dependency_links.txt new/python-prctl-1.8.1/python_prctl.egg-info/dependency_links.txt --- old/python-prctl-1.7/python_prctl.egg-info/dependency_links.txt 1970-01-01 01:00:00.000000000 +0100 +++ new/python-prctl-1.8.1/python_prctl.egg-info/dependency_links.txt 2020-11-02 20:30:24.000000000 +0100 @@ -0,0 +1 @@ + diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-prctl-1.7/python_prctl.egg-info/top_level.txt new/python-prctl-1.8.1/python_prctl.egg-info/top_level.txt --- old/python-prctl-1.7/python_prctl.egg-info/top_level.txt 1970-01-01 01:00:00.000000000 +0100 +++ new/python-prctl-1.8.1/python_prctl.egg-info/top_level.txt 2020-11-02 20:30:24.000000000 +0100 @@ -0,0 +1,2 @@ +_prctl +prctl diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-prctl-1.7/setup.cfg new/python-prctl-1.8.1/setup.cfg --- old/python-prctl-1.7/setup.cfg 1970-01-01 01:00:00.000000000 +0100 +++ new/python-prctl-1.8.1/setup.cfg 2020-11-02 20:30:24.616678500 +0100 @@ -0,0 +1,4 @@ +[egg_info] +tag_build = +tag_date = 0 + diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-prctl-1.7/setup.py new/python-prctl-1.8.1/setup.py --- old/python-prctl-1.7/setup.py 2018-01-26 22:02:52.000000000 +0100 +++ new/python-prctl-1.8.1/setup.py 2020-11-02 20:30:09.000000000 +0100 @@ -1,6 +1,6 @@ #!/usr/bin/python -from distutils.core import setup, Extension +from setuptools import setup, Extension import glob import os import subprocess @@ -33,13 +33,13 @@ sys.stderr.write("You need to install gcc to build this module\n") sys.exit(1) -sp = subprocess.Popen(['cpp'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) +sp = subprocess.Popen(['cpp'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=os.environ) sp.communicate('#include <sys/prctl.h>\n'.encode()) if sp.returncode: sys.stderr.write("You need to install libc development headers to build this module\n") exit = True -sp = subprocess.Popen(['cpp'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) +sp = subprocess.Popen(['cpp'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=os.environ) sp.communicate('#include <sys/capability.h>\n'.encode()) if sp.returncode: sys.stderr.write("You need to install libcap development headers to build this module\n") @@ -54,7 +54,7 @@ libraries = ['cap']) setup(name = "python-prctl", - version = "1.7", + version = "1.8.1", author = "Dennis Kaarsemaker", author_email = "den...@kaarsemaker.net", url = "http://github.com/seveas/python-prctl", diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-prctl-1.7/test_prctl.py new/python-prctl-1.8.1/test_prctl.py --- old/python-prctl-1.7/test_prctl.py 2018-01-26 22:02:52.000000000 +0100 +++ new/python-prctl-1.8.1/test_prctl.py 2020-11-02 20:30:09.000000000 +0100 @@ -1,5 +1,5 @@ # python-pctrl -- python interface to the prctl function -# (c)2010-2018 Dennis Kaarsemaker <den...@kaarsemaker.net> +# (c)2010-2020 Dennis Kaarsemaker <den...@kaarsemaker.net> # See COPYING for licensing details import distutils.util @@ -7,6 +7,7 @@ import os import re import signal +import stat import sys import subprocess import unittest @@ -14,7 +15,7 @@ so = '.so' try: import sysconfig - so = sysconfig.get_config_var('SO') + so = sysconfig.get_config_var('EXT_SUFFIX') or sysconfig.get_config_var('SO') except ImportError: pass @@ -147,6 +148,32 @@ self.assertRaises(OSError, prctl.get_fpexc) self.assertRaises(OSError, prctl.set_fpexc) + @require('set_fp_mode') + def test_fp_mode(self): + """Test manipulation of the fp_mode setting""" + if self.arch == 'mips': + # FIXME - untested + prctl.set_fp_mode(prctl.FP_MODE_FR) + self.assertEqual(prctl.get_fp_mode(), prctl.FP_MODE_FR) + prctl.set_fp_mode(prctl.FP_MODE_FRE) + self.assertEqual(prctl.get_fp_mode(), prctl.FP_MODE_FRE) + self.assertRaises(ValueError, prctl.set_fp_mode, 999) + else: + self.assertRaises(OSError, prctl.get_fpexc) + self.assertRaises(OSError, prctl.set_fpexc) + + @require('set_io_flusher') + def test_io_flusher(self): + if self.am_root: + self.assertEqual(prctl.get_io_flusher(), 0) + self.assertEqual(prctl.set_io_flusher(True), None) + self.assertEqual(prctl.get_io_flusher(), 1) + self.assertEqual(prctl.set_io_flusher(False), None) + self.assertEqual(prctl.get_io_flusher(), 0) + else: + self.assertRaises(OSError, prctl.get_io_flusher) + self.assertRaises(OSError, prctl.set_io_flusher) + def test_keepcaps(self): """Test manipulation of the keepcaps setting""" prctl.set_keepcaps(True) @@ -157,6 +184,8 @@ @require('set_mce_kill') def test_mce_kill(self): """Test the MCE_KILL setting""" + if not os.path.exists('/proc/sys/vm/memory_failure_early_kill'): + return fd = open('/proc/sys/vm/memory_failure_early_kill') current = int(fd.read().strip()) fd.close() @@ -167,6 +196,16 @@ prctl.set_mce_kill(prctl.MCE_KILL_DEFAULT) self.assertEqual(prctl.get_mce_kill(), prctl.MCE_KILL_DEFAULT) + @require('mpx_enable_management') + def test_mpx(self): + """Test MPX enabling/disabling""" + if os.uname().release > "5.4": + self.assertRaises(OSError, prctl.mpx_enable_management) + self.assertRaises(OSError, prctl.mpx_disable_management) + else: + self.assertEqual(prctl.mpx_enable_management(), None) + self.assertEqual(prctl.mpx_disable_management(), None) + def test_name(self): """Test setting the process name""" name = prctl.get_name().swapcase() * 16 @@ -177,6 +216,9 @@ def test_no_new_privs(self): """Test the no_new_privs function""" self.assertEqual(prctl.get_no_new_privs(), 0) + if not (os.stat('/bin/ping').st_mode & stat.S_ISUID): + # Test doesn't work unless ping is setuid + return pid = os.fork() if pid: self.assertEqual(os.waitpid(pid, 0)[1], 0) @@ -189,19 +231,30 @@ self.assertNotEqual(sp.returncode, 0) os._exit(0) + @require('pac_reset_keys') + def test_pac_reset_keys(self): + if self.arch == 'arm64': + # FIXME untested + self.assertEqual(prctl.pac_reset_keys(prctl.PAC_APIAKEY), None) + self.assertRaises(ValueError, prctl.pac_reset_keys, 0xff) + else: + self.assertRaises(OSError, prctl.pac_reset_keys, prctl.PAC_APIAKEY) + def test_proctitle(self): """Test setting the process title, including too long titles""" + with open('/proc/self/cmdline') as fd: + orig = len(fd.read()) title = "This is a test!" prctl.set_proctitle(title) - ps_output = subprocess.Popen(['ps', '-f', '-p', '%d' % os.getpid()], - stdout=subprocess.PIPE).communicate()[0].decode('ascii') - self.assertTrue(ps_output.strip().endswith(title)) - # This should not segfault but truncate - title2 = "And this is a test too! Don't segfault." + with open('/proc/self/cmdline') as fd: + cmdline = fd.read().rstrip('\n\0') + self.assertEqual(cmdline, title) + # This should not segfault + title2 = "And this is a test too! Don't segfault." * 3 prctl.set_proctitle(title2) - ps_output = subprocess.Popen(['ps', '-f', '-p', '%d' % os.getpid()], - stdout=subprocess.PIPE).communicate()[0].decode('ascii') - self.assertTrue(ps_output.strip().endswith(title2[:len(title)])) + with open('/proc/self/cmdline') as fd: + cmdline = fd.read().rstrip('\n\0') + self.assertEqual(cmdline, title2[:orig-1]) def test_pdeathsig(self): """Test manipulation of the pdeathsig setting""" @@ -269,6 +322,30 @@ prctl.securebits.noroot = True self.assertRaises(OSError, set_true) + @require('set_speculation_ctrl') + def test_speculation_ctrl(self): + self.assertTrue(prctl.get_speculation_ctrl(prctl.SPEC_STORE_BYPASS) > 0) + self.assertTrue(prctl.get_speculation_ctrl(prctl.SPEC_INDIRECT_BRANCH) > 0) + self.assertRaises(ValueError, prctl.get_speculation_ctrl, 99) + self.assertRaises(ValueError, prctl.set_speculation_ctrl, 99) + prctl.set_speculation_ctrl(prctl.SPEC_STORE_BYPASS, prctl.SPEC_ENABLE) + self.assertEqual(prctl.get_speculation_ctrl(prctl.SPEC_STORE_BYPASS) & ~prctl.SPEC_PRCTL, prctl.SPEC_ENABLE) + prctl.set_speculation_ctrl(prctl.SPEC_STORE_BYPASS, prctl.SPEC_FORCE_DISABLE) + self.assertRaises(PermissionError, prctl.set_speculation_ctrl, prctl.SPEC_STORE_BYPASS, prctl.SPEC_ENABLE) + + @require('task_perf_events_enable') + def test_task_perf_events(self): + prctl.task_perf_events_disable() + prctl.task_perf_events_enable() + + @require('get_thp_disable') + def test_thp_disable(self): + self.assertEqual(prctl.get_thp_disable(), False) + prctl.set_thp_disable(True) + self.assertEqual(prctl.get_thp_disable(), True) + prctl.set_thp_disable(False) + self.assertEqual(prctl.get_thp_disable(), False) + @require('get_timerslack') def test_timerslack(self): """Test manipulation of the timerslack value""" ++++++ skip-speculation.patch ++++++ Index: python-prctl-1.8.1/test_prctl.py =================================================================== --- python-prctl-1.8.1.orig/test_prctl.py +++ python-prctl-1.8.1/test_prctl.py @@ -371,6 +371,7 @@ class PrctlTest(unittest.TestCase): self.assertRaises(OSError, set_true) @require('set_speculation_ctrl') + @unittest.skip('borked in sandbox') def test_speculation_ctrl(self): self.assertTrue(prctl.get_speculation_ctrl(prctl.SPEC_STORE_BYPASS) > 0) self.assertTrue(prctl.get_speculation_ctrl(prctl.SPEC_INDIRECT_BRANCH) > 0)