goto ERROR;
}
- // Executable Stack
- if (file->issues & PAKFIRE_FILE_EXECSTACK) {
- r = asprintf(&buffer, "%s [EXECSTACK]", buffer);
- if (r < 0)
- goto ERROR;
- }
-
// Not RELRO
if (file->issues & PAKFIRE_FILE_NO_RELRO) {
r = asprintf(&buffer, "%s [NO-RELRO]", buffer);
return pakfire_file_open_elf(file, __pakfire_file_check_debuginfo, NULL);
}
-static int __pakfire_file_check_execstack(
- struct pakfire_file* file, Elf* elf, void* data) {
- GElf_Phdr phdr;
- int r;
-
- size_t phnum = 0;
-
- // Fetch the total numbers of program headers
- r = elf_getphdrnum(elf, &phnum);
- if (r) {
- ERROR(file->ctx, "Could not fetch number of program headers: %s\n",
- elf_errmsg(-1));
- return 1;
- }
-
- // Walk through all program headers
- for (unsigned int i = 0; i < phnum; i++) {
- if (!gelf_getphdr(elf, i, &phdr)) {
- ERROR(file->ctx, "Could not parse program header: %s\n", elf_errmsg(-1));
- return 1;
- }
-
- switch (phdr.p_type) {
- case PT_GNU_STACK:
- DEBUG(file->ctx,
- "%s: GNU_STACK flags: %c%c%c\n",
- pakfire_file_get_path(file),
- (phdr.p_flags & PF_R) ? 'R' : '-',
- (phdr.p_flags & PF_W) ? 'W' : '-',
- (phdr.p_flags & PF_X) ? 'X' : '-'
- );
-
- // The stack cannot be writable and executable
- if ((phdr.p_flags & PF_W) && (phdr.p_flags & PF_X))
- file->issues |= PAKFIRE_FILE_EXECSTACK;
-
- // Done
- return 0;
-
- default:
- break;
- }
- }
-
- return 0;
-}
-
-static int pakfire_file_check_execstack(struct pakfire_file* file) {
- return pakfire_file_open_elf(file, __pakfire_file_check_execstack, NULL);
-}
-
static int __pakfire_file_process_bind_now(struct pakfire_file* file,
Elf* elf, const GElf_Shdr* shdr, const GElf_Dyn* dyn, void* data) {
int* has_bind_now = (int*)data;
if (r)
return r;
- // Check for executable stacks
- r = pakfire_file_check_execstack(file);
- if (r)
- return r;
-
// Check for RELRO
r = pakfire_file_check_relro(file);
if (r)
enum pakfire_file_check_issues {
PAKFIRE_FILE_FHS_ERROR = (1 << 0),
PAKFIRE_FILE_MISSING_DEBUGINFO = (1 << 1),
- PAKFIRE_FILE_EXECSTACK = (1 << 4),
PAKFIRE_FILE_NO_RELRO = (1 << 5),
PAKFIRE_FILE_HAS_RUNPATH = (1 << 6),
PAKFIRE_FILE_INVALID_CAPS = (1 << 7),
return pakfire_linter_file_elf(lfile, __pakfire_linter_file_check_ssp, NULL);
}
+static int __pakfire_linter_file_check_execstack(
+ struct pakfire_linter_file* lfile, Elf* elf, void* data) {
+ GElf_Phdr phdr;
+ int r;
+
+ size_t phnum = 0;
+
+ // Fetch the total numbers of program headers
+ r = elf_getphdrnum(elf, &phnum);
+ if (r) {
+ ERROR(lfile->ctx,
+ "Could not fetch number of program headers: %s\n", elf_errmsg(-1));
+ return -EINVAL;
+ }
+
+ // Walk through all program headers
+ for (unsigned int i = 0; i < phnum; i++) {
+ if (!gelf_getphdr(elf, i, &phdr)) {
+ ERROR(lfile->ctx, "Could not parse program header: %s\n", elf_errmsg(-1));
+ return -ENOTSUP;
+ }
+
+ switch (phdr.p_type) {
+ case PT_GNU_STACK:
+ DEBUG(lfile->ctx,
+ "%s: GNU_STACK flags: %c%c%c\n",
+ lfile->path,
+ (phdr.p_flags & PF_R) ? 'R' : '-',
+ (phdr.p_flags & PF_W) ? 'W' : '-',
+ (phdr.p_flags & PF_X) ? 'X' : '-'
+ );
+
+ // The stack cannot be writable and executable
+ if ((phdr.p_flags & PF_W) && (phdr.p_flags & PF_X))
+ return pakfire_linter_file_error(lfile->linter, lfile->file, "Executable Stack");
+
+ default:
+ break;
+ }
+ }
+
+ return 0;
+}
+
+static int pakfire_linter_file_check_execstack(struct pakfire_linter_file* lfile) {
+ return pakfire_linter_file_elf(lfile, __pakfire_linter_file_check_execstack, NULL);
+}
+
int pakfire_linter_file_lint(struct pakfire_linter_file* lfile) {
int r = 0;
r = pakfire_linter_file_check_ssp(lfile);
if (r < 0)
return r;
+
+ // Check for Executable Stacks
+ r = pakfire_linter_file_check_execstack(lfile);
+ if (r < 0)
+ return r;
}
return 0;