Skip to content

Commit 0b156e3

Browse files
committed
add verify tag function
1 parent 2ba00f6 commit 0b156e3

9 files changed

Lines changed: 108 additions & 1 deletion

File tree

Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,7 +305,9 @@ tests: clean library_debug_unit_tests
305305
@echo "make tests"
306306
$(CC) $(CFLAGS) $(EXE_CFLAGS) $(DEBUG_LOG_FLAGS) $(GDB_FLAGS) $(OS_FLAGS) tests/rand_freelist.c $(ISO_ALLOC_PRINTF_SRC) -o $(BUILD_DIR)/rand_freelist $(LDFLAGS)
307307
$(CC) $(CFLAGS) $(EXE_CFLAGS) $(DEBUG_LOG_FLAGS) $(GDB_FLAGS) $(OS_FLAGS) tests/tagged_ptr_test.c $(ISO_ALLOC_PRINTF_SRC) -o $(BUILD_DIR)/tagged_ptr_test $(LDFLAGS)
308+
$(CC) $(CFLAGS) $(EXE_CFLAGS) $(DEBUG_LOG_FLAGS) $(GDB_FLAGS) $(OS_FLAGS) tests/uaf_tag_ptr_test.c $(ISO_ALLOC_PRINTF_SRC) -o $(BUILD_DIR)/uaf_tag_ptr_test $(LDFLAGS)
308309
$(CC) $(CFLAGS) $(EXE_CFLAGS) $(DEBUG_LOG_FLAGS) $(GDB_FLAGS) $(OS_FLAGS) tests/bad_tag_ptr_test.c $(ISO_ALLOC_PRINTF_SRC) -o $(BUILD_DIR)/bad_tag_ptr_test $(LDFLAGS)
310+
$(CC) $(CFLAGS) $(EXE_CFLAGS) $(DEBUG_LOG_FLAGS) $(GDB_FLAGS) $(OS_FLAGS) tests/verify_tag_ptr_test.c $(ISO_ALLOC_PRINTF_SRC) -o $(BUILD_DIR)/verify_tag_ptr_test $(LDFLAGS)
309311
$(CC) $(CFLAGS) $(EXE_CFLAGS) $(DEBUG_LOG_FLAGS) $(GDB_FLAGS) $(OS_FLAGS) tests/tests.c $(ISO_ALLOC_PRINTF_SRC) -o $(BUILD_DIR)/tests $(LDFLAGS)
310312
$(CC) $(CFLAGS) $(EXE_CFLAGS) $(DEBUG_LOG_FLAGS) $(GDB_FLAGS) $(OS_FLAGS) tests/uaf.c $(ISO_ALLOC_PRINTF_SRC) -o $(BUILD_DIR)/uaf $(LDFLAGS)
311313
$(CC) $(CFLAGS) $(EXE_CFLAGS) $(DEBUG_LOG_FLAGS) $(GDB_FLAGS) $(OS_FLAGS) tests/interfaces_test.c $(ISO_ALLOC_PRINTF_SRC) -o $(BUILD_DIR)/interfaces_test $(LDFLAGS)

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,8 @@ If all else fails please file an issue on the [github project](https://github.co
178178

179179
`void *iso_alloc_from_zone_tagged(iso_alloc_zone_handle *zone)` - Same as `iso_alloc_from_zone` but returns a tagged pointer if `MEMORY_TAGGING` is enabled.
180180

181+
`void iso_alloc_verify_ptr_tag(void *p, iso_alloc_zone_handle *zone)` - Verifies the tag for a pointer is correct, aborts if not. Requires `MEMORY_TAGGING`.
182+
181183
`void iso_alloc_destroy_zone(iso_alloc_zone_handle *zone)` - Destroy a zone created with `iso_alloc_from_zone`.
182184

183185
`void *iso_alloc_tag_ptr(void *p, iso_alloc_zone_handle *zone)` - Tags a pointer from a private zone if `MEMORY_TAGGING` is enabled.

include/iso_alloc.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ EXTERNAL_API void iso_free_permanently(void *p);
5050
EXTERNAL_API void iso_free_from_zone(void *p, iso_alloc_zone_handle *zone);
5151
EXTERNAL_API void iso_free_from_zone_permanently(void *p, iso_alloc_zone_handle *zone);
5252
EXTERNAL_API size_t iso_chunksz(void *p);
53+
EXTERNAL_API void iso_alloc_verify_ptr_tag(void *p, iso_alloc_zone_handle *zone);
5354
EXTERNAL_API NO_DISCARD uint8_t iso_alloc_get_mem_tag(void *p, iso_alloc_zone_handle *zone);
5455
EXTERNAL_API NO_DISCARD ASSUME_ALIGNED char *iso_strdup(const char *str);
5556
EXTERNAL_API NO_DISCARD ASSUME_ALIGNED char *iso_strdup_from_zone(iso_alloc_zone_handle *zone, const char *str);

include/iso_alloc_internal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,7 @@ INTERNAL_HIDDEN uint64_t __iso_alloc_mem_usage(void);
395395
INTERNAL_HIDDEN INLINE uint64_t us_rand_uint64(uint64_t *seed);
396396
INTERNAL_HIDDEN INLINE uint64_t rand_uint64(void);
397397
INTERNAL_HIDDEN uint8_t _iso_alloc_get_mem_tag(void *p, iso_alloc_zone_t *zone);
398+
INTERNAL_HIDDEN void _iso_alloc_verify_tag(void *p, iso_alloc_zone_t *zone);
398399
INTERNAL_HIDDEN size_t _iso_alloc_print_stats(void);
399400
INTERNAL_HIDDEN size_t _iso_chunk_size(void *p);
400401
INTERNAL_HIDDEN int64_t check_canary_no_abort(iso_alloc_zone_t *zone, const void *p);

src/iso_alloc_interfaces.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,16 @@ EXTERNAL_API NO_DISCARD void *iso_alloc_untag_ptr(void *p, iso_alloc_zone_handle
201201
return _untag_ptr(p, zone);
202202
}
203203

204+
EXTERNAL_API void iso_alloc_verify_ptr_tag(void *p, iso_alloc_zone_handle *zone) {
205+
if(zone == NULL) {
206+
return;
207+
}
208+
209+
UNMASK_ZONE_HANDLE(zone);
210+
_iso_alloc_verify_tag(p, zone);
211+
return;
212+
}
213+
204214
EXTERNAL_API NO_DISCARD uint8_t iso_alloc_get_mem_tag(void *p, iso_alloc_zone_handle *zone) {
205215
if(zone == NULL || p == NULL) {
206216
return 0;

src/iso_alloc_mem_tags.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,22 @@ INTERNAL_HIDDEN uint8_t _iso_alloc_get_mem_tag(void *p, iso_alloc_zone_t *zone)
2828
#endif
2929
}
3030

31+
INTERNAL_HIDDEN void _iso_alloc_verify_tag(void *p, iso_alloc_zone_t *zone) {
32+
#if MEMORY_TAGGING
33+
if(UNLIKELY(p == NULL || zone == NULL)) {
34+
return;
35+
}
36+
37+
void *untagged_p = (void *) ((uintptr_t) p & TAGGED_PTR_MASK);
38+
const uint64_t tag = _iso_alloc_get_mem_tag(untagged_p, zone);
39+
40+
if(tag != ((uintptr_t) p & IS_TAGGED_PTR_MASK)) {
41+
LOG_AND_ABORT("Pointer %p has wrong tag %x, expected %x", p, ((uintptr_t) p & IS_TAGGED_PTR_MASK), tag);
42+
}
43+
#endif
44+
return;
45+
}
46+
3147
INTERNAL_HIDDEN void *_tag_ptr(void *p, iso_alloc_zone_t *zone) {
3248
#if MEMORY_TAGGING
3349
if(UNLIKELY(p == NULL || zone == NULL)) {

tests/uaf_tag_ptr_test.c

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/* iso_alloc uaf_tag_ptr_test.c
2+
* Copyright 2022 - chris.rohlf@gmail.com */
3+
4+
#include <stdio.h>
5+
#include <string.h>
6+
#include "iso_alloc.h"
7+
#include "iso_alloc_internal.h"
8+
9+
#define SIZE 256
10+
11+
int main(int argc, char *argv[]) {
12+
iso_alloc_zone_handle *_zone_handle = iso_alloc_new_zone(SIZE);
13+
14+
if(_zone_handle == NULL) {
15+
abort();
16+
}
17+
18+
void *p = iso_alloc_from_zone_tagged(_zone_handle);
19+
void *up = iso_alloc_untag_ptr(p, _zone_handle);
20+
iso_free_from_zone(up, _zone_handle);
21+
iso_flush_caches();
22+
p = iso_alloc_untag_ptr(p, _zone_handle);
23+
24+
/* This should crash on systems without TBI as p is
25+
* already free and the untagging operation should
26+
* result in a bad pointer */
27+
memset(p, 0x41, SIZE);
28+
29+
iso_alloc_destroy_zone(_zone_handle);
30+
31+
#if !MEMORY_TAGGING
32+
return -1;
33+
#endif
34+
35+
return 0;
36+
}

tests/verify_tag_ptr_test.c

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/* iso_alloc verify_tag_ptr_test.c
2+
* Copyright 2022 - chris.rohlf@gmail.com */
3+
4+
#include <stdio.h>
5+
#include <string.h>
6+
#include "iso_alloc.h"
7+
#include "iso_alloc_internal.h"
8+
9+
#define SIZE 256
10+
11+
int main(int argc, char *argv[]) {
12+
iso_alloc_zone_handle *_zone_handle = iso_alloc_new_zone(SIZE);
13+
14+
if(_zone_handle == NULL) {
15+
abort();
16+
}
17+
18+
void *p = iso_alloc_from_zone_tagged(_zone_handle);
19+
void *up = iso_alloc_untag_ptr(p, _zone_handle);
20+
iso_free_from_zone(up, _zone_handle);
21+
iso_flush_caches();
22+
iso_alloc_verify_ptr_tag(p, _zone_handle);
23+
24+
p = iso_alloc_untag_ptr(p, _zone_handle);
25+
26+
/* This should crash on systems without TBI as p is
27+
* already free and the untagging operation should
28+
* result in a bad pointer */
29+
memset(p, 0x41, SIZE);
30+
31+
iso_alloc_destroy_zone(_zone_handle);
32+
33+
#if !MEMORY_TAGGING
34+
return -1;
35+
#endif
36+
37+
return 0;
38+
}

utils/run_tests.sh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ done
3131

3232
fail_tests=("double_free" "big_double_free" "heap_overflow" "heap_underflow"
3333
"leaks_test" "wild_free" "unaligned_free" "incorrect_chunk_size_multiple"
34-
"big_canary_test" "zero_alloc" "sized_free" "bad_tag_ptr_test")
34+
"big_canary_test" "zero_alloc" "sized_free" "bad_tag_ptr_test"
35+
"verify_tag_ptr_test")
3536

3637
for t in "${fail_tests[@]}"; do
3738
echo -n "Running $t test"

0 commit comments

Comments
 (0)