#include <gelf.h>
-// Enable legacy logging
-#define PAKFIRE_LEGACY_LOGGING
-
#include <pakfire/ctx.h>
#include <pakfire/constants.h>
#include <pakfire/digest.h>
// Allocate capabilities
file->caps = cap_init();
if (!file->caps) {
- ERROR(file->pakfire, "Could not allocate capabilities: %m\n");
+ CTX_ERROR(file->ctx, "Could not allocate capabilities: %m\n");
r = 1;
goto ERROR;
}
if (cap_permitted) {
r = cap_set_flag(file->caps, CAP_PERMITTED, 1, caps, CAP_SET);
if (r) {
- ERROR(file->pakfire, "Could not set capability %u: %m\n", cap);
+ CTX_ERROR(file->ctx, "Could not set capability %u: %m\n", cap);
goto ERROR;
}
}
if (cap_inheritable) {
r = cap_set_flag(file->caps, CAP_INHERITABLE, 1, caps, CAP_SET);
if (r) {
- ERROR(file->pakfire, "Could not set capability %u: %m\n", cap);
+ CTX_ERROR(file->ctx, "Could not set capability %u: %m\n", cap);
goto ERROR;
}
}
if (cap_effective) {
r = cap_set_flag(file->caps, CAP_EFFECTIVE, 1, caps, CAP_SET);
if (r) {
- ERROR(file->pakfire, "Could not set capability %u: %m\n", cap);
+ CTX_ERROR(file->ctx, "Could not set capability %u: %m\n", cap);
goto ERROR;
}
}
#ifdef ENABLE_DEBUG
char* text = cap_to_text(file->caps, NULL);
if (text) {
- DEBUG(file->pakfire, "%s: Capabilities %s\n", pakfire_file_get_path(file), text);
+ CTX_DEBUG(file->ctx, "%s: Capabilities %s\n", pakfire_file_get_path(file), text);
cap_free(text);
}
#endif
// Fetch CAP_PERMITTED
r = cap_get_flag(file->caps, cap, CAP_PERMITTED, &cap_permitted);
if (r) {
- ERROR(file->pakfire, "Could not fetch capability %u: %m\n", cap);
+ CTX_ERROR(file->ctx, "Could not fetch capability %u: %m\n", cap);
goto ERROR;
}
// Fetch CAP_INHERITABLE
r = cap_get_flag(file->caps, cap, CAP_INHERITABLE, &cap_inheritable);
if (r) {
- ERROR(file->pakfire, "Could not fetch capability %u: %m\n", cap);
+ CTX_ERROR(file->ctx, "Could not fetch capability %u: %m\n", cap);
goto ERROR;
}
// Fetch CAP_EFFECTIVE
r = cap_get_flag(file->caps, cap, CAP_EFFECTIVE, &cap_effective);
if (r) {
- ERROR(file->pakfire, "Could not fetch capability %u: %m\n", cap);
+ CTX_ERROR(file->ctx, "Could not fetch capability %u: %m\n", cap);
goto ERROR;
}
goto ERROR;
} else {
- DEBUG(file->pakfire, "Received an unknown extended attribute: %s\n", attr);
+ CTX_DEBUG(file->ctx, "Received an unknown extended attribute: %s\n", attr);
}
}
// Read everything
r = archive_read_disk_entry_from_file(reader, file->entry, -1, NULL);
if (r) {
- ERROR(file->pakfire, "Could not read %s: %s\n", path, archive_error_string(reader));
+ CTX_ERROR(file->ctx, "Could not read %s: %s\n", path, archive_error_string(reader));
return 1;
}
if (file->caps) {
r = pakfire_file_write_fcaps(file, &cap_data);
if (r) {
- ERROR(file->pakfire, "Could not export capabilities: %m\n");
+ CTX_ERROR(file->ctx, "Could not export capabilities: %m\n");
goto ERROR;
}
return r;
ERROR:
- ERROR(file->pakfire, "Could not set path '%s': %m\n", path);
+ CTX_ERROR(file->ctx, "Could not set path '%s': %m\n", path);
return r;
}
// Check buffer length
if (pakfire_digest_length(type) != length) {
- ERROR(file->pakfire, "Digest has an incorrect length of %zu byte(s)\n", length);
+ CTX_ERROR(file->ctx, "Digest has an incorrect length of %zu byte(s)\n", length);
return -ENOMSG;
}
if (file->caps) {
text = cap_to_text(file->caps, &length);
if (!text) {
- ERROR(file->pakfire, "Could not export capabilities: %m\n");
+ CTX_ERROR(file->ctx, "Could not export capabilities: %m\n");
goto ERROR;
}
FILE* f = fopen(path, "r+");
if (!f)
- ERROR(file->pakfire, "Could not open %s: %m\n", path);
+ CTX_ERROR(file->ctx, "Could not open %s: %m\n", path);
return f;
}
const char* path = pakfire_file_get_path(file);
const char* abspath = pakfire_file_get_abspath(file);
- DEBUG(file->pakfire, "Removing %s...\n", path);
+ CTX_DEBUG(file->ctx, "Removing %s...\n", path);
// We cannot delete if we don't have the absolute path
if (!abspath)
// Log anything else
default:
- ERROR(file->pakfire, "Could not remove directory %s: %m\n", path);
+ CTX_ERROR(file->ctx, "Could not remove directory %s: %m\n", path);
break;
}
}
break;
default:
- ERROR(file->pakfire, "Could not remove %s: %m\n", path);
+ CTX_ERROR(file->ctx, "Could not remove %s: %m\n", path);
break;
}
}
// Check the file
const char* mimetype = magic_file(magic, path);
if (!mimetype) {
- ERROR(file->pakfire, "Could not classify %s: %s\n",
+ CTX_ERROR(file->ctx, "Could not classify %s: %s\n",
pakfire_file_get_path(file), magic_error(magic));
return 1;
}
- DEBUG(file->pakfire, "Classified %s as %s\n", pakfire_file_get_path(file), mimetype);
+ CTX_DEBUG(file->ctx, "Classified %s as %s\n", pakfire_file_get_path(file), mimetype);
// Store the value
return pakfire_file_set_mimetype(file, mimetype);
Classification
*/
-static int setup_libelf(struct pakfire* pakfire) {
+static int setup_libelf(struct pakfire_ctx* ctx) {
// Initialize libelf
if (elf_version(EV_CURRENT) == EV_NONE) {
- ERROR(pakfire, "Could not initialize libelf: %s\n", elf_errmsg(-1));
+ CTX_ERROR(ctx, "Could not initialize libelf: %s\n", elf_errmsg(-1));
return 1;
}
return 0;
// Setup libelf
- r = setup_libelf(file->pakfire);
+ r = setup_libelf(file->ctx);
if (r)
return r;
// Open the file
f = pakfire_file_open(file);
if (!f) {
- ERROR(file->pakfire, "Could not open %s: %m\n", pakfire_file_get_path(file));
+ CTX_ERROR(file->ctx, "Could not open %s: %m\n", pakfire_file_get_path(file));
return 1;
}
if (!*path)
break;
- DEBUG(file->pakfire, "Trying to remove parent directory %s\n", path);
+ CTX_DEBUG(file->ctx, "Trying to remove parent directory %s\n", path);
r = rmdir(path);
if (type != (st->st_mode & S_IFMT)) {
file->verify_status |= PAKFIRE_FILE_TYPE_CHANGED;
- DEBUG(file->pakfire, "%s: File Type changed\n", pakfire_file_get_path(file));
+ CTX_DEBUG(file->ctx, "%s: File Type changed\n", pakfire_file_get_path(file));
}
const mode_t perms = pakfire_file_get_perms(file);
if (perms != (st->st_mode & 0777)) {
file->verify_status |= PAKFIRE_FILE_PERMISSIONS_CHANGED;
- DEBUG(file->pakfire, "%s: Permissions changed\n", pakfire_file_get_path(file));
+ CTX_DEBUG(file->ctx, "%s: Permissions changed\n", pakfire_file_get_path(file));
}
#if 0
if (dev != st->st_dev) {
file->verify_status |= PAKFIRE_FILE_DEV_CHANGED;
- DEBUG(file->pakfire, "%s: Device Node changed\n", pakfire_file_get_path(file));
+ CTX_DEBUG(file->ctx, "%s: Device Node changed\n", pakfire_file_get_path(file));
}
}
#endif
// Size differs
file->verify_status |= PAKFIRE_FILE_SIZE_CHANGED;
- DEBUG(file->pakfire, "%s: Filesize differs (expected %zd, got %zd byte(s))\n",
+ CTX_DEBUG(file->ctx, "%s: Filesize differs (expected %zd, got %zd byte(s))\n",
pakfire_file_get_path(file), size, st->st_size);
return 0;
if (!owner || owner->pw_uid != uid) {
file->verify_status |= PAKFIRE_FILE_OWNER_CHANGED;
- DEBUG(file->pakfire, "%s: Owner differs\n", pakfire_file_get_path(file));
+ CTX_DEBUG(file->ctx, "%s: Owner differs\n", pakfire_file_get_path(file));
}
// Check if group matches
if (!group || group->gr_gid != gid) {
file->verify_status |= PAKFIRE_FILE_GROUP_CHANGED;
- DEBUG(file->pakfire, "%s: Group differs\n", pakfire_file_get_path(file));
+ CTX_DEBUG(file->ctx, "%s: Group differs\n", pakfire_file_get_path(file));
}
return 0;
if (ctime != st->st_ctime) {
file->verify_status |= PAKFIRE_FILE_CTIME_CHANGED;
- DEBUG(file->pakfire, "%s: Creation time changed\n", pakfire_file_get_path(file));
+ CTX_DEBUG(file->ctx, "%s: Creation time changed\n", pakfire_file_get_path(file));
}
// Check modification time
if (mtime != st->st_mtime) {
file->verify_status |= PAKFIRE_FILE_MTIME_CHANGED;
- DEBUG(file->pakfire, "%s: Modification time changed\n", pakfire_file_get_path(file));
+ CTX_DEBUG(file->ctx, "%s: Modification time changed\n", pakfire_file_get_path(file));
}
return 0;
digest_types = pakfire_digest_has_any(&file->digests);
if (!digest_types) {
- ERROR(file->pakfire, "%s: No digests available\n", pakfire_file_get_path(file));
+ CTX_ERROR(file->ctx, "%s: No digests available\n", pakfire_file_get_path(file));
return 0;
}
if (r) {
file->verify_status |= PAKFIRE_FILE_PAYLOAD_CHANGED;
- DEBUG(file->pakfire, "%s: Digest(s) do not match\n", pakfire_file_get_path(file));
+ CTX_DEBUG(file->ctx, "%s: Digest(s) do not match\n", pakfire_file_get_path(file));
}
ERROR:
struct stat st;
int r;
- DEBUG(file->pakfire, "Verifying %s...\n", pakfire_file_get_path(file));
+ CTX_DEBUG(file->ctx, "Verifying %s...\n", pakfire_file_get_path(file));
const char* abspath = pakfire_file_get_abspath(file);
}
// Setup libelf
- r = setup_libelf(file->pakfire);
+ r = setup_libelf(file->ctx);
if (r)
return r;
// Open the file
f = pakfire_file_open(file);
if (!f) {
- ERROR(file->pakfire, "Could not open %s: %m\n", pakfire_file_get_abspath(file));
+ CTX_ERROR(file->ctx, "Could not open %s: %m\n", pakfire_file_get_abspath(file));
return 1;
}
// Parse the ELF header
elf = elf_begin(fileno(f), ELF_C_READ, NULL);
if (!elf) {
- ERROR(file->pakfire, "Could not open ELF file: %s\n", elf_errmsg(-1));
+ CTX_ERROR(file->ctx, "Could not open ELF file: %s\n", elf_errmsg(-1));
r = 1;
goto ERROR;
}
break;
default:
- ERROR(file->pakfire, "%s is not an ELF object\n", pakfire_file_get_path(file));
+ CTX_ERROR(file->ctx, "%s is not an ELF object\n", pakfire_file_get_path(file));
r = 1;
goto ERROR;
}
// Fetch the ELF header
if (!gelf_getehdr(elf, &ehdr)) {
- ERROR(file->pakfire, "Could not parse ELF header: %s\n", elf_errmsg(-1));
+ CTX_ERROR(file->ctx, "Could not parse ELF header: %s\n", elf_errmsg(-1));
return 1;
}
// Find the dynamic linking information
r = pakfire_file_get_elf_section(file, elf, SHT_DYNAMIC, &dynamic, &shdr, &elf_data);
if (r) {
- DEBUG(file->pakfire, "%s does not have a dynamic section\n", pakfire_file_get_path(file));
+ CTX_DEBUG(file->ctx, "%s does not have a dynamic section\n", pakfire_file_get_path(file));
return 0;
}
// Not found
if (r) {
- DEBUG(file->pakfire, "%s has no debug sections\n", pakfire_file_get_path(file));
+ CTX_DEBUG(file->ctx, "%s has no debug sections\n", pakfire_file_get_path(file));
// Store the result
file->issues |= PAKFIRE_FILE_MISSING_DEBUGINFO;
// Fetch the symbol table
r = pakfire_file_get_elf_section(file, elf, SHT_SYMTAB, &symtab, &shdr, &elf_data);
if (r) {
- ERROR(file->pakfire, "%s has no symbol table\n", pakfire_file_get_path(file));
+ CTX_ERROR(file->ctx, "%s has no symbol table\n", pakfire_file_get_path(file));
return 1;
}
// 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(file->pakfire, "%s: File has no functions. Skipping SSP check.\n",
+ CTX_DEBUG(file->ctx, "%s: File has no functions. Skipping SSP check.\n",
pakfire_file_get_path(file));
return 0;
}
// Check if this file is whitelisted
for (const char** path = whitelist; *path; path++) {
if (pakfire_file_matches(file, *path)) {
- DEBUG(file->pakfire, "Skipping SSP check for whitelisted file %s\n",
+ CTX_DEBUG(file->ctx, "Skipping SSP check for whitelisted file %s\n",
pakfire_file_get_path(file));
return 0;
}
// Fetch the total numbers of program headers
r = elf_getphdrnum(elf, &phnum);
if (r) {
- ERROR(file->pakfire, "Could not fetch number of program headers: %s\n",
+ CTX_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->pakfire, "Could not parse program header: %s\n", elf_errmsg(-1));
+ CTX_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->pakfire,
+ CTX_DEBUG(file->ctx,
"%s: GNU_STACK flags: %c%c%c\n",
pakfire_file_get_path(file),
(phdr.p_flags & PF_R) ? 'R' : '-',
if (!value)
return 1;
- DEBUG(file->pakfire, "%s has a RUNPATH: %s\n",
+ CTX_DEBUG(file->ctx, "%s has a RUNPATH: %s\n",
pakfire_file_get_path(file), value);
// Copy the value into a buffer we can modify
// Iterate over all elements
while (runpath) {
- ERROR(file->pakfire, "Checking RUNPATH %s\n", runpath);
+ CTX_ERROR(file->ctx, "Checking RUNPATH %s\n", runpath);
// We do not allow any relative RUNPATHs
if (pakfire_path_match(runpath, "**/../**"))
// Handle any reading errors
if (bytes_read < 0) {
- ERROR(file->pakfire, "Could not read from file %s: %m\n",
+ CTX_ERROR(file->ctx, "Could not read from file %s: %m\n",
pakfire_file_get_path(file));
r = 1;
goto ERROR;
}
if (strncmp("#!", shebang, 2) == 0) {
- DEBUG(file->pakfire, "%s is a script\n", pakfire_file_get_path(file));
+ CTX_DEBUG(file->ctx, "%s is a script\n", pakfire_file_get_path(file));
// Find the end of the first line (to be able to perform string operations)
p = memchr(shebang, '\n', sizeof(shebang));
if (!p) {
- ERROR(file->pakfire, "%s: First line seems to be too long\n",
+ CTX_ERROR(file->ctx, "%s: First line seems to be too long\n",
pakfire_file_get_path(file));
errno = ENOBUFS;
r = 1;
const char* path = pakfire_file_get_path(file);
- DEBUG(file->pakfire, "%s: Fixing interpreter %s\n", path, interpreter);
+ CTX_DEBUG(file->ctx, "%s: Fixing interpreter %s\n", path, interpreter);
// Open the file
f = pakfire_file_open(file);
if (!f) {
- ERROR(file->pakfire, "Could not open %s: %m\n", path);
+ CTX_ERROR(file->ctx, "Could not open %s: %m\n", path);
r = -errno;
goto ERROR;
}
if (feof(f))
break;
- ERROR(file->pakfire, "Could not read line from %s: %m\n", path);
+ CTX_ERROR(file->ctx, "Could not read line from %s: %m\n", path);
goto ERROR;
}
if (*p)
args = p;
- DEBUG(file->pakfire, "%s: Found command %s (%s)\n", path, interpreter, args);
+ CTX_DEBUG(file->ctx, "%s: Found command %s (%s)\n", path, interpreter, args);
// Find the real path
r = pakfire_which(file->pakfire, command, interpreter);
if (r) {
- ERROR(file->pakfire, "%s: Could not resolve %s: %m\n", path, interpreter);
+ CTX_ERROR(file->ctx, "%s: Could not resolve %s: %m\n", path, interpreter);
goto ERROR;
}
// If we could not resolve the command, this file has an invalid interpreter
if (!*command) {
- ERROR(file->pakfire, "%s: Could not find path for command %s\n", path, interpreter);
+ CTX_ERROR(file->ctx, "%s: Could not find path for command %s\n", path, interpreter);
file->issues |= PAKFIRE_FILE_INVALID_INTERPRETER;
r = 0;
// Truncate the existing content
r = ftruncate(fileno(f), 0);
if (r) {
- ERROR(file->pakfire, "Could not truncate %s: %m\n", path);
+ CTX_ERROR(file->ctx, "Could not truncate %s: %m\n", path);
r = -errno;
goto ERROR;
}
if (buffer) {
size_t bytes_written = fwrite(buffer, 1, l, f);
if (bytes_written < l) {
- ERROR(file->pakfire, "%s: Could not write the payload: %m\n", path);
+ CTX_ERROR(file->ctx, "%s: Could not write the payload: %m\n", path);
r = -errno;
goto ERROR;
}
if (!interpreter)
return 0;
- DEBUG(file->pakfire, "%s: Interpreter: %s\n",
+ CTX_DEBUG(file->ctx, "%s: Interpreter: %s\n",
pakfire_file_get_path(file), interpreter);
// Paths must be absolute
else if (strcmp(interpreter, "/usr/bin/env") == 0) {
r = pakfire_file_fix_interpreter(file, interpreter);
if (r) {
- ERROR(file->pakfire, "%s: Could not fix interpreter: %m\n",
+ CTX_ERROR(file->ctx, "%s: Could not fix interpreter: %m\n",
pakfire_file_get_path(file));
goto ERROR;
}
// Check for IBT
if (!(property & GNU_PROPERTY_X86_FEATURE_1_IBT)) {
- DEBUG(file->pakfire, "%s: IBT property is not enabled\n",
+ CTX_DEBUG(file->ctx, "%s: IBT property is not enabled\n",
pakfire_file_get_path(file));
// XXX TODO Actually modify any flags
// Check for Shadow Stack
if (!(property & GNU_PROPERTY_X86_FEATURE_1_SHSTK)) {
- DEBUG(file->pakfire, "%s: Shadow Stack is not enabled\n",
+ CTX_DEBUG(file->ctx, "%s: Shadow Stack is not enabled\n",
pakfire_file_get_path(file));
// XXX TODO Actually modify any flags
// Fetch the ELF header
if (!gelf_getehdr(elf, &ehdr)) {
- ERROR(file->pakfire, "Could not fetch the ELF header for %s: %m\n",
+ CTX_ERROR(file->ctx, "Could not fetch the ELF header for %s: %m\n",
pakfire_file_get_path(file));
return 1;
}
// Fetch the .note header
offset = gelf_getnote(data, offset, &nhdr, &offset_name, &offset_data);
if (!offset) {
- ERROR(file->pakfire, "Could not read note section: %m\n");
+ CTX_ERROR(file->ctx, "Could not read note section: %m\n");
return 1;
}
payload += sizeof(type) + sizeof(size);
if (length < size) {
- ERROR(file->pakfire, "GNU Property note has an incorrect format\n");
+ CTX_ERROR(file->ctx, "GNU Property note has an incorrect format\n");
return 1;
}
break;
default:
- ERROR(file->pakfire, "Unsupported ELF type (%d)\n", ehdr.e_machine);
+ CTX_ERROR(file->ctx, "Unsupported ELF type (%d)\n", ehdr.e_machine);
return 1;
}