在内核模式下在ext4中设置自定义扩展属性

时间:2018-04-19 21:51:49

标签: c linux linux-kernel

我试图在linux内核的ext4文件系统中实现自定义扩展属性。我添加了两个新的系统调用来设置和获取文件的Security_Tag(我的新属性)。在执行这些系统调用时,我使用了setxattrgetxattraccess函数。

这是我执行系统调用的源代码:

#include <linux/kernel.h>
#include <linux/unistd.h>
#include <linux/syscalls.h>
#include <linux/types.h>
#include <linux/xattr.h>

// Sets the Security_Tag attribute for the given file to the  specified
// integer value.
asmlinkage int sys_set_security_tag(const char *filename, int new_tag)
{
        // Check if the current user has write access to this file
        int permissions = access(filename, W_OK);
        if(permissions < 0){
                printk("ERROR: Permission Denied");
                return -1;
        }

        // Set the value of the Security_Tag attribute to the value of new_tag
        int *val_p = &new_tag;
        int err = setxattr(filename, "Security_Tag", val_p, sizeof(int), 0);
        if(err < 0){
                printk("ERROR: Set attribute failed.");
                return -1;
        }

        return 0;
}

// Returns the value of the Security_Tag attribute for the given file.
asmlinkage int sys_get_security_tag(const char *filename)
{
        // Check if the user has read access to this file
        int permissions = access(filename, R_OK);
        if(permissions < 0){
                printk("ERROR: Permission Denied.");
                return -1;
        }

        // Allocate a buffer for the value of the tag and retrieve it's value
        int *buff = kmalloc(sizeof(int));
        ssize_t bytesRead = getxattr(filename, "Security_Tag", buff, sizeof(int));

        if(bytesRead < 0){
                // Attribute does not exist for this file yet, so create the
                // attribute and set it to the default value of 0.
                int val = 0;
                int *val_p = &val;
                int err = setxattr(filename, "Security_Tag", val_p, sizeof(int), XATTR_CREATE);

                if(err < 0){
                        printk("ERROR: Attribute Creation Failed");
                        return -1;
                }
                return val;
        }

        // Store the return value, free the buff pointer, and return the
        // Security_Tag value.
        int ret = *buff;
        free(buff);
        return ret;
}

当我尝试制作内核时,我收到以下错误:

$ sudo make && sudo make install && sudo make modules_install
make[1]: Entering directory '/usr/rep/out/kernel'
  CHK     include/config/kernel.release
  Using /usr/rep/src/kernel as source for kernel
  CHK     include/generated/uapi/linux/version.h
  CHK     include/generated/utsrelease.h
  CHK     include/generated/bounds.h
  CHK     include/generated/timeconst.h
  CHK     include/generated/asm-offsets.h
  CALL    /usr/rep/src/kernel/scripts/checksyscalls.sh
  CHK     include/generated/compile.h
  SKIPPED include/generated/compile.h
  CC      filesecuritytag/filesecuritytag.o
/usr/rep/src/kernel/filesecuritytag/filesecuritytag.c: In function 'sys_set_security_tag':
/usr/rep/src/kernel/filesecuritytag/filesecuritytag.c:12:2: error: implicit declaration of function 'access' [-Werror=implicit-function-declaration]
/usr/rep/src/kernel/filesecuritytag/filesecuritytag.c:12:37: error: 'W_OK' undeclared (first use in this function)
/usr/rep/src/kernel/filesecuritytag/filesecuritytag.c:12:37: note: each undeclared identifier is reported only once for each function it appears in
/usr/rep/src/kernel/filesecuritytag/filesecuritytag.c:19:2: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]
/usr/rep/src/kernel/filesecuritytag/filesecuritytag.c:20:2: error: implicit declaration of function 'setxattr' [-Werror=implicit-function-declaration]
/usr/rep/src/kernel/filesecuritytag/filesecuritytag.c: In function 'sys_get_security_tag':
/usr/rep/src/kernel/filesecuritytag/filesecuritytag.c:33:37: error: 'R_OK' undeclared (first use in this function)
/usr/rep/src/kernel/filesecuritytag/filesecuritytag.c:40:2: error: too few arguments to function 'kmalloc'
/usr/rep/src/kernel/include/linux/slab.h:478:30: note: declared here
/usr/rep/src/kernel/filesecuritytag/filesecuritytag.c:40:2: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]
/usr/rep/src/kernel/filesecuritytag/filesecuritytag.c:41:2: error: implicit declaration of function 'getxattr' [-Werror=implicit-function-declaration]
/usr/rep/src/kernel/filesecuritytag/filesecuritytag.c:59:2: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]
/usr/rep/src/kernel/filesecuritytag/filesecuritytag.c:60:2: error: implicit declaration of function 'free' [-Werror=implicit-function-declaration]
/usr/rep/src/kernel/filesecuritytag/filesecuritytag.c:60:2: warning: incompatible implicit declaration of built-in function 'free' [enabled by default]
cc1: some warnings being treated as errors

/usr/rep/src/kernel/scripts/Makefile.build:293: recipe for target 'filesecuritytag/filesecuritytag.o' failed
make[2]: *** [filesecuritytag/filesecuritytag.o] Error 1
/usr/rep/src/kernel/Makefile:991: recipe for target 'filesecuritytag' failed
make[1]: *** [filesecuritytag] Error 2
make[1]: Leaving directory '/usr/rep/out/kernel'
Makefile:150: recipe for target 'sub-make' failed
make: *** [sub-make] Error 2

据我所知,这意味着我上面列出的所有函数都没有被原型化(标题没有正确包含在我最初的想法)。免责声明:这是我第一次编译我的代码,所以我不知道我的实现是否有效,而且我对C来说相对较新,所以我可能会忽略一些小的代码。

我的问题是:

  1. 是否可以在内核中使用setxattr,getxattr和access?如果没有,我应该使用哪些等效的内核模式函数呢? (例如,必须在内核中使用printk而不是printf)。

  2. 手册指出我需要包含unistd.h,sys / types.h和attr / xattr.h。我尝试将它们包含在手册中并显示错误,但是当我使用linux / types.h,linux / xattr.h和linux / unistd.h时,我没有收到任何错误。这是包含这些标题的正确方法吗?

  3. 编辑:响应此标记为重复。另一个链接的帖子只回答了使用什么代替setxattr函数的问题(这导致我自己找到了vfs_getxattr函数),但它没有解释如何在不使用的情况下处理文件系统权限检查访问呼叫。所以,继续:

    1. 如果无法使用访问调用,可以使用什么来检查内核中的用户/进程文件权限?

0 个答案:

没有答案