我正在尝试创建一个内核模块,需要查找是否连接了特定的USB设备,即 USB键盘以及是否具有DMA访问权限。
为了实现这一目标,我将遍历RAM中存在的所有URB结构(linux / usb.h)。当我发现一个非null的结构时,我试图通过在URB结构中声明的struct usb_device * dev指针来访问设备信息。 但是,访问* dev中的任何信息会导致OOPS条件,并且错误说明无法在ffffe00121160800处理内核分页请求。地址每次都保持不变。
以下只是我整个内核模块的一个片段。
#define x(y) ((void *)((uint32_t)(y)+PAGE_OFFSET))
static int __init check(void)
{
unsigned long long i;
for(i = 0; i < ULLONG_MAX; i += 0x10)
{ struct urb *urbptr = (struct urb *)x(i);
if((((unsigned long)urbptr->dev) % 0x400) == 0)
{
if ((((unsigned long)urbptr->transfer_dma) % 0x20) == 0)
{
if (urbptr->transfer_buffer_length ==8)
{
if (urbptr->transfer_buffer_length ==8)
{
if (urbptr->transfer_buffer !=NULL)
{
if(urbptr->dev !=NULL)
{
printk("\n%s\n",urbptr->dev->product);
}
}
}
}
}
}
}
每次我尝试访问usb_device结构的任何值(不仅仅是char * product)时都会发生错误。经过大量的调试后,我能够识别错误只发生在printk语句中,即* dev不为null,只有在我尝试访问其数据成员时才会发生页面错误。
以下是 dmesg 输出:
[ 93.925232] BUG: unable to handle kernel paging request at ffffe00121160800
[ 93.925287] IP: [<ffffffffc01320f0>] check+0xf0/0x1000 [check]
[ 93.925334] PGD 0
[ 93.925350] Oops: 0000 [#1] SMP
[ 93.925375] Modules linked in: check(POE+) ctr ccm nvram msr pci_stub vboxpci(OE) vboxnetadp(OE) vboxnetflt(OE) vboxdrv(OE) bnep rfcomm binfmt_misc nls_iso8859_1 uvcvideo videobuf2_vmalloc videobuf2_memops videobuf2_core v4l2_common videodev media rtsx_usb_ms memstick btusb bluetooth 6lowpan_iphc fglrx(POE) ip6t_REJECT xt_hl ip6t_rt nf_conntrack_ipv6 nf_defrag_ipv6 ipt_REJECT xt_LOG xt_limit xt_tcpudp xt_addrtype nf_conntrack_ipv4 nf_defrag_ipv4 xt_conntrack ip6table_filter ip6_tables nf_conntrack_netbios_ns nf_conntrack_broadcast nf_nat_ftp nf_nat nf_conntrack_ftp nf_conntrack iptable_filter ip_tables x_tables wl(POE) arc4 iwldvm mac80211 dell_wmi sparse_keymap dell_laptop dcdbas snd_hda_codec_hdmi intel_rapl x86_pkg_temp_thermal intel_powerclamp coretemp snd_hda_codec_realtek snd_hda_codec_generic kvm_intel kvm snd_hda_intel snd_hda_controller snd_hda_codec crct10dif_pclmul crc32_pclmul snd_hwdep ghash_clmulni_intel aesni_intel aes_x86_64 lrw gf128mul snd_pcm glue_helper ablk_helper cryptd snd_seq_midi snd_seq_midi_event snd_rawmidi snd_seq joydev serio_raw iwlwifi cfg80211 snd_seq_device snd_timer snd lpc_ich soundcore mei_me mei amd_iommu_v2 mac_hid shpchp parport_pc ppdev lp parport rtsx_usb_sdmmc rtsx_usb i915 psmouse ahci libahci i2c_algo_bit drm_kms_helper drm r8169 mii wmi video
[ 93.926369] CPU: 3 PID: 3410 Comm: modprobe Tainted: P OE 3.16.0-41-generic #57~14.04.1-Ubuntu
[ 93.926439] task: ffff88008b7fd180 ti: ffff880221114000 task.ti: ffff880221114000
[ 93.926448] RIP: 0010:[<ffffffffc01320f0>] [<ffffffffc01320f0>] scan_start+0xf0/0x1000 [check]
[ 93.926449] RSP: 0018:ffff880221117d28 EFLAGS: 00010282
[ 93.926450] RAX: 0000000000000005 RBX: 0000000000207f40 RCX: 0000000000004c00
[ 93.926451] RDX: 000000000000e76a RSI: 0000000000000046 RDI: 0000000000000246
[ 93.926453] RBP: ffff880221117d40 R08: 0000000000000092 R09: 0000000000061bd7
[ 93.926454] R10: 0000000000000000 R11: ffff880221117ac6 R12: ffffe00121160800
[ 93.926455] R13: ffff880000000000 R14: ffffffffc0132000 R15: ffffffffc1c42000
[ 93.926457] FS: 00007f3eb6c9e740(0000) GS:ffff88025f2c0000(0000) knlGS:0000000000000000
[ 93.926459] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 93.926460] CR2: ffffe00121160800 CR3: 00000002210c3000 CR4: 00000000001407e0
[ 93.926461] Stack:
[ 93.926464] ffffffff81c1a020 ffff8802371db940 0000000000000000 ffff880221117db8
[ 93.926466] ffffffff81002144 0000000000000001 0000000000000001 0000000000000002
[ 93.926468] ffff8802502e4140 0000000000000001 ffff880221117da0 ffffffff8119d672
[ 93.926469] Call Trace:
[ 93.926479] [<ffffffff81002144>] do_one_initcall+0xd4/0x210
[ 93.926488] [<ffffffff8119d672>] ? __vunmap+0xb2/0x100
[ 93.926498] [<ffffffff810edc91>] load_module+0x13c1/0x1b80
[ 93.926505] [<ffffffff810e9840>] ? store_uevent+0x40/0x40
[ 93.926510] [<ffffffff810ee5c6>] SyS_finit_module+0x86/0xb0
[ 93.926519] [<ffffffff8176de4d>] system_call_fastpath+0x1a/0x1f
[ 93.926631] Code: 24 68 00 74 38 31 c0 48 c7 c7 4b 10 c4 c1 e8 b2 c5 62 c1 4d 8b 64 24 48 4d 85 e4 74 20 48 c7 c7 50 10 c4 c1 31 c0 e8 9a c5 62 c1 <41> 8b 34 24 48 c7 c7 56 10 c4 c1 31 c0 e8 88 c5 62 c1 48 c7 c7
[ 93.926636] RIP [<ffffffffc01320f0>] check+0xf0/0x1000 [check]
[ 93.926639] RSP <ffff880221117d28>
[ 93.926641] CR2: ffffe00121160800
[ 93.940769] ---[ end trace f2349a61d7dd6264 ]---
内核是否有任何理由无法访问此特定结构?即使该内核空间被写保护,我也只是想读它。像 lsusb 这样的命令在用户空间中访问相同的结构,所以我相信这个内核没有理由超越它的界限。