access_ok inside kernelspace -- part II --

Vasili Goutas (vgo@ratio.de)
Thu, 21 Oct 1999 15:19:40 +0200


Hi,

I'm sorry contacting you again for the same thing, but I get some strange
thinks by using the get_fs()/set_fs() makros.

I tryed it out it in the driver I developed for the company I
work for, by using set_fs()/get_fs() to be able to call sys_open(),
sys_write(), sys_read() and sys_close.
At the beginning all seems ok, but after unloading at some time I get
segmantation faults. The seq. faults came from processes like sendmail or
cron, and I wandered why.
I started a test running top on one shell and unloading the driver on an other,
and I got the seg. faults faster (and every time from the top process) then
without running top.
I have to say, that my driver is programmed in C++ and I created a Class for
FileAccess. To be sure that it has nothing to do with C++ I wrote a litle
driver which does nothing exept file access and memory
allocation/deallocation if special ioctl commands are called, in the form of
init_module:
fs=get_fs();
set_fs(get_ds());
printk("orig. fs.seg = 0x%X, new fs.seg = 0x%X\n", fs.seg, get_fs().seg);
/* User space is now the kernel */

fd = sys_open(logfile, flags, mode);
printk("sys_open(%s, 0x%X, 0x%X) returned %i\n", logfile, flags, mode, fd);

if(fd >= 0)
{
err = sys_write (fd, writebuf, blasize);
printk("sys_write(%i, %s, %i) returned %i\n", fd, writebuf, blasize, err);
err = sys_close(fd);
printk("sys_close(%i) returned %i\n", fd, err);
}

set_fs(fs);

cleanup_module:
fs=get_fs();
set_fs(get_ds());
/* User space is now the kernel */
printk("orig. fs.seg = 0x%X, new fs.seg = 0x%X\n", fs.seg, get_fs().seg);
fd = sys_open(logfile, flags, mode);
printk("sys_open(%s, 0x%X, 0x%X) returned %i\n", logfile, flags, mode, fd);
if(fd)
{
err = sys_read(fd, readbuffer, 256);
printk("sys_read(%i, ...) returned %i\n", fd, err);
printk("readbuffer = %s\n", readbuffer);

err = sys_close(fd);
printk("sys_close(%i) returned %i\n", fd, err);
}
/* Put it back again */
set_fs(fs);

ioctl:
switch(cmd){
case TEST_ALLOC:
testpointer=(char*)vmalloc((unsigned long)arg);//, GFP_KERNEL);
printk("testpointer = 0x%X\n");
(unsigned long)rc = (unsigned long)testpointer;
break;
case TEST_FREE:
vfree(testpointer);
printk("testpointer free\n");
(unsigned long)rc = (unsigned long)testpointer;
break;
default:
printk("unknown command\n");
rc -1;
break;
}
return rc;

and a litle program which calls the ioctl commands.

If I insmod/remove the driver nothing special hapens.
Only some file operations are done.
Oct 21 14:56:16 debug kernel: init
Oct 21 14:56:16 debug kernel: orig. fs.seg = 0xC0000000, new fs.seg = 0xFFFFFFFF
Oct 21 14:56:16 debug kernel: sys_open(/tmp/driverlog.txt, 0x442, 0x1C0) returned 4
Oct 21 14:56:16 debug kernel: sys_write(4, bla bla from kernel driver
Oct 21 14:56:16 debug kernel: , 27) returned 27
Oct 21 14:56:16 debug kernel: sys_close(4) returned 0
Oct 21 14:56:31 debug kernel: cleanup
Oct 21 14:56:31 debug kernel: orig. fs.seg = 0xC0000000, new fs.seg = 0xFFFFFFFF
Oct 21 14:56:31 debug kernel: sys_open(/tmp/driverlog.txt, 0x0, 0x0) returned 3
Oct 21 14:56:31 debug kernel: sys_read(3, ...) returned 81
Oct 21 14:56:31 debug kernel: readbuffer = bla bla from kernel driver
Oct 21 14:56:31 debug kernel: bla bla from kernel driver
Oct 21 14:56:31 debug kernel: bla bla from kernel driver
Oct 21 14:56:31 debug kernel:
Oct 21 14:56:31 debug kernel: sys_close(3) returned 0

If I insmod it and run the program, I get a seg. fault realy fast.
After that the machine is dead at all and can only powered off.
Oct 21 15:04:50 debug kernel: init
Oct 21 15:04:50 debug kernel: orig. fs.seg = 0xC0000000, new fs.seg = 0xFFFFFFFF
Oct 21 15:04:50 debug kernel: sys_open(/tmp/driverlog.txt, 0x442, 0x1C0) returned 4
Oct 21 15:04:50 debug kernel: sys_write(4, bla bla from kernel driver
Oct 21 15:04:50 debug kernel: , 27) returned 27
Oct 21 15:04:50 debug kernel: sys_close(4) returned 0
Oct 21 15:04:59 debug kernel: Unable to handle kernel paging request at virtual address ca758b84
Oct 21 15:04:59 debug kernel: current->tss.cr3 = 03062000, %cr3 = 03062000
Oct 21 15:04:59 debug kernel: *pde = 00000000
Oct 21 15:04:59 debug kernel: Oops: 0000
Oct 21 15:04:59 debug kernel: CPU: 0

An other problem is that the file descriptor cannot be createt ones and used in
different functions. I tryed getting the file descr. in init_module with
sys_open() stored it and reused it in cleanup_module() by sys_read() and
sys_close(), but I get back -EBADF
in sys_read the lines returning that are
ret = -EBADF;
file = fget(fd);
if (!file)
goto bad_file;

If the file descr. is created inside the function it needs, all file accesses
works fine.

I created a patch for the sysbols which have to be exported and put it together
with the source of the simple driver and the testprogram on our ftp server.
You can download it from ftp.ratio.de/linux-file-access/ if you want.

On my first posting 'access_ok inside kernel' people discussed the use of
sys_xxx() calls insted of calling __syscallX.
I would use the __syscall functions if I knew how. If someone can tell me how I
would try to use them, but I think there have to be used the
get_fs()/set_fs() makros too, so it will be the same problem.

I hope anybody will help me getting access to the filesystem within the
kernel.

TIA

Vasili

On Mon, 18 Oct 1999, you wrote:
>> I patched the 2.2.12 kernel to be able to write to the file system within my
>> driver.
>> I do this by patching the copy_to/from_user functions like this
>
>You don't need to do this
>
>> If someone has written such a function, or knows which already implemented
>> function of Linux does that, please inform me.
>
>
> mm_segment_t fs;
>
> fs=get_fs();
> set_fs(get_ds());
>
> /* User space is now the kernel */
>
>
> /* Put it back again */
>
> set_fs(fs);

--
Vasilios Goutas
Software-Development
RATIO Entwicklungen GmbH
Phone:+49-(0)40-369007-0   Admiralitätstr. 59
Fax:+49-(0)40-369007-25    20459 Hamburg
Email: mailto:vgo@ratio.de

- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/