Add options to print, clear and set executable stack state
Add options the modify the state of the executable flag of the GNU_STACK program header. That header indicates whether the object is requiring an executable stack.
This commit is contained in:
parent
5908e16cd5
commit
f7d304eeb1
|
@ -32,6 +32,7 @@ Makefile
|
||||||
/tests/libbig-dynstr.debug
|
/tests/libbig-dynstr.debug
|
||||||
/tests/contiguous-note-sections
|
/tests/contiguous-note-sections
|
||||||
/tests/simple-pie
|
/tests/simple-pie
|
||||||
|
/tests/simple-execstack
|
||||||
|
|
||||||
.direnv/
|
.direnv/
|
||||||
.vscode/
|
.vscode/
|
||||||
|
|
|
@ -114,6 +114,15 @@ This means that when a shared library has an entry point (so that it
|
||||||
can be run as an executable), the debugger does not connect to it correctly and
|
can be run as an executable), the debugger does not connect to it correctly and
|
||||||
symbols are not resolved.
|
symbols are not resolved.
|
||||||
|
|
||||||
|
.IP "--print-execstack"
|
||||||
|
Prints the state of the executable flag of the GNU_STACK program header, if present.
|
||||||
|
|
||||||
|
.IP "--clear-execstack"
|
||||||
|
Clears the executable flag of the GNU_STACK program header, or adds a new header.
|
||||||
|
|
||||||
|
.IP "--set-execstack"
|
||||||
|
Sets the executable flag of the GNU_STACK program header, or adds a new header.
|
||||||
|
|
||||||
.IP "--output FILE"
|
.IP "--output FILE"
|
||||||
Set the output file name. If not specified, the input will be modified in place.
|
Set the output file name. If not specified, the input will be modified in place.
|
||||||
|
|
||||||
|
|
105
src/patchelf.cc
105
src/patchelf.cc
|
@ -1010,10 +1010,10 @@ void ElfFile<ElfFileParamNames>::normalizeNoteSegments()
|
||||||
|
|
||||||
|
|
||||||
template<ElfFileParams>
|
template<ElfFileParams>
|
||||||
void ElfFile<ElfFileParamNames>::rewriteSections()
|
void ElfFile<ElfFileParamNames>::rewriteSections(bool force)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (replacedSections.empty()) return;
|
if (!force && replacedSections.empty()) return;
|
||||||
|
|
||||||
for (auto & i : replacedSections)
|
for (auto & i : replacedSections)
|
||||||
debug("replacing section '%s' with size %d\n",
|
debug("replacing section '%s' with size %d\n",
|
||||||
|
@ -1890,6 +1890,85 @@ void ElfFile<ElfFileParamNames>::clearSymbolVersions(const std::set<std::string>
|
||||||
this->rewriteSections();
|
this->rewriteSections();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<ElfFileParams>
|
||||||
|
void ElfFile<ElfFileParamNames>::modifyExecstack(ExecstackMode op)
|
||||||
|
{
|
||||||
|
if (op == ExecstackMode::clear || op == ExecstackMode::set) {
|
||||||
|
size_t nullhdr = (size_t)-1;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < phdrs.size(); i++) {
|
||||||
|
auto & header = phdrs[i];
|
||||||
|
const auto type = rdi(header.p_type);
|
||||||
|
if (type != PT_GNU_STACK) {
|
||||||
|
if (!nullhdr && type == PT_NULL)
|
||||||
|
nullhdr = i;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (op == ExecstackMode::clear && (rdi(header.p_flags) & PF_X) == PF_X) {
|
||||||
|
debug("simple execstack clear of header %zu\n", i);
|
||||||
|
|
||||||
|
wri(header.p_flags, rdi(header.p_flags) & ~PF_X);
|
||||||
|
* ((Elf_Phdr *) (fileContents->data() + rdi(hdr()->e_phoff)) + i) = header;
|
||||||
|
changed = true;
|
||||||
|
} else if (op == ExecstackMode::set && (rdi(header.p_flags) & PF_X) != PF_X) {
|
||||||
|
debug("simple execstack set of header %zu\n", i);
|
||||||
|
|
||||||
|
wri(header.p_flags, rdi(header.p_flags) | PF_X);
|
||||||
|
* ((Elf_Phdr *) (fileContents->data() + rdi(hdr()->e_phoff)) + i) = header;
|
||||||
|
changed = true;
|
||||||
|
} else {
|
||||||
|
debug("execstack already in requested state\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nullhdr != (size_t)-1) {
|
||||||
|
debug("replacement execstack of header %zu\n", nullhdr);
|
||||||
|
|
||||||
|
auto & header = phdrs[nullhdr];
|
||||||
|
header = {};
|
||||||
|
wri(header.p_type, PT_GNU_STACK);
|
||||||
|
wri(header.p_flags, PF_R | PF_W | (op == ExecstackMode::set ? PF_X : 0));
|
||||||
|
wri(header.p_align, 0x1);
|
||||||
|
|
||||||
|
* ((Elf_Phdr *) (fileContents->data() + rdi(hdr()->e_phoff)) + nullhdr) = header;
|
||||||
|
changed = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
debug("header addition for execstack\n");
|
||||||
|
|
||||||
|
Elf_Phdr new_phdr = {};
|
||||||
|
wri(new_phdr.p_type, PT_GNU_STACK);
|
||||||
|
wri(new_phdr.p_flags, PF_R | PF_W | (op == ExecstackMode::set ? PF_X : 0));
|
||||||
|
wri(new_phdr.p_align, 0x1);
|
||||||
|
phdrs.push_back(new_phdr);
|
||||||
|
|
||||||
|
wri(hdr()->e_phnum, rdi(hdr()->e_phnum) + 1);
|
||||||
|
|
||||||
|
changed = true;
|
||||||
|
rewriteSections(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
char result = '?';
|
||||||
|
|
||||||
|
for (const auto & header : phdrs) {
|
||||||
|
if (rdi(header.p_type) != PT_GNU_STACK)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if ((rdi(header.p_flags) & PF_X) == PF_X)
|
||||||
|
result = 'X';
|
||||||
|
else
|
||||||
|
result = '-';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("execstack: %c\n", result);
|
||||||
|
}
|
||||||
|
|
||||||
static bool printInterpreter = false;
|
static bool printInterpreter = false;
|
||||||
static bool printOsAbi = false;
|
static bool printOsAbi = false;
|
||||||
static bool setOsAbi = false;
|
static bool setOsAbi = false;
|
||||||
|
@ -1912,6 +1991,9 @@ static std::set<std::string> neededLibsToAdd;
|
||||||
static std::set<std::string> symbolsToClearVersion;
|
static std::set<std::string> symbolsToClearVersion;
|
||||||
static bool printNeeded = false;
|
static bool printNeeded = false;
|
||||||
static bool noDefaultLib = false;
|
static bool noDefaultLib = false;
|
||||||
|
static bool printExecstack = false;
|
||||||
|
static bool clearExecstack = false;
|
||||||
|
static bool setExecstack = false;
|
||||||
|
|
||||||
template<class ElfFile>
|
template<class ElfFile>
|
||||||
static void patchElf2(ElfFile && elfFile, const FileContents & fileContents, const std::string & fileName)
|
static void patchElf2(ElfFile && elfFile, const FileContents & fileContents, const std::string & fileName)
|
||||||
|
@ -1937,6 +2019,13 @@ static void patchElf2(ElfFile && elfFile, const FileContents & fileContents, con
|
||||||
if (printRPath)
|
if (printRPath)
|
||||||
elfFile.modifyRPath(elfFile.rpPrint, {}, "");
|
elfFile.modifyRPath(elfFile.rpPrint, {}, "");
|
||||||
|
|
||||||
|
if (printExecstack)
|
||||||
|
elfFile.modifyExecstack(ElfFile::ExecstackMode::print);
|
||||||
|
else if (clearExecstack)
|
||||||
|
elfFile.modifyExecstack(ElfFile::ExecstackMode::clear);
|
||||||
|
else if (setExecstack)
|
||||||
|
elfFile.modifyExecstack(ElfFile::ExecstackMode::set);
|
||||||
|
|
||||||
if (shrinkRPath)
|
if (shrinkRPath)
|
||||||
elfFile.modifyRPath(elfFile.rpShrink, allowedRpathPrefixes, "");
|
elfFile.modifyRPath(elfFile.rpShrink, allowedRpathPrefixes, "");
|
||||||
else if (removeRPath)
|
else if (removeRPath)
|
||||||
|
@ -2019,6 +2108,9 @@ void showHelp(const std::string & progName)
|
||||||
[--no-sort]\t\tDo not sort program+section headers; useful for debugging patchelf.\n\
|
[--no-sort]\t\tDo not sort program+section headers; useful for debugging patchelf.\n\
|
||||||
[--clear-symbol-version SYMBOL]\n\
|
[--clear-symbol-version SYMBOL]\n\
|
||||||
[--add-debug-tag]\n\
|
[--add-debug-tag]\n\
|
||||||
|
[--print-execstack]\t\tPrints whether the object requests an executable stack\n\
|
||||||
|
[--clear-execstack]\n\
|
||||||
|
[--set-execstack]\n\
|
||||||
[--output FILE]\n\
|
[--output FILE]\n\
|
||||||
[--debug]\n\
|
[--debug]\n\
|
||||||
[--version]\n\
|
[--version]\n\
|
||||||
|
@ -2127,6 +2219,15 @@ int mainWrapped(int argc, char * * argv)
|
||||||
if (++i == argc) error("missing argument");
|
if (++i == argc) error("missing argument");
|
||||||
symbolsToClearVersion.insert(resolveArgument(argv[i]));
|
symbolsToClearVersion.insert(resolveArgument(argv[i]));
|
||||||
}
|
}
|
||||||
|
else if (arg == "--print-execstack") {
|
||||||
|
printExecstack = true;
|
||||||
|
}
|
||||||
|
else if (arg == "--clear-execstack") {
|
||||||
|
clearExecstack = true;
|
||||||
|
}
|
||||||
|
else if (arg == "--set-execstack") {
|
||||||
|
setExecstack = true;
|
||||||
|
}
|
||||||
else if (arg == "--output") {
|
else if (arg == "--output") {
|
||||||
if (++i == argc) error("missing argument");
|
if (++i == argc) error("missing argument");
|
||||||
outputFileName = resolveArgument(argv[i]);
|
outputFileName = resolveArgument(argv[i]);
|
||||||
|
|
|
@ -105,7 +105,7 @@ private:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
void rewriteSections();
|
void rewriteSections(bool force = false);
|
||||||
|
|
||||||
std::string getInterpreter();
|
std::string getInterpreter();
|
||||||
|
|
||||||
|
@ -139,6 +139,10 @@ public:
|
||||||
|
|
||||||
void clearSymbolVersions(const std::set<std::string> & syms);
|
void clearSymbolVersions(const std::set<std::string> & syms);
|
||||||
|
|
||||||
|
enum class ExecstackMode { print, set, clear };
|
||||||
|
|
||||||
|
void modifyExecstack(ExecstackMode op);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
/* Convert an integer in big or little endian representation (as
|
/* Convert an integer in big or little endian representation (as
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
LIBS =
|
LIBS =
|
||||||
|
|
||||||
check_PROGRAMS = simple-pie simple main too-many-strtab main-scoped big-dynstr no-rpath contiguous-note-sections
|
check_PROGRAMS = simple-pie simple simple-execstack main too-many-strtab main-scoped big-dynstr no-rpath contiguous-note-sections
|
||||||
|
|
||||||
no_rpath_arch_TESTS = \
|
no_rpath_arch_TESTS = \
|
||||||
no-rpath-amd64.sh \
|
no-rpath-amd64.sh \
|
||||||
|
@ -43,7 +43,9 @@ src_TESTS = \
|
||||||
replace-needed.sh \
|
replace-needed.sh \
|
||||||
replace-add-needed.sh \
|
replace-add-needed.sh \
|
||||||
add-debug-tag.sh \
|
add-debug-tag.sh \
|
||||||
empty-note.sh
|
empty-note.sh \
|
||||||
|
print-execstack.sh \
|
||||||
|
modify-execstack.sh
|
||||||
|
|
||||||
build_TESTS = \
|
build_TESTS = \
|
||||||
$(no_rpath_arch_TESTS)
|
$(no_rpath_arch_TESTS)
|
||||||
|
@ -71,10 +73,15 @@ export NIX_LDFLAGS=
|
||||||
simple_SOURCES = simple.c
|
simple_SOURCES = simple.c
|
||||||
# no -fpic for simple.o
|
# no -fpic for simple.o
|
||||||
simple_CFLAGS =
|
simple_CFLAGS =
|
||||||
|
simple_LDFLAGS = -Wl,-z,noexecstack
|
||||||
|
|
||||||
simple_pie_SOURCES = simple.c
|
simple_pie_SOURCES = simple.c
|
||||||
simple_pie_CFLAGS = -fPIC -pie
|
simple_pie_CFLAGS = -fPIC -pie
|
||||||
|
|
||||||
|
simple_execstack_SOURCES = simple.c
|
||||||
|
simple_execstack_CFLAGS =
|
||||||
|
simple_execstack_LDFLAGS = -Wl,-z,execstack
|
||||||
|
|
||||||
main_SOURCES = main.c
|
main_SOURCES = main.c
|
||||||
main_LDADD = -lfoo $(AM_LDADD)
|
main_LDADD = -lfoo $(AM_LDADD)
|
||||||
main_DEPENDENCIES = libfoo.so
|
main_DEPENDENCIES = libfoo.so
|
||||||
|
@ -108,7 +115,7 @@ check_DATA = libbig-dynstr.debug
|
||||||
# - without libtool, only archives (static libraries) can be built by automake
|
# - without libtool, only archives (static libraries) can be built by automake
|
||||||
# - with libtool, it is difficult to control options
|
# - with libtool, it is difficult to control options
|
||||||
# - with libtool, it is not possible to compile convenience *dynamic* libraries :-(
|
# - with libtool, it is not possible to compile convenience *dynamic* libraries :-(
|
||||||
check_PROGRAMS += libfoo.so libfoo-scoped.so libbar.so libbar-scoped.so libsimple.so libbuildid.so libtoomanystrtab.so \
|
check_PROGRAMS += libfoo.so libfoo-scoped.so libbar.so libbar-scoped.so libsimple.so libsimple-execstack.so libbuildid.so libtoomanystrtab.so \
|
||||||
phdr-corruption.so
|
phdr-corruption.so
|
||||||
|
|
||||||
libbuildid_so_SOURCES = simple.c
|
libbuildid_so_SOURCES = simple.c
|
||||||
|
@ -131,7 +138,10 @@ libbar_scoped_so_SOURCES = bar.c
|
||||||
libbar_scoped_so_LDFLAGS = $(LDFLAGS_sharedlib)
|
libbar_scoped_so_LDFLAGS = $(LDFLAGS_sharedlib)
|
||||||
|
|
||||||
libsimple_so_SOURCES = simple.c
|
libsimple_so_SOURCES = simple.c
|
||||||
libsimple_so_LDFLAGS = $(LDFLAGS_sharedlib)
|
libsimple_so_LDFLAGS = $(LDFLAGS_sharedlib) -Wl,-z,noexecstack
|
||||||
|
|
||||||
|
libsimple_execstack_so_SOURCES = simple.c
|
||||||
|
libsimple_execstack_so_LDFLAGS = $(LDFLAGS_sharedlib) -Wl,-z,execstack
|
||||||
|
|
||||||
too_many_strtab_SOURCES = too-many-strtab.c too-many-strtab2.s
|
too_many_strtab_SOURCES = too-many-strtab.c too-many-strtab2.s
|
||||||
libtoomanystrtab_so_SOURCES = too-many-strtab.c too-many-strtab2.s
|
libtoomanystrtab_so_SOURCES = too-many-strtab.c too-many-strtab2.s
|
||||||
|
|
|
@ -0,0 +1,225 @@
|
||||||
|
#! /bin/sh -e
|
||||||
|
SCRATCH=scratch/$(basename $0 .sh)
|
||||||
|
PATCHELF=$(readlink -f "../src/patchelf")
|
||||||
|
|
||||||
|
rm -rf ${SCRATCH}
|
||||||
|
mkdir -p ${SCRATCH}
|
||||||
|
|
||||||
|
cp simple ${SCRATCH}/
|
||||||
|
cp simple-execstack ${SCRATCH}/
|
||||||
|
cp libsimple.so ${SCRATCH}/
|
||||||
|
cp libsimple-execstack.so ${SCRATCH}/
|
||||||
|
|
||||||
|
cd ${SCRATCH}
|
||||||
|
|
||||||
|
|
||||||
|
## simple
|
||||||
|
|
||||||
|
cp simple backup
|
||||||
|
|
||||||
|
if ! ${PATCHELF} --print-execstack simple | grep -q 'execstack: -'; then
|
||||||
|
echo "[simple] wrong initial execstack detection"
|
||||||
|
${PATCHELF} --print-execstack simple
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! ${PATCHELF} --clear-execstack simple; then
|
||||||
|
echo "[simple] failed noop initial clear"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! ${PATCHELF} --set-execstack simple; then
|
||||||
|
echo "[simple] failed set"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! ${PATCHELF} --print-execstack simple | grep -q 'execstack: X'; then
|
||||||
|
echo "[simple] wrong execstack detection after set"
|
||||||
|
${PATCHELF} --print-execstack simple
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if diff simple backup; then
|
||||||
|
echo "[simple] no change after set"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! ${PATCHELF} --set-execstack simple; then
|
||||||
|
echo "[simple] failed noop set"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! ${PATCHELF} --clear-execstack simple; then
|
||||||
|
echo "[simple] failed clear after set"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! ${PATCHELF} --print-execstack simple | grep -q 'execstack: -'; then
|
||||||
|
echo "[simple] wrong execstack detection after clear after set"
|
||||||
|
${PATCHELF} --print-execstack simple
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! diff simple backup; then
|
||||||
|
echo "[simple] change against backup after clear after set"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
## simple-execstack
|
||||||
|
|
||||||
|
cp simple-execstack backup
|
||||||
|
|
||||||
|
if ! ${PATCHELF} --print-execstack simple-execstack | grep -q 'execstack: X'; then
|
||||||
|
echo "[simple-execstack] wrong initial execstack detection"
|
||||||
|
${PATCHELF} --print-execstack simple-execstack
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! ${PATCHELF} --set-execstack simple-execstack; then
|
||||||
|
echo "[simple-execstack] failed noop initial set"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! ${PATCHELF} --clear-execstack simple-execstack; then
|
||||||
|
echo "[simple-execstack] failed clear"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! ${PATCHELF} --print-execstack simple-execstack | grep -q 'execstack: -'; then
|
||||||
|
echo "[simple-execstack] wrong execstack detection after clear"
|
||||||
|
${PATCHELF} --print-execstack simple-execstack
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if diff simple-execstack backup; then
|
||||||
|
echo "[simple-execstack] no change after set"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! ${PATCHELF} --clear-execstack simple-execstack; then
|
||||||
|
echo "[simple-execstack] failed noop clear"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! ${PATCHELF} --set-execstack simple-execstack; then
|
||||||
|
echo "[simple-execstack] failed set after clear"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! ${PATCHELF} --print-execstack simple-execstack | grep -q 'execstack: X'; then
|
||||||
|
echo "[simple-execstack] wrong execstack detection after set after clear"
|
||||||
|
${PATCHELF} --print-execstack simple-execstack
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! diff simple-execstack backup; then
|
||||||
|
echo "[simple-execstack] change against backup after set after clear"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
## libsimple.so
|
||||||
|
|
||||||
|
cp libsimple.so backup
|
||||||
|
|
||||||
|
if ! ${PATCHELF} --print-execstack libsimple.so | grep -q 'execstack: -'; then
|
||||||
|
echo "[libsimple.so] wrong initial execstack detection"
|
||||||
|
${PATCHELF} --print-execstack libsimple.so
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! ${PATCHELF} --clear-execstack libsimple.so; then
|
||||||
|
echo "[libsimple.so] failed noop initial clear"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! ${PATCHELF} --set-execstack libsimple.so; then
|
||||||
|
echo "[libsimple.so] failed set"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! ${PATCHELF} --print-execstack libsimple.so | grep -q 'execstack: X'; then
|
||||||
|
echo "[libsimple.so] wrong execstack detection after set"
|
||||||
|
${PATCHELF} --print-execstack libsimple.so
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if diff libsimple.so backup; then
|
||||||
|
echo "[libsimple.so] no change after set"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! ${PATCHELF} --set-execstack libsimple.so; then
|
||||||
|
echo "[libsimple.so] failed noop set"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! ${PATCHELF} --clear-execstack libsimple.so; then
|
||||||
|
echo "[libsimple.so] failed clear after set"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! ${PATCHELF} --print-execstack libsimple.so | grep -q 'execstack: -'; then
|
||||||
|
echo "[libsimple.so] wrong execstack detection after clear after set"
|
||||||
|
${PATCHELF} --print-execstack libsimple.so
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! diff libsimple.so backup; then
|
||||||
|
echo "[libsimple.so] change against backup after clear after set"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
## libsimple-execstack.so
|
||||||
|
|
||||||
|
cp libsimple-execstack.so backup
|
||||||
|
|
||||||
|
if ! ${PATCHELF} --print-execstack libsimple-execstack.so | grep -q 'execstack: X'; then
|
||||||
|
echo "[libsimple-execstack.so] wrong initial execstack detection"
|
||||||
|
${PATCHELF} --print-execstack libsimple-execstack.so
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! ${PATCHELF} --set-execstack libsimple-execstack.so; then
|
||||||
|
echo "[libsimple-execstack.so] failed noop initial set"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! ${PATCHELF} --clear-execstack libsimple-execstack.so; then
|
||||||
|
echo "[libsimple-execstack.so] failed clear"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! ${PATCHELF} --print-execstack libsimple-execstack.so | grep -q 'execstack: -'; then
|
||||||
|
echo "[libsimple-execstack.so] wrong execstack detection after clear"
|
||||||
|
${PATCHELF} --print-execstack libsimple-execstack.so
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if diff libsimple-execstack.so backup; then
|
||||||
|
echo "[libsimple-execstack.so] no change after set"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! ${PATCHELF} --clear-execstack libsimple-execstack.so; then
|
||||||
|
echo "[libsimple-execstack.so] failed noop clear"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! ${PATCHELF} --set-execstack libsimple-execstack.so; then
|
||||||
|
echo "[libsimple-execstack.so] failed set after clear"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! ${PATCHELF} --print-execstack libsimple-execstack.so | grep -q 'execstack: X'; then
|
||||||
|
echo "[libsimple-execstack.so] wrong execstack detection after set after clear"
|
||||||
|
${PATCHELF} --print-execstack libsimple-execstack.so
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! diff libsimple-execstack.so backup; then
|
||||||
|
echo "[libsimple-execstack.so] change against backup after set after clear"
|
||||||
|
exit 1
|
||||||
|
fi
|
|
@ -0,0 +1,23 @@
|
||||||
|
#! /bin/sh -e
|
||||||
|
SCRATCH=scratch/$(basename $0 .sh)
|
||||||
|
PATCHELF=$(readlink -f "../src/patchelf")
|
||||||
|
|
||||||
|
rm -rf ${SCRATCH}
|
||||||
|
mkdir -p ${SCRATCH}
|
||||||
|
|
||||||
|
cp simple ${SCRATCH}/
|
||||||
|
cp simple-execstack ${SCRATCH}/
|
||||||
|
|
||||||
|
cd ${SCRATCH}
|
||||||
|
|
||||||
|
if ! ${PATCHELF} --print-execstack simple | grep -q 'execstack: -'; then
|
||||||
|
echo "wrong execstack detection"
|
||||||
|
${PATCHELF} --print-execstack simple
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! ${PATCHELF} --print-execstack simple-execstack | grep -q 'execstack: X'; then
|
||||||
|
echo "wrong execstack detection"
|
||||||
|
${PATCHELF} --print-execstack simple-execstack
|
||||||
|
exit 1
|
||||||
|
fi
|
Loading…
Reference in New Issue