public inbox for gentoo-commits@lists.gentoo.org
 help / color / mirror / Atom feed
From: "Anthony G. Basile" <blueness@gentoo.org>
To: gentoo-commits@lists.gentoo.org
Subject: [gentoo-commits] proj/elfix:master commit in: src/, scripts/
Date: Thu, 20 Oct 2011 17:09:29 +0000 (UTC)	[thread overview]
Message-ID: <b0e634a482a5eab43b58e2d35aee54cfa38fea88.blueness@gentoo> (raw)

commit:     b0e634a482a5eab43b58e2d35aee54cfa38fea88
Author:     Anthony G. Basile <blueness <AT> gentoo <DOT> org>
AuthorDate: Thu Oct 20 17:09:22 2011 +0000
Commit:     Anthony G. Basile <blueness <AT> gentoo <DOT> org>
CommitDate: Thu Oct 20 17:09:22 2011 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/elfix.git;a=commit;h=b0e634a4

scripts/paxmodule.c: add XT_PAX write support, code cleanup

---
 scripts/paxmodule.c |  172 +++++++++++++++++++++++++++++++--------------------
 src/paxctl-ng.c     |  146 ++++++++++++++++++++++++++++---------------
 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);
 }



             reply	other threads:[~2011-10-20 17:09 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-10-20 17:09 Anthony G. Basile [this message]
  -- strict thread matches above, loose matches on Subject: below --
2012-11-10 20:52 [gentoo-commits] proj/elfix:master commit in: src/, scripts/ Anthony G. Basile
2012-07-21 17:09 Anthony G. Basile
2011-10-21 21:19 Anthony G. Basile
2011-10-20 18:12 Anthony G. Basile
2011-10-20 14:12 Anthony G. Basile
2011-10-18 18:15 Anthony G. Basile

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=b0e634a482a5eab43b58e2d35aee54cfa38fea88.blueness@gentoo \
    --to=blueness@gentoo.org \
    --cc=gentoo-commits@lists.gentoo.org \
    --cc=gentoo-dev@lists.gentoo.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox