2

I tried to hook syscall __x64_sys_execve with kretprobe. So in the entry handler, I tried to get its params, and use strncpy_from_user to get the char* filename, (char**)argv.But after I compiled the module and insmod, nothing new was got from dmesg, and when i tried to removed the module, it was killed and system broke down.

my code:

#ifndef _LARGEFILE64_SOURCE
#define _LARGEFILE64_SOURCE
#endif

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/syscalls.h>
#include <linux/file.h>
#include <linux/fs.h>
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/unistd.h>
#include <asm/pgtable.h>
#include <asm/uaccess.h>
#include <asm/ptrace.h>
#include <linux/kprobes.h>
#include <linux/net.h>
#include <linux/in.h>
/*
** module macros
*/
MODULE_LICENSE("GPL");
MODULE_AUTHOR("sena");
MODULE_DESCRIPTION("hook execve");

#define MAX_LENGTH 256
#define PREDEFINED_RET -2024
#define SUCCESS_RET 1
#define MAX_ARGS 10
#define MAX_ARG_LENGTH 50
typedef struct execve_data_t{
    char filename[MAX_LENGTH];
    char argv[MAX_ARGS][MAX_ARG_LENGTH];
} execve_data_t;
execve_data_t execve_data;

static int sys_execve_kretprobe_entry_handler(struct kretprobe_instance *ri, struct pt_regs *regs){
    memset(&execve_data, 0, sizeof(execve_data));
    struct pt_regs *user_regs;
    user_regs = regs->di;
    char __user* __user* argv_tmp = (char __user* __user*)user_regs->si; //maybe stuck here
    if(strncpy_from_user(execve_data.filename, (char __user*)user_regs->di, sizeof(execve_data.filename)) > 0){
        pr_info("execve filename success\n");
    }
    for(int i = 0 ; i < MAX_ARGS ; i++){
        if(!argv_tmp[i]) break;
        if(strncpy_from_user(execve_data.argv[i], (char __user*)argv_tmp[i], sizeof(execve_data.argv[i])) > 0){
            pr_info("execve argv: %s", execve_data.argv[i]);
        }
        else{
            break;
        }
    }    
    return 0;
}

struct kretprobe syscall_execve_kretprobe = {
    .kp.symbol_name = "__x64_sys_execve",
    .entry_handler = sys_execve_kretprobe_entry_handler,
    .maxactive = 20,  // Maximum number of concurrent probes
};

static int __init audit_init(void)
{
    int err = 0;
    err += register_kretprobe(&syscall_execve_kretprobe);
    if (err) {
        pr_err("register_kprobe() failed: %d\n", err);
        return err;
    }
    else{
        pr_info("register_kprobe() init: %d\n", err);
    }
    return 0;
}


static void __exit audit_exit(void)
{
    unregister_kretprobe(&syscall_execve_kretprobe);
    pr_info("kprobe unregistered\n");
}

module_init(audit_init);
module_exit(audit_exit);

I guess that the problem is all about argv, since if i replace the entry_handler with:

static int sys_execve_kretprobe_entry_handler(struct kretprobe_instance *ri, struct pt_regs *regs){
    memset(&execve_data, 0, sizeof(execve_data));
    struct pt_regs *user_regs;
    user_regs = regs->di;
    if(strncpy_from_user(execve_data.filename, (char __user*)user_regs->di, sizeof(execve_data.filename)) > 0){
        pr_info("execve filename success\n");
    }  
    return 0;
}

then it works well with filename.

I got an err in dmesg

[   77.019298] execve filename success
[   77.019307] BUG: unable to handle page fault for address: 0000212400c64d20
[   77.019312] #PF: supervisor read access in kernel mode
[   77.019315] #PF: error_code(0x0001) - permissions violation
[   77.019318] PGD 7ae64067 P4D 7ae64067 PUD 3131d067 PMD 5239067 PTE 8000000091a8e845
[   77.019327] Oops: 0001 [#1] PREEMPT SMP NOPTI
[   77.019364] CPU: 0 PID: 4118 Comm: code Tainted: G           OE      6.5.0-41-generic #41~22.04.2-Ubuntu
[   77.019369] Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform, BIOS 6.00 07/22/2020
[   77.019371] RIP: 0010:sys_execve_kretprobe_entry_handler+0x5d/0xf0 [AuditModule]
[   77.019384] Code: 8b 46 70 48 8b 70 70 4c 8b 68 68 e8 8d 0a f9 c0 48 85 c0 7e 0c 48 c7 c7 86 c1 93 c0 e8 fc f4 86 c0 49 c7 c4 00 8f 93 c0 31 db <4d> 8b 75 00 4d 85 f6 74 43 4c 63 fb 49 83 ff 0a 77 53 ba 14 00 00
[   77.019387] RSP: 0018:ffffc90005547cb0 EFLAGS: 00010246
[   77.019391] RAX: 0000000000000017 RBX: 0000000000000000 RCX: 0000000000000000
[   77.019393] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000
[   77.019395] RBP: ffffc90005547cd8 R08: 0000000000000000 R09: 0000000000000000
[   77.019398] R10: 0000000000000000 R11: 0000000000000000 R12: ffffffffc0938f00
[   77.019400] R13: 0000212400c64d20 R14: ffffffffc09382e0 R15: ffff888139e1fec0
[   77.019403] FS:  00007b20a38b8e80(0000) GS:ffff888139e00000(0000) knlGS:0000000000000000
[   77.019405] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[   77.019408] CR2: 0000212400c64d20 CR3: 000000000518c000 CR4: 00000000003506f0
[   77.019412] Call Trace:
[   77.019415]  <TASK>
[   77.019420]  ? show_regs+0x6d/0x80
[   77.019453]  ? __die+0x24/0x80
[   77.019458]  ? page_fault_oops+0x99/0x1b0
[   77.019476]  ? do_user_addr_fault+0x31d/0x6b0
[   77.019479]  ? srso_alias_return_thunk+0x5/0x7f
[   77.019497]  ? exc_page_fault+0x83/0x1b0
[   77.019503]  ? asm_exc_page_fault+0x27/0x30
[   77.019535]  ? sys_execve_kretprobe_entry_handler+0x5d/0xf0 [AuditModule]
[   77.019543]  pre_handler_kretprobe+0x3f/0xa0
[   77.019549]  ? __x64_sys_execve+0x1/0x60
[   77.019568]  kprobe_ftrace_handler+0x125/0x240
[   77.019584]  ? __x64_sys_execve+0x5/0x60
[   77.019588]  0xffffffffc09430f7
[   77.019612] RIP: 0010:__x64_sys_execve+0x1/0x60
[   77.019615] Code: ff 45 31 c0 45 31 c9 e9 ad 0f c8 00 66 66 2e 0f 1f 84 00 00 00 00 00 66 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 e8 <cb> 12 48 3f 55 48 89 e5 41 54 53 4c 8b 67 60 48 8b 5f 68 48 8b 7f
[   77.019618] RSP: 0018:ffffc90005547e30 EFLAGS: 00000202 ORIG_RAX: 0000000000000000
[   77.019622] RAX: 000000000000003b RBX: ffffc90005547f58 RCX: 0000000000000000
[   77.019624] RDX: ffffffffffffffff RSI: 000000000000003b RDI: ffffc90005547f58
[   77.019627] RBP: ffffc90005547e38 R08: 0000000000000000 R09: 0000000000000000
[   77.019629] R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000000
[   77.019631] R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000
[   77.019637]  ? __x64_sys_execve+0x5/0x60
[   77.019640]  ? x64_sys_call+0x7a3/0x20b0
[   77.019676]  ? __x64_sys_execve+0x5/0x60
[   77.019679]  ? x64_sys_call+0x7a3/0x20b0
[   77.019682]  do_syscall_64+0x55/0x90
[   77.019686]  ? srso_alias_return_thunk+0x5/0x7f
[   77.019690]  ? __count_memcg_events+0x7d/0x110
[   77.019713]  ? srso_alias_return_thunk+0x5/0x7f
[   77.019716]  ? count_memcg_events.constprop.0+0x2a/0x50
[   77.019722]  ? srso_alias_return_thunk+0x5/0x7f
[   77.019725]  ? handle_mm_fault+0xad/0x360
[   77.019730]  ? srso_alias_return_thunk+0x5/0x7f
[   77.019733]  ? do_user_addr_fault+0x238/0x6b0
[   77.019748]  ? srso_alias_return_thunk+0x5/0x7f
[   77.019752]  ? exit_to_user_mode_prepare+0x30/0xb0
[   77.019768]  ? srso_alias_return_thunk+0x5/0x7f
[   77.019771]  ? irqentry_exit_to_user_mode+0x17/0x20
[   77.019775]  ? srso_alias_return_thunk+0x5/0x7f
[   77.019778]  ? irqentry_exit+0x43/0x50
[   77.019782]  ? srso_alias_return_thunk+0x5/0x7f
[   77.019784]  ? exc_page_fault+0x94/0x1b0
[   77.019787]  entry_SYSCALL_64_after_hwframe+0x73/0xdd
[   77.019789] RIP: 0033:0x7b20a470117b
[   77.019794] 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 e5 8c 10 00 f7 d8 64 89 01 48
[   77.019796] RSP: 002b:00007ffd6725eb78 EFLAGS: 00000202 ORIG_RAX: 000000000000003b
[   77.019798] RAX: ffffffffffffffda RBX: 0000212400c64d20 RCX: 00007b20a470117b
[   77.019799] RDX: 000021240083d200 RSI: 0000212400c64d20 RDI: 00007ffd6725f770
[   77.019801] RBP: 00007ffd6725ec00 R08: 00007ffd6725ec10 R09: 0000000000000000
[   77.019802] R10: 0000000000000008 R11: 0000000000000202 R12: 000021240083d200
[   77.019804] R13: 00007ffd6725f770 R14: 00007ffd6725ec10 R15: 00007ffd6725ede0
[   77.019808]  </TASK>
[   77.019809] Modules linked in: AuditModule(OE) isofs bnep intel_rapl_msr vsock_loopback vmw_vsock_virtio_transport_common vmw_vsock_vmci_transport vsock vmw_balloon snd_ens1371 snd_ac97_codec gameport ac97_bus snd_pcm binfmt_misc intel_rapl_common nls_iso8859_1 crct10dif_pclmul polyval_clmulni polyval_generic ghash_clmulni_intel sha256_ssse3 sha1_ssse3 snd_seq_midi aesni_intel crypto_simd cryptd snd_seq_midi_event snd_rawmidi snd_seq snd_seq_device joydev input_leds serio_raw snd_timer btusb btrtl btbcm btintel btmtk snd bluetooth ecdh_generic ecc soundcore vmw_vmci mac_hid sch_fq_codel vmwgfx drm_ttm_helper ttm drm_kms_helper msr parport_pc ppdev lp parport drm efi_pstore ip_tables x_tables autofs4 hid_generic crc32_pclmul psmouse usbhid hid ahci e1000 libahci mptspi mptscsih mptbase scsi_transport_spi i2c_piix4 pata_acpi
[   77.019885] CR2: 0000212400c64d20
[   77.019887] ---[ end trace 0000000000000000 ]---
[   77.019889] RIP: 0010:sys_execve_kretprobe_entry_handler+0x5d/0xf0 [AuditModule]
[   77.019893] Code: 8b 46 70 48 8b 70 70 4c 8b 68 68 e8 8d 0a f9 c0 48 85 c0 7e 0c 48 c7 c7 86 c1 93 c0 e8 fc f4 86 c0 49 c7 c4 00 8f 93 c0 31 db <4d> 8b 75 00 4d 85 f6 74 43 4c 63 fb 49 83 ff 0a 77 53 ba 14 00 00
[   77.019904] RSP: 0018:ffffc90005547cb0 EFLAGS: 00010246
[   77.019906] RAX: 0000000000000017 RBX: 0000000000000000 RCX: 0000000000000000
[   77.019908] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000
[   77.019909] RBP: ffffc90005547cd8 R08: 0000000000000000 R09: 0000000000000000
[   77.019911] R10: 0000000000000000 R11: 0000000000000000 R12: ffffffffc0938f00
[   77.019912] R13: 0000212400c64d20 R14: ffffffffc09382e0 R15: ffff888139e1fec0
[   77.019914] FS:  00007b20a38b8e80(0000) GS:ffff888139e00000(0000) knlGS:0000000000000000
[   77.019915] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[   77.019917] CR2: 0000212400c64d20 CR3: 000000000518c000 CR4: 00000000003506f0
[   77.019920] note: code[4118] exited with irqs disabled
[   77.019938] note: code[4118] exited with preempt_count 1
[   77.034386] execve filename success
[   77.034396] BUG: unable to handle page fault for address: 00005e44508637b8
[   77.034399] #PF: supervisor read access in kernel mode
[   77.034401] #PF: error_code(0x0001) - permissions violation
[   77.034403] PGD 5209067 P4D 5209067 PUD b18cc067 PMD b18cb067 PTE 80000000b62d6867
[   77.034409] Oops: 0001 [#2] PREEMPT SMP NOPTI
[   77.034412] CPU: 1 PID: 4125 Comm: ps.sh Tainted: G      D    OE      6.5.0-41-generic #41~22.04.2-Ubuntu
[   77.034415] Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform, BIOS 6.00 07/22/2020
[   77.034417] RIP: 0010:sys_execve_kretprobe_entry_handler+0x5d/0xf0 [AuditModule]
[   77.034426] Code: 8b 46 70 48 8b 70 70 4c 8b 68 68 e8 8d 0a f9 c0 48 85 c0 7e 0c 48 c7 c7 86 c1 93 c0 e8 fc f4 86 c0 49 c7 c4 00 8f 93 c0 31 db <4d> 8b 75 00 4d 85 f6 74 43 4c 63 fb 49 83 ff 0a 77 53 ba 14 00 00
[   77.034464] RSP: 0018:ffffc90002717d10 EFLAGS: 00010246
[   77.034466] RAX: 0000000000000017 RBX: 0000000000000000 RCX: 0000000000000000
[   77.034468] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000
[   77.034469] RBP: ffffc90002717d38 R08: 0000000000000000 R09: 0000000000000000
[   77.034471] R10: 0000000000000000 R11: 0000000000000000 R12: ffffffffc0938f00
[   77.034472] R13: 00005e44508637b8 R14: ffffffffc09382e0 R15: ffff888139e5fec0
[   77.034474] FS:  00007f69d5c19740(0000) GS:ffff888139e40000(0000) knlGS:0000000000000000
[   77.034476] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[   77.034478] CR2: 00005e44508637b8 CR3: 000000006d7f0000 CR4: 00000000003506e0
[   77.034481] Call Trace:
[   77.034483]  <TASK>
[   77.034486]  ? show_regs+0x6d/0x80
[   77.034493]  ? __die+0x24/0x80
[   77.034496]  ? page_fault_oops+0x99/0x1b0
[   77.034501]  ? do_user_addr_fault+0x31d/0x6b0
[   77.034504]  ? srso_alias_return_thunk+0x5/0x7f
[   77.034510]  ? exc_page_fault+0x83/0x1b0
[   77.034514]  ? asm_exc_page_fault+0x27/0x30
[   77.034521]  ? sys_execve_kretprobe_entry_handler+0x5d/0xf0 [AuditModule]
[   77.034526]  pre_handler_kretprobe+0x3f/0xa0
[   77.034531]  ? __x64_sys_execve+0x1/0x60
[   77.034535]  kprobe_ftrace_handler+0x125/0x240
[   77.034540]  ? __x64_sys_execve+0x5/0x60
[   77.034543]  0xffffffffc09430f7
[   77.034593] RIP: 0010:__x64_sys_execve+0x1/0x60
[   77.034615] Code: ff 45 31 c0 45 31 c9 e9 ad 0f c8 00 66 66 2e 0f 1f 84 00 00 00 00 00 66 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 e8 <cb> 12 48 3f 55 48 89 e5 41 54 53 4c 8b 67 60 48 8b 5f 68 48 8b 7f
[   77.034616] RSP: 0018:ffffc90002717e90 EFLAGS: 00000202 ORIG_RAX: 0000000000000000
[   77.034620] RAX: 000000000000003b RBX: ffffc90002717f58 RCX: 0000000000000000
[   77.034622] RDX: ffffffffffffffff RSI: 000000000000003b RDI: ffffc90002717f58
[   77.034623] RBP: ffffc90002717e98 R08: 0000000000000000 R09: 0000000000000000
[   77.034625] R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000000
[   77.034626] R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000
[   77.034630]  ? __x64_sys_execve+0x5/0x60
[   77.034632]  ? x64_sys_call+0x7a3/0x20b0
[   77.034636]  ? __x64_sys_execve+0x5/0x60
[   77.034638]  ? x64_sys_call+0x7a3/0x20b0
[   77.034640]  do_syscall_64+0x55/0x90
[   77.034646]  ? srso_alias_return_thunk+0x5/0x7f
[   77.034674]  ? do_user_addr_fault+0x238/0x6b0
[   77.034677]  ? srso_alias_return_thunk+0x5/0x7f
[   77.034679]  ? exit_to_user_mode_prepare+0x30/0xb0
[   77.034687]  ? srso_alias_return_thunk+0x5/0x7f
[   77.034689]  ? irqentry_exit_to_user_mode+0x17/0x20
[   77.034693]  ? srso_alias_return_thunk+0x5/0x7f
[   77.034696]  ? irqentry_exit+0x43/0x50
[   77.034698]  ? srso_alias_return_thunk+0x5/0x7f
[   77.034700]  ? exc_page_fault+0x94/0x1b0
[   77.034703]  entry_SYSCALL_64_after_hwframe+0x73/0xdd
[   77.034706] RIP: 0033:0x7f69d58eb08b
[   77.034710] Code: f8 01 0f 8e bd fe ff ff 5b 48 8d 3d 4f 6a 13 00 5d 41 5c e9 87 62 fa ff 0f 1f 80 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 75 ed 12 00 f7 d8 64 89 01 48
[   77.034712] RSP: 002b:00007ffd1b60e5c8 EFLAGS: 00000246 ORIG_RAX: 000000000000003b
[   77.034714] RAX: ffffffffffffffda RBX: 00005e44508637b8 RCX: 00007f69d58eb08b
[   77.034716] RDX: 00005e4451fba498 RSI: 00005e44508637b8 RDI: 00005e4451fba750
[   77.034717] RBP: 00005e445085c027 R08: 00005e445085c1ff R09: 00005e4451fba490
[   77.034719] R10: 0000000000000000 R11: 0000000000000246 R12: 00005e4451fba498
[   77.034720] R13: 00007ffd1b60e6b8 R14: 00005e4451fba498 R15: 00005e4451fba750
[   77.034724]  </TASK>
[   77.034726] Modules linked in: AuditModule(OE) isofs bnep intel_rapl_msr vsock_loopback vmw_vsock_virtio_transport_common vmw_vsock_vmci_transport vsock vmw_balloon snd_ens1371 snd_ac97_codec gameport ac97_bus snd_pcm binfmt_misc intel_rapl_common nls_iso8859_1 crct10dif_pclmul polyval_clmulni polyval_generic ghash_clmulni_intel sha256_ssse3 sha1_ssse3 snd_seq_midi aesni_intel crypto_simd cryptd snd_seq_midi_event snd_rawmidi snd_seq snd_seq_device joydev input_leds serio_raw snd_timer btusb btrtl btbcm btintel btmtk snd bluetooth ecdh_generic ecc soundcore vmw_vmci mac_hid sch_fq_codel vmwgfx drm_ttm_helper ttm drm_kms_helper msr parport_pc ppdev lp parport drm efi_pstore ip_tables x_tables autofs4 hid_generic crc32_pclmul psmouse usbhid hid ahci e1000 libahci mptspi mptscsih mptbase scsi_transport_spi i2c_piix4 pata_acpi
[   77.034814] CR2: 00005e44508637b8
[   77.034817] ---[ end trace 0000000000000000 ]---
[   77.034818] RIP: 0010:sys_execve_kretprobe_entry_handler+0x5d/0xf0 [AuditModule]
[   77.034823] Code: 8b 46 70 48 8b 70 70 4c 8b 68 68 e8 8d 0a f9 c0 48 85 c0 7e 0c 48 c7 c7 86 c1 93 c0 e8 fc f4 86 c0 49 c7 c4 00 8f 93 c0 31 db <4d> 8b 75 00 4d 85 f6 74 43 4c 63 fb 49 83 ff 0a 77 53 ba 14 00 00
[   77.034824] RSP: 0018:ffffc90005547cb0 EFLAGS: 00010246
[   77.034826] RAX: 0000000000000017 RBX: 0000000000000000 RCX: 0000000000000000
[   77.034828] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000
[   77.034829] RBP: ffffc90005547cd8 R08: 0000000000000000 R09: 0000000000000000
[   77.034831] R10: 0000000000000000 R11: 0000000000000000 R12: ffffffffc0938f00
[   77.034832] R13: 0000212400c64d20 R14: ffffffffc09382e0 R15: ffff888139e1fec0
[   77.034834] FS:  00007f69d5c19740(0000) GS:ffff888139e40000(0000) knlGS:0000000000000000
[   77.034836] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[   77.034837] CR2: 00005e44508637b8 CR3: 000000006d7f0000 CR4: 00000000003506e0
[   77.034840] note: ps.sh[4125] exited with irqs disabled
[   77.034869] note: ps.sh[4125] exited with preempt_count 1

My system: Ubuntu22.04 on VMWare

Kernel: 6.5.0-41-generic

3
  • "If this line is added, then i have an overflow warning in dmesg" - What exact warning do you get? That line just reads the field si of the struct user_regs; such reading shouldn't emit any warning at runtime. BTW, the actual type of the argv parameter of execve syscall is char __user* __user*. Why do you define the variable argv_tmp with incompatible type char**? (Linux kernel introduces __user specifier with the purpose to detect incorrect dereferences of a pointer to user-space area. You suppress such detection and wonder why you code doesn't work.)
    – Tsyvarev
    Commented Jul 7 at 12:03
  • @Tsyvarev I've corrected the mistake of the incompatible type. But still doesn't work. In fact I've tried the compatible one before.The problem should lie in the loop strncopy after pr_info("execve filename success\n");
    – sena
    Commented Jul 7 at 15:57
  • "The problem should lie in the loop strncopy" - Actually, there is no needs to guess here. The call trace contains the line sys_execve_kretprobe_entry_handler+0x5d/0xf0 [AuditModule]. You need to find out which instruction has offset 0x5d from the start of your function. For resolve the offset you could use objdump or addr2line utility for your module (.ko file).
    – Tsyvarev
    Commented Jul 7 at 16:07

1 Answer 1

0

The problem is: It's illegal to directly read a char __user* pointer with argv_tmp[i], since the address is in user space, so I should first copy argv_tmp[i] with the offset from argv_tmp and copy_from_user(). Till this time, the data (argv_tmp[i]) is in kernel space, and then use strncpy_from_user() to get that string

The final code should be:

static int sys_execve_kretprobe_entry_handler(struct kretprobe_instance *ri, struct pt_regs *regs){
    execve_data_t* tmp = (execve_data_t*)ri->data;
    struct pt_regs* user_regs = regs->di;
    char __user* __user* argv_tmp = (char __user* __user*)user_regs->si;
    if(strncpy_from_user(tmp->filename, (char __user*)user_regs->di, sizeof(tmp->filename)) > 0){
        pr_info("execve filename success%s\n", tmp->filename);
    }
    char __user** tmp_ptr;
    tmp_ptr = kmalloc(sizeof(char __user*), GFP_KERNEL);
    for(int i = 0 ; i < MAX_ARGS ; i++){
        copy_from_user(tmp_ptr, (char __user**)argv_tmp + i, sizeof(char __user*));
        pr_info("copy_from_user: ");
        if(strncpy_from_user(tmp->argv[i], *tmp_ptr, sizeof(tmp->argv[i])) > 0){
            pr_info("execve argv: %s", tmp->argv[i]);
        }
        else{
            break;
        }
    }
    kfree(tmp_ptr);
    return 0;
}
3
  • What do you think kmalloc(sizeof(char __user*), GFP_KERNEL); do? Allocating 8 bytes from heap is pointless. Commented Jul 8 at 14:28
  • @Employed Russian The allocation,8 bytes of space in kernel space, is used to load (char __user*)argv[i] with copy_from_user into kernel space so that it would be legal to access that pointer in the kernel address space. Directly using argv[i] to visit (char __user*)argv[i] is illegal because the address of the pointer is still in the user space(an offset from argv), and that will cause access error in a kernel module.
    – sena
    Commented Jul 9 at 6:57
  • 2
    You can very well do char __user *tmp_ptr; and then copy_from_user(&tmp_ptr, ...). No need at all to kmalloc() a single pointer. Commented Jul 9 at 10:19

Not the answer you're looking for? Browse other questions tagged or ask your own question.