I have recently begun experimenting with kernel modules and have several questions about dealing with errno. Since this post is quite lengthy I have bolded the most relevant parts. I'm aware that errno is not part of the FreeBSD kernel and is actually part of the C language. From what I understand, the return value that a function stores in EAX prior to exiting is what decides whether errno is needed or not.
The problem I am having is that I have yet to find a way to 'catch' the value of errno after a system call executes while within a hooked syscall function. In short, I want to find out when a system call causes errno to be set, and what with.
For example, in my function 'open_hook':
Getting the value through rval is the only way I have been able to do this, and I'm positive there are far better ways. One that comes to mind is modifying the syscall 'dispatcher' to include something that works on all system calls, rather than relying on hooks.
Some ideas I have (but have no idea how to implement) to remedy the problem are:
- Using cpu_set_syscall_retval(), found @ http://lists.freebsd.org/pipermail/freebsd-hackers/2010-March/031094.html
- Checking td_errno
- Hooking some sort of function related to traps
Basically what I'm asking is:
- Are those ideas I mentioned dead-ends?
- Are syscall hooks the wrong way to go about detecting EACCES et al?
- Is there anything global (ie. a function) that handles errno?
I suspect that I am in far over my head but I figured I would ask incase there is a simple solution that I am overlooking. This has been bugging me for quite a while, so if I am indeed in over my head I would really appreciate some recommended reading material.
Thank you.
The problem I am having is that I have yet to find a way to 'catch' the value of errno after a system call executes while within a hooked syscall function. In short, I want to find out when a system call causes errno to be set, and what with.
For example, in my function 'open_hook':
Code:
static int
open_hook(struct thread *td, void *args)
{
int rval;
rval = open(td, args);
if(rval == EACESS)
uprintf("Error was 'Permission denied'\n");
...
}
Getting the value through rval is the only way I have been able to do this, and I'm positive there are far better ways. One that comes to mind is modifying the syscall 'dispatcher' to include something that works on all system calls, rather than relying on hooks.
Some ideas I have (but have no idea how to implement) to remedy the problem are:
- Using cpu_set_syscall_retval(), found @ http://lists.freebsd.org/pipermail/freebsd-hackers/2010-March/031094.html
- Checking td_errno
- Hooking some sort of function related to traps
Basically what I'm asking is:
- Are those ideas I mentioned dead-ends?
- Are syscall hooks the wrong way to go about detecting EACCES et al?
- Is there anything global (ie. a function) that handles errno?
I suspect that I am in far over my head but I figured I would ask incase there is a simple solution that I am overlooking. This has been bugging me for quite a while, so if I am indeed in over my head I would really appreciate some recommended reading material.
Thank you.