Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions tests/type_confusion/dav1d.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,21 @@ RUN: cat dav1d_call_gates_1.ld | FileCheck --check-prefix=LINKARGS %s
#define IA2_COMPARTMENT 2
#include <ia2_compartment_init.inc>

struct Dav1dContext {
int field;
};

const size_t DAV1D_CONTEXT_SIZE = sizeof(Dav1dContext);

/// Allocate memory in dav1d's compartment 2.
void* dav1d_alloc(const size_t size) {
return malloc(size);
}

void dav1d_free(void* const memory) {
free(memory);
}

IA2_CONSTRUCTOR // Registers that ptr `this` has type `Dav1dContext` now.
int dav1d_open(Dav1dContext *const this, const Dav1dSettings *const s) {
// Initialize `this`; implementation omitted.
Expand Down
10 changes: 7 additions & 3 deletions tests/type_confusion/include/dav1d.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

#include <stddef.h>

typedef struct {
int field;
} Dav1dContext;
typedef struct Dav1dContext Dav1dContext;

extern const size_t DAV1D_CONTEXT_SIZE;

typedef struct Dav1dSettings {
int field;
Expand All @@ -14,6 +14,10 @@ typedef struct {
ptrdiff_t stride[2];
} Dav1dPicture;

void* dav1d_alloc(size_t size);

void dav1d_free(void* memory);

int dav1d_open(Dav1dContext *this, const Dav1dSettings *s);

void dav1d_close(Dav1dContext *this);
Expand Down
78 changes: 58 additions & 20 deletions tests/type_confusion/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,41 +14,79 @@ INIT_RUNTIME(2);
#define IA2_COMPARTMENT 1
#include <ia2_compartment_init.inc>

Dav1dContext c IA2_SHARED_DATA;
Dav1dSettings settings IA2_SHARED_DATA;
Dav1dPicture pic IA2_SHARED_DATA;
Dav1dContext c2 IA2_SHARED_DATA;

Test(type_confusion, normal) {
dav1d_open(&c, &settings);
dav1d_get_picture(&c, &pic);
dav1d_close(&c);
// `Dav1dContext` is opaque.
Dav1dContext *c = dav1d_alloc(DAV1D_CONTEXT_SIZE);
Dav1dSettings *settings = dav1d_alloc(sizeof(Dav1dSettings));
Dav1dPicture *pic = dav1d_alloc(sizeof(Dav1dPicture));

dav1d_open(c, settings);
dav1d_get_picture(c, pic);
dav1d_close(c);

dav1d_free(pic);
dav1d_free(settings);
dav1d_free(c);
}

Test(type_confusion, uninitialized, .signal = SIGABRT) {
dav1d_open(&c, &settings);
Dav1dContext *c = dav1d_alloc(DAV1D_CONTEXT_SIZE);
Dav1dContext *c2 = dav1d_alloc(DAV1D_CONTEXT_SIZE);
Dav1dSettings *settings = dav1d_alloc(sizeof(Dav1dSettings));
Dav1dPicture *pic = dav1d_alloc(sizeof(Dav1dPicture));

dav1d_open(c, settings);
// Try to use another `Dav1dContext` that hasn't been constructed/opened yet.
dav1d_get_picture(&c2, &pic);
dav1d_close(&c);
dav1d_get_picture(c2, pic); // Will `SIGABRT`.
dav1d_close(c);

dav1d_free(pic);
dav1d_free(settings);
dav1d_free(c2);
dav1d_free(c);
}

Test(type_confusion, wrong_type, .signal = SIGABRT) {
dav1d_open(&c, &settings);
Dav1dContext *c = dav1d_alloc(DAV1D_CONTEXT_SIZE);
Dav1dSettings *settings = dav1d_alloc(sizeof(Dav1dSettings));
Dav1dPicture *pic = dav1d_alloc(sizeof(Dav1dPicture));

dav1d_open(c, settings);
// Try to use another type (`Dav1dPicture`) instead.
dav1d_get_picture((Dav1dContext *)&pic, &pic);
dav1d_close(&c);
dav1d_get_picture((Dav1dContext *)pic, pic); // Will `SIGABRT`.
dav1d_close(c);

dav1d_free(pic);
dav1d_free(settings);
dav1d_free(c);
}

Test(type_confusion, null, .signal = SIGABRT) {
dav1d_open(&c, &settings);
Dav1dContext *c = dav1d_alloc(DAV1D_CONTEXT_SIZE);
Dav1dSettings *settings = dav1d_alloc(sizeof(Dav1dSettings));
Dav1dPicture *pic = dav1d_alloc(sizeof(Dav1dPicture));

dav1d_open(c, settings);
// Try to `NULL`.
dav1d_get_picture(NULL, &pic);
dav1d_close(&c);
dav1d_get_picture(NULL, pic); // Will `SIGABRT`.
dav1d_close(c);

dav1d_free(pic);
dav1d_free(settings);
dav1d_free(c);
}

Test(type_confusion, use_after_free, .signal = SIGABRT) {
dav1d_open(&c, &settings);
dav1d_close(&c);
Dav1dContext *c = dav1d_alloc(DAV1D_CONTEXT_SIZE);
Dav1dSettings *settings = dav1d_alloc(sizeof(Dav1dSettings));
Dav1dPicture *pic = dav1d_alloc(sizeof(Dav1dPicture));

dav1d_open(c, settings);
dav1d_close(c);
// Try to use an already destructed `Dav1dContext`.
dav1d_get_picture(&c, &pic);
dav1d_get_picture(c, pic); // Will `SIGABRT`.

dav1d_free(pic);
dav1d_free(settings);
dav1d_free(c);
}