You are not logged in.
Hi all, I am trying to allocate memory for a pointer in another function in Linux Kernel module file, and it causes error_code(0x0001) - permissions violation. Here is a simpler reproduction of what i am trying to do.
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/slab.h>
int another(char **name){
*name = kmalloc(16, GFP_KERNEL);
return 0;
}
static int __init test_init(void){
char *name;
another(&name);
printk(KERN_INFO "Hello!");
return 0;
}
static void __exit test_exit(void){
printk(KERN_INFO "Goodbye!");
}
MODULE_LICENSE("GPL");
module_init(test_init);
module_exit(test_exit);
I did this a lot in userspace and it works just fine, but here it crashes every time. Please let me know if dmesg info is needed.
Last edited by Samo____ (2022-09-26 06:12:47)
Offline
Hello, I've just tried this and its working fine on latest kernel (5.19.9). Can you post your dmesg?
It looks to me that something else could be triggering this error. Most likely you are trying to write to protected read-only pages.
Thanks.
Offline
While your code might work (no way in hell I will test it) it completely breaks the resource ownership and causes a memory leak.
another() allocates memory for a resource owned by test_init(), which is the first big no-no.
Then you never call kfree() on the resource.
What are you doing there?
Last edited by schard (2022-09-18 16:00:20)
?לאן אתה רוצה ללכת היום
Offline
@schard why so hostile? Are you from the arch police? Have you ever been a beginner? Let's see your code. OP was very clear what he thought his issue was.
"It bReAkS tHe ReSoUrCe OwNeRsHiP"
I write audio drivers for a living on multiple platforms, and its always Linux users with the elitist and condescending attitudes.
Get fucked. I'm, out.
Offline
I am not aware that I was being hostile in any way.
I pointed out, which I believe to be flaws in the code and possible security issues with it.
This is also why I strongly emphasized, that I will not run this code as it stands.
I also hinted on how to eliminate the issues I see with the code.
Memory leaks due to ownership issues frequently lead to use-after-free and other memory-related vulnerabilities.
To avoid such issues from the beginning, I felt obliged to hint at the breakage of memory ownership in the OP's code.
At any rate your insult is entirely uncalled for.
If you really are a driver developer and get aggressive on a random code review like this, if it does not even concern your code, I hope that I will never have to use any of the code you wrote.
Last edited by schard (2022-09-18 18:14:32)
?לאן אתה רוצה ללכת היום
Offline
I write audio drivers for a living on multiple platforms, and its always Linux users with the elitist and condescending attitudes.
Get fucked. I'm, out.
To get that straight: after hurling a silly stereotype at the general audience you abandon the OP because of what another forum user said that you kind took personal despite not being addressed.
Ok…
Ftr, the OP has posted the same question on SO, https://stackoverflow.com/questions/737 … nel-module and should elaborate in that sense (stack trace, full dmesg context) and also on the specific kernel (though that should be included in the stack trace) in use and whether this is a virtual machine and everything else that might be "non-standard".
Also assure whether the presented test code actually produces this error or is a simplified version and the actual problem is maybe some address send to the kernel from userspace w/o https://www.kernel.org/doc/htmldocs/ker … -user.html
Offline
Hello, I've just tried this and its working fine on latest kernel (5.19.9). Can you post your dmesg?
It looks to me that something else could be triggering this error. Most likely you are trying to write to protected read-only pages.Thanks.
Hello, and sorry for late reply.
I am using 5.19.9-arch1-1.
[ 313.588325] BUG: unable to handle page fault for address: 00007fa96fb6c768
[ 313.588328] #PF: supervisor read access in kernel mode
[ 313.588329] #PF: error_code(0x0001) - permissions violation
[ 313.588330] PGD 80000001ed9ab067 P4D 80000001ed9ab067 PUD 1e7961067 PMD 172bfb067 PTE 8000000203cad867
[ 313.588334] Oops: 0001 [#1] PREEMPT SMP PTI
[ 313.588337] CPU: 0 PID: 3225 Comm: insmod Tainted: P OE 5.19.9-arch1-1 #1 3da5a84b9442a05cd5bc412feaf8d6ab31862ed4
[ 313.588339] Hardware name: System manufacturer System Product Name/PRIME H270-PRO, BIOS 0808 07/10/2017
[ 313.588340] RIP: 0010:test_init+0xc/0x1000 [ldlox]
[ 313.588346] Code: Unable to access opcode bytes at RIP 0xffffffffc36e0fe2.
[ 313.588347] RSP: 0018:ffffa61e830d3d28 EFLAGS: 00010286
[ 313.588349] RAX: 0000000000000000 RBX: ffffffffc36e1000 RCX: 0000000000000000
[ 313.588350] RDX: 0000000000000000 RSI: ffffffffc36e1000 RDI: ffffa61e830d3d28
[ 313.588351] RBP: ffffa61e830d3d38 R08: 0000000000000010 R09: ffff96b66407b210
[ 313.588353] R10: ffff96b664da2790 R11: 0000000000000100 R12: 0000000000000000
[ 313.588354] R13: 0000000000000003 R14: 0000000000000000 R15: 0000000000000000
[ 313.588355] FS: 00007fa96fb6c740(0000) GS:ffff96b77ec00000(0000) knlGS:0000000000000000
[ 313.588357] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 313.588358] CR2: ffffffffc36e0fe2 CR3: 0000000205752005 CR4: 00000000003706f0
[ 313.588360] Call Trace:
[ 313.588361] <TASK>
[ 313.588363] ? 0xffffffffc36e1000
[ 313.588365] do_one_initcall+0x5d/0x220
[ 313.588370] do_init_module+0x4a/0x1e0
[ 313.588373] __do_sys_finit_module+0xac/0x120
[ 313.588376] do_syscall_64+0x5f/0x90
[ 313.588380] ? syscall_exit_to_user_mode+0x1b/0x40
[ 313.588383] ? do_syscall_64+0x6b/0x90
[ 313.588385] ? exc_page_fault+0x74/0x170
[ 313.588387] entry_SYSCALL_64_after_hwframe+0x63/0xcd
[ 313.588390] RIP: 0033:0x7fa96f71959d
[ 313.588392] Code: 5d c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d bb 77 0d 00 f7 d8 64 89 01 48
[ 313.588394] RSP: 002b:00007ffdbca6d348 EFLAGS: 00000246 ORIG_RAX: 0000000000000139
[ 313.588396] RAX: ffffffffffffffda RBX: 0000559aa257f7b0 RCX: 00007fa96f71959d
[ 313.588397] RDX: 0000000000000000 RSI: 0000559aa0cb0cb2 RDI: 0000000000000003
[ 313.588398] RBP: 0000559aa0cb0cb2 R08: 0000000000000000 R09: 0000559aa2581cf0
[ 313.588399] R10: 0000000000000003 R11: 0000000000000246 R12: 0000000000000000
[ 313.588400] R13: 0000559aa257f760 R14: 00007ffdbca6d588 R15: 0000559aa257f8c0
[ 313.588402] </TASK>
[ 313.588403] Modules linked in: ldlox(OE+) snd_seq_dummy snd_hrtimer snd_seq snd_seq_device xt_CHECKSUM xt_MASQUERADE xt_conntrack ipt_REJECT nf_reject_ipv4 xt_tcpudp nft_compat nft_chain_nat nf_nat nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 nf_tables libcrc32c nfnetlink bridge intel_rapl_msr intel_rapl_common intel_tcc_cooling cfg80211 x86_pkg_temp_thermal intel_powerclamp coretemp 8021q garp kvm_intel mrp stp snd_hda_codec_realtek llc kvm irqbypass snd_hda_codec_generic crct10dif_pclmul ledtrig_audio crc32_pclmul nvidia_drm(POE) ghash_clmulni_intel nvidia_uvm(POE) nvidia_modeset(POE) aesni_intel eeepc_wmi crypto_simd iTCO_wdt asus_wmi intel_pmc_bxt mei_pxp mei_hdcp snd_hda_codec_hdmi cryptd ee1004 sparse_keymap iTCO_vendor_support rapl platform_profile snd_hda_intel intel_cstate vfat snd_intel_dspcfg wmi_bmof rfkill mxm_wmi fat snd_intel_sdw_acpi intel_uncore nvidia(POE) i915 mousedev snd_hda_codec snd_hda_core drm_buddy snd_hwdep ttm snd_pcm drm_display_helper snd_timer video mei_me
[ 313.588439] cec e1000e snd intel_gtt soundcore i2c_i801 mei mac_hid i2c_smbus wmi acpi_pad pcspkr dm_multipath dm_mod sg crypto_user fuse bpf_preload ip_tables x_tables ext4 crc32c_generic crc16 mbcache jbd2 usbhid crc32c_intel xhci_pci xhci_pci_renesas
[ 313.588452] Unloaded tainted modules: acpi_cpufreq():1 acpi_cpufreq():1 acpi_cpufreq():1 acpi_cpufreq():1 fjes():1 fjes():1 pcc_cpufreq():1 fjes():1 pcc_cpufreq():1 acpi_cpufreq():1 acpi_cpufreq():1 pcc_cpufreq():1 fjes():1 pcc_cpufreq():1 acpi_cpufreq():1 fjes():1 fjes():1 acpi_cpufreq():1 pcc_cpufreq():1 fjes():1 pcc_cpufreq():1 acpi_cpufreq():1 pcc_cpufreq():1 acpi_cpufreq():1 fjes():1 acpi_cpufreq():1 fjes():1 pcc_cpufreq():1 acpi_cpufreq():1
[ 313.588471] CR2: 00007fa96fb6c768
[ 313.588472] ---[ end trace 0000000000000000 ]---
[ 313.588474] RIP: 0010:test_init+0xc/0x1000 [ldlox]
[ 313.588477] Code: Unable to access opcode bytes at RIP 0xffffffffc36e0fe2.
[ 313.588478] RSP: 0018:ffffa61e830d3d28 EFLAGS: 00010286
[ 313.588479] RAX: 0000000000000000 RBX: ffffffffc36e1000 RCX: 0000000000000000
[ 313.588480] RDX: 0000000000000000 RSI: ffffffffc36e1000 RDI: ffffa61e830d3d28
[ 313.588481] RBP: ffffa61e830d3d38 R08: 0000000000000010 R09: ffff96b66407b210
[ 313.588482] R10: ffff96b664da2790 R11: 0000000000000100 R12: 0000000000000000
[ 313.588483] R13: 0000000000000003 R14: 0000000000000000 R15: 0000000000000000
[ 313.588484] FS: 00007fa96fb6c740(0000) GS:ffff96b77ec00000(0000) knlGS:0000000000000000
[ 313.588486] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 313.588487] CR2: ffffffffc36e0fe2 CR3: 0000000205752005 CR4: 00000000003706f0
And i am getting these messages while making it.
/home/sam/projects/test.o: warning: objtool: another+0x40: 'naked' return found in RETHUNK build
/home/sam/projects/test.o: warning: objtool: test_init+0x55: 'naked' return found in RETHUNK build
/home/sam/projects/test.o: warning: objtool: test_exit+0x1e: 'naked' return found in RETHUNK build
/home/sam/projects/test.o: warning: objtool: folio_flags+0x29: missing int3 after ret
/home/sam/projects/test.o: warning: objtool: another+0x40: missing int3 after ret
/home/sam/projects/test.o: warning: objtool: test_init+0x55: missing int3 after ret
/home/sam/projects/test.o: warning: objtool: test_exit+0x1e: missing int3 after ret
Thank You very much for attention!
Last edited by Samo____ (2022-09-21 07:42:52)
Offline
While your code might work (no way in hell I will test it) it completely breaks the resource ownership and causes a memory leak.
another() allocates memory for a resource owned by test_init(), which is the first big no-no.
Then you never call kfree() on the resource.
What are you doing there?
Hello, and thank you for responding.
I am not indeed freeing the memory, since this is a very small example to introduce the issue. However the bug appears even if i am not doing anything in another() function. Also i do not really understand this part to be honest
another() allocates memory for a resource owned by test_init(), which is the first big no-no.
How should i allocate memory for a pointer in another function? or you mean it is a bad practice anyway?
Thank You.
Offline
How should i allocate memory for a pointer in another function? or you mean it is a bad practice anyway?
Yes, I would consider it bad practice, because you tend to lose track of what part of the program is responsible for managing the memory.
I still would very much like to know, why you want to do this and to what end you are experimenting with this.
It may be a classic xy problem we're facing here.
If you are attempting to write a device driver, have a look at devm_kzalloc[1,2].
It will handle the freeing of the memory for you.
[1] https://docs.huihoo.com/linux/kernel/2. … re121.html
[2] https://github.com/conqp/amd-sfh-hid-dk … pci.c#L200
?לאן אתה רוצה ללכת היום
Offline
I still would very much like to know, why you want to do this and to what end you are experimenting with this.
I am trying to create data serialization functions and allocate memory given the length of data in each member of a structure.
Thanks for the links.
Offline
I don't understand that.
1) If you want to serialize data structures, you already have data for their members allocated, since you already have the respective data structure?!?!
2) If you want to implement functions (a library) to serialize structs, why do you do it in kernel space and not try it in user space first?
?לאן אתה רוצה ללכת היום
Offline
1) If you want to serialize data structures, you already have data for their members allocated, since you already have the respective data structure?!?!
Exactly, but i want to serialize all members into a char array.
2) If you want to implement functions (a library) to serialize structs, why do you do it in kernel space and not try it in user space first?
I do exactly that way, and in user space it works perfectly, the same code in kernel causes aforementioned issues (of course i am replacing malloc, free, printf etc.. with corresponding functions in the Kernel)
.
Last edited by Samo____ (2022-09-20 13:37:30)
Offline
Anyways, my question is more about this:
Why this construct works ok in user space:
void test(char **){
}
int main(int argc, char **argv){
char *str;
test(&str);
return 0;
}
But the following causes a crash in the kernel:
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
int another(char **name){
return 0;
}
static int __init test_init(void){
char *name;
another(&name);
return 0;
}
static void __exit test_exit(void){
}
MODULE_LICENSE("GPL");
module_init(test_init);
module_exit(test_exit);
Offline
Well, the above module works fine for me:
Makefile
obj-m = testmod.o
KVERSION = $(shell uname -r)
all:
make -C /lib/modules/$(KVERSION)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(KVERSION)/build M=$(PWD) clean
testmod.c
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
int another(char **name){
return 0;
}
static int __init test_init(void){
char *name;
another(&name);
return 0;
}
static void __exit test_exit(void){
}
MODULE_LICENSE("GPL");
module_init(test_init);
module_exit(test_exit);
After
# insmod ./testmod.ko
dmesg results in:
[334960.791038] testmod: loading out-of-tree module taints kernel.
[334960.796311] testmod: module verification failed: signature and/or required key missing - tainting kernel
$ uname -r
5.19.9-arch1-1
Removing works fine, too:
0 ✓ srv /home/build $ rmmod testmod
0 ✓ srv /home/build $ rmmod testmod
rmmod: ERROR: Module testmod is not currently loaded
Do you use SELinux or the like?
Update
With
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/slab.h>
int another(char **name){
printk(KERN_INFO "Allocating memory!\n");
*name = kmalloc(16, GFP_KERNEL);
return 0;
}
static int __init test_init(void){
char *name;
printk(KERN_INFO "Hello!\n");
another(&name);
printk(KERN_INFO "Freeing memory!\n");
kfree(name);
return 0;
}
static void __exit test_exit(void){
printk(KERN_INFO "Goodbye!");
}
MODULE_LICENSE("GPL");
module_init(test_init);
module_exit(test_exit);
[335459.551823] Hello!
[335459.551828] Allocating memory!
[335459.551829] Freeing memory!
[335468.107093] Goodbye!
Also this works:
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/slab.h>
char *NAME;
int another(char **name){
printk(KERN_INFO "Allocating memory!\n");
*name = kmalloc(16, GFP_KERNEL);
return 0;
}
static int __init test_init(void){
printk(KERN_INFO "Hello!\n");
another(&NAME);
return 0;
}
static void __exit test_exit(void){
printk(KERN_INFO "Freeing memory!\n");
kfree(NAME);
printk(KERN_INFO "Goodbye!");
}
MODULE_LICENSE("GPL");
module_init(test_init);
module_exit(test_exit);
Last edited by schard (2022-09-20 15:17:44)
?לאן אתה רוצה ללכת היום
Offline
And i am getting these messages while making it.
/home/sam/projects/test.o: warning: objtool: another+0x40: 'naked' return found in RETHUNK build /home/sam/projects/test.o: warning: objtool: test_init+0x55: 'naked' return found in RETHUNK build /home/sam/projects/test.o: warning: objtool: test_exit+0x1e: 'naked' return found in RETHUNK build /home/sam/projects/test.o: warning: objtool: folio_flags+0x29: missing int3 after ret /home/sam/projects/test.o: warning: objtool: another+0x40: missing int3 after ret /home/sam/projects/test.o: warning: objtool: test_init+0x55: missing int3 after ret /home/sam/projects/test.o: warning: objtool: test_exit+0x1e: missing int3 after ret
Seems a toolchain issue - are you using clang?
Otherwise
gcc --version
Offline
Please provide exact command line how do you compile your module. And your Makefile content.
Last edited by dimich (2022-09-20 20:09:37)
Offline
Seems a toolchain issue - are you using clang?
I am using
gcc (GCC) 12.2.0
And here is
gcc -v
output if also needed:
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-pc-linux-gnu/12.2.0/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: /build/gcc/src/gcc/configure --enable-languages=c,c++,ada,fortran,go,lto,objc,obj-c++,d --enable-bootstrap --prefix=/usr --libdir=/usr/lib --libexecdir=/usr/lib --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=https://bugs.archlinux.org/ --with-build-config=bootstrap-lto --with-linker-hash-style=gnu --with-system-zlib --enable-__cxa_atexit --enable-cet=auto --enable-checking=release --enable-clocale=gnu --enable-default-pie --enable-default-ssp --enable-gnu-indirect-function --enable-gnu-unique-object --enable-libstdcxx-backtrace --enable-link-serialization=1 --enable-linker-build-id --enable-lto --enable-multilib --enable-plugin --enable-shared --enable-threads=posix --disable-libssp --disable-libstdcxx-pch --disable-werror
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 12.2.0 (GCC)
Offline
HI all!
Well, the above module works fine for me:
Thank you very much, with your Makefile it compiled without any warnings and insmod/rmmod work just fine.
So there is clearly an issue with my Makefile and/or flags. I am posting it down below as also was requested by @dimich
Please provide exact command line how do you compile your module. And your Makefile content.
Here is my original Makefile that was causing issues
KBUILD_CFLAGS := -g -Wall
EXTRA_CFLAGS += -I$(PWD)/
obj-m += ldlox.o
ldlox-y += rbl_serdes.o
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
Removing this line solves the issue:
KBUILD_CFLAGS := -g -Wall
And the solution is just to replace that line with:
KBUILD_CFLAGS += -g -Wall
i.e. := with +=
Thank you all for help! without your advices this would take ages!
Last edited by Samo____ (2022-09-21 09:35:51)
Offline