Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 24 Jul 2001 13:01:37 +0400 (MSD)
From:      "Eugene L. Vorokov" <vel@bugz.infotecs.ru>
To:        rootx11@xfreek.mindriot.net
Cc:        freebsd-hackers@freebsd.org
Subject:   Re: calling kernel functions
Message-ID:  <200107240901.f6O91bH00518@bugz.infotecs.ru>
In-Reply-To: <20010724011123.610.qmail@xfreek.mindriot.net> "from rootx11@xfreek.mindriot.net at Jul 24, 2001 01:11:23 am"

next in thread | previous in thread | raw e-mail | index | archive | help
> Thank you very much for the help so far
> the functions open() and write() expect there arguments to be in user space
> and not kernel space, which is what I was doing wrong.  My question is, how
> then would you go about opening and editing a file from the kernel?
> 
> To Unsubscribe: send mail to majordomo@FreeBSD.org
> with "unsubscribe freebsd-hackers" in the body of the message

I think I've been posting this about 2 times already. Please search
mailing list archive prior to asking next time.

First of all, you rarely need to work with files directly in kernel.
Do not do this just because it's "cool" to use kernel module for the tasks
which can be done better with a user process. However, there are cases
when it's really needed. If you aren't going to do it from interrupt
routines or things like that, it's not that hard.

The way I do it for myself is taking current process and simulating that
this process is doing the syscall, and then stealing results. Note that
this only works if the process has permission to read the file you need.
It's not always safe; I think it wouldn't work if you try to do file i/o
from a routine which is added to packet filtering chain or things like
that. At least, I think it's safe to use this method when you're in
MOD_LOAD or MOD_UNLOAD state, or when you add a syscall and some user
program called it (but can't it read the file itself then and just pass
a pointer to a buffer to your module ?)

You can allocate userspace memory in the current process' address space
using mmap() syscall with fd == -1 and MAP_ANON flag. curpoc variable
(of type struct proc *) points to the current process, and you must
pass it to mmap(). Do note that it returns error code only; actuall address
of allocated memory (if call is successful) is located in the
curproc->p_retval[0], which you should rather save before doing the
syscall and restore later. Also note that you can't access such a memory
with usual C operators, because in general case kernel and user process
may have separate address spaces; you must rather use fubyte(), subyte(),
copyin(), copyout() routines; try reading the manual about them.

When you have some piece of userspace memory, you can copy filename
into it (not directly, as mentioned above), and pass it to open()
syscall. The same way you can use read(), write(), etc., passing
allocated userspace buffers to them, and once call is completed, you
can fetch the result from your buffer. Of course, don't forget close()
and munmap() when you're done.

And remember, it all is not really a proper way, but a very ugly
hack. Still, in conditions I described it works.

Regards,
Eugene


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200107240901.f6O91bH00518>