Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Write file from kernel land

Tags:

c

linux

kernel

I would like to write into a log file from the kernel space. I can create, open & close file (/var/log/my_kern_module.log) but if I try to write something into, my module crash... So I know read/write file from kernel space is bad, but I must do it in this module. Do you have any suggestion to help me ? thx

Here you can find the code who perform write on my kernel module. It code run into a thread (kthread)

mutex_lock(&gl_mtx_writelog);
      printk(KERN_EMERG "Readed : %s\n", buffer);

      fd = filp_open("/var/log/my_kern_module.log", O_CREAT | O_WRONLY | O_APPEND, S_IRWXU);
      if (!IS_ERR (fd)) {
        fs = get_fs();
        set_fs(KERNEL_DS);

        do_sync_write(fd, buffer, readed, 0);

        set_fs(fs);
        filp_close(fd, NULL);
      }
      mutex_unlock(&gl_mtx_writelog);

so, i've tried to use fd->f_op->write(...), but module crash too.

BUG: unable to handle kernel NULL pointer dereference at (null)
IP: [<c10df83a>] do_sync_write+0x6a/0xe0
*pde = 00000000
Oops: 0000 [#1] SMP
last sysfs file: /sys/module/snd_mixer_oss/initstate
Modules linked in: trigger_server snd_seq_dummy snd_seq_oss snd_seq_midi_event s                          nd_seq snd_seq_device snd_pcm_oss snd_mixer_oss ipv6 pcmcia pcmcia_core agpgart                           lp fuse ppdev snd_intel8x0 snd_ac97_codec ac97_bus thermal i2c_piix4 snd_pcm the                          rmal_sys i2c_core snd_timer e1000 parport_pc parport snd rtc_cmos rtc_core rtc_l                          ib joydev psmouse soundcore snd_page_alloc evdev usbhid serio_raw hid hwmon ac b                          utton sg [last unloaded: pcmcia_core]

Pid: 2468, comm: kthread_cli Not tainted 2.6.33.4-smp #1 /VirtualBox
EIP: 0060:[<c10df83a>] EFLAGS: 00010287 CPU: 0
EIP is at do_sync_write+0x6a/0xe0
EAX: f6434000 EBX: 00000000 ECX: 00000200 EDX: f5c26400
ESI: f653ca80 EDI: f5cf1f14 EBP: f5cf1f98 ESP: f5cf1f0c
 DS: 007b ES: 007b FS: 00d8 GS: 00e0 SS: 0068
Process kthread_cli (pid: 2468, ti=f5cf0000 task=f6434000 task.ti=f5cf0000)
Stack:
 c103de14 00000441 00000000 00000442 00000000 00000001 ffffffff f653ca80
<0> 00000000 00000000 00000000 00000000 f6434000 00000000 00000000 c10384a6
<0> 0000052b 00000000 0000052b ffffffff f5c26400 00000400 f5cf1f98 00000442
Call Trace:
 [<c103de14>] ? vprintk+0x184/0x3d0
 [<c10384a6>] ? try_to_wake_up+0x226/0x350
 [<f887b226>] ? thread_client+0x106/0x130 [trigger_server]
 [<f887b120>] ? thread_client+0x0/0x130 [trigger_server]
 [<c1058cf4>] ? kthread+0x74/0x80
 [<c1058c80>] ? kthread+0x0/0x80
 [<c10035be>] ? kernel_thread_helper+0x6/0x10
Code: 94 00 00 00 00 c7 45 98 00 00 00 00 c7 45 9c 00 00 00 00 c7 45 a0 00 00 00                           00 89 45 a4 c7 45 a8 00 00 00 00 c7 45 ac 00 00 00 00 <8b> 03 8b 53 04 89 4d c8                           89 45 b0 89 55 b4 eb 13 8d b6 00 00 00
EIP: [<c10df83a>] do_sync_write+0x6a/0xe0 SS:ESP 0068:f5cf1f0c
CR2: 0000000000000000
---[ end trace 32d03f08f128f335 ]---
like image 833
0xBAADF00D Avatar asked Jun 18 '11 12:06

0xBAADF00D


People also ask

What is Loff_t in Linux?

loff_t is a 64-bit value ( long long in gcc terminology). The driver can read this value if it needs to know the current position in the file, but should never change it (read and write should update a position using the pointer they receive as the last argument instead of acting on filp->f_pos directly).

How Linux operating system is able to read a file from disk?

Reading a file from the disk in Linux is a paging-based architecture. The data that is needed by the operating system might not be available at that time on the RAM. For that, OS divides the entire file into pages and fetches the data file which is needed from the memory.

How does a process read a file?

At first, parent process read some contents of the file. Then, child process is executed and child process's ID is printed. When the execution comes to the while loop which reads the file in child process, operating system continue to execute parent process.


2 Answers

One obvious problem is that the 4th parameter to do_sync_write() is a pointer to where the file offset is stored (so it can be updated). You are passing 0 which might explain the NULL pointer problem. Could try:

 loff_t ppos = 0;
 do_sync_write(fd, buffer, readed, &ppos);
like image 98
Dipstick Avatar answered Oct 07 '22 20:10

Dipstick


Equivalent methods to do what you need are listed here.

Why writing files from the kernel is bad ?

like image 31
sigjuice Avatar answered Oct 07 '22 20:10

sigjuice