4 ms·
It can be done easier with sigsetjmp, siglongjmp.
by zX41ZdbW 6y ago
It can be done easier with sigsetjmp, siglongjmp.
- zX41ZdbW 6y agoAlso you can check it with the `write` syscall (just write a byte pointed by address to /dev/null). If a pointer is invalid, it will return setting errno to EFAULT.
- scottlamb 6y agoNeat trick. I suppose you could also write the bytes to a self-pipe, avoiding the race the article mentions between ensuring the bytes are readable and actually reading them.
- jmgao 6y agoAnd if you're on Linux, you can read the memory directly with process_vm_readv.
- oomo 6y agoLeaving this here as comments on that blog seem broken. TL;DR: access(2) is a bit more lightweight than write(2) for this purpose. Consider the following (from memory, untested): word_t peek(word_t addr, int success) { word_t ret; errno = 0; access(addr, F_OK); if (success) success = (errno != EFAULT); if (errno != EFAULT) ret = *addr; return ret; } I first learnt about this trick in http://www.gcu-squad.org/2005/08/non-ce-n-est-pas-sale%21/ http://www.gcu-squad.org/2005/08/non-ce-n-est-pas-sale%21/
- s_gourichon 6y agoThe link posted by oomo contains (in French) an explanation about why it just works and is clean, general and guaranteed: from the page "les syscall ne peuvent pas segfault [dek\] Donc tous ceux qui acceptent une adresse [dek\] Sont obligées de checker qu’elles est valide [dek\] Et retournent EFAULT en cas d’erreur" In English: "syscalls cannot segfault, so all that accept an address (as parameter) have to check if it is valid and return EFAULT in case of error." (Since C code actually calls libc not system calls directly, this rationale fails on calls that do something on pointers before calling the actual kernel system call.) Also, given the time cost of making a system call, one has to has an approach finer than "pay a system call for each byte to write" if there are many. Anyway, TL;DR : it's not a dirty hack, it has some general validity!