Skip to content

Instantly share code, notes, and snippets.

@eurocat2k
Created October 9, 2023 14:55
Show Gist options
  • Save eurocat2k/494095ed5dd0fa7c5fc1d34aeba2a745 to your computer and use it in GitHub Desktop.
Save eurocat2k/494095ed5dd0fa7c5fc1d34aeba2a745 to your computer and use it in GitHub Desktop.
C pointer check at runtime
# Assembly code of:
# clang -arch x86_64 -masm=intel -S -Wall -O3 -o - ptrcheck.c
#
.text
.intel_syntax noprefix
.file "ptrcheck.c"
.globl isValidPointer # -- Begin function isValidPointer
.p2align 4, 0x90
.type isValidPointer,@function
isValidPointer: # @isValidPointer
.cfi_startproc
# %bb.0:
push rbp
.cfi_def_cfa_offset 16
.cfi_offset rbp, -16
mov rbp, rsp
.cfi_def_cfa_register rbp
push rbx
push rax
.cfi_offset rbx, -24
test rdi, rdi
je .LBB0_3
# %bb.1:
mov rbx, rdi
lea rdi, [rbp - 16]
call pipe
test eax, eax
je .LBB0_4
.LBB0_3:
xor ebx, ebx
jmp .LBB0_7
.LBB0_4:
mov edi, dword ptr [rbp - 12]
mov edx, 8
mov rsi, rbx
call write
mov rbx, rax
test rax, rax
jns .LBB0_6
# %bb.5:
call __error
.LBB0_6:
test rbx, rbx
setns bl
mov edi, dword ptr [rbp - 16]
call close
mov edi, dword ptr [rbp - 12]
call close
.LBB0_7:
mov eax, ebx
add rsp, 8
pop rbx
pop rbp
.cfi_def_cfa rsp, 8
ret
.Lfunc_end0:
.size isValidPointer, .Lfunc_end0-isValidPointer
.cfi_endproc
# -- End function
.ident "FreeBSD clang version 14.0.5 (https://github.com/llvm/llvm-project.git llvmorg-14.0.5-0-gc12386ae247c)"
.section ".note.GNU-stack","",@progbits
.addrsig
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdbool.h>
#include <unistd.h>
bool isValidPointer(void * ptr) {
bool ret = false;
int fd[2];
if (NULL == ptr) {
return ret;
}
if (pipe(fd) == 0) {
if (write(fd[1], ptr, sizeof(ptr)) < 0) {
if (errno == EFAULT) {
// strerror(errno); // this is what we expected to happen
}
// strerror(errno); // to see what happened...
} else {
ret = true;
}
close(fd[0]); // close filedescriptors
close(fd[1]); //
}
return ret;
}
#ifndef __PTRCHECK__H__
#define __PTRCHECK__H__
#include <stdbool.h>
bool isValidPointer(void *ptr);
#endif //!__PTRCHECK__H__
#include <stdio.h>
#include <stdlib.h>
#include "ptrcheck.h"
int main(int argc, char** argv) {
void *ptr = NULL;
int a = 0;
int* pa = &a;
int* ip = 0x08219431a2;
printf(" void* ptr: %s [%p]\n", isValidPointer(ptr) ? "Valid" : "Invalid", ptr);
printf(" int* a: %s [%p]\n", isValidPointer(pa) ? "Valid" : "Invalid", pa);
printf(" int* ip: %s [%p]\n", isValidPointer(ip) ? "Valid" : "Invalid", ip);
printf(" void** ptr: %s [%p]\n", isValidPointer(&ptr) ? "Valid" : "Invalid", &ptr);
return EXIT_SUCCESS;
}
@eurocat2k
Copy link
Author

How to check is your C pointer is valid in your process's address space?
After a great review of Jacob Sorber.

After a test run, the output should be: "Invalid, Valid, Invalid, Valid" in this order.

However as it used to be, better to avoid bad pointers in your code, than utilize extra resources to check their validity.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment