diff options
author | Anthony G. Basile <blueness@gentoo.org> | 2011-10-20 10:12:50 -0400 |
---|---|---|
committer | Anthony G. Basile <blueness@gentoo.org> | 2011-10-20 10:12:50 -0400 |
commit | 284875fb709fb1bf5530c78491c9a39539104f25 (patch) | |
tree | 5c50175fb7d2fbb0944db919450d9707f348613f | |
parent | Add doc/revdep-pax.pod and remove EI_PAX docs from doc/paxctl* (diff) | |
download | elfix-284875fb709fb1bf5530c78491c9a39539104f25.tar.gz elfix-284875fb709fb1bf5530c78491c9a39539104f25.tar.bz2 elfix-284875fb709fb1bf5530c78491c9a39539104f25.zip |
scripts/paxmodule.c: add XT_PAX read support
-rw-r--r-- | scripts/paxmodule.c | 167 | ||||
-rw-r--r-- | src/paxctl-ng.c | 6 |
2 files changed, 120 insertions, 53 deletions
diff --git a/scripts/paxmodule.c b/scripts/paxmodule.c index 9cffb12..6a158fc 100644 --- a/scripts/paxmodule.c +++ b/scripts/paxmodule.c @@ -3,13 +3,15 @@ #include <string.h> #include <gelf.h> +#include <attr/xattr.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> -#define BUF_SIZE 7 //Buffer for holding human readable flags +#define BUF_SIZE 7 //Buffer size for holding human readable flags +#define PAX_NAMESPACE "user.pax" static PyObject * pax_getflags(PyObject *, PyObject *); @@ -38,45 +40,30 @@ initpax(void) } -static PyObject * -pax_getflags(PyObject *self, PyObject *args) +uint16_t +read_pt_flags(int fd) { - const char *f_name; - int fd; Elf *elf; - - char pax_buf[BUF_SIZE]; - uint16_t pax_flags; - GElf_Phdr phdr; - char found_pt_pax; size_t i, phnum; - memset(pax_buf, 0, BUF_SIZE); + uint16_t pt_flags; + char found_pt_pax; - if (!PyArg_ParseTuple(args, "s", &f_name)) - { - PyErr_SetString(PaxError, "pax_getflags: PyArg_ParseTuple failed"); - return NULL; - } + pt_flags = UINT16_MAX; if(elf_version(EV_CURRENT) == EV_NONE) { + close(fd); PyErr_SetString(PaxError, "pax_getflags: library out of date"); - return NULL; - } - - if((fd = open(f_name, O_RDONLY)) < 0) - { - PyErr_SetString(PaxError, "pax_getflags: open() failed"); - return NULL; + return pt_flags; } if((elf = elf_begin(fd, ELF_C_READ_MMAP, NULL)) == NULL) { close(fd); PyErr_SetString(PaxError, "pax_getflags: elf_begin() failed"); - return NULL; + return pt_flags; } if(elf_kind(elf) != ELF_K_ELF) @@ -84,53 +71,131 @@ pax_getflags(PyObject *self, PyObject *args) elf_end(elf); close(fd); PyErr_SetString(PaxError, "pax_getflags: elf_kind() failed: this is not an elf file."); - return NULL; + return pt_flags; } - found_pt_pax = 0; - pax_flags = 0; - elf_getphdrnum(elf, &phnum); - for(i=0; i<phnum; ++i) + + for(i=0; i<phnum; i++) { if(gelf_getphdr(elf, i, &phdr) != &phdr) - { - elf_end(elf); - close(fd); - PyErr_SetString(PaxError, "pax_getflags: gelf_getphdr() failed"); - return NULL; - } + error(EXIT_FAILURE, 0, "gelf_getphdr(): %s", elf_errmsg(elf_errno())); if(phdr.p_type == PT_PAX_FLAGS) { found_pt_pax = 1; - pax_flags = phdr.p_flags; + pt_flags = phdr.p_flags; + } + } - pax_buf[0] = pax_flags & PF_PAGEEXEC ? 'P' : - pax_flags & PF_NOPAGEEXEC ? 'p' : '-' ; + if(!found_pt_pax) + printf("PT_PAX: not found\n"); - pax_buf[1] = pax_flags & PF_SEGMEXEC ? 'S' : - pax_flags & PF_NOSEGMEXEC ? 's' : '-'; + return pt_flags; +} - pax_buf[2] = pax_flags & PF_MPROTECT ? 'M' : - pax_flags & PF_NOMPROTECT ? 'm' : '-'; - pax_buf[3] = pax_flags & PF_EMUTRAMP ? 'E' : - pax_flags & PF_NOEMUTRAMP ? 'e' : '-'; +uint16_t +read_xt_flags(int fd) +{ + uint16_t xt_flags; - pax_buf[4] = pax_flags & PF_RANDMMAP ? 'R' : - pax_flags & PF_NORANDMMAP ? 'r' : '-'; + xt_flags = UINT16_MAX; - pax_buf[5] = pax_flags & PF_RANDEXEC ? 'X' : - pax_flags & PF_NORANDEXEC ? 'x' : '-'; + if(fgetxattr(fd, PAX_NAMESPACE, &xt_flags, sizeof(uint16_t)) == -1) + { + // ERANGE = xattrs supported, PAX_NAMESPACE present, but wrong size + // ENOATTR = xattrs supported, PAX_NAMESPACE not present + if(errno == ERANGE || errno == ENOATTR) + { + printf("XT_PAX: not present or corrupted\n"); + /* + printf("XT_PAX: creating/repairing flags\n"); + xt_flags = PF_NOEMUTRAMP | PF_NORANDEXEC; + if(fsetxattr(fd, PAX_NAMESPACE, &xt_flags, sizeof(uint16_t), 0) == -1) + { + xt_flags = UINT16_MAX; + if(errno == ENOSPC || errno == EDQUOT) + printf("XT_PAX: access error\n"); + if(errno == ENOTSUP) + printf("XT_PAX: not supported\n"); + } + */ } + + // ENOTSUP = xattrs not supported + if(errno == ENOTSUP) + printf("XT_PAX: not supported\n"); } - elf_end(elf); - close(fd); + return xt_flags; +} + + +void +bin2string(uint16_t flags, char *buf) +{ + buf[0] = flags & PF_PAGEEXEC ? 'P' : + flags & PF_NOPAGEEXEC ? 'p' : '-' ; + + buf[1] = flags & PF_SEGMEXEC ? 'S' : + flags & PF_NOSEGMEXEC ? 's' : '-'; + + buf[2] = flags & PF_MPROTECT ? 'M' : + flags & PF_NOMPROTECT ? 'm' : '-'; + + buf[3] = flags & PF_EMUTRAMP ? 'E' : + flags & PF_NOEMUTRAMP ? 'e' : '-'; + + buf[4] = flags & PF_RANDMMAP ? 'R' : + flags & PF_NORANDMMAP ? 'r' : '-'; + + buf[5] = flags & PF_RANDEXEC ? 'X' : + flags & PF_NORANDEXEC ? 'x' : '-'; +} + + +static PyObject * +pax_getflags(PyObject *self, PyObject *args) +{ + const char *f_name; + int fd; + + uint16_t flags; + char buf[BUF_SIZE]; + + memset(buf, 0, BUF_SIZE); + + if (!PyArg_ParseTuple(args, "s", &f_name)) + { + PyErr_SetString(PaxError, "pax_getflags: PyArg_ParseTuple failed"); + return NULL; + } + + if((fd = open(f_name, O_RDONLY)) < 0) + { + PyErr_SetString(PaxError, "pax_getflags: open() failed"); + return NULL; + } + + flags = read_xt_flags(fd); + if( flags != UINT16_MAX ) + { + memset(buf, 0, BUF_SIZE); + bin2string(flags, buf); + } + else + { + flags = read_pt_flags(fd); + if( flags != UINT16_MAX ) + { + memset(buf, 0, BUF_SIZE); + bin2string(flags, buf); + } + } - return Py_BuildValue("si", pax_buf, pax_flags); + return Py_BuildValue("si", buf, flags); } diff --git a/src/paxctl-ng.c b/src/paxctl-ng.c index 0df3a59..70c2a2c 100644 --- a/src/paxctl-ng.c +++ b/src/paxctl-ng.c @@ -34,7 +34,7 @@ #include <config.h> -#define PAX_NAMESPACE "trusted.pax" +#define PAX_NAMESPACE "user.pax" #define BUF_SIZE 7 void @@ -197,11 +197,12 @@ read_xt_flags(int fd) if(fgetxattr(fd, PAX_NAMESPACE, &xt_flags, sizeof(uint16_t)) == -1) { - // ERANGE = xattrs supported, PAX_NAMESPACE present, but wrong size // ENOATTR = xattrs supported, PAX_NAMESPACE not present if(errno == ERANGE || errno == ENOATTR) { + printf("XT_PAX: not present or corrupted\n"); + /* printf("XT_PAX: creating/repairing flags\n"); xt_flags = PF_NOEMUTRAMP | PF_NORANDEXEC; if(fsetxattr(fd, PAX_NAMESPACE, &xt_flags, sizeof(uint16_t), 0) == -1) @@ -211,6 +212,7 @@ read_xt_flags(int fd) if(errno == ENOTSUP) printf("XT_PAX: not supported\n"); } + */ } // ENOTSUP = xattrs not supported |