When compiling the kernel using make -j4
, I got the following error:
./arch/x86/include/asm/uaccess_64.h:56:1: error: conflicting types for ‘raw_copy_to_user’; have ‘long unsigned int(void *, const void *, long unsigned int)’
56 | raw_copy_to_user(void __user *dst, const void *src, unsigned long size)
so I thought it might be because of getting an error:
pointer to incomplete class type "struct pt_regs" is not allowedC/C (393) on SYSCALL_DEFINE2.
// strcpy.c: code for the new system call
#include <linux/kernel.h>
#include <linux/slab.h> // kmalloc()
#include <asm-generic/uaccess.h> // copy_from_user()
#include <linux/syscalls.h> // SYSCALL_DEFINE2
typedef unsigned int __bitwise gfp_t;
SYSCALL_DEFINE2(strcpy, char*, dest, char*, src) {
int i = 0, size;
char *tmp1, *tmp2;
size = 1 strlen(src) * sizeof(char);
tmp1 = (char *) kmalloc(size, GFP_KERNEL);
tmp2 = (char *) kmalloc(size, GFP_KERNEL);
if (copy_from_user(tmp1, src, size) == 0) {
tmp2[0] = tmp1[0];
while(tmp1[i ] != '\0') tmp2[i] = tmp1[i];
} else {
printk(KERN_ALERT "error memory access\n");
return 0;
}
if (copy_to_user(dest, tmp2, size) != 0) {
printk(KERN_ALERT "error memory access\n");
return 0;
}
kfree(tmp1); kfree(tmp2);
printk(KERN_ALERT "done system call strcpy...\n");
return 1;
}
configuration:
"configurations": [
{
"name": "Linux",
"includePath": [
"${workspaceFolder}/**",
"/usr/**",
],
"defines": [],
"compilerPath": "/usr/bin/gcc",
"cStandard": "gnu17",
"cppStandard": "gnu 17",
"intelliSenseMode": "linux-gcc-x64",
"configurationProvider": "ms-vscode.cpptools"
}
],
"version": 4
}
and here is the configuration file: c_cpp_properties.json the struct error is on the word: SYSCALL_DEFINE2
CodePudding user response:
It says "pointer to incomplete class type" which means that you are compiling C code with a C compiler. The solution is either to reinstall your C compiler (sudo apt reinstall gcc
), or to edit the Makefile if you made any changes to it.
CodePudding user response:
The reason for the conflicting types is the use of #include <asm-generic/uaccess.h>
. Header files in asm-generic/
should never be included directly by normal Linux kernel code. Use asm/
instead. For uaccess.h
it is preferable to use #include <linux/uaccess.h>
instead of #include <asm/uaccess.h>
, at least since kernel version 2.6.18.
There are other problems with the code:
- The line
typedef unsigned int __bitwise gfp_t;
is not required; Thegfp_t
type will be defined in the included header files. strlen
should not be called pointers to user memory such as thesrc
parameter; callstrlen_user
instead.- In the calculation
1 strlen(src) * sizeof(char)
, the multiplication has not been distributed properly. It could be changed to(1 strlen(src)) * sizeof(char)
to make logical sense, but sincesizeof(char)
is 1 by definition, it can be changed to1 strlen(src)
(except that it needs to usestrlen_user
in this case, as described above). - The function does not check the result on the calls to
kmalloc
. All memory allocations in kernel code should be checked for success. - The function has a memory leak when it returns 0 without freeing the memory blocks pointed to by
tmp1
andtmp2
. - The
src
parameter type should beconst char*
. - The
dest
andsrc
parameter types should be tagged as pointers to user memory; they should bechar __user*
andconst char __user*
, respectively.