return 0;
}
+int pakfire_elf_has_ssp(struct pakfire_elf* self) {
+ const char* name = NULL;
+ Elf_Scn* symtab = NULL;
+ GElf_Shdr shdr;
+ Elf_Data* data = NULL;
+ GElf_Sym symbol;
+ int r;
+
+ // Fetch the symbol table
+ r = pakfire_elf_get_section(self, SHT_SYMTAB, &symtab, &shdr, &data);
+ if (r) {
+ DEBUG(self->ctx, "%s has no symbol table\n", self->path);
+ return 0;
+ }
+
+ // Count any global functions
+ size_t counter = 0;
+
+ // Walk through all symbols
+ for (unsigned int i = 0; i < shdr.sh_size / shdr.sh_entsize; i++) {
+ gelf_getsym(data, i, &symbol);
+
+ // Fetch the symbol name
+ name = elf_strptr(self->elf, shdr.sh_link, symbol.st_name);
+
+ // Skip empty section names
+ if (!name || !*name)
+ continue;
+
+ // Exit if there is a symbol called "__stack_chk_fail"
+ if (pakfire_string_startswith(name, "__stack_chk_fail"))
+ return 1;
+
+ // Or if the symbol is called __stack_chk_guard
+ else if (pakfire_string_startswith(name, "__stack_chk_guard"))
+ return 1;
+
+ // Or if the symbol is called __intel_security_cookie
+ else if (pakfire_string_startswith(name, "__intel_security_cookie"))
+ return 1;
+
+ // Count any global functions
+ if ((ELF64_ST_BIND(symbol.st_info) == STB_GLOBAL) &&
+ (ELF64_ST_TYPE(symbol.st_info) == STT_FUNC))
+ counter++;
+ }
+
+ // If we have something that does not have an exported function, we just assume yes
+ if (!counter) {
+ DEBUG(self->ctx, "%s has no functions. Skipping SSP check.\n", self->path);
+ return 1;
+ }
+
+ return 0;
+}
+
int pakfire_elf_is_stripped(struct pakfire_elf* self) {
Elf_Scn* symtab = NULL;
}
static int pakfire_linter_file_check_ssp(struct pakfire_linter_file* lfile) {
- Elf_Scn* symtab = NULL;
- GElf_Shdr shdr;
- Elf_Data* elf_data = NULL;
- GElf_Sym symbol;
- const char* name = NULL;
- int r;
-
// This check will be skipped for these files
static const char* whitelist[] = {
"/usr/lib64/libgcc_s.so.*",
}
}
- // Fetch the symbol table
- r = pakfire_linter_file_get_elf_section(lfile, SHT_SYMTAB, &symtab, &shdr, &elf_data);
- if (r) {
- DEBUG(lfile->ctx, "%s has no symbol table\n", lfile->path);
- return 1;
- }
-
- // Count any global functions
- size_t counter = 0;
-
- // Walk through all symbols
- for (unsigned int i = 0; i < shdr.sh_size / shdr.sh_entsize; i++) {
- gelf_getsym(elf_data, i, &symbol);
-
- // Fetch the symbol name
- name = elf_strptr(lfile->elf, shdr.sh_link, symbol.st_name);
-
- // Skip empty section names
- if (!name || !*name)
- continue;
-
- // Exit if there is a symbol called "__stack_chk_fail"
- if (pakfire_string_startswith(name, "__stack_chk_fail"))
- return 0;
-
- // Or if the symbol is called __stack_chk_guard
- else if (pakfire_string_startswith(name, "__stack_chk_guard"))
- return 0;
-
- // Or if the symbol is called __intel_security_cookie
- else if (pakfire_string_startswith(name, "__intel_security_cookie"))
- return 0;
-
- // Count any global functions
- if ((ELF64_ST_BIND(symbol.st_info) == STB_GLOBAL) &&
- (ELF64_ST_TYPE(symbol.st_info) == STT_FUNC))
- counter++;
- }
-
- // We do not perform the check for libraries that do not contain any functions.
- // Some packages use shared libraries to provide data.
- if (!counter) {
- DEBUG(lfile->ctx, "%s: File has no functions. Skipping SSP check.\n", lfile->path);
- return 0;
- }
+ // Report an error if there is not SSP
+ if (!pakfire_elf_has_ssp(lfile->_elf))
+ return pakfire_linter_file_error(lfile, "Missing Stack Smashing Protection");
- // The file does not seem to have SSP enabled
- return pakfire_linter_file_error(lfile, "Missing Stack Smashing Protection");
+ return 0;
}
static int pakfire_linter_file_check_execstack(struct pakfire_linter_file* lfile) {