diff options
author | Anthony G. Basile <blueness@gentoo.org> | 2011-10-17 15:28:22 -0400 |
---|---|---|
committer | Anthony G. Basile <blueness@gentoo.org> | 2011-10-17 15:28:22 -0400 |
commit | f1097c9e8fc1624799f7a08c7e510e24903f1f7d (patch) | |
tree | d05276fd5667048a554983154ce34bfd9b8be46c | |
parent | scripts/revdep-pax: make only one of -f -r -b -s -l allowed (diff) | |
download | elfix-f1097c9e8fc1624799f7a08c7e510e24903f1f7d.tar.gz elfix-f1097c9e8fc1624799f7a08c7e510e24903f1f7d.tar.bz2 elfix-f1097c9e8fc1624799f7a08c7e510e24903f1f7d.zip |
scripts/{paxmodule.c,revdep-pax}: add code to set pax flags
-rw-r--r-- | scripts/paxmodule.c | 183 | ||||
-rwxr-xr-x | scripts/revdep-pax | 100 |
2 files changed, 101 insertions, 182 deletions
diff --git a/scripts/paxmodule.c b/scripts/paxmodule.c index eac774a..32c8768 100644 --- a/scripts/paxmodule.c +++ b/scripts/paxmodule.c @@ -1,6 +1,5 @@ #include <Python.h> -#include <stdio.h> //remove when you remove printf #include <string.h> #include <gelf.h> @@ -53,14 +52,13 @@ static PyObject * pax_getflags(PyObject *self, PyObject *args) { const char *f_name; - int fd, sts; + int fd; Elf *elf; char pax_buf[BUF_SIZE]; + uint16_t pax_flags; GElf_Ehdr ehdr; - uint16_t ei_flags; - GElf_Phdr phdr; char found_pt_pax; size_t i, phnum; @@ -102,6 +100,8 @@ pax_getflags(PyObject *self, PyObject *args) found_pt_pax = 0; + pax_flags = 0; + elf_getphdrnum(elf, &phnum); for(i=0; i<phnum; ++i) { @@ -116,24 +116,25 @@ pax_getflags(PyObject *self, PyObject *args) if(phdr.p_type == PT_PAX_FLAGS) { found_pt_pax = 1; + pax_flags = phdr.p_flags; - pax_buf[0] = phdr.p_flags & PF_PAGEEXEC ? 'P' : - phdr.p_flags & PF_NOPAGEEXEC ? 'p' : '-' ; + pax_buf[0] = pax_flags & PF_PAGEEXEC ? 'P' : + pax_flags & PF_NOPAGEEXEC ? 'p' : '-' ; - pax_buf[1] = phdr.p_flags & PF_SEGMEXEC ? 'S' : - phdr.p_flags & PF_NOSEGMEXEC ? 's' : '-'; + pax_buf[1] = pax_flags & PF_SEGMEXEC ? 'S' : + pax_flags & PF_NOSEGMEXEC ? 's' : '-'; - pax_buf[2] = phdr.p_flags & PF_MPROTECT ? 'M' : - phdr.p_flags & PF_NOMPROTECT ? 'm' : '-'; + pax_buf[2] = pax_flags & PF_MPROTECT ? 'M' : + pax_flags & PF_NOMPROTECT ? 'm' : '-'; - pax_buf[3] = phdr.p_flags & PF_EMUTRAMP ? 'E' : - phdr.p_flags & PF_NOEMUTRAMP ? 'e' : '-'; + pax_buf[3] = pax_flags & PF_EMUTRAMP ? 'E' : + pax_flags & PF_NOEMUTRAMP ? 'e' : '-'; - pax_buf[4] = phdr.p_flags & PF_RANDMMAP ? 'R' : - phdr.p_flags & PF_NORANDMMAP ? 'r' : '-'; + pax_buf[4] = pax_flags & PF_RANDMMAP ? 'R' : + pax_flags & PF_NORANDMMAP ? 'r' : '-'; - pax_buf[5] = phdr.p_flags & PF_RANDEXEC ? 'X' : - phdr.p_flags & PF_NORANDEXEC ? 'x' : '-'; + pax_buf[5] = pax_flags & PF_RANDEXEC ? 'X' : + pax_flags & PF_NORANDEXEC ? 'x' : '-'; } } @@ -147,20 +148,20 @@ pax_getflags(PyObject *self, PyObject *args) return NULL; } - ei_flags = ehdr.e_ident[EI_PAX] + (ehdr.e_ident[EI_PAX + 1] << 8); + pax_flags = ehdr.e_ident[EI_PAX] + (ehdr.e_ident[EI_PAX + 1] << 8); - pax_buf[0] = ei_flags & HF_PAX_PAGEEXEC ? 'p' : 'P'; - pax_buf[1] = ei_flags & HF_PAX_SEGMEXEC ? 's' : 'S'; - pax_buf[2] = ei_flags & HF_PAX_MPROTECT ? 'm' : 'M'; - pax_buf[3] = ei_flags & HF_PAX_EMUTRAMP ? 'E' : 'e'; - pax_buf[4] = ei_flags & HF_PAX_RANDMMAP ? 'r' : 'R'; - pax_buf[5] = ei_flags & HF_PAX_RANDEXEC ? 'X' : 'x'; + pax_buf[0] = pax_flags & HF_PAX_PAGEEXEC ? 'p' : 'P'; + pax_buf[1] = pax_flags & HF_PAX_SEGMEXEC ? 's' : 'S'; + pax_buf[2] = pax_flags & HF_PAX_MPROTECT ? 'm' : 'M'; + pax_buf[3] = pax_flags & HF_PAX_EMUTRAMP ? 'E' : 'e'; + pax_buf[4] = pax_flags & HF_PAX_RANDMMAP ? 'r' : 'R'; + pax_buf[5] = pax_flags & HF_PAX_RANDEXEC ? 'X' : 'x'; } elf_end(elf); close(fd); - return Py_BuildValue("s", pax_buf); + return Py_BuildValue("si", pax_buf, pax_flags); } @@ -168,10 +169,11 @@ static PyObject * pax_setflags(PyObject *self, PyObject *args) { const char *f_name; - int pax_flags; - int fd, sts; + uint16_t pax_flags; + int fd; Elf *elf; + GElf_Ehdr ehdr; uint16_t ei_flags; @@ -190,13 +192,13 @@ pax_setflags(PyObject *self, PyObject *args) return NULL; } - if((fd = open(f_name, O_RDONLY)) < 0) + if((fd = open(f_name, O_RDWR)) < 0) { PyErr_SetString(PaxError, "pax_setflags: open() failed"); return NULL; } - if((elf = elf_begin(fd, ELF_C_READ_MMAP, NULL)) == NULL) + if((elf = elf_begin(fd, ELF_C_RDWR_MMAP, NULL)) == NULL) { close(fd); PyErr_SetString(PaxError, "pax_setflags: elf_begin() failed"); @@ -211,8 +213,6 @@ pax_setflags(PyObject *self, PyObject *args) return NULL; } - - if(gelf_getehdr(elf, &ehdr) != &ehdr) { elf_end(elf); @@ -223,54 +223,48 @@ pax_setflags(PyObject *self, PyObject *args) ei_flags = ehdr.e_ident[EI_PAX] + (ehdr.e_ident[EI_PAX + 1] << 8); + ei_flags &= ~HF_PAX_PAGEEXEC; + ei_flags &= ~HF_PAX_SEGMEXEC; + ei_flags &= ~HF_PAX_MPROTECT; + ei_flags |= HF_PAX_EMUTRAMP; + ei_flags &= ~HF_PAX_RANDMMAP; + ei_flags |= HF_PAX_RANDEXEC; + //PAGEEXEC if(pax_flags & PF_PAGEEXEC) ei_flags &= ~HF_PAX_PAGEEXEC; if(pax_flags & PF_NOPAGEEXEC) ei_flags |= HF_PAX_PAGEEXEC; - if((pax_flags & PF_PAGEEXEC) && (pax_flags & PF_NOPAGEEXEC)) - ei_flags &= ~HF_PAX_PAGEEXEC; //SEGMEXEC if(pax_flags & PF_SEGMEXEC) ei_flags &= ~HF_PAX_SEGMEXEC; if(pax_flags & PF_NOSEGMEXEC) ei_flags |= HF_PAX_SEGMEXEC; - if((pax_flags & PF_SEGMEXEC) && (pax_flags & PF_NOSEGMEXEC)) - ei_flags &= ~HF_PAX_SEGMEXEC; //MPROTECT if(pax_flags & PF_MPROTECT) ei_flags &= ~HF_PAX_MPROTECT; if(pax_flags & PF_NOMPROTECT) ei_flags |= HF_PAX_MPROTECT; - if((pax_flags & PF_MPROTECT) && (pax_flags & PF_NOMPROTECT)) - ei_flags &= ~HF_PAX_MPROTECT; //EMUTRAMP if(pax_flags & PF_EMUTRAMP) ei_flags |= HF_PAX_EMUTRAMP; if(pax_flags & PF_NOEMUTRAMP) ei_flags &= ~HF_PAX_EMUTRAMP; - if((pax_flags & PF_EMUTRAMP) && (pax_flags & PF_NOEMUTRAMP)) - ei_flags &= ~HF_PAX_EMUTRAMP; //RANDMMAP if(pax_flags & PF_RANDMMAP) ei_flags &= ~HF_PAX_RANDMMAP; if(pax_flags & PF_NORANDMMAP) ei_flags |= HF_PAX_RANDMMAP; - if((pax_flags & PF_RANDMMAP) && (pax_flags & PF_NORANDMMAP)) - ei_flags &= ~HF_PAX_RANDMMAP; //RANDEXEC if(pax_flags & PF_RANDEXEC) ei_flags |= HF_PAX_RANDEXEC; if(pax_flags & PF_NORANDEXEC) ei_flags &= ~HF_PAX_RANDEXEC; - if((pax_flags & PF_RANDEXEC) && (pax_flags & PF_NORANDEXEC)) - ei_flags |= HF_PAX_RANDEXEC; - ehdr.e_ident[EI_PAX] = (uint8_t)ei_flags ; ehdr.e_ident[EI_PAX + 1] = (uint8_t)(ei_flags >> 8) ; @@ -283,6 +277,7 @@ pax_setflags(PyObject *self, PyObject *args) return NULL; } + elf_getphdrnum(elf, &phnum); for(i=0; i<phnum; ++i) { @@ -296,107 +291,7 @@ pax_setflags(PyObject *self, PyObject *args) if(phdr.p_type == PT_PAX_FLAGS) { - //PAGEEXEC - if(pax_flags & PF_PAGEEXEC) - { - phdr.p_flags |= PF_PAGEEXEC; - phdr.p_flags &= ~PF_NOPAGEEXEC; - } - if(pax_flags & PF_NOPAGEEXEC) - { - phdr.p_flags &= ~PF_PAGEEXEC; - phdr.p_flags |= PF_NOPAGEEXEC; - } - if((pax_flags & PF_PAGEEXEC) && (pax_flags & PF_NOPAGEEXEC)) - { - phdr.p_flags &= ~PF_PAGEEXEC; - phdr.p_flags &= ~PF_NOPAGEEXEC; - } - - //SEGMEXEC - if(pax_flags & PF_SEGMEXEC) - { - phdr.p_flags |= PF_SEGMEXEC; - phdr.p_flags &= ~PF_NOSEGMEXEC; - } - if(pax_flags & PF_NOSEGMEXEC) - { - phdr.p_flags &= ~PF_SEGMEXEC; - phdr.p_flags |= PF_NOSEGMEXEC; - } - if((pax_flags & PF_SEGMEXEC) && (pax_flags & PF_NOSEGMEXEC)) - { - phdr.p_flags &= ~PF_SEGMEXEC; - phdr.p_flags &= ~PF_NOSEGMEXEC; - } - - //MPROTECT - if(pax_flags & PF_MPROTECT) - { - phdr.p_flags |= PF_MPROTECT; - phdr.p_flags &= ~PF_NOMPROTECT; - } - if(pax_flags & PF_NOMPROTECT) - { - phdr.p_flags &= ~PF_MPROTECT; - phdr.p_flags |= PF_NOMPROTECT; - } - if((pax_flags & PF_MPROTECT) && (pax_flags & PF_NOMPROTECT)) - { - phdr.p_flags &= ~PF_MPROTECT; - phdr.p_flags &= ~PF_NOMPROTECT; - } - - //EMUTRAMP - if(pax_flags & PF_EMUTRAMP) - { - phdr.p_flags |= PF_EMUTRAMP; - phdr.p_flags &= ~PF_NOEMUTRAMP; - } - if(pax_flags & PF_NOEMUTRAMP) - { - phdr.p_flags &= ~PF_EMUTRAMP; - phdr.p_flags |= PF_NOEMUTRAMP; - } - if((pax_flags & PF_EMUTRAMP) && (pax_flags & PF_NOEMUTRAMP)) - { - phdr.p_flags &= ~PF_EMUTRAMP; - phdr.p_flags &= ~PF_NOEMUTRAMP; - } - - //RANDMMAP - if(pax_flags & PF_RANDMMAP) - { - phdr.p_flags |= PF_RANDMMAP; - phdr.p_flags &= ~PF_NORANDMMAP; - } - if(pax_flags & PF_NORANDMMAP) - { - phdr.p_flags &= ~PF_RANDMMAP; - phdr.p_flags |= PF_NORANDMMAP; - } - if((pax_flags & PF_RANDMMAP) && (pax_flags & PF_NORANDMMAP)) - { - phdr.p_flags &= ~PF_RANDMMAP; - phdr.p_flags &= ~PF_NORANDMMAP; - } - - //RANDEXEC - if(pax_flags & PF_RANDEXEC) - { - phdr.p_flags |= PF_RANDEXEC; - phdr.p_flags &= ~PF_NORANDEXEC; - } - if(pax_flags & PF_NORANDEXEC) - { - phdr.p_flags &= ~PF_RANDEXEC; - phdr.p_flags |= PF_NORANDEXEC; - } - if((pax_flags & PF_RANDEXEC) && (pax_flags & PF_NORANDEXEC)) - { - phdr.p_flags &= ~PF_RANDEXEC; - phdr.p_flags &= ~PF_NORANDEXEC; - } + phdr.p_flags = pax_flags; if(!gelf_update_phdr(elf, i, &phdr)) { diff --git a/scripts/revdep-pax b/scripts/revdep-pax index 326007e..7a8da3e 100755 --- a/scripts/revdep-pax +++ b/scripts/revdep-pax @@ -8,7 +8,6 @@ import re import pax def get_ldd_linkings(binary): - try: #TODO: when subprocess.DEVNULL makes it to python, change this: http://bugs.python.org/issue5870 ldd_output = subprocess.check_output(['/usr/bin/ldd', binary], stderr=subprocess.PIPE) @@ -83,8 +82,8 @@ def print_forward_linkings( forward_linkings, so2library_mappings, verbose ): for binary in forward_linkings: try: - binary_flags = pax.getflags(binary) - sv = "%s ( %s )" % ( binary, binary_flags ) + ( binary_flags, binary_pax_flags ) = pax.getflags(binary) + sv = '%s ( %s )' % ( binary, binary_flags ) s = sv except: missing_binaries.append(binary) @@ -94,10 +93,10 @@ def print_forward_linkings( forward_linkings, so2library_mappings, verbose ): for soname in forward_linkings[binary]: try: library = so2library_mappings[soname] - library_flags = pax.getflags(library) - sv = "%s\n\t%s\t%s ( %s )" % ( sv, soname, library, library_flags ) + ( library_flags, library_pax_flags ) = pax.getflags(library) + sv = '%s\n\t%s\t%s ( %s )' % ( sv, soname, library, library_flags ) if binary_flags != library_flags: - s = "%s\n\t%s\t%s ( %s )" % ( s, soname, library, library_flags ) + s = '%s\n\t%s\t%s ( %s )' % ( s, soname, library, library_flags ) count = count + 1 except: missing_links.append(soname) @@ -145,8 +144,8 @@ def print_reverse_linkings( reverse_linkings, so2library_mappings, verbose ): try: library = so2library_mappings[soname] - library_flags = pax.getflags(library) - sv = "%s\t%s ( %s )" % ( soname, library, library_flags ) + ( library_flags, library_pax_flags ) = pax.getflags(library) + sv = '%s\t%s ( %s )' % ( soname, library, library_flags ) s = sv except: missing_sonames.append(soname) @@ -155,10 +154,10 @@ def print_reverse_linkings( reverse_linkings, so2library_mappings, verbose ): count = 0 for binary in reverse_linkings[soname]: try: - binary_flags = pax.getflags(binary) - sv = "%s\n\t%s ( %s )" % ( sv, binary, binary_flags ) + ( binary_flags, binary_pax_flags ) = pax.getflags(binary) + sv = '%s\n\t%s ( %s )' % ( sv, binary, binary_flags ) if library_flags != binary_flags: - s = "%s\n\t%s ( %s )" % ( s, binary, binary_flags ) + s = '%s\n\t%s ( %s )' % ( s, binary, binary_flags ) count = count + 1 except: missing_links.append(binary) @@ -203,12 +202,13 @@ def run_usage(): print 'Program Name : revdep-pax' print 'Description : Get or set pax flags on an ELF object' print - print 'Usage : revdep-pax -f [-v] print out all forward mappings for all system binaries' - print ' : revdep-pax -r [-v] print out all reverse mappints for all system sonames' - print ' : revdep-pax -b BINARY [-v] print all forward mappings only for BINARY' - print ' : revdep-pax -s SONAME [-v] print all reverse mappings only for SONAME' - print ' : revdep-pax [-h] print out this help' - print ' : -v verbose, otherwise just print mismatched flags' + print 'Usage : revdep-pax -f [-mv] print out all forward mappings for all system binaries' + print ' : revdep-pax -r [-mv] print out all reverse mappints for all system sonames' + print ' : revdep-pax -b BINARY [-mv] print all forward mappings only for BINARY' + print ' : revdep-pax -s SONAME [-mv] print all reverse mappings only for SONAME' + print ' : revdep-pax [-h] print out this help' + print ' : -v verbose, otherwise just print mismatched flags' + print ' : -m prompt to mark the found objects' print @@ -225,28 +225,28 @@ def run_reverse(verbose): print -def run_binary(binary, verbose): +def run_binary(binary, verbose, mark): ( linkings, mappings ) = get_ldd_linkings(binary) - - binary_flags = pax.getflags(binary) - print binary, '(', binary_flags, ')' + ( binary_flags, binary_pax_flags ) = pax.getflags(binary) + print '%s (%s)' % ( binary, binary_flags ) print - count = 0 + mismatched_libraries = [] + for soname in linkings: try: library = mappings[soname] - library_flags = pax.getflags(library) + ( library_flags, library_pax_flags ) = pax.getflags(library) if verbose: - print '\t', soname, '\t', library, '(', library_flags, ')' - else: - if binary_flags != library_flags: - print '\t', soname, '\t', library, '(', library_flags, ')' - count = count + 1 + print '\t%s\t%s ( %s )' % ( soname, library, library_flags ) + if binary_flags != library_flags: + mismatched_libraries.append(library) + if not verbose: + print '\t%s\t%s ( %s )' % ( soname, library, library_flags ) except: - print "file for soname %s not found" % soname + print 'file for soname %s not found' % soname - if count == 0: + if len(mismatched_libraries) == 0: print print '\tNo mismatches' print @@ -254,6 +254,27 @@ def run_binary(binary, verbose): print print '\tMismatches' print + if mark: + print '\tWill mark libraries with %s' % binary_flags + print + for library in mismatched_libraries: + do_marking = False + while True: + ans = raw_input('\tSet flags for %s (y/n): ' % library) + if ans == 'y': + do_marking = True + break + elif ans == 'n': + do_marking = False + break + else: + print '\t\tPlease enter y or n' + + if do_marking: + pax.setflags(library, binary_pax_flags) + ( library_flags, library_pax_flags ) = pax.getflags(library) + print '\t%s ( %s )' % ( library, library_flags ) + print def invert_so2library_mappings( so2library_mappings ): @@ -263,7 +284,7 @@ def invert_so2library_mappings( so2library_mappings ): return library2soname_mappings -def run_soname(name, verbose, use_soname): +def run_soname(name, verbose, use_soname, mark): ( forward_linkings, so2library_mappings ) = get_forward_linkings() reverse_linkings = invert_linkings( forward_linkings ) @@ -276,14 +297,14 @@ def run_soname(name, verbose, use_soname): linkings = reverse_linkings[soname] library = so2library_mappings[soname] - library_flags = pax.getflags(library) + ( library_flags, library_pax_flags ) = pax.getflags(library) print soname, '\t', library, '(', library_flags, ')' print count = 0 for binary in linkings: try: - binary_flags = pax.getflags(binary) + ( binary_flags, binary_pax_flags ) = pax.getflags(binary) if verbose: print '\t', binary, '(', binary_flags, ')' else: @@ -291,7 +312,7 @@ def run_soname(name, verbose, use_soname): print '\t', binary, '(', binary_flags, ')' count = count + 1 except: - print "cannot obtain pax flags for %s" % binary + print 'cannot obtain pax flags for %s' % binary if count == 0: print @@ -305,7 +326,7 @@ def run_soname(name, verbose, use_soname): def main(): try: - opts, args = getopt.getopt(sys.argv[1:], 'hfrb:s:l:v') + opts, args = getopt.getopt(sys.argv[1:], 'hfrb:s:l:vm') except getopt.GetoptError, err: print str(err) # will print something like 'option -a not recognized' run_usage() @@ -324,6 +345,7 @@ def main(): library = None verbose = False + mark = False opt_count = 0 @@ -348,6 +370,8 @@ def main(): opt_count += 1 elif o == '-v': verbose = True + elif o == '-m': + mark = True else: print 'Option included in getopt but not handled here!' print 'Please file a bug' @@ -361,12 +385,12 @@ def main(): elif do_reverse: run_reverse(verbose) elif binary != None: - run_binary(binary, verbose) + run_binary(binary, verbose, mark) elif soname != None: - run_soname(soname, verbose, True) + run_soname(soname, verbose, True, mark) elif library != None: library = os.path.realpath(library) - run_soname(library, verbose, False) + run_soname(library, verbose, False, mark) if __name__ == '__main__': main() |