How to modify a 'struct msghdr' in Linux Kernel Module?

52 Views Asked by At

I want to implement a new transport layer protocol above UDP in Linux. To send a datagram, I registered my rudp_sendmsg like this:

int rudp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
{
    struct RUDP_header hdr = {
        .seq = 12345,
        .ack = 23456,
        .len = len,
    };
    int hlen = sizeof(hdr);
    void *ubuf = msg->msg_iter.ubuf;
    memcpy(ubuf+hlen,ubuf,len);
    memcpy(ubuf,&hdr,len);
    return udp_prot.sendmsg(sk,msg,len+hlen);
}

Before sending a datagram through UDP, I want to insert a my RUDP_header in front of msg(the app data), but i does'nt work, this is what the dmesg command shows:

[  235.256131] BUG: unable to handle page fault for address: 00007ffd0047db50
[  235.256140] #PF: supervisor read access in kernel mode
[  235.256142] #PF: error_code(0x0001) - permissions violation
[  235.256144] PGD 1156e5067 P4D 1156e5067 PUD 1088c1067 PMD 108725067 PTE 800000012d61c867
[  235.256151] Oops: 0001 [#1] PREEMPT SMP NOPTI
[  235.256155] CPU: 2 PID: 4678 Comm: client Tainted: G           OE      6.5.0-26-generic #26~22.04.1-Ubuntu
[  235.256159] Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform, BIOS 6.00 11/12/2020
[  235.256161] RIP: 0010:memcpy_orig+0x8c/0x130
[  235.256167] Code: 5e e0 48 8d 76 e0 4c 89 47 f8 4c 89 4f f0 4c 89 57 e8 4c 89 5f e0 48 8d 7f e0 73 d2 83 c2 20 48 29 d6 48 29 d7 83 fa 10 72 34 <4c> 8b 06 4c 8b 4e 08 4c 8b 54 16 f0 4c 8b 5c 16 f8 4c 89 07 4c 89
[  235.256170] RSP: 0018:ffffb42403a7bce0 EFLAGS: 00010202
[  235.256173] RAX: 00007ffd0047db5e RBX: 000000000000001b RCX: 0000000000000000
[  235.256175] RDX: 000000000000001b RSI: 00007ffd0047db50 RDI: 00007ffd0047db5e
[  235.256177] RBP: ffffb42403a7bd20 R08: 0000000000000000 R09: 0000000000000000
[  235.256179] R10: 0000000000000000 R11: 0000000000000000 R12: ffffb42403a7bd78
[  235.256182] R13: ffff8ee008c12d00 R14: 00007ffd0047db50 R15: ffffb42403a7bde0
[  235.256184] FS:  00007f03baab03c0(0000) GS:ffff8ee039e80000(0000) knlGS:0000000000000000
[  235.256187] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[  235.256189] CR2: 00007ffd0047db50 CR3: 000000010345e000 CR4: 0000000000350ee0
[  235.256207] Call Trace:
[  235.256210]  <TASK>
[  235.256215]  ? show_regs+0x6d/0x80
[  235.256222]  ? __die+0x24/0x80
[  235.256226]  ? page_fault_oops+0x99/0x1b0
[  235.256231]  ? do_user_addr_fault+0x31d/0x6b0
[  235.256233]  ? srso_return_thunk+0x5/0x10
[  235.256238]  ? sock_i_uid+0x3a/0x50
[  235.256243]  ? exc_page_fault+0x83/0x1b0
[  235.256248]  ? asm_exc_page_fault+0x27/0x30
[  235.256256]  ? memcpy_orig+0x8c/0x130
[  235.256262]  ? rudp_sendmsg+0x5a/0xc0 [RUDP_mod]
[  235.256269]  inet_sendmsg+0x7d/0x80
[  235.256274]  __sys_sendto+0x220/0x250
[  235.256297]  __x64_sys_sendto+0x24/0x40
[  235.256300]  do_syscall_64+0x5b/0x90
[  235.256304]  ? srso_return_thunk+0x5/0x10
[  235.256307]  ? do_user_addr_fault+0x238/0x6b0
[  235.256310]  ? srso_return_thunk+0x5/0x10
[  235.256313]  ? exit_to_user_mode_prepare+0x30/0xb0
[  235.256317]  ? srso_return_thunk+0x5/0x10
[  235.256320]  ? irqentry_exit_to_user_mode+0x17/0x20
[  235.256323]  ? srso_return_thunk+0x5/0x10
[  235.256327]  ? irqentry_exit+0x43/0x50
[  235.256330]  ? srso_return_thunk+0x5/0x10
[  235.256333]  ? exc_page_fault+0x94/0x1b0
[  235.256337]  entry_SYSCALL_64_after_hwframe+0x6e/0xd8
[  235.256341] RIP: 0033:0x7f03ba527a0a
[  235.256359] Code: d8 64 89 02 48 c7 c0 ff ff ff ff eb b8 0f 1f 00 f3 0f 1e fa 41 89 ca 64 8b 04 25 18 00 00 00 85 c0 75 15 b8 2c 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 7e c3 0f 1f 44 00 00 41 54 48 83 ec 30 44 89
[  235.256361] RSP: 002b:00007ffd0047db28 EFLAGS: 00000246 ORIG_RAX: 000000000000002c
[  235.256364] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f03ba527a0a
[  235.256367] RDX: 000000000000001b RSI: 00007ffd0047db50 RDI: 0000000000000003
[  235.256369] RBP: 00007ffd0047dbc0 R08: 00007ffd0047db40 R09: 0000000000000010
[  235.256371] R10: 0000000000000000 R11: 0000000000000246 R12: 00007ffd0047dcd8
[  235.256373] R13: 000064cb39e0e32e R14: 000064cb39e10d50 R15: 00007f03bab1b040
[  235.256378]  </TASK>
[  235.256380] Modules linked in: RUDP_mod(OE) isofs bnep snd_ens1371 snd_ac97_codec intel_rapl_msr gameport ac97_bus snd_pcm intel_rapl_common vsock_loopback vmw_vsock_virtio_transport_common vmw_balloon vmw_vsock_vmci_transport crct10dif_pclmul polyval_clmulni snd_seq_midi polyval_generic ghash_clmulni_intel sha256_ssse3 vsock snd_seq_midi_event sha1_ssse3 aesni_intel snd_rawmidi crypto_simd cryptd binfmt_misc snd_seq btusb btrtl nls_iso8859_1 joydev snd_seq_device btbcm btintel input_leds btmtk snd_timer serio_raw bluetooth ecdh_generic ecc snd 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 mptspi usbhid hid ahci mptscsih mptbase e1000 scsi_transport_spi libahci i2c_piix4 pata_acpi
[  235.256467] CR2: 00007ffd0047db50
[  235.256470] ---[ end trace 0000000000000000 ]---
[  235.256472] RIP: 0010:memcpy_orig+0x8c/0x130
[  235.256475] Code: 5e e0 48 8d 76 e0 4c 89 47 f8 4c 89 4f f0 4c 89 57 e8 4c 89 5f e0 48 8d 7f e0 73 d2 83 c2 20 48 29 d6 48 29 d7 83 fa 10 72 34 <4c> 8b 06 4c 8b 4e 08 4c 8b 54 16 f0 4c 8b 5c 16 f8 4c 89 07 4c 89
[  235.256478] RSP: 0018:ffffb42403a7bce0 EFLAGS: 00010202
[  235.256480] RAX: 00007ffd0047db5e RBX: 000000000000001b RCX: 0000000000000000
[  235.256482] RDX: 000000000000001b RSI: 00007ffd0047db50 RDI: 00007ffd0047db5e
[  235.256484] RBP: ffffb42403a7bd20 R08: 0000000000000000 R09: 0000000000000000
[  235.256486] R10: 0000000000000000 R11: 0000000000000000 R12: ffffb42403a7bd78
[  235.256488] R13: ffff8ee008c12d00 R14: 00007ffd0047db50 R15: ffffb42403a7bde0
[  235.256491] FS:  00007f03baab03c0(0000) GS:ffff8ee039e80000(0000) knlGS:0000000000000000
[  235.256493] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[  235.256495] CR2: 00007ffd0047db50 CR3: 000000010345e000 CR4: 0000000000350ee0
[  235.256505] note: client[4678] exited with irqs disabled

It seems like struct msghdr has to be read and write by copy_to_iter and copy_from_iter, but I can only read from msg, I can't write to msg. The Linux Kernel version is 6.5.0, so the 'struct msghdr' is different from old version, it has no iovec, but iov_iter. Does anybody know how to solve this, I need help, thanks a lot!

I tried memcpy, copy_to_iter, iov_iter_init and copy_to_user, but none of them works. May be I didn't use them correctly. copy_to_iter and copy_to_user always return 0, but I don't know why.

0

There are 0 best solutions below