Home > front end >  pointer to incomplete class type "struct pt_regs" is not allowed
pointer to incomplete class type "struct pt_regs" is not allowed

Time:10-05

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:

  1. The line typedef unsigned int __bitwise gfp_t; is not required; The gfp_t type will be defined in the included header files.
  2. strlen should not be called pointers to user memory such as the src parameter; call strlen_user instead.
  3. 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 since sizeof(char) is 1 by definition, it can be changed to 1 strlen(src) (except that it needs to use strlen_user in this case, as described above).
  4. The function does not check the result on the calls to kmalloc. All memory allocations in kernel code should be checked for success.
  5. The function has a memory leak when it returns 0 without freeing the memory blocks pointed to by tmp1 and tmp2.
  6. The src parameter type should be const char*.
  7. The dest and src parameter types should be tagged as pointers to user memory; they should be char __user* and const char __user*, respectively.
  • Related