diff --git a/main.c b/main.c index 98999c3..c48a88b 100644 --- a/main.c +++ b/main.c @@ -1,5 +1,5 @@ - - +/* For using free() */ +#include #include "seccomp.h" int main(int argc, char **argv) { @@ -13,7 +13,11 @@ int main(int argc, char **argv) { const char *profile_path = argv[1]; FILE *file = sc_must_read_and_validate_header_from_file(profile_path, &hdr); sc_must_read_filter_from_file(file, hdr.len_filter, &prog_allow); + /* Close file as we are done reading */ + fclose(file); sc_apply_seccomp_filter(&prog_allow); + /* Clear filter memory */ + free(prog_allow.filter); } diff --git a/seccomp.c b/seccomp.c index 27c5971..d1874b8 100644 --- a/seccomp.c +++ b/seccomp.c @@ -41,16 +41,45 @@ FILE* sc_must_read_and_validate_header_from_file(const char *profile_path, struc if (num_read < sizeof(struct sc_seccomp_file_header)) { die("short read on seccomp header: %zu", num_read); } + + /* Validation: Magic Bytes */ + if (hdr->header[0] != SC_HEADER_MAGIC_0 || hdr->header[1] != SC_HEADER_MAGIC_1) { + die("invalid seccomp file header magic"); + } + + /* Validation: Version */ + if (hdr->version != SC_VERSION) { + die("unsupported seccomp file version: %d", hdr->version); + } + + /* Validation: Filter Length (Size Limit) */ + if (hdr->len_filter > MAX_BPF_SIZE) { + die("seccomp filter too large: %u (max %d)", hdr->len_filter, MAX_BPF_SIZE); + } + + /* Validation: Filter Length (Alignment) */ + if (hdr->len_filter % sizeof(struct sock_filter) != 0) { + die("invalid seccomp filter length: %u (must be multiple of %zu)", + hdr->len_filter, sizeof(struct sock_filter)); + } + return file; } void sc_must_read_filter_from_file(FILE *file, uint32_t len_bytes, struct sock_fprog *prog) { + /* Double check length before allocation */ + if (len_bytes > MAX_BPF_SIZE) { + die("filter length %u exceeds max %d", len_bytes, MAX_BPF_SIZE); + } + prog->len = len_bytes / sizeof(struct sock_filter); - prog->filter = (struct sock_filter *)malloc(MAX_BPF_SIZE); + + prog->filter = (struct sock_filter *)malloc(len_bytes); if (prog->filter == NULL) { die("cannot allocate %u bytes of memory for seccomp filter ", len_bytes); } + size_t num_read = fread(prog->filter, 1, len_bytes, file); if (ferror(file)) { die("cannot read filter"); @@ -71,4 +100,3 @@ void sc_apply_seccomp_filter(struct sock_fprog *prog) { die("cannot apply seccomp profile"); } } - diff --git a/seccomp.h b/seccomp.h index d60ce6b..3dd28f9 100644 --- a/seccomp.h +++ b/seccomp.h @@ -7,6 +7,11 @@ #include +/* Validations Constants */ +#define SC_HEADER_MAGIC_0 'S' +#define SC_HEADER_MAGIC_1 'C' +#define SC_VERSION 1 + struct sc_seccomp_file_header { char header[2]; uint8_t version;