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_ttype will be defined in the included header files. strlenshould not be called pointers to user memory such as thesrcparameter; callstrlen_userinstead.- 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_userin 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
tmp1andtmp2. - The
srcparameter type should beconst char*. - The
destandsrcparameter types should be tagged as pointers to user memory; they should bechar __user*andconst char __user*, respectively.
