aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnthony G. Basile <blueness@gentoo.org>2011-10-20 13:09:22 -0400
committerAnthony G. Basile <blueness@gentoo.org>2011-10-20 13:09:22 -0400
commitb0e634a482a5eab43b58e2d35aee54cfa38fea88 (patch)
tree07512ba009c1e205a1fe1c1bb832f2a4995c3d96
parentscripts/paxmodule.c: add XT_PAX read support (diff)
downloadelfix-b0e634a482a5eab43b58e2d35aee54cfa38fea88.tar.gz
elfix-b0e634a482a5eab43b58e2d35aee54cfa38fea88.tar.bz2
elfix-b0e634a482a5eab43b58e2d35aee54cfa38fea88.zip
scripts/paxmodule.c: add XT_PAX write support, code cleanup
-rw-r--r--scripts/paxmodule.c172
-rw-r--r--src/paxctl-ng.c146
2 files changed, 198 insertions, 120 deletions
diff --git a/scripts/paxmodule.c b/scripts/paxmodule.c
index 6a158fc..c5a7aa6 100644
--- a/scripts/paxmodule.c
+++ b/scripts/paxmodule.c
@@ -1,3 +1,21 @@
+/*
+ paxmodule.c: python module to get/set pax flags on an ELF object
+ Copyright (C) 2011 Anthony G. Basile
+
+ 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
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
#include <Python.h>
#include <string.h>
@@ -41,63 +59,54 @@ initpax(void)
uint16_t
-read_pt_flags(int fd)
+get_pt_flags(int fd)
{
Elf *elf;
GElf_Phdr phdr;
size_t i, phnum;
uint16_t pt_flags;
- char found_pt_pax;
pt_flags = UINT16_MAX;
if(elf_version(EV_CURRENT) == EV_NONE)
{
- close(fd);
- PyErr_SetString(PaxError, "pax_getflags: library out of date");
+ PyErr_SetString(PaxError, "get_pt_flags: library out of date");
return pt_flags;
}
if((elf = elf_begin(fd, ELF_C_READ_MMAP, NULL)) == NULL)
{
- close(fd);
- PyErr_SetString(PaxError, "pax_getflags: elf_begin() failed");
+ PyErr_SetString(PaxError, "get_pt_flags: elf_begin() failed");
return pt_flags;
}
if(elf_kind(elf) != ELF_K_ELF)
{
elf_end(elf);
- close(fd);
- PyErr_SetString(PaxError, "pax_getflags: elf_kind() failed: this is not an elf file.");
+ PyErr_SetString(PaxError, "get_pt_flags: elf_kind() failed: this is not an elf file.");
return pt_flags;
}
- found_pt_pax = 0;
elf_getphdrnum(elf, &phnum);
for(i=0; i<phnum; i++)
{
if(gelf_getphdr(elf, i, &phdr) != &phdr)
- error(EXIT_FAILURE, 0, "gelf_getphdr(): %s", elf_errmsg(elf_errno()));
+ PyErr_SetString(PaxError, "get_pt_flags: gelf_getphdr() failed: could not get phdr.");
if(phdr.p_type == PT_PAX_FLAGS)
- {
- found_pt_pax = 1;
pt_flags = phdr.p_flags;
- }
}
- if(!found_pt_pax)
- printf("PT_PAX: not found\n");
+ elf_end(elf);
return pt_flags;
}
uint16_t
-read_xt_flags(int fd)
+get_xt_flags(int fd)
{
uint16_t xt_flags;
@@ -105,28 +114,31 @@ 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_PAX: not present or corrupted
+
+ //BEGIN: create flags
+ PyErr_SetString(PaxError, "XT_PAX: creating/repairing flags");
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");
+ PyErr_SetString(PaxError, "XT_PAX: access error");
if(errno == ENOTSUP)
- printf("XT_PAX: not supported\n");
+ PyErr_SetString(PaxError, "XT_PAX: not supported");
}
- */
+ // END: create flags
}
// ENOTSUP = xattrs not supported
if(errno == ENOTSUP)
- printf("XT_PAX: not supported\n");
+ PyErr_SetString(PaxError, "XT_PAX: not supported\n");
+ */
}
return xt_flags;
@@ -161,9 +173,8 @@ pax_getflags(PyObject *self, PyObject *args)
{
const char *f_name;
int fd;
-
- uint16_t flags;
- char buf[BUF_SIZE];
+ uint16_t flags;
+ char buf[BUF_SIZE];
memset(buf, 0, BUF_SIZE);
@@ -179,96 +190,121 @@ pax_getflags(PyObject *self, PyObject *args)
return NULL;
}
- flags = read_xt_flags(fd);
- if( flags != UINT16_MAX )
- {
- memset(buf, 0, BUF_SIZE);
- bin2string(flags, buf);
- }
+ flags = get_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 )
+ flags = get_pt_flags(fd);
+ if( flags != UINT16_MAX )
{
memset(buf, 0, BUF_SIZE);
bin2string(flags, buf);
}
}
+ close(fd);
+
return Py_BuildValue("si", buf, flags);
}
-static PyObject *
-pax_setflags(PyObject *self, PyObject *args)
+void
+set_pt_flags(int fd, uint16_t pt_flags)
{
- const char *f_name;
- uint16_t pax_flags;
- int fd;
-
Elf *elf;
GElf_Phdr phdr;
size_t i, phnum;
- if (!PyArg_ParseTuple(args, "si", &f_name, &pax_flags))
- {
- PyErr_SetString(PaxError, "pax_setflags: PyArg_ParseTuple failed");
- return NULL;
- }
-
if(elf_version(EV_CURRENT) == EV_NONE)
{
- PyErr_SetString(PaxError, "pax_setflags: library out of date");
- return NULL;
- }
-
- if((fd = open(f_name, O_RDWR)) < 0)
- {
- PyErr_SetString(PaxError, "pax_setflags: open() failed");
- return NULL;
+ PyErr_SetString(PaxError, "set_pt_flags: library out of date");
+ return;
}
if((elf = elf_begin(fd, ELF_C_RDWR_MMAP, NULL)) == NULL)
{
- close(fd);
- PyErr_SetString(PaxError, "pax_setflags: elf_begin() failed");
- return NULL;
+ PyErr_SetString(PaxError, "set_pt_flags: elf_begin() failed");
+ return;
}
if(elf_kind(elf) != ELF_K_ELF)
{
elf_end(elf);
- close(fd);
- PyErr_SetString(PaxError, "pax_setflags: elf_kind() failed: this is not an elf file.");
- return NULL;
+ PyErr_SetString(PaxError, "set_pt_flags: elf_kind() failed: this is not an elf file.");
+ return;
}
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_setflags: gelf_getphdr() failed");
- return NULL;
+ PyErr_SetString(PaxError, "set_pt_flags: gelf_getphdr() failed");
+ return;
}
if(phdr.p_type == PT_PAX_FLAGS)
{
- phdr.p_flags = pax_flags;
+ phdr.p_flags = pt_flags;
if(!gelf_update_phdr(elf, i, &phdr))
{
elf_end(elf);
- close(fd);
- PyErr_SetString(PaxError, "pax_setflags: gelf_update_phdr() failed");
- return NULL;
+ PyErr_SetString(PaxError, "set_pt_flags: gelf_update_phdr() failed");
+ return;
}
}
}
elf_end(elf);
+}
+
+
+void
+set_xt_flags(int fd, uint16_t xt_flags)
+{
+ if(fsetxattr(fd, PAX_NAMESPACE, &xt_flags, sizeof(uint16_t), 0) == -1)
+ {
+ /*
+ if(errno == ENOSPC || errno == EDQUOT)
+ PyErr_SetString(PaxError, "XT_PAX: access error");
+ if(errno == ENOTSUP)
+ PyErr_SetString(PaxError, "XT_PAX: not supported\n");
+ */
+ }
+}
+
+
+static PyObject *
+pax_setflags(PyObject *self, PyObject *args)
+{
+ const char *f_name;
+ int fd, iflags;
+ uint16_t flags;
+
+ if (!PyArg_ParseTuple(args, "si", &f_name, &iflags))
+ {
+ PyErr_SetString(PaxError, "pax_setflags: PyArg_ParseTuple failed");
+ return NULL;
+ }
+
+ if((fd = open(f_name, O_RDWR)) < 0)
+ {
+ PyErr_SetString(PaxError, "pax_setflags: open() failed");
+ return NULL;
+ }
+
+ flags = (uint16_t) iflags;
+
+ set_pt_flags(fd, flags);
+ set_xt_flags(fd, flags);
+
close(fd);
return Py_BuildValue("");
diff --git a/src/paxctl-ng.c b/src/paxctl-ng.c
index 70c2a2c..aaeadaf 100644
--- a/src/paxctl-ng.c
+++ b/src/paxctl-ng.c
@@ -128,7 +128,7 @@ parse_cmd_args(int c, char *v[], uint16_t *pax_flags, int *view_flags)
break ;
case 'Z':
*pax_flags = PF_PAGEEXEC | PF_SEGMEXEC | PF_MPROTECT |
- PF_NOEMUTRAMP | PF_RANDMMAP | PF_RANDEXEC;
+ PF_NOEMUTRAMP | PF_RANDMMAP | PF_NORANDEXEC;
compat += 1;
break ;
case 'z':
@@ -157,15 +157,35 @@ parse_cmd_args(int c, char *v[], uint16_t *pax_flags, int *view_flags)
uint16_t
-read_pt_flags(Elf *elf)
+get_pt_flags(int fd)
{
+ Elf *elf;
GElf_Phdr phdr;
size_t i, phnum;
uint16_t pt_flags;
- char found_pt_pax;
- found_pt_pax = 0;
+ pt_flags = UINT16_MAX;
+
+ if(elf_version(EV_CURRENT) == EV_NONE)
+ {
+ error(EXIT_FAILURE, 0, "Library out of date.");
+ return;
+ }
+
+ if((elf = elf_begin(fd, ELF_C_READ_MMAP, NULL)) == NULL)
+ {
+ error(EXIT_FAILURE, 0, "elf_begin() fail: %s", elf_errmsg(elf_errno()));
+ return;
+ }
+
+ if(elf_kind(elf) != ELF_K_ELF)
+ {
+ elf_end(elf);
+ error(EXIT_FAILURE, 0, "elf_kind() fail: this is not an elf file.");
+ return;
+ }
+
elf_getphdrnum(elf, &phnum);
for(i=0; i<phnum; i++)
@@ -174,27 +194,22 @@ read_pt_flags(Elf *elf)
error(EXIT_FAILURE, 0, "gelf_getphdr(): %s", elf_errmsg(elf_errno()));
if(phdr.p_type == PT_PAX_FLAGS)
- {
- found_pt_pax = 1;
pt_flags = phdr.p_flags;
- }
}
- if(!found_pt_pax)
- {
- printf("PT_PAX: not found\n");
- pt_flags = UINT16_MAX;
- }
+ elf_end(elf);
return pt_flags;
}
uint16_t
-read_xt_flags(int fd)
+get_xt_flags(int fd)
{
uint16_t xt_flags;
+ xt_flags = UINT16_MAX;
+
if(fgetxattr(fd, PAX_NAMESPACE, &xt_flags, sizeof(uint16_t)) == -1)
{
// ERANGE = xattrs supported, PAX_NAMESPACE present, but wrong size
@@ -207,6 +222,7 @@ read_xt_flags(int fd)
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)
@@ -217,10 +233,7 @@ read_xt_flags(int fd)
// ENOTSUP = xattrs not supported
if(errno == ENOTSUP)
- {
- xt_flags = UINT16_MAX; //invalid value
printf("XT_PAX: not supported\n");
- }
}
return xt_flags;
@@ -251,21 +264,29 @@ bin2string(uint16_t flags, char *buf)
void
-print_flags(int fd, Elf *elf)
+print_flags(int fd)
{
uint16_t flags;
char buf[BUF_SIZE];
- flags = read_pt_flags(elf);
- if( flags != UINT16_MAX )
+ flags = get_pt_flags(fd);
+ if( flags == UINT16_MAX )
+ {
+ printf("PT_PAX: not found\n");
+ }
+ else
{
memset(buf, 0, BUF_SIZE);
bin2string(flags, buf);
printf("PT_PAX: %s\n", buf);
}
- flags = read_xt_flags(fd);
- if( flags != UINT16_MAX )
+ flags = get_xt_flags(fd);
+ if( flags == UINT16_MAX )
+ {
+ printf("XT_PAX: not found\n");
+ }
+ else
{
memset(buf, 0, BUF_SIZE);
bin2string(flags, buf);
@@ -385,25 +406,56 @@ new_flags(uint16_t flags, uint16_t pax_flags)
void
-set_pt_flags(Elf *elf, uint16_t pt_flags)
+set_pt_flags(int fd, uint16_t pt_flags)
{
+ Elf *elf;
GElf_Phdr phdr;
size_t i, phnum;
+ if(elf_version(EV_CURRENT) == EV_NONE)
+ {
+ error(EXIT_FAILURE, 0, "Library out of date.");
+ return;
+ }
+
+ if((elf = elf_begin(fd, ELF_C_RDWR_MMAP, NULL)) == NULL)
+ {
+ error(EXIT_FAILURE, 0, "elf_begin() fail: %s", elf_errmsg(elf_errno()));
+ return;
+ }
+
+ if(elf_kind(elf) != ELF_K_ELF)
+ {
+ elf_end(elf);
+ error(EXIT_FAILURE, 0, "elf_kind() fail: this is not an elf file.");
+ return;
+ }
+
elf_getphdrnum(elf, &phnum);
for(i=0; i<phnum; i++)
{
if(gelf_getphdr(elf, i, &phdr) != &phdr)
+ {
+ elf_end(elf);
error(EXIT_FAILURE, 0, "gelf_getphdr(): %s", elf_errmsg(elf_errno()));
+ return;
+ }
if(phdr.p_type == PT_PAX_FLAGS)
{
phdr.p_flags = pt_flags;
+
if(!gelf_update_phdr(elf, i, &phdr))
+ {
+ elf_end(elf);
error(EXIT_FAILURE, 0, "gelf_update_phdr(): %s", elf_errmsg(elf_errno()));
+ return;
+ }
}
}
+
+ elf_end(elf);
}
@@ -421,56 +473,46 @@ set_xt_flags(int fd, uint16_t xt_flags)
void
-set_flags(int fd, Elf *elf, uint16_t *pax_flags)
+set_flags(int fd, uint16_t *pax_flags)
{
uint16_t flags;
- flags = read_pt_flags(elf);
- if( flags != UINT16_MAX )
- {
- flags = new_flags( flags, *pax_flags);
- set_pt_flags(elf, flags);
- }
-
- flags = read_xt_flags(fd);
- if( flags != UINT16_MAX )
- {
- flags = new_flags( flags, *pax_flags);
- set_xt_flags(fd, flags);
- }
+ flags = get_pt_flags(fd);
+ if( flags == UINT16_MAX )
+ flags = PF_PAGEEXEC | PF_SEGMEXEC | PF_MPROTECT |
+ PF_NOEMUTRAMP | PF_RANDMMAP | PF_NORANDEXEC;
+ flags = new_flags( flags, *pax_flags);
+ set_pt_flags(fd, flags);
+
+ flags = get_xt_flags(fd);
+ if( flags == UINT16_MAX )
+ flags = PF_PAGEEXEC | PF_SEGMEXEC | PF_MPROTECT |
+ PF_NOEMUTRAMP | PF_RANDMMAP | PF_NORANDEXEC;
+ flags = new_flags( flags, *pax_flags);
+ set_xt_flags(fd, flags);
}
int
main( int argc, char *argv[])
{
+ const char *f_name;
int fd;
- uint16_t pax_flags;
+ uint16_t flags;
int view_flags;
- char *f_name;
Elf *elf;
- f_name = parse_cmd_args(argc, argv, &pax_flags, &view_flags);
-
- if(elf_version(EV_CURRENT) == EV_NONE)
- error(EXIT_FAILURE, 0, "Library out of date.");
+ f_name = parse_cmd_args(argc, argv, &flags, &view_flags);
if((fd = open(f_name, O_RDWR)) < 0)
error(EXIT_FAILURE, 0, "open() fail.");
- if((elf = elf_begin(fd, ELF_C_RDWR_MMAP, NULL)) == NULL)
- error(EXIT_FAILURE, 0, "elf_begin() fail: %s", elf_errmsg(elf_errno()));
-
- if(elf_kind(elf) != ELF_K_ELF)
- error(EXIT_FAILURE, 0, "elf_kind() fail: this is not an elf file.");
-
- if(pax_flags != 0)
- set_flags(fd, elf, &pax_flags);
+ if(flags != 0)
+ set_flags(fd, &flags);
if(view_flags == 1)
- print_flags(fd, elf);
+ print_flags(fd);
- elf_end(elf);
close(fd);
}