return pakfire_file_open_elf(file, __pakfire_file_check_debuginfo, 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;
-
- switch (dyn->d_tag) {
- case DT_BIND_NOW:
- *has_bind_now = 1;
- break;
-
- case DT_FLAGS:
- if (dyn->d_un.d_val & DF_BIND_NOW)
- *has_bind_now = 1;
- break;
-
- case DT_FLAGS_1:
- if (dyn->d_un.d_val & DF_1_NOW)
- *has_bind_now = 1;
- break;
-
- default:
- break;
- }
-
- return 0;
-}
-
-static int __pakfire_file_check_relro(
- struct pakfire_file* file, Elf* elf, void* data) {
- int has_bind_now = 0;
- GElf_Phdr phdr;
- int r;
-
- // Check if we have BIND_NOW
- r = pakfire_file_elf_dyn_walk(file, elf,
- __pakfire_file_process_bind_now, &has_bind_now);
- if (r)
- return r;
-
- // We are not fully RELRO
- if (!has_bind_now) {
- file->issues |= PAKFIRE_FILE_NO_RELRO;
-
- return 0;
- }
-
- // Walk through all program headers
- for (unsigned int i = 0;; i++) {
- if (!gelf_getphdr(elf, i, &phdr))
- break;
-
- switch (phdr.p_type) {
- case PT_GNU_RELRO:
- return 0;
-
- default:
- break;
- }
- }
-
- // This file does not seem to have PT_GNU_RELRO set
- file->issues |= PAKFIRE_FILE_NO_RELRO;
-
- return 0;
-}
-
-static int pakfire_file_check_relro(struct pakfire_file* file) {
- return pakfire_file_open_elf(file, __pakfire_file_check_relro, NULL);
-}
-
/*
RPATH/RUNPATH
*/
if (r)
return r;
- // Check for RELRO
- r = pakfire_file_check_relro(file);
- if (r)
- return r;
-
// Check for RUNPATH
r = pakfire_file_check_runpath(file);
if (r)
return 1;
}
+static int pakfire_linter_file_elf_dyn_walk(struct pakfire_linter_file* lfile, Elf* elf,
+ int (*callback)(struct pakfire_linter_file* lfile, Elf* elf,
+ const GElf_Shdr* shdr, const GElf_Dyn* dyn, void* data), void* data) {
+ Elf_Scn* dynamic = NULL;
+ GElf_Shdr shdr;
+ Elf_Data* elf_data = NULL;
+ GElf_Dyn dyn;
+ int r;
+
+ // Find the dynamic linking information
+ r = pakfire_linter_file_get_elf_section(lfile, elf, SHT_DYNAMIC, &dynamic, &shdr, &elf_data);
+ if (r) {
+ DEBUG(lfile->ctx, "%s does not have a dynamic section\n", lfile->path);
+ return 0;
+ }
+
+ // Walk through all entries...
+ for (unsigned int i = 0; ; i++) {
+ // Fetch the next entry
+ if (!gelf_getdyn(elf_data, i, &dyn))
+ break;
+
+ // Call the callback
+ r = callback(lfile, elf, &shdr, &dyn, data);
+ if (r)
+ return r;
+ }
+
+ return 0;
+}
+
+
static int pakfire_linter_file_check_pie(struct pakfire_linter_file* lfile) {
switch (pakfire_linter_file_get_elf_type(lfile)) {
// Shared Object files are good
return pakfire_linter_file_elf(lfile, __pakfire_linter_file_check_execstack, NULL);
}
+
+static int __pakfire_linter_file_has_bind_now(struct pakfire_linter_file* lfile,
+ Elf* elf, const GElf_Shdr* shdr, const GElf_Dyn* dyn, void* data) {
+ int* has_bind_now = (int*)data;
+
+ switch (dyn->d_tag) {
+ case DT_BIND_NOW:
+ *has_bind_now = 1;
+ break;
+
+ case DT_FLAGS:
+ if (dyn->d_un.d_val & DF_BIND_NOW)
+ *has_bind_now = 1;
+ break;
+
+ case DT_FLAGS_1:
+ if (dyn->d_un.d_val & DF_1_NOW)
+ *has_bind_now = 1;
+ break;
+
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+static int __pakfire_linter_file_check_relro(
+ struct pakfire_linter_file* lfile, Elf* elf, void* data) {
+ int has_bind_now = 0;
+ GElf_Phdr phdr;
+ int r;
+
+ // Check if we have BIND_NOW
+ r = pakfire_linter_file_elf_dyn_walk(lfile, elf,
+ __pakfire_linter_file_has_bind_now, &has_bind_now);
+ if (r)
+ return r;
+
+ // We are not fully RELRO
+ if (!has_bind_now)
+ return pakfire_linter_file_error(lfile, "Is not fully RELRO");
+
+ // Walk through all program headers
+ for (unsigned int i = 0;; i++) {
+ if (!gelf_getphdr(elf, i, &phdr))
+ break;
+
+ switch (phdr.p_type) {
+ case PT_GNU_RELRO:
+ r = pakfire_linter_file_warning(lfile, "Is partially RELRO");
+ if (r < 0)
+ return 0;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ // This file does not seem to have PT_GNU_RELRO set
+ return pakfire_linter_file_error(lfile, "Is not fully RELRO");
+}
+
+static int pakfire_linter_file_check_relro(struct pakfire_linter_file* lfile) {
+ return pakfire_linter_file_elf(lfile, __pakfire_linter_file_check_relro, NULL);
+}
+
int pakfire_linter_file_lint(struct pakfire_linter_file* lfile) {
int r = 0;
r = pakfire_linter_file_check_execstack(lfile);
if (r < 0)
return r;
+
+ // Check RELRO
+ r = pakfire_linter_file_check_relro(lfile);
+ if (r < 0)
+ return r;
}
return 0;