summaryrefslogtreecommitdiffstats
path: root/lib.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2019-09-30 06:59:05 -0700
committerKaz Kylheku <kaz@kylheku.com>2019-09-30 06:59:05 -0700
commit7098518a9bc43378afb5cbf599a074775c1d1d55 (patch)
tree4aef76fd2598ccdc4d5f1fb13fd056de8e19bb59 /lib.c
parent48ef128584e4b15c8b83de0f10f6d077031fa0ee (diff)
downloadtxr-7098518a9bc43378afb5cbf599a074775c1d1d55.tar.gz
txr-7098518a9bc43378afb5cbf599a074775c1d1d55.tar.bz2
txr-7098518a9bc43378afb5cbf599a074775c1d1d55.zip
safety: fix type tests that code can subvert.
This patch fixes numerous instances of a safety hole which involves the type of a COBJ object being tested to be of a given class using logic that can be subverted by the definition of a like-named struct. Specifically logic like (typeof(obj) == hash_s) is broken, because if a struct type called hash is defined, then the test will yield true for instances of that struct type. Those instances can then be passed into code that only works on COBJ hashes, and relies on this test to reject invalid objects. * ffi.c (make_carray): Replace fragile test with strong one, using new cobjclassp function. * hash.c (hashp): Likewise. * lib.c (class_check): The expression used here for the type test moves into the new function cobjclassp and so is replaced by a call to that function. (cobjclassp): New function. * lib.h (cobjclassp): Declared. * rand.c (random_state_p): Replace fragile test using cobjclassp. * regex.c (char_set_compile): Replace fragile typeof tests for character type with is_chr. (reg_derivative, regexp): Replace fragile test with cobjclassp. * struct.c (struct_type_p): Replace fragile test with cobjclassp.
Diffstat (limited to 'lib.c')
-rw-r--r--lib.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/lib.c b/lib.c
index 3e439437..ef781a89 100644
--- a/lib.c
+++ b/lib.c
@@ -499,8 +499,7 @@ val throw_mismatch(val self, val obj, type_t t)
val class_check(val self, val cobj, val class_sym)
{
- type_assert (is_ptr(cobj) && cobj->t.type == COBJ &&
- (cobj->co.cls == class_sym || subtypep(cobj->co.cls, class_sym)),
+ type_assert (cobjclassp(cobj, class_sym),
(lit("~a: ~s is not of type ~s"), self, cobj, class_sym, nao));
return t;
}
@@ -7828,6 +7827,13 @@ val cobjp(val obj)
return type(obj) == COBJ ? t : nil;
}
+val cobjclassp(val obj, val cls_sym)
+{
+ return if2(is_ptr(obj) && obj->t.type == COBJ &&
+ (obj->co.cls == cls_sym || subtypep(obj->co.cls, cls_sym)),
+ one);
+}
+
mem_t *cobj_handle(val self, val cobj, val cls_sym)
{
class_check(self, cobj, cls_sym);