/* * python-pctrl -- python interface to the prctl function * (c)2010-2020 Dennis Kaarsemaker * See COPYING for licensing details */ #include #if PY_MAJOR_VERSION >= 3 #define PyInt_FromLong PyLong_FromLong #define PyInt_Check PyLong_Check #define PyInt_AsLong PyLong_AsLong #endif #include "securebits.h" #include #include #include /* New in 2.6.32, but named and implemented inconsistently. The linux * implementation has two ways of setting the policy to the default, and thus * needs an extra argument. We ignore the first argument and always call * PR_MCE_KILL_SET. This makes our implementation simpler and keeps the prctl * interface more consistent */ #ifdef PR_MCE_KILL #define PR_GET_MCE_KILL PR_MCE_KILL_GET #define PR_SET_MCE_KILL PR_MCE_KILL #endif /* New in 2.6.XX (Ubuntu 10.10) */ #define NOT_SET (-1) #ifdef PR_SET_PTRACER /* This one has no getter for some reason, but guard against that being fixed */ #ifndef PR_GET_PTRACER #define PR_GET_PTRACER NOT_SET /* Icky global variable to cache ptracer */ static int __cached_ptracer = NOT_SET; #endif #endif /* This function is not in Python.h, so define it here */ #if PY_MAJOR_VERSION < 3 void Py_GetArgcArgv(int*, char***); #else void Py_GetArgcArgv(int*, wchar_t***); #endif /* The prctl wrapper */ static PyObject * prctl_prctl(PyObject *self, PyObject *args) { 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; /* * Accept single int, two ints and int+string. That covers all current * prctl possibilities. int+string is required for (and only accepted for) * PR_SET_NAME */ if(!PyArg_ParseTuple(args, "l|ll", &option, &arg, &arg2)) { if(!PyArg_ParseTuple(args, "ls", &option, &argstr)) { return NULL; } if(option != PR_SET_NAME) { PyErr_SetString(PyExc_TypeError, "an integer is required"); return NULL; } PyErr_Clear(); } else { if(option == PR_SET_NAME) { PyErr_SetString(PyExc_TypeError, "a string is required"); return NULL; } } /* Validate the optional arguments */ switch(option) { #ifdef PR_CAPBSET_READ case(PR_CAPBSET_READ): case(PR_CAPBSET_DROP): if(!cap_valid(arg)) { PyErr_SetString(PyExc_ValueError, "Unknown capability"); return NULL; } 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; break; case(PR_SET_ENDIAN): if(arg != PR_ENDIAN_LITTLE && arg != PR_ENDIAN_BIG && arg != PR_ENDIAN_PPC_LITTLE) { PyErr_SetString(PyExc_ValueError, "Unknown endianness"); return NULL; } break; case(PR_SET_FPEMU): if(arg != PR_FPEMU_NOPRINT && arg != PR_FPEMU_SIGFPE) { PyErr_SetString(PyExc_ValueError, "Unknown floating-point emulation setting"); return NULL; } break; case(PR_SET_FPEXC): if(arg & ~(PR_FP_EXC_SW_ENABLE | PR_FP_EXC_DIV | PR_FP_EXC_OVF | PR_FP_EXC_UND | PR_FP_EXC_RES | PR_FP_EXC_INV | PR_FP_EXC_DISABLED | PR_FP_EXC_NONRECOV | PR_FP_EXC_ASYNC | PR_FP_EXC_PRECISE)) { PyErr_SetString(PyExc_ValueError, "Unknown floating-point exception mode"); 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) { PyErr_SetString(PyExc_ValueError, "Unknown memory corruption kill policy"); return NULL; } break; #endif case(PR_SET_NAME): if(strlen(argstr) > 16) { /* FIXME: warn */ } 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"); return NULL; } break; #ifdef PR_SET_SECCOMP case(PR_SET_SECCOMP): #ifdef PR_SET_NO_NEW_PRIVS case(PR_SET_NO_NEW_PRIVS): #endif if(!arg) { PyErr_SetString(PyExc_ValueError, "Argument must be 1"); return NULL; } arg = 1; break; #endif #ifdef PR_SET_SECUREBITS case(PR_SET_SECUREBITS): if(arg & ~ ((1 << SECURE_NOROOT) | (1 << SECURE_NOROOT_LOCKED) | (1 << SECURE_NO_SETUID_FIXUP) | (1 << SECURE_NO_SETUID_FIXUP_LOCKED) | (1 << SECURE_KEEP_CAPS) | (1 << SECURE_KEEP_CAPS_LOCKED))) { PyErr_SetString(PyExc_ValueError, "Invalid securebits set"); return NULL; } 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"); return NULL; } break; #ifdef PR_SET_TSC case(PR_SET_TSC): if(arg != PR_TSC_ENABLE && arg != PR_TSC_SIGSEGV) { PyErr_SetString(PyExc_ValueError, "Invalid TSC setting"); return NULL; } break; #endif case(PR_SET_UNALIGN): if(arg != PR_UNALIGN_NOPRINT && arg != PR_UNALIGN_SIGBUS) { PyErr_SetString(PyExc_ValueError, "Invalid TSC setting"); return NULL; } break; } /* * Calling prctl * There are 3 basic call modes: * - Setters and getters for which the return value is the result * - Getters for which the result is placed in arg2 * - Getters and setters that deal with strings. * * This function takes care of all that and always returns Py_None for * settings or the result of a getter call as a PyInt or PyString. */ switch(option) { #ifdef PR_CAPBSET_READ case(PR_CAPBSET_READ): case(PR_CAPBSET_DROP): #endif #ifdef PR_SET_CHILD_SUBREAPER case(PR_SET_CHILD_SUBREAPER): #endif case(PR_SET_DUMPABLE): case(PR_GET_DUMPABLE): 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): #endif #ifdef PR_SET_PTRACER case(PR_SET_PTRACER): #endif #ifdef PR_SET_SECCOMP case(PR_SET_SECCOMP): case(PR_GET_SECCOMP): #endif #ifdef PR_SET_SECUREBITS 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): #endif case(PR_SET_TIMING): case(PR_GET_TIMING): #ifdef PR_SET_TSC case(PR_SET_TSC): #endif case(PR_SET_UNALIGN): result = prctl(option, arg, arg2, 0, 0); if(result < 0) { PyErr_SetFromErrno(PyExc_OSError); return NULL; } switch(option) { #ifdef PR_CAPBSET_READ 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 #ifdef PR_GET_NO_NEW_PRIVS case(PR_GET_NO_NEW_PRIVS): #endif #if defined(PR_GET_PTRACER) && (PR_GET_PTRACER != NOT_SET) case(PR_GET_PTRACER): #endif #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 return PyInt_FromLong(result); #if defined(PR_GET_PTRACER) && (PR_GET_PTRACER == NOT_SET) case(PR_SET_PTRACER): __cached_ptracer = arg; break; #endif } break; #ifdef PR_GET_CHILD_SUBREAPER case(PR_GET_CHILD_SUBREAPER): #endif case(PR_GET_ENDIAN): case(PR_GET_FPEMU): case(PR_GET_FPEXC): case(PR_GET_PDEATHSIG): #ifdef PR_GET_TSC case(PR_GET_TSC): #endif case(PR_GET_UNALIGN): #ifdef PR_GET_TID_ADDRESS case(PR_GET_TID_ADDRESS): #endif result = prctl(option, &arg, 0, 0, 0); if(result < 0) { PyErr_SetFromErrno(PyExc_OSError); return NULL; } return PyInt_FromLong(arg); case(PR_SET_NAME): case(PR_GET_NAME): result = prctl(option, name, 0, 0, 0); if(result < 0) { PyErr_SetFromErrno(PyExc_OSError); return NULL; } if(option == PR_GET_NAME) { return Py_BuildValue("s", name); } break; #if defined(PR_GET_PTRACER) && (PR_GET_PTRACER == NOT_SET) case(PR_GET_PTRACER): if(__cached_ptracer == NOT_SET) return PyInt_FromLong(getppid()); return PyInt_FromLong(__cached_ptracer); #endif #ifdef PR_MCE_KILL case(PR_SET_MCE_KILL): result = prctl(option, PR_MCE_KILL_SET, arg, 0, 0); if(result < 0) { PyErr_SetFromErrno(PyExc_OSError); return NULL; } break; #endif default: PyErr_SetString(PyExc_ValueError, "Unknown prctl option"); return NULL; } /* None is returned by default */ Py_RETURN_NONE; } #if PY_MAJOR_VERSION < 3 #define _Py_GetArgcArgv Py_GetArgcArgv #else /* In python 3, Py_GetArgcArgv doesn't actually return the real argv, but an * encoded copy of it. We try to find the real one by going back from the start * of environ. */ static char * encode(wchar_t *wstr) { PyObject *unicodestr = NULL, *bytesstr = NULL; char *str = NULL; unicodestr = PyUnicode_FromWideChar(wstr, -1); if(!unicodestr) { PyErr_Clear(); return NULL; } bytesstr = PyUnicode_AsEncodedString(unicodestr, PyUnicode_GetDefaultEncoding(), "strict"); if(!bytesstr) { PyErr_Clear(); Py_XDECREF(unicodestr); return NULL; } str = PyBytes_AsString(bytesstr); Py_XDECREF(unicodestr); Py_XDECREF(bytesstr); return str; } static int _Py_GetArgcArgv(int* argc, char ***argv) { int i = 0; wchar_t **argv_w; 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; /* Walk back from environ until you find argc-1 null-terminated strings. */ ptr = environ[0] - 1; limit = ptr - 8192; for(i=*argc-1; i >= 1; --i) { ptr--; while (*ptr && ptr-- > limit); if (ptr <= limit) { free(buf); return 0; } buf[i] = (ptr + 1); } /* Now try to find argv[0] */ arg0 = encode(argv_w[0]); if(!arg0) { free(buf); return 0; } ptr -= strlen(arg0); if(strcmp(ptr, arg0)) { free(buf); return 0; } buf[0] = ptr; *argv = buf; return 1; } #endif static PyObject * prctl_set_proctitle(PyObject *self, PyObject *args) { int argc = 0; char *title; static size_t len = 0; static char **argv; if(!PyArg_ParseTuple(args, "s", &title)) { return NULL; } if(argv == NULL) { _Py_GetArgcArgv(&argc, &argv); if(argc > 0) { len = (size_t)(argv[argc-1]) + strlen(argv[argc-1]) - (size_t)(argv[0]); } } if(len <= 0) { PyErr_SetString(PyExc_RuntimeError, "Failed to locate argc/argv"); return NULL; } strncpy(argv[0], title, len); if(strlen(title) < len) memset(argv[0] + strlen(title), 0, len - strlen(title)); Py_RETURN_NONE; } /* TODO: Add a getter? */ static PyObject * prctl_get_caps_flag(PyObject *list, cap_t caps, int flag) { int i; PyObject *ret, *item, *val; cap_flag_value_t value; if(list && !PySequence_Check(list)) { PyErr_SetString(PyExc_TypeError, "A sequence of integers is required"); return NULL; } ret = PyDict_New(); if(!list) return ret; for(i=0; i < PyList_Size(list); i++) { item = PyList_GetItem(list, i); if(!PyInt_Check(item)) { PyErr_SetString(PyExc_TypeError, "A sequence of integers is required"); return ret; /* Return the list so it can be freed */ } if(cap_get_flag(caps, PyInt_AsLong(item), flag, &value) == -1) { PyErr_SetFromErrno(PyExc_OSError); return ret; } val = PyBool_FromLong(value); PyDict_SetItem(ret, item, val); Py_XDECREF(val); } return ret; } static int prctl_set_caps_flag(PyObject *list, cap_t caps, int flag, cap_flag_value_t value) { int i; cap_value_t cap; PyObject *item; if(list && !PySequence_Check(list)) { PyErr_SetString(PyExc_TypeError, "A sequence of integers is required"); return 0; } if(!list) return 1; for(i=0; i < PyList_Size(list); i++) { item = PyList_GetItem(list, i); if(!PyInt_Check(item)) { PyErr_SetString(PyExc_TypeError, "A sequence of integers is required"); return 0; } cap = PyInt_AsLong(item); if(cap_set_flag(caps, flag, 1, &cap, value) == -1) { PyErr_SetFromErrno(PyExc_OSError); return 0; } } return 1; } static PyObject * prctl_get_caps(PyObject *self, PyObject *args) { PyObject *effective = NULL; PyObject *permitted = NULL; PyObject *inheritable = NULL; PyObject *effective_ = NULL; PyObject *permitted_ = NULL; PyObject *inheritable_ = NULL; PyObject *ret = NULL; PyObject *key = NULL; cap_t caps = NULL; if(!PyArg_ParseTuple(args, "O|OO", &effective, &permitted, &inheritable)) { return NULL; } caps = cap_get_proc(); if(!caps) { PyErr_SetFromErrno(PyExc_OSError); return NULL; } effective_ = prctl_get_caps_flag(effective, caps, CAP_EFFECTIVE); if(PyErr_Occurred()) goto error; permitted_ = prctl_get_caps_flag(permitted, caps, CAP_PERMITTED); if(PyErr_Occurred()) goto error; inheritable_ = prctl_get_caps_flag(inheritable, caps, CAP_INHERITABLE); if(PyErr_Occurred()) goto error; /* Now build the dict */ ret = PyDict_New(); key = PyInt_FromLong(CAP_EFFECTIVE); PyDict_SetItem(ret, key, effective_); Py_XDECREF(key); key = PyInt_FromLong(CAP_PERMITTED); PyDict_SetItem(ret, key, permitted_); Py_XDECREF(key); key = PyInt_FromLong(CAP_INHERITABLE); PyDict_SetItem(ret, key, inheritable_); Py_XDECREF(key); error: cap_free(caps); Py_XDECREF(effective_); Py_XDECREF(permitted_); Py_XDECREF(inheritable_); return ret; } static PyObject * prctl_set_caps(PyObject *self, PyObject *args) { PyObject *effective_set = NULL; PyObject *permitted_set = NULL; PyObject *inheritable_set = NULL; PyObject *effective_clear = NULL; PyObject *permitted_clear = NULL; PyObject *inheritable_clear = NULL; cap_t caps = NULL; if(!PyArg_ParseTuple(args, "O|OOOOO", &effective_set, &permitted_set, &inheritable_set, &effective_clear, &permitted_clear, &inheritable_clear)) { return NULL; } caps = cap_get_proc(); if(!caps) { PyErr_SetFromErrno(PyExc_OSError); return NULL; } if(!prctl_set_caps_flag(effective_set, caps, CAP_EFFECTIVE, CAP_SET)) return NULL; if(!prctl_set_caps_flag(permitted_set, caps, CAP_PERMITTED, CAP_SET)) return NULL; if(!prctl_set_caps_flag(inheritable_set, caps, CAP_INHERITABLE, CAP_SET)) return NULL; if(!prctl_set_caps_flag(effective_clear, caps, CAP_EFFECTIVE, CAP_CLEAR)) return NULL; if(!prctl_set_caps_flag(permitted_clear, caps, CAP_PERMITTED, CAP_CLEAR)) return NULL; if(!prctl_set_caps_flag(inheritable_clear, caps, CAP_INHERITABLE, CAP_CLEAR)) return NULL; if(cap_set_proc(caps) == -1) { PyErr_SetFromErrno(PyExc_OSError); return NULL; } Py_RETURN_NONE; } #ifdef cap_to_name static PyObject * prctl_cap_to_name(PyObject *self, PyObject *args) { cap_value_t cap; char *name; PyObject *ret; if(!PyArg_ParseTuple(args, "i", &cap)){ return NULL; } name = cap_to_name(cap); if(!name) { PyErr_SetFromErrno(PyExc_OSError); return NULL; } ret = Py_BuildValue("s", name+4); /* Exclude the cap_ prefix */ cap_free(name); return ret; } #endif static PyMethodDef PrctlMethods[] = { {"get_caps", prctl_get_caps, METH_VARARGS, "Get process capabilities"}, {"set_caps", prctl_set_caps, METH_VARARGS, "Set process capabilities"}, #ifdef cap_to_name {"cap_to_name", prctl_cap_to_name, METH_VARARGS, "Convert capability number to name"}, #endif {"prctl", prctl_prctl, METH_VARARGS, "Call prctl"}, {"set_proctitle", prctl_set_proctitle, METH_VARARGS, "Set the process title"}, {NULL, NULL, 0, NULL} /* Sentinel */ }; #if PY_MAJOR_VERSION >= 3 static struct PyModuleDef prctlmodule = { PyModuleDef_HEAD_INIT, "_prctl", NULL, -1, PrctlMethods }; #endif /* These macros avoid tediously repeating a name 2 or 4 times */ #define namedconstant(x) PyModule_AddIntConstant(_prctl, #x, x) #define namedattribute(x) do{ \ PyModule_AddIntConstant(_prctl, "PR_GET_" #x, PR_GET_ ## x); \ PyModule_AddIntConstant(_prctl, "PR_SET_" #x, PR_SET_ ## x); \ } while(0) PyMODINIT_FUNC #if PY_MAJOR_VERSION < 3 init_prctl(void) #else PyInit__prctl(void) #endif { #if PY_MAJOR_VERSION < 3 PyObject *_prctl = Py_InitModule("_prctl", PrctlMethods); #else PyObject *_prctl = PyModule_Create(&prctlmodule); #endif /* Add the PR_* constants */ #ifdef PR_CAPBSET_READ 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); namedconstant(PR_ENDIAN_LITTLE); namedconstant(PR_ENDIAN_PPC_LITTLE); namedattribute(FPEMU); namedconstant(PR_FPEMU_NOPRINT); namedconstant(PR_FPEMU_SIGFPE); namedattribute(FPEXC); namedconstant(PR_FP_EXC_SW_ENABLE); namedconstant(PR_FP_EXC_DIV); namedconstant(PR_FP_EXC_OVF); namedconstant(PR_FP_EXC_UND); namedconstant(PR_FP_EXC_RES); namedconstant(PR_FP_EXC_INV); namedconstant(PR_FP_EXC_DISABLED); 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); namedconstant(PR_MCE_KILL_DEFAULT); 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); #endif #ifdef PR_SET_PTRACER_ANY namedconstant(PR_SET_PTRACER_ANY); #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 namedattribute(TIMING); namedconstant(PR_TIMING_STATISTICAL); namedconstant(PR_TIMING_TIMESTAMP); #ifdef PR_SET_TSC namedattribute(TSC); namedconstant(PR_TSC_ENABLE); namedconstant(PR_TSC_SIGSEGV); #endif namedattribute(UNALIGN); namedconstant(PR_UNALIGN_NOPRINT); namedconstant(PR_UNALIGN_SIGBUS); /* 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_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_RAW); #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); #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); namedconstant(SECURE_NOROOT); namedconstant(SECURE_KEEP_CAPS_LOCKED); namedconstant(SECURE_NO_SETUID_FIXUP_LOCKED); namedconstant(SECURE_NOROOT_LOCKED); namedconstant(SECBIT_KEEP_CAPS); namedconstant(SECBIT_NO_SETUID_FIXUP); namedconstant(SECBIT_NOROOT); namedconstant(SECBIT_KEEP_CAPS_LOCKED); namedconstant(SECBIT_NO_SETUID_FIXUP_LOCKED); namedconstant(SECBIT_NOROOT_LOCKED); #if PY_MAJOR_VERSION >= 3 return _prctl; #endif }