aboutgitcodelistschat:MatrixIRC
path: root/operations.c
diff options
context:
space:
mode:
Diffstat (limited to 'operations.c')
-rw-r--r--operations.c149
1 files changed, 119 insertions, 30 deletions
diff --git a/operations.c b/operations.c
index eb8d614..4438879 100644
--- a/operations.c
+++ b/operations.c
@@ -459,6 +459,8 @@ int op_iovload(const struct seccomp_notif *req, int notifier, struct gluten *g,
close(fd);
+ memset(dst + count, 0, load->size - count + load->zero_fill);
+
return 0;
}
@@ -592,8 +594,11 @@ int op_bitwise(const struct seccomp_notif *req, int notifier, struct gluten *g,
struct op_bitwise *op)
{
const struct bitwise_desc *desc = gluten_ptr(&req->data, g, op->desc);
- const unsigned char *x, *y;
- unsigned char *dst;
+ const struct vec_desc vec = desc->vec;
+ const unsigned char *x_ptr, *y_ptr;
+ struct gluten_offset x, dst;
+ unsigned char *dst_ptr;
+ uint32_t *vlen;
unsigned i;
(void)notifier;
@@ -601,10 +606,6 @@ int op_bitwise(const struct seccomp_notif *req, int notifier, struct gluten *g,
if (!desc)
return -1;
- dst = gluten_write_ptr( g, desc->dst);
- x = gluten_ptr(&req->data, g, desc->x);
- y = gluten_ptr(&req->data, g, desc->y);
-
/*
if (!dst || !src || !mask ||
!check_gluten_limits(desc->dst, desc->size) ||
@@ -612,6 +613,7 @@ int op_bitwise(const struct seccomp_notif *req, int notifier, struct gluten *g,
!check_gluten_limits(desc->mask, desc->size))
return -1;
*/
+
debug(" op_bitwise: dst=(%s %d) := x=(%s %d) %s y=(%s %d) size=%d",
gluten_offset_name[desc->dst.type], desc->dst.offset,
gluten_offset_name[desc->x.type], desc->x.offset,
@@ -619,13 +621,37 @@ int op_bitwise(const struct seccomp_notif *req, int notifier, struct gluten *g,
gluten_offset_name[desc->y.type], desc->y.offset,
desc->size);
- for (i = 0; i < desc->size; i++) {
- if (desc->type == BITWISE_AND)
- dst[i] = x[i] & y[i];
- else if (desc->type == BITWISE_OR)
- dst[i] = x[i] | y[i];
- else
- return -1;
+ if (vec.start.type != OFFSET_NULL) {
+ debug(" vector start=(%s %d), length offset: %i",
+ gluten_offset_name[vec.start.type], vec.start.offset,
+ vec.len_offset);
+ }
+
+ if (vec.start.type == OFFSET_NULL)
+ vlen = &((uint32_t){ 1 });
+ else
+ vlen = (uint32_t *)gluten_ptr(&req->data, g, vec.start);
+
+ y_ptr = gluten_ptr(&req->data, g, desc->y);
+
+ for (x = desc->x, dst = desc->dst;
+ *vlen;
+ x.offset += *vlen, vlen += *vlen, dst.offset += desc->size) {
+
+ x_ptr = gluten_ptr(&req->data, g, x);
+ dst_ptr = gluten_write_ptr( g, dst);
+
+ for (i = 0; i < desc->size; i++) {
+ if (desc->type == BITWISE_AND)
+ dst_ptr[i] = x_ptr[i] & y_ptr[i];
+ else if (desc->type == BITWISE_OR)
+ dst_ptr[i] = x_ptr[i] | y_ptr[i];
+ else
+ return -1;
+ }
+
+ if (vec.start.type == OFFSET_NULL)
+ break;
}
return 0;
@@ -683,9 +709,13 @@ int op_cmp(const struct seccomp_notif *req, int notifier, struct gluten *g,
struct op_cmp *op)
{
const struct cmp_desc *desc = gluten_ptr(&req->data, g, op->desc);
+ bool some = false, all = true, verdict;
+ const struct vec_desc vec = desc->vec;
char str_x[PATH_MAX], str_y[PATH_MAX];
+ const void *x_ptr, *y_ptr;
+ struct gluten_offset x;
enum op_cmp_type cmp;
- const void *px, *py;
+ uint32_t *vlen;
int res;
(void)notifier;
@@ -693,29 +723,88 @@ int op_cmp(const struct seccomp_notif *req, int notifier, struct gluten *g,
if (!desc)
return -1;
- px = gluten_ptr(&req->data, g, desc->x);
- py = gluten_ptr(&req->data, g, desc->y);
- cmp = desc->cmp;
-
- if (!px || !py ||
- !check_gluten_limits(desc->x, desc->size) ||
- !check_gluten_limits(desc->y, desc->size))
- return -1;
str_offset_value(req, g, &desc->x, desc->size, str_x, PATH_MAX);
str_offset_value(req, g, &desc->y, desc->size, str_y, PATH_MAX);
debug(" op_cmp: operands x=%s y=%s", str_x, str_y);
- res = memcmp(px, py, desc->size);
+ if (vec.start.type != OFFSET_NULL) {
+ debug(" vector start=(%s %d), length offset: %i",
+ gluten_offset_name[vec.start.type], vec.start.offset,
+ vec.len_offset);
+ }
+
+ if (vec.start.type == OFFSET_NULL)
+ vlen = &((uint32_t){ 1 });
+ else
+ vlen = (uint32_t *)gluten_ptr(&req->data, g, vec.start);
+
+ y_ptr = gluten_ptr(&req->data, g, desc->y);
- if ((res == 0 && (cmp == CMP_EQ || cmp == CMP_LE || cmp == CMP_GE)) ||
- (res < 0 && (cmp == CMP_LT || cmp == CMP_LE)) ||
- (res > 0 && (cmp == CMP_GT || cmp == CMP_GE)) ||
- (res != 0 && (cmp == CMP_NE))) {
- debug(" op_cmp: successful comparison, jump to %d",
- desc->jmp.offset);
+ if (!y_ptr || !check_gluten_limits(desc->y, desc->size))
+ return -1;
+
+ cmp = desc->cmp;
+
+ for (x = desc->x;
+ *vlen;
+ x.offset += *vlen, vlen = (uint32_t *)((uint8_t *)vlen + *vlen)) {
+ unsigned char *c;
+ int __i;
+
+ debug(" in loop, vlen: %u", *vlen);
+
+ x_ptr = gluten_ptr(&req->data, g, x);
+
+ if (!x_ptr || !check_gluten_limits(x, desc->size))
+ return -1;
+
+ debug(" in loop #2");
+
+ res = memcmp(x_ptr, y_ptr, desc->size);
+
+ debug("=== x: %04x, y: %04x", *(uint16_t *)x_ptr, *(uint16_t *)y_ptr);
+
+ c = (unsigned char *)x_ptr;
+ for (__i = 0; __i < 32; __i += 4)
+ debug("%02x %02x %02x %02x", c[__i], c[__i + 1], c[__i + 2], c[__i + 3]);
+
+ if ((res == 0 &&
+ (cmp == CMP_EQ || cmp == CMP_LE || cmp == CMP_GE)) ||
+ (res < 0 &&
+ (cmp == CMP_LT || cmp == CMP_LE)) ||
+ (res > 0 &&
+ (cmp == CMP_GT || cmp == CMP_GE)) ||
+ (res != 0 &&
+ (cmp == CMP_NE)))
+ some = true;
+ else
+ all = false;
+
+ if (vec.start.type == OFFSET_NULL)
+ break;
+
+ debug(" in loop #3");
+ }
+
+ /* FIXME: vectors always imply the existential quantifier for now:
+ * CMP_NE and all non-equal: jump
+ * CMP_EQ and some equal: jump
+ */
+ if (vec.start.type == OFFSET_NULL)
+ verdict = some;
+ else if (cmp == CMP_NE)
+ verdict = all;
+ else
+ verdict = some;
+
+ debug(" op_cmp: comparison: %s for some, %s for all, verdict: %s",
+ some ? "true" : "false", all ? "true" : "false",
+ verdict ? "true" : "false");
+
+ if (verdict) {
+ debug(" -> jump to %d", desc->jmp.offset);
return desc->jmp.offset;
}
- debug(" op_cmp: comparison is false");
return 0;
}