Search code examples
gcclinux-kernelx86-64inline-assemblyatt

Fail to change CS register value from kernel mode. invalid opcode: 0000


From module code with this snippet I'm trying to change the value of CS register:

asm("pushq %rax");
asm("mov $0x10,%rax");
asm("mov %rax,%cs");
asm("popq %rax");

Actually the CS register contains segment selector - $0x10, also this value returned by kernel macro __KERNEL_CS. And what I want to do that is rewrite CS register with exactly the same value. Unfortunately I get error, without the snippet the error is absent.

Aug  1 20:26:37 myhost kernel: [ 2905.693297] invalid opcode: 0000 [#1] SMP 
Aug  1 20:26:37 myhost kernel: [ 2905.694223] CPU: 0 PID: 7140 Comm: insmod Tainted: P           OE   4.4.0-148-generic #174~14.04.1-Ubuntu
Aug  1 20:26:37 myhost kernel: [ 2905.694362] task: ffff88007a0edb00 ti: ffff880068c54000 task.ti: ffff880068c54000
Aug  1 20:26:37 myhost kernel: [ 2905.694420] RIP: 0010:[<ffffffffc114e114>]  [<ffffffffc114e114>] hello_init+0x44/0xe0 [hello_module]
Aug  1 20:26:37 myhost kernel: [ 2905.694497] RSP: 0018:ffff880068c57ca0  EFLAGS: 00010282
Aug  1 20:26:37 myhost kernel: [ 2905.694540] RAX: 0000000000000010 RBX: ffffffff81e15080 RCX: 0000000000005768
Aug  1 20:26:37 myhost kernel: [ 2905.694595] RDX: 000000000000b1e4 RSI: 0000000000000246 RDI: 0000000000000246
Aug  1 20:26:37 myhost kernel: [ 2905.694649] RBP: ffff880068c57cc0 R08: 3231203a657a6973 R09: 6461202c66373a37
Aug  1 20:26:37 myhost kernel: [ 2905.694703] R10: 203a737365726464 R11: 0000000000000363 R12: ffff8800b7e7e980
Aug  1 20:26:37 myhost kernel: [ 2905.694757] R13: 0000000000000000 R14: ffffffffc114e0d0 R15: ffff880068c57eb0
Aug  1 20:26:37 myhost kernel: [ 2905.694813] FS:  00007f8c1c36b740(0000) GS:ffff88013fa00000(0000) knlGS:0000000000000000
Aug  1 20:26:37 myhost kernel: [ 2905.694875] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
Aug  1 20:26:37 myhost kernel: [ 2905.694920] CR2: 00005575a6b20248 CR3: 0000000075efc000 CR4: 0000000000060670
Aug  1 20:26:37 myhost kernel: [ 2905.694975] Stack:
Aug  1 20:26:37 myhost kernel: [ 2905.694995]  0000000000000000 007f000081e15080 ffff88013fa0c000 ffffffff81e15080
Aug  1 20:26:37 myhost kernel: [ 2905.695065]  ffff880068c57d38 ffffffff8100216f ffff880068c57eb0 ffff880068c57d10
Aug  1 20:26:37 myhost kernel: [ 2905.695133]  0000000000000246 0000000000000002 ffffffff811eab7f ffff88013b003c00
Aug  1 20:26:37 myhost kernel: [ 2905.695201] Call Trace:
Aug  1 20:26:37 myhost kernel: [ 2905.695230]  [<ffffffff8100216f>] do_one_initcall+0xcf/0x200
Aug  1 20:26:37 myhost kernel: [ 2905.695281]  [<ffffffff811eab7f>] ? kmem_cache_alloc_trace+0x1af/0x220
Aug  1 20:26:37 myhost kernel: [ 2905.695338]  [<ffffffff8118d293>] ? do_init_module+0x27/0x1d2
Aug  1 20:26:37 myhost kernel: [ 2905.695387]  [<ffffffff8118d2cc>] do_init_module+0x60/0x1d2
Aug  1 20:26:37 myhost kernel: [ 2905.695432]  [<ffffffff8110b42d>] load_module+0x145d/0x1b50
Aug  1 20:26:37 myhost kernel: [ 2905.695480]  [<ffffffff81107b60>] ? __symbol_put+0x40/0x40
Aug  1 20:26:37 myhost kernel: [ 2905.695528]  [<ffffffff812137a1>] ? kernel_read+0x41/0x60
Aug  1 20:26:37 myhost kernel: [ 2905.695574]  [<ffffffff8110bcee>] SYSC_finit_module+0x7e/0xa0
Aug  1 20:26:37 myhost kernel: [ 2905.695620]  [<ffffffff8110bd2e>] SyS_finit_module+0xe/0x10
Aug  1 20:26:37 myhost kernel: [ 2905.697884]  [<ffffffff8182d61b>] entry_SYSCALL_64_fastpath+0x22/0xcb
Aug  1 20:26:37 myhost kernel: [ 2905.700094] Code: eb 03 c0 0f 01 45 ee 0f b7 75 ee 48 8b 4d f0 48 c7 c7 9d f0 14 c1 31 c0 89 f2 e8 73 eb 03 c0 8c 5d ec 41 55 49 c7 c5 10 00 00 00 <49> 8e cd 41 5d 8c 4d ea 0f b7 55 ec 0f b7 75 ea 48 c7 c7 b8 f0 
Aug  1 20:26:37 myhost kernel: [ 2905.704976] RIP  [<ffffffffc114e114>] hello_init+0x44/0xe0 [hello_module]
Aug  1 20:26:37 myhost kernel: [ 2905.707358]  RSP <ffff880068c57ca0>
Aug  1 20:26:37 myhost kernel: [ 2905.719667] ---[ end trace 48f04fe6e7ff0ed6 ]---

Updated with R13 register

Aug  1 21:05:25 myhost kernel: [  146.818158] invalid opcode: 0000 [#1] SMP 
Aug  1 21:05:25 myhost kernel: [  146.818699] CPU: 1 PID: 5108 Comm: insmod Tainted: P           OE   4.4.0-148-generic #174~14.04.1-Ubuntu
Aug  1 21:05:25 myhost kernel: [  146.818778] task: ffff880097a45b00 ti: ffff880085d58000 task.ti: ffff880085d58000
Aug  1 21:05:25 myhost kernel: [  146.818810] RIP: 0010:[<ffffffffc109e114>]  [<ffffffffc109e114>] hello_init+0x44/0xe0 [hello_module]
Aug  1 21:05:25 myhost kernel: [  146.818854] RSP: 0018:ffff880085d5bca0  EFLAGS: 00010282
Aug  1 21:05:25 myhost kernel: [  146.818880] RAX: 000000000000001f RBX: ffffffff81e15080 RCX: 0000000000002298
Aug  1 21:05:25 myhost kernel: [  146.818911] RDX: 00000000000051a2 RSI: 0000000000000246 RDI: 0000000000000246
Aug  1 21:05:25 myhost kernel: [  146.818942] RBP: ffff880085d5bcc0 R08: 3231203a657a6973 R09: 6461202c66373a37
Aug  1 21:05:25 myhost kernel: [  146.818973] R10: 203a737365726464 R11: 0000000000000353 R12: ffff880085cc0b60
Aug  1 21:05:25 myhost kernel: [  146.819004] R13: 0000000000000010 R14: ffffffffc109e0d0 R15: ffff880085d5beb0
Aug  1 21:05:25 myhost kernel: [  146.819037] FS:  00007fd564d44740(0000) GS:ffff88013fa40000(0000) knlGS:0000000000000000
Aug  1 21:05:25 myhost kernel: [  146.819072] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
Aug  1 21:05:25 myhost kernel: [  146.819097] CR2: 0000558a2aa16248 CR3: 0000000085d5c000 CR4: 0000000000060670
Aug  1 21:05:25 myhost kernel: [  146.819128] Stack:
Aug  1 21:05:25 myhost kernel: [  146.819139]  0000000000000000 007f000081e15080 ffff88013fa4c000 ffffffff81e15080
Aug  1 21:05:25 myhost kernel: [  146.819178]  ffff880085d5bd38 ffffffff8100216f ffff880085d5beb0 ffff880085d5bd10
Aug  1 21:05:25 myhost kernel: [  146.819217]  0000000000000246 0000000000000002 ffffffff811eab7f ffff88013b003c00
Aug  1 21:05:25 myhost kernel: [  146.819255] Call Trace:
Aug  1 21:05:25 myhost kernel: [  146.819273]  [<ffffffff8100216f>] do_one_initcall+0xcf/0x200
Aug  1 21:05:25 myhost kernel: [  146.819301]  [<ffffffff811eab7f>] ? kmem_cache_alloc_trace+0x1af/0x220
Aug  1 21:05:25 myhost kernel: [  146.819332]  [<ffffffff8118d293>] ? do_init_module+0x27/0x1d2
Aug  1 21:05:25 myhost kernel: [  146.819359]  [<ffffffff8118d2cc>] do_init_module+0x60/0x1d2
Aug  1 21:05:25 myhost kernel: [  146.819385]  [<ffffffff8110b42d>] load_module+0x145d/0x1b50
Aug  1 21:05:25 myhost kernel: [  146.819412]  [<ffffffff81107b60>] ? __symbol_put+0x40/0x40
Aug  1 21:05:25 myhost kernel: [  146.819440]  [<ffffffff812137a1>] ? kernel_read+0x41/0x60
Aug  1 21:05:25 myhost kernel: [  146.819466]  [<ffffffff8110bcee>] SYSC_finit_module+0x7e/0xa0
Aug  1 21:05:25 myhost kernel: [  146.819492]  [<ffffffff8110bd2e>] SyS_finit_module+0xe/0x10
Aug  1 21:05:25 myhost kernel: [  146.820820]  [<ffffffff8182d61b>] entry_SYSCALL_64_fastpath+0x22/0xcb
Aug  1 21:05:25 myhost kernel: [  146.822117] Code: eb 0e c0 0f 01 45 ee 0f b7 75 ee 48 8b 4d f0 48 c7 c7 9d f0 09 c1 31 c0 89 f2 e8 73 eb 0e c0 8c 5d ec 41 55 49 c7 c5 10 00 00 00 <49> 8e cd 41 5d 8c 4d ea 0f b7 55 ec 0f b7 75 ea 48 c7 c7 b8 f0 
Aug  1 21:05:25 myhost kernel: [  146.824981] RIP  [<ffffffffc109e114>] hello_init+0x44/0xe0 [hello_module]
Aug  1 21:05:25 myhost kernel: [  146.826376]  RSP <ffff880085d5bca0>
Aug  1 21:05:25 myhost kernel: [  146.833469] ---[ end trace 6525f2f63d2f58dd ]---

Solution

  • There is no mov instruction to write to cs. From Intel® 64 and IA-32 architectures software developer’s manual, MOV spec:

    The MOV instruction cannot be used to load the CS register. Attempting to do so results in an invalid opcode exception (#UD).

    You need to do a far jump to change cs, check restrictions in ch.5.8 for changing cs.