For debugging purposes I need to test a pointer to see if it points to a valid readable page. Currently I am parsing /proc/[pid]/maps to see if the address is mapped ok, but this seems a bit long-winded. Is there a better way? Thanks.
The canonical way is to use the write() system call to read from the page (writing to a dummy pipe() file descriptor). Instead of faulting, it will return -1 with errno == EFAULT if the buffer passed to write() is unreadable.
Related
I have a program which opens a static file with sys_open() and wants to receive a file descriptor equals to zero (=stdin). I have the ability to write to the file, remove it or modify it, so I tried to create a symbolic link to /dev/stdin from the static file name. It opens stdin, but returns with the lowest available fd (not equal to zero). How can I cause the syscall to return zero, without hooking the syscall or modifying the program itself? it that even possible?
(It's part of a challenge, not a real case scenario)
Thank you as always
Posix guarantees that the lowest available FD will be returned. Therefore you can just invoke the program with stdin closed:
./myprogram 0>&-
I tried adding this inside the brk system call function :
void *addr = sbrk(0);
printk("current-add-is-%p-\n", addr);
But it returned error during kernel compilation that implicit declaration of sbrk function. And I could not find where sbrk is defined!!
All I need to measure that whenever some user process tries to extended its program break address, I would know its current program break address, so that I can measure how much memory processes are requesting.
Thank you.
Looks like you are trying to do something wrong.
There is no 'sbrk' syscall, there is 'brk'. Except then it would be named sys_brk, but you have no reasons to call it. So if you want to find out how to learn the current break address, read brk's sources.
However, where exactly did you put this in if you did not happen to find brk's sources?
Add this line of code:
printf("Address of program break is %p\n", (void *)sbrk(0));
It will return a message to terminal with hex address of the program break.(e.g., 0x#### #### ####.)
If you want the address in other than hex, then use %u or similar. The use of sbrk(0) is documented in man pages (linux programmers manual).
To see documentation, type in command line: man sbrk and documentation will pop up.
I created a syscall same as /usr/share/examples/kld/syscall/module/syscall.c with a little change in message.
I used kldload and module loaded. now I want to call the syscall.
what is this syscall number so I can call it?
or what is the way to call this syscall?
I suggest you take a look at Designing BSD rootkits, that's how I learned kernel programming on FreeBSD, there's even a section that talks all about making your own syscalls.
Well, if you check /usr/share/examples/kld/syscall directory you will see it contains a test program..... but hey, let's assume the program is not there.
Let's take a look at part of the module itself:
/*
* The offset in sysent where the syscall is allocated.
*/
static int offset = NO_SYSCALL;
[..]
case MOD_LOAD :
printf("syscall loaded at %d\n", offset);
break;
The module prints syscall number on load, so the job now is to learn how to call it... a 'freebsd call syscall' search on google...
Reveals: http://www.freebsd.cz/doc/en/books/developers-handbook/x86-system-calls.html (although arguably not something to use on amd64) and.. https://www.freebsd.org/cgi/man.cgi?query=syscall&sektion=2 - a manual page for a function which allows you to call arbitrary syscalls.
I strongly suggest you do some digging on your own. If you don't, there is absolutely no way you will be able to write any kernel code.
I'm writing a program to track the mouse movements in linux. I read in another post that this can be done using read() system call to read the EventX file related to the mouse. I earlier was reading the serial port file and i used the read() to read it. But, then i sent in a character array to it and got back the serial characters. But, it doesnt seem to be in the mouse's case. The lines:
struct input_event ie;
read(fd, &ie, sizeof(struct input_event)
are used to read it. Here the ie is a struct. But i used to send in a char buffer in the serial port case. So, my question is: how do I know what struct/buffer to send. I got to know the answer for the above two code lines after googling, but if I want to read some other file,how would i know what struct/buffer to send. Please help me.
Thank you.
The input subsystem in Linux uses a standarized format to deliver its messages. It is actually quite simple:
You open the relevant input file, usually /dev/input/event<n>, using the open() system call.
You read input events from that file, using the read() function, as you noted in your question.
Every event from that file has a well known structure: that is struct input_event. You don't need to know the exact layout of that structure, that is done by the compiler. Just include the relevant header file: #include <linux/input.h>.
What you do want to know are the fields of this structure that are useful, and what they mean. I recommend you to read the official documentation as well as the input.h source.
Given an untrusted memory address, is there a way in Linux to test whether it points to valid, accessible memory?
For example, in mach you can use vm_read_overwrite() to attempt to copy data from the specified location. If the address is invalid or inaccessible, it will return an error code rather than crashing the process.
write from that memory (into /dev/null, for example (EDIT: with /dev/null it might not work as expected, use a pipe)), and you'll receive EFAULT error if the address is unaccessible.
I have no idea how to test for writable memory without destroying its content if it is writable.
This a typical case of TOCTOU - you check at some point that the memory is writeable, then later on you try to write to it, and somehow (e.g. because the application deallocated it), the memory is no longer accessible.
There is only one valid way to actually do this, and that is, trap the fault you get from writing to it when you actually need to use it.
Of course, you can use tricks to try to figure out if the memory "may be writeable", but there is no way you can actually ensure it is writeable.
You may want to explain slightly more what you are actually trying to do, and maybe we can have some better ideas if you are more specific.
You can try msync:
int page_size = getpagesize();
void *aligned = (void *)((uintptr_t)p & ~(page_size - 1));
if (msync(aligned, page_size, MS_ASYNC) == -1 && errno == ENOMEM) {
// Non-accessibe
}
But this function may be slow and should not be used in performance critical circumstance.