LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Software > Linux - Kernel
User Name
Password
Linux - Kernel This forum is for all discussion relating to the Linux kernel.

Notices


Reply
  Search this Thread
Old 08-05-2020, 10:17 AM   #1
afronteau
LQ Newbie
 
Registered: Jan 2020
Posts: 2

Rep: Reputation: Disabled
Kernel panic in a module with sprintf in read function


Hi,
I want to write a driver that simply signal to user when an interrupt occured. It works most of the time but sometimes there is a kernel panic :
Unable to handle kernel paging request at virtual address 6d904ad8
pgd = a9428000
[6d904ad8] *pgd=38e8f831, *pte=10b1075f, *ppte=10b10c7f
Internal error: Oops: 81f [#1] PREEMPT SMP ARM
Modules linked in: mxc_v4l2_capture ipu_bg_overlay_sdc ipu_still 8723bu(O) ipu_prp_enc ipu_csi_enc ipu_fg_overlay_sdc sbs_battery platformw_fpga_module(O) platformw_adis16488_driver(O) platformw_fpga_fw_loader_mo
CPU: 2 PID: 292 Comm: imajboxwd Tainted: G O 3.14.52 #1
task: a8701300 ti: a9756000 task.ti: a9756000
PC is at number.isra.1+0x314/0x458
LR is at 0x2
pc : [<802069cc>] lr : [<00000002>] psr: 300d0013
sp : a9757df8 ip : a9757e2d fp : a9757e9c
r10: ed904ad7 r9 : a9757f1c r8 : 00000000
r7 : 00000002 r6 : 7f026506 r5 : 7f026506 r4 : 6d904ad9
r3 : fffffffc r2 : 00000031 r1 : 00000020 r0 : 6d904ad9
Flags: nzCV IRQs on FIQs on Mode SVC_32 ISA ARM Segment user
Control: 10c5387d Table: 3942804a DAC: 00000015
Process imajboxwd (pid: 292, stack limit = 0xa9756238)
Stack: (0xa9757df8 to 0xa9758000)
7de0: a8008e40 807c003e
7e00: a9757e44 00000000 00000000 00000000 00000001 00000000 ffffffff 0000000a
7e20: 00000001 00000002 f4a00100 00310001 00000002 00000000 a9757e64 a9757e48
7e40: 8006b164 80587b9c a8008e40 a8008e9c a8008e40 a8008e9c a9756000 0000003d
7e60: 00000000 f4a00100 00000001 00000002 a9757e94 6d904ad8 7f026506 7f026506
7e80: 00000002 ed904ad7 a9757f1c 805ac2d8 a9757ef4 a9757ea0 80208ad4 802066c4
7ea0: 00000002 0000000a ffffffff ffffffff 80008520 6d904ad8 807c00fe 7fffffff
7ec0: ff0a0210 ffffffff a9757f44 00000002 a89c0010 6d904ad8 a89c0094 00000001
7ee0: 00000002 00000000 a9757f10 a9757ef8 80208cc0 80208774 00000001 a9757f18
00000000 a9757f44 a9757f20 7f023a5c 80208ca8 7f026504 00000001 00000000
7f20: a893c300 6d904ad8 a9757f78 7f0239f8 6d904ad8 00000002 a9757f74 a9757f48
7f40: 800e1c88 7f023a04 800fc190 800fc088 a893c301 a893c300 00000000 00000000
7f60: 6d904ad8 00000002 a9757fa4 a9757f78 800e233c 800e1bfc 00000000 00000000
7f80: 00000002 6d904ad8 00000012 00000003 8000e8c4 a9756000 00000000 a9757fa8
7fa0: 8000e740 800e2304 00000002 6d904ad8 00000012 6d904ad8 00000002 00000000
Aug 4 15:44:51 imajboxw user.emerg kernel: [ 252.999664] 7fc0: 00000002 6d904ad8 00000012 00000003 712feb5a 00000000 712feb60 6bcfdf4c
7fe0: 6bcfdbb4 6bcfdbc8 6bcfe8d0 76e65858 800d0010 00000012 f1f79ebf d6dfc8b7
Backtrace:
[<802066b8>] (number.isra.1) from [<80208ad4>] (vsnprintf+0x36c/0x46c)
r10:805ac2d8 r9:a9757f1c r8:ed904ad7 r7:00000002 r6:7f026506 r5:7f026506
r4:6d904ad8
[<80208768>] (vsnprintf) from [<80208cc0>] (sprintf+0x28/0x30)
r10:00000000 r9:00000002 r8:00000001 r7:a89c0094 r6:6d904ad8 r5:a89c0010
r4:00000002
[<80208c9c>] (sprintf) from [<7f023a5c>] (platformw_fpga_stat_read+0x64/0x68 [platformw_fpga_module])
r3:00000000 r2:00000001 r1:7f026504
[<7f0239f8>] (platformw_fpga_stat_read [platformw_fpga_module]) from [<800e1c88>] (vfs_read+0x98/0x140)
r9:00000002 r8:6d904ad8 r7:7f0239f8 r6:a9757f78 r5:6d904ad8 r4:a893c300
[<800e1bf0>] (vfs_read) from [<800e233c>] (SyS_read+0x44/0x98)
r9:00000002 r8:6d904ad8 r7:00000000 r6:00000000 r5:a893c300 r4:a893c301
[<800e22f8>] (SyS_read) from [<8000e740>] (ret_fast_syscall+0x0/0x38)
r9:a9756000 r8:8000e8c4 r7:00000003 r6:00000012 r5:6d904ad8 r4:00000002
Code: e15a0004 e2844001 e24cc001 85dc2001 (85442001)
---[ end trace 6f394a5be0d7261c ]---


The three functions involved are the irq handler, the read function, and the poll one :

unsigned int platformw_fpga_stat_poll(struct file *file, poll_table *wait)
{
struct module_data * pdata = (struct module_data *) file->private_data;

if (pdata->dev_data.new_stats_available == 1)
{
return POLLIN | POLLRDNORM;
}

poll_wait(file, &pdata->dev_data.event_statCollected, wait);
if (pdata->dev_data.new_stats_available == 1)
{
return POLLIN | POLLRDNORM;
}

return 0;
}

ssize_t platformw_fpga_stat_read (struct file * file ,
char __user * buffer, size_t len, loff_t * offset)
{
struct module_data * pdata = (struct module_data *) file->private_data;
unsigned long flags;
uint8_t available = 0;
int ret = 0;

spin_lock_irqsave(&pdata->dev_data.read_stat_lock, flags);
available = pdata->dev_data.new_stats_available;
pdata->dev_data.new_stats_available = 0;
spin_unlock_irqrestore(&pdata->dev_data.read_stat_lock, flags);

if ((len >= 2) && (buffer))
{
ret = sprintf(buffer, "%d\n", available);
}
return ret;
}

static irqreturn_t platformw_fpga_stat_collected_irq(int irq, void * data)
{
struct module_data * pdata = (struct module_data *) data;

spin_lock(&pdata->dev_data.read_stat_lock);
pdata->dev_data.new_stats_available = 1;
spin_unlock(&pdata->dev_data.read_stat_lock);

wake_up_interruptible(&pdata->dev_data.event_statCollected);
return IRQ_HANDLED;
}


The trace indicates the "sprintf" in the read function but I don't see what is wrong, so I would like to know what can cause this kind of issues ?
 
Old 01-18-2021, 04:28 AM   #2
dracayr
LQ Newbie
 
Registered: May 2008
Posts: 23

Rep: Reputation: 15
You're writing directly from kernel space to user space memory, which is a bad idea for a few reasons such as swapping (which only exists in user space) and potential unhandled kernel mode page faults (as you can see). The kernel provides the function copy_to_user in asm/uaccess.h to do this safely. So, first allocate a buffer from within the module, do sprintf into that buffer, then call copy_to_user to copy the buffer over to the user space address.

Last edited by dracayr; 01-18-2021 at 04:29 AM.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Can a kernel module call the function of another kernel module sceadu Programming 3 05-02-2011 02:22 AM
[SOLVED] how to make a messy sprintf function work smeezekitty Programming 7 10-03-2009 11:49 AM
How to print the "%m" "%d" using sprintf command ? stny Linux - Software 1 02-08-2006 09:55 PM
programming-segmentation fault(sprintf) ramakrishna sura Linux - General 1 12-20-2005 04:12 AM
sprintf not working in char driver module snigglyfox Programming 2 04-27-2004 01:25 PM

LinuxQuestions.org > Forums > Linux Forums > Linux - Software > Linux - Kernel

All times are GMT -5. The time now is 12:08 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration