Messages in this thread | | | From | THOBY Simon <> | Subject | kernel BUG on public_key_verify_signature with CONFIG_VMAP_STACK and CONFIG_DEBUG_SG | Date | Fri, 16 Jul 2021 13:14:24 +0000 |
| |
Hello,
I cannot use IMA digital signatures with CONFIG_VMAP_STACK if some kernel debugging options are selected (namely CONFIG_DEBUG_SG and/or CONFIG_DEBUG_VIRTUAL).
When taking a look at public_key_verify_signature() definition in crypto/asymmetric_keys/public_key.c, we can see the following code:
struct scatterlist src_sg[2]; [...] sg_init_table(src_sg, 2); sg_set_buf(&src_sg[0], sig->s, sig->s_size); sg_set_buf(&src_sg[1], sig->digest, sig->digest_size); akcipher_request_set_crypt(req, src_sg, NULL, sig->s_size, sig->digest_size);
While this code runs perfectly fine with kernels packaged by distributors, they do not enable CONFIG_DEBUG_VIRTUAL nor CONFIG_DEBUG_SG. When enabling either of these options with CONFIG_VMAP_STACK, it triggers a kernel BUG() when trying to measure a signed file. BUG() result below:
[ 7583.382625] kernel BUG at include/linux/scatterlist.h:137! [ 7583.382684] invalid opcode: 0000 [#1] SMP NOPTI [ 7583.382732] CPU: 3 PID: 2219 Comm: bash Not tainted 5.13.0-vanilla.viveris.x86_64 #1 [ 7583.382804] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 0.0.0 02/06/2015 [ 7583.382878] RIP: 0010:public_key_verify_signature+0x3be/0x3d0 [ 7583.382944] Code: e9 6f ff ff ff 0f 0b 4c 89 ef e8 3d 37 cb ff 4c 89 e6 4c 89 e7 e8 f2 79 fd ff b8 f4 ff ff ff e9 50 ff ff ff 0f 0b 0f 0b 0f 0b <0f> 0b 0f 0b e8 a9 21 64 00 66 0f 1f 84 00 00 00 00 00 0f 1f 44 00 [ 7583.383099] RSP: 0018:ffffa773c08f7930 EFLAGS: 00010246 [ 7583.383143] RAX: 0000000000000000 RBX: 0000000000000020 RCX: 0000000000000028 [ 7583.383198] RDX: 0000171ec08f7b38 RSI: 0000000000000017 RDI: ffffa774408f7b38 [ 7583.383260] RBP: ffffa773c08f7a70 R08: 0000000000000000 R09: ffffa773c08f7960 [ 7583.383314] R10: 000000000000000a R11: 0000000000000004 R12: ffff905602ba9e80 [ 7583.383356] R13: ffff905601131600 R14: ffff90560153aa00 R15: ffffa773c08f7b38 [ 7583.383397] FS: 00007ff25b9de740(0000) GS:ffff90567b980000(0000) knlGS:0000000000000000 [ 7583.383455] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 7583.383489] CR2: 0000561db1b06b88 CR3: 0000000103702002 CR4: 0000000000770ee0 [ 7583.383554] PKRU: 55555554 [ 7583.383573] Call Trace: [ 7583.383607] ? kfree+0xd6/0x420 [ 7583.383632] ? keyring_search+0xc2/0xf0 [ 7583.383661] ? asymmetric_key_match_preparse+0x90/0x90 [ 7583.383696] ? key_default_cmp+0x20/0x20 [ 7583.383727] asymmetric_verify+0x13f/0x310 [ 7583.383757] evm_verify_hmac+0x23b/0x2e0 [ 7583.383785] ima_appraise_measurement+0x799/0x7f0 [ 7583.383817] process_measurement+0x728/0x920 [ 7583.383846] ? avc_has_perm+0xc4/0x1d0 [ 7583.383874] ? __kernel_read+0x19b/0x2c0 [ 7583.383902] ? __kernel_read+0x19b/0x2c0 [ 7583.383929] ima_bprm_check+0x55/0xb0 [ 7583.383954] bprm_execve+0x29b/0x5b0 [ 7583.383979] do_execveat_common.isra.39+0x199/0x1c0 [ 7583.384012] __x64_sys_execve+0x32/0x40 [ 7583.384038] do_syscall_64+0x5a/0x70 [ 7583.384066] ? do_user_addr_fault+0x1ce/0x640 [ 7583.384095] ? do_syscall_64+0x69/0x70 [ 7583.384121] ? exc_page_fault+0x7f/0x170 [ 7583.384149] entry_SYSCALL_64_after_hwframe+0x44/0xae [ 7583.384182] RIP: 0033:0x7ff25b09005b [ 7583.385275] Code: 41 89 01 eb da 66 2e 0f 1f 84 00 00 00 00 00 f7 d8 64 41 89 01 eb d6 0f 1f 84 00 00 00 00 00 f3 0f 1e fa b8 3b 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d fd 5d 2f 00 f7 d8 64 89 01 48 [ 7583.387623] RSP: 002b:00007fffa3461d78 EFLAGS: 00000246 ORIG_RAX: 000000000000003b [ 7583.388801] RAX: ffffffffffffffda RBX: 0000561db1b20020 RCX: 00007ff25b09005b [ 7583.389976] RDX: 0000561db1a51b40 RSI: 0000561db1b06b80 RDI: 0000561db1b20020 [ 7583.391193] RBP: 0000000000000000 R08: 0000000000000000 R09: 0000000000000001 [ 7583.392288] R10: 0000000000000008 R11: 0000000000000246 R12: 0000561db1b20020 [ 7583.393209] R13: 0000561db1b06b80 R14: 0000561db1a51b40 R15: 0000561db194d880 [ 7583.394121] Modules linked in: nft_fib_inet nft_fib_ipv4 nft_fib_ipv6 nft_fib nft_reject_inet nf_reject_ipv4 nf_reject_ipv6 nft_reject nft_ct nft_chain_nat nf_nat nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 rfkill ip_set nf_tables nfnetlink vfat fat intel_rapl_msr intel_rapl_common kvm_intel kvm ppdev irqbypass iTCO_wdt intel_pmc_bxt iTCO_vendor_support parport_pc parport joydev pcspkr i2c_i801 lpc_ich i2c_smbus dm_crypt xfs bochs_drm drm_vram_helper drm_kms_helper crct10dif_pclmul cec drm_ttm_helper crc32_pclmul ttm crc32c_intel drm ghash_clmulni_intel serio_raw virtio_net net_failover virtio_blk failover qemu_fw_cfg fuse [ 7583.398129] ---[ end trace 42ba5ecbb402c663 ]--- [ 7583.398798] RIP: 0010:public_key_verify_signature+0x3be/0x3d0 [ 7583.399256] Code: e9 6f ff ff ff 0f 0b 4c 89 ef e8 3d 37 cb ff 4c 89 e6 4c 89 e7 e8 f2 79 fd ff b8 f4 ff ff ff e9 50 ff ff ff 0f 0b 0f 0b 0f 0b <0f> 0b 0f 0b e8 a9 21 64 00 66 0f 1f 84 00 00 00 00 00 0f 1f 44 00 [ 7583.400187] RSP: 0018:ffffa773c08f7930 EFLAGS: 00010246 [ 7583.400734] RAX: 0000000000000000 RBX: 0000000000000020 RCX: 0000000000000028 [ 7583.401200] RDX: 0000171ec08f7b38 RSI: 0000000000000017 RDI: ffffa774408f7b38 [ 7583.401695] RBP: ffffa773c08f7a70 R08: 0000000000000000 R09: ffffa773c08f7960 [ 7583.402044] R10: 000000000000000a R11: 0000000000000004 R12: ffff905602ba9e80 [ 7583.402425] R13: ffff905601131600 R14: ffff90560153aa00 R15: ffffa773c08f7b38 [ 7583.402775] FS: 00007ff25b9de740(0000) GS:ffff90567b980000(0000) knlGS:0000000000000000 [ 7583.403121] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 7583.403511] CR2: 0000561db1b06b88 CR3: 0000000103702002 CR4: 0000000000770ee0 [ 7583.403868] PKRU: 55555554 [ 7583.591257] BUG: Bad rss-counter state mm:00000000085d4bcd type:MM_ANONPAGES val:1
This BUG() was collected on a vanilla 5.13.0 kernel, and I can confirm I also ran into this with 5.14.0-rc1. I'm afraid I don't have a simple reproducer here, as it currently involves building the kernel with CONFIG DEBUG_SG, enabling IMA digital signatures and running any signed file. That said, there are probably other users of skcipher with on-stack addresses and they should experience the same problem.
Variants of this bug are already known as it was identified and explained back in 2016: http://lkml.iu.edu/hypermail/linux/kernel/1612.1/01472.html It was explained again in another mail by Andy Lutomirski 6 months later: https://seclists.org/oss-sec/2017/q2/600
Other commits also referenced the limitations of using scatterlist on the stack, like 5a3235e50c0e3219d8659cbec996dae960acfee8 (net: phy: mscc: avoid skcipher API for single block AES encryption) that say: "Note that the scatterlist API does not permit references to buffers that are located on the stack, so the existing code is incorrect in any case, but avoiding the skcipher and scatterlist APIs entirely is the most straight-forward approach to fixing this."
As a quick TL:DR; from what I could gather of the above exchanges, scatter-gather operations are theoretically not usable on the stack as they expect the memory addresses they manipulate to be convertible to physical addresses and back (by adding/subtracting PAGE_OFFSET). That doesn't work very well when CONFIG_VMAP_STACK is in use: the physical address obtained through this process is invalid. However, because the two operations (virt_to_page/page_address) are inverse of each other, and the (invalid) physical address is not used directly anywhere, it works in pratice! At least, it works as long as you do not enable CONFIG_DEBUG_SG and/or CONFIG_DEBUG_VIRTUAL, as they will BUG() on invalid physical addresses, even if those addresses are never dereferenced. As a consequence, it appears one cannot use IMA with digital signatures if both VMAP_STACK and (DEBUG_SC || DEBUG_VIRTUAL) are enabled.
I was wondering if this behavior was considered correct and if there was some official guidance on enabling DEBUG_SG/DEBUG_VIRTUAL for "hardened" Linux systems? Do you believe I should just disable DEBUG_SG and DEBUG_VIRTUAL ?
Note: I CC'ed Andy Lutomirski as he was the main developer of CONFIG_VMAP_STACK and he identified this problem in the past. I did not CC linux-integrity because while it occurs when using IMA, the code triggering the bug appears to be part of the crypto subsystem.
Thanks, Simon | |