LinuxDev 板


LINE

大家好,想请问kernel module的function中array of struct与struct的记忆体配置方式 是不是不一样(变数为函数中直接宣告,未使用kmalloc)?会这样问是因为最近在写作业时 遇到使用copy_to_user复制一段记忆体内容到userspace时只要复制的内容是array of struct就会panic,log如下: usercopy: kernel memory exposure attempt detected from 00000000e7ee16e5 (<process stack>) (16 bytes) 但只要把原本要复制的内容放到同个资料结构的struct中就可以正常copy...,以下是复 时用到的资料结构: struct U64 { unsigned long long msl; unsigned long long lsl; }; 然後喂给copy_to_user的arg(size)都一样是16 bytes。目前推测array of struct配置的 成员记忆体是不连续的,可是kernelspace的virtual address让我在debug时看到的记忆 体都是不连续的(array of struct与struct),所以不确定这样推测是否正确。 不知道各位前辈有什麽看法,谢谢大家! **更新**(补上程式码),以下为可以正常运作的程式码,原本有问题的版本是使用fib(ar ra of struct)做复制(copy_to_user(buf, &fib[g - 1], size)),另外,size一直都是16 bytes: static long long fib_sequence(long long g, char *buf, size_t size) { unsigned long long a; a = 10000000000000000000; struct U64 fib[g + 1], tmp = {0}; memset(fib, 0, sizeof(struct U64) * (g + 1)); int k; fib[0].lsl = 1; fib[1].lsl = 1; for (k = 2; k <= g; k++) { fib[k].lsl = fib[k - 1].lsl + fib[k - 2].lsl; fib[k].msl = fib[k - 1].msl + fib[k - 2].msl; if (fib[k].lsl > a) { fib[k].lsl = fib[k].lsl - a; fib[k].msl = fib[k].msl + 1; } } tmp = fib[g - 1]; copy_to_user(buf, &tmp, size); return 1; } --



※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 49.213.161.228
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/LinuxDev/M.1553628544.A.D7C.html ※ 编辑: dces4212 (49.213.161.228), 03/27/2019 03:40:15
1F:→ wens: array 是 struct xxx XXX[N] 宣告? copy_to_user 呼叫方法呢03/27 16:17
2F:→ wens: 要问 code 就要把 code 贴出来,不要请人隔空抓药...03/27 16:18
3F:→ dces4212: 抱歉 原本想说只是个很直观的array of struct跟struct03/27 20:41
4F:→ dces4212: 的配置差别 所以就没贴上来,等等补上!03/27 20:41
※ 编辑: dces4212 (140.128.72.6), 03/27/2019 20:54:24
5F:→ wens: 不太相干的事情: 不要用 VLA, 很容易爆 stack03/28 00:17
6F:→ dces4212: 有爆过了哈哈 惨死 要做完整应该会根据资料结构算个上限03/28 00:28
7F:→ dces4212: 16 KB真的不小心就爆掉..,只是现在遇到这问题实在不解.03/28 00:29
8F:→ wens: 你出现错误的时候 g 是多少? 我觉得可能是你 stack 爆了去踩03/28 00:35
9F:→ wens: 到 text section ...03/28 00:35
10F:→ wens: 看 mm/usercopy.c 应该是没大到踩到 text section 不然错误03/28 00:49
11F:→ wens: 讯息不太一样,而且中间踩到 unmapped page 应该会先炸03/28 00:50
12F:→ wens: 看起来像是 x86 上超出 stack frame 之类的03/28 00:51
13F:→ wens: 乖乖用 kmalloc 吧03/28 00:51
只要用array of struct当copy_to_user()的arg就一次都没成功过(g范围是0~100),但只 要单用struct就不会出问题。会考虑kmalloc的,感谢。目前推测触发BUG()的地方是这里 (因为就连g很小的时候都有问题,就不太可能是#L50的检查了) (https://elixir.bootlin.com/linux/v4.15.18/source/mm/usercopy.c#L54),#L54做的 检查其实看不太懂,#L50已经检查过是否要复制的范围在stack内,不知道这个是不是检 查是否为stack内可存取的记忆体,注解写的if object is safely感觉又不太像这意思, 不知道大大有啥看法。 ※ 编辑: dces4212 (49.213.161.228), 03/28/2019 01:13:03
14F:→ wens: 对吼... 应该要请你附 backtrace 跟解析过的行数才对XD03/28 10:52
15F:→ wens: arch_within_stack_frames 好像 x86 才有实作03/28 10:52
16F:→ dces4212: backtrace 是指 call stack 跟dump出的register那些吗03/28 13:24
17F:→ dces4212: 应该是只有x86有这实作 arch/下只看到x8603/28 13:32
18F:→ wens: 对啊 # backtrace 是指 call stack 跟dump出的register03/28 15:56
了解! [ 4167.013170] usercopy: kernel memory exposure attempt detected from 00000000e7ee16e5 (<process stack>) (16 bytes) [ 4167.013177] ------------[ cut here ]------------ [ 4167.013178] kernel BUG at /build/linux-7kdHqT/linux-4.15.0/mm/usercopy.c:72! [ 4167.013183] invalid opcode: 0000 [#1] SMP PTI [ 4167.013184] Modules linked in: fibdrv(OE)....(已省略) [ 4167.013262] CPU: 1 PID: 16325 Comm: client Tainted: G W OE 4.15.0-46-generic #49-Ubuntu [ 4167.013263] Hardware name: ASUSTeK COMPUTER INC. UX430UN/UX430UN, BIOS UX430UN.302 11/28/2017 [ 4167.013268] RIP: 0010:__check_object_size+0x123/0x1b0 [ 4167.013269] RSP: 0018:ffffbc64858f7e08 EFLAGS: 00010286 [ 4167.013271] RAX: 0000000000000064 RBX: 0000000000000010 RCX: 0000000000000006 [ 4167.013273] RDX: 0000000000000000 RSI: 0000000000000092 RDI: ffff9ac0eec96490 [ 4167.013274] RBP: ffffbc64858f7e28 R08: 0000000000000000 R09: 0000000000001831 [ 4167.013275] R10: 0000000000000000 R11: ffffffffaff5380d R12: 0000000000000001 [ 4167.013276] R13: ffffbc64858f7e38 R14: ffffbc64858f7e28 R15: 1ffff78c90b1efc7 [ 4167.013278] FS: 00007ff1e9d3d500(0000) GS:ffff9ac0eec80000(0000) knlGS:0000000000000000 [ 4167.013279] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 4167.013281] CR2: 00007fffc3d96080 CR3: 00000003d28fe006 CR4: 00000000003606e0 [ 4167.013282] Call Trace: [ 4167.013288] fib_read+0x159/0x197 [fibdrv] [ 4167.013290] ? fib_read+0x34/0x197 [fibdrv] [ 4167.013293] __vfs_read+0x1b/0x40 [ 4167.013294] vfs_read+0x8e/0x130 [ 4167.013296] SyS_read+0x55/0xc0 [ 4167.013300] do_syscall_64+0x73/0x130 [ 4167.013303] entry_SYSCALL_64_after_hwframe+0x3d/0xa2 [ 4167.013305] RIP: 0033:0x7ff1e9861081 [ 4167.013306] RSP: 002b:00007fffc3d51638 EFLAGS: 00000246 ORIG_RAX: 0000000000000000 [ 4167.013308] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007ff1e9861081 [ 4167.013309] RDX: 0000000000000010 RSI: 00007fffc3d51650 RDI: 0000000000000003 [ 4167.013310] RBP: 00007fffc3d516a0 R08: 00007ff1e9b3dd80 R09: 00007ff1e9b3dd80 [ 4167.013311] R10: 00007fffc3d51620 R11: 0000000000000246 R12: 000055f6d8e947c0 [ 4167.013313] R13: 00007fffc3d51780 R14: 0000000000000000 R15: 0000000000000000 [ 4167.013314] Code: 48 0f 45 d1 48 c7 c6 53 f2 6d af 48 c7 c1 ef ff 6e af 48 0f 45 f1 49 89 d9 49 89 c0 4c 89 f1 48 c7 c7 f8 ff 6e af e8 fd dd e7 ff <0f> 0b f3 c3 48 8b 3d 82 18 1a 01 48 8b 0d 13 99 1d 01 be 00 00 [ 4167.013369] RIP: __check_object_size+0x123/0x1b0 RSP: ffffbc64858f7e08 ※ 编辑: dces4212 (49.213.161.228), 03/28/2019 21:31:09
19F:→ dces4212: 补充一下,copy_to_user只有在fib__sequence用到03/28 21:32
20F:→ xam: struct U64 fib[g + 1] 为什麽你这样写编译会过?03/31 04:31
21F:推 yvb: 楼上: google: VLA c9903/31 10:04
22F:→ yvb: 回原PO: 你确认过 wens 在 8 楼的问题了吗?03/31 10:06
23F:→ yvb: g=0 时, fib[0-1] => fib[-1] 是该被 usercopy 报 BUG(),03/31 10:09
24F:→ yvb: 但你确定 g=1 到 g=100 也报 BUG() ? 03/31 10:10
25F:推 xam: 看起来kernel对vla的支援还有点问题03/31 10:11
26F:推 xam: https://m.slashdot.org/story/34774103/31 10:13
27F:→ yvb: 另外, 既然for(...k<=g...)算到 fib[g], 为何是回 fib[g-1]?03/31 10:14
28F:→ yvb: @xam: 嗯,要看原PO用的是gcc还是clang.若是clang也许有问题.03/31 10:33
29F:→ yvb: 又, 原PO用的是4.15, 要4.20才有设-Wvla对VLA给warning.03/31 10:38
30F:→ yvb: @xam: 又看了一下那篇,指的是struct的member用到VLA有问题,03/31 10:44
31F:→ yvb: 而原PO的VLA是C99-style,所以clang支援.03/31 10:47
32F:→ yvb: 至於第1点, 只是 overhead 问题; 但第3点就不大明了了...03/31 10:54
33F:→ yvb: 猜测是要做阵列大小检查(还是直接改用kmalloc乾脆XD).03/31 11:01
34F:→ xam: 用了 kmalloc 就是避用 vla 啊03/31 11:03
35F:→ yvb: 是说原PO的 fib[g+1] 其实大小只要 fib[3], 撘配 % 运算即可.03/31 11:03
36F:→ xam: 然後我猜直接 struct U64 fib[101] 应该也会正常.... 03/31 11:05
发现有意思的地方了...,g=0的时候只要用tmp=fib[-1]再把tmp喂给copy_to_user就不会 触发BUG(),但假如直接喂fib[-1]给copy_to_user就会panic。推测先喂给tmp这边没有检 查是否非法存取所以没事(目前在userspace测试只能往後拿到6KB左右的资料,之後就被 seg fault了,而kernel space是比较有趣的地方,只要我不把往後拿拿到的资料喂给 copy_to_user,我往後-20000 * 16 byte (struct大小为16bytes)都可以拿到,但假如要 传到userspace我只能在stack frame(16KB)内偷资料,只要超过就会被panic,这边很怪 的 地方是kernel怎知道我这tmp里面偷拿了甚至超过stack frame(16KB)的资料,目前猜测是 kernel 自己有个trap之类的机制随时在监测是否有access violation)。 另外我是用GCC编译的。 感谢两位大大,让我知道根本不是array of struct跟struct记忆体配置差别,是我自己 在copy_to_user面前非法存取了哈哈。 ※ 编辑: dces4212 (49.213.161.228), 03/31/2019 21:25:14
37F:→ dces4212: 另外我发现我在g=0 时,fib[1].lsl = 1;这段expression03/31 21:27
38F:→ dces4212: 也非法存取了.. 只是没有panic03/31 21:28
忘记补充一点,刚刚测试发现当g=0的时候我对fib[0]赋值後再使用copy_to_user会发生 copy失败的问题(copy_to_user回传了16 bytes),蛮怪的..,g>0後都可以正常复制。 ※ 编辑: dces4212 (49.213.161.228), 03/31/2019 22:05:31
39F:推 yvb: 触发BUG()就是因为arch_within_stack_frames()回传BAD_STACK.04/04 12:11
40F:→ yvb: 超过16KB被panic: google "虚拟记忆体" "MMU" "分页表" 几项.04/04 12:12
41F:→ yvb: fib[1].lsl = 1 可能写到其它变数(a,tmp,k), 或变数间有空区.04/04 12:12
42F:→ yvb: 至於 fib[0]赋值後 copy失败 ==> 程式码是修改成怎样? 04/04 12:13
程式码几乎一样,一开始是发现g=0时userspace拿到的资料是0(应为1,fib[0]=1),这时 候觉得很奇怪所以就加个if(g=0) {printk(当下的fib[0].msl, lsl 还有copy_to_user的 ret val)},然後发现fib在kernelspace是有拿到1的,还有copy_to_user的ret是16(复制 失败大小,成功应为0),差不多是这样。手机排版,sorry. ※ 编辑: dces4212 (101.10.82.251), 04/05/2019 16:00:31
43F:推 yvb: 所以 g==0 时, 依旧会执行 fib[1].lsl = 1; 的意思?04/09 13:07
44F:→ yvb: 或许上述 assignment 恰巧改写到 copy_to_user(buf, ...) 中 04/09 13:08
45F:→ yvb: buf 的位址? 编译器产生怎样的 obj 不是光看 src 就可得知的.04/09 13:08
46F:→ yvb: 若是已避掉非法存取, 似乎没道理发生问题, 除非编译器有bug?04/09 13:12
没错,fib[1].lsl=1;这段每次都会执行到。刚测试了一下,发现确实是这个assigment去 改到buf的内容,会确定的原因挺诡异的,我最先是在assigment前後放printk看buf的内 容,然後只要我保留那段assigment,我新加的printk就会导致panic,而一旦我把那段 assigment 移掉,printk就正常印出位置了...,看来是非法写入後又尝试读取相关记忆 体导致的,这跟之前说tmp偷到的资料只要不copy_to_user就没事有差不多的概念..,挺 好奇kernel是怎做这个检查的..,因为这不是直接触发BUG(),不知道y大有什麽看法? 感谢大大! ※ 编辑: dces4212 (49.213.161.228), 04/12/2019 03:10:28 ※ 编辑: dces4212 (49.213.161.228), 04/12/2019 03:11:12
47F:推 yvb: 就如前几句说的, obj code 不是光看 src code 就可得知的.04/16 20:26
48F:→ yvb: 或许 objdump -S 搭配 panic 讯息可窥之一二 (也或许不能).04/16 20:27
49F:→ yvb: 另外, 是用什麽参数印 buf? &fib[1].lsl 及 &buf 又各是多少?04/16 20:28
了解,感谢y大。 用的参数是%p, &fib[1].lsl 及 &buf 都落在0x0~0xffffffff间(多次测试)
50F:→ zack2004: 想知道为什麽原PO要用VLA?目的是什麽?04/24 20:54
51F:→ zack2004: Linux kernel目前已禁用VLA。且从需求来看,这函式不需04/24 20:55
52F:→ zack2004: 要不定长度的暂存空间。04/24 20:56
53F:→ zack2004: https://bit.ly/2IJDnyT 04/24 20:57
感谢z大提醒,这是作业,预期是会有不同项的费氏数列输入,并且在计算过程中一一印 出每一项的结果,其实也可以不用VLA来实做的。 ※ 编辑: dces4212 (49.213.161.228), 04/26/2019 05:02:50 ※ 编辑: dces4212 (101.9.132.120), 04/26/2019 05:15:12
54F:→ dces4212: 忽然想到好像不该用%p 04/26 05:23
56F:→ dces4212: -formats.txt 04/26 05:23
57F:→ dces4212: 用px pK可能比较妥 04/26 05:24







like.gif 您可能会有兴趣的文章
icon.png[问题/行为] 猫晚上进房间会不会有憋尿问题
icon.pngRe: [闲聊] 选了错误的女孩成为魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一张
icon.png[心得] EMS高领长版毛衣.墨小楼MC1002
icon.png[分享] 丹龙隔热纸GE55+33+22
icon.png[问题] 清洗洗衣机
icon.png[寻物] 窗台下的空间
icon.png[闲聊] 双极の女神1 木魔爵
icon.png[售车] 新竹 1997 march 1297cc 白色 四门
icon.png[讨论] 能从照片感受到摄影者心情吗
icon.png[狂贺] 贺贺贺贺 贺!岛村卯月!总选举NO.1
icon.png[难过] 羡慕白皮肤的女生
icon.png阅读文章
icon.png[黑特]
icon.png[问题] SBK S1安装於安全帽位置
icon.png[分享] 旧woo100绝版开箱!!
icon.pngRe: [无言] 关於小包卫生纸
icon.png[开箱] E5-2683V3 RX480Strix 快睿C1 简单测试
icon.png[心得] 苍の海贼龙 地狱 执行者16PT
icon.png[售车] 1999年Virage iO 1.8EXi
icon.png[心得] 挑战33 LV10 狮子座pt solo
icon.png[闲聊] 手把手教你不被桶之新手主购教学
icon.png[分享] Civic Type R 量产版官方照无预警流出
icon.png[售车] Golf 4 2.0 银色 自排
icon.png[出售] Graco提篮汽座(有底座)2000元诚可议
icon.png[问题] 请问补牙材质掉了还能再补吗?(台中半年内
icon.png[问题] 44th 单曲 生写竟然都给重复的啊啊!
icon.png[心得] 华南红卡/icash 核卡
icon.png[问题] 拔牙矫正这样正常吗
icon.png[赠送] 老莫高业 初业 102年版
icon.png[情报] 三大行动支付 本季掀战火
icon.png[宝宝] 博客来Amos水蜡笔5/1特价五折
icon.pngRe: [心得] 新鲜人一些面试分享
icon.png[心得] 苍の海贼龙 地狱 麒麟25PT
icon.pngRe: [闲聊] (君の名は。雷慎入) 君名二创漫画翻译
icon.pngRe: [闲聊] OGN中场影片:失踪人口局 (英文字幕)
icon.png[问题] 台湾大哥大4G讯号差
icon.png[出售] [全国]全新千寻侘草LED灯, 水草

请输入看板名称,例如:Soft_Job站内搜寻

TOP