小编Cor*_*son的帖子

在Linux内核版本上递归禁用CONFIG依赖项

配置Linux内核时,我通常从我的发行版的内核配置文件开始.我经常想关闭一些条目,但它们有时是不可更改的,因为启用了依赖于它的其他CONFIG选项.

我可以手动查找依赖项,这些依赖项通常具有自己的依赖项.通过这些操作可能非常耗时,特别是如果您尝试关闭CONFIG_KALLSYMS之类的东西.

问题:有没有办法指定您想要的配置选项,并自动选择/分析所有依赖关系作为nessisary?我查看了所有make选项和scripts目录,但没有看到任何可用的内容.

更新:有人回答说make oldconfig应该从.config文件中删除(删除)所需的CONFIG选项后执行该工作,但这不起作用(他的答案消失了):

$ make oldconfig
scripts/kconfig/conf -o arch/x86/Kconfig
*
* Restart config...
*
*
* Configure standard kernel features (for small systems)
*
Configure standard kernel features (for small systems) (EMBEDDED) [N/y/?] n
  Load all symbols for debugging/ksymoops (KALLSYMS) [Y/?] (NEW) y
    Include all symbols in kallsyms (KALLSYMS_ALL) [Y/?] (NEW) y
    Do an extra kallsyms pass (KALLSYMS_EXTRA_PASS) [N/y/?] (NEW) 
Run Code Online (Sandbox Code Playgroud)

它会自动地说"y"两个前两个,我试图找到一种自动删除它们并让它们消失的方法.

linux configuration kernel makefile

15
推荐指数
2
解决办法
2442
查看次数

在Linux内核中包装函数时遇到问题

我写了一个LKM,它将可信路径执行(TPE)实现到你的内核中:

https://github.com/cormander/tpe-lkm

当我将WRAP_SYSCALLS定义为1时,我偶尔遇到一个内核OOPS(在这个问题的最后描述),并且在我的智慧结束时尝试跟踪它.

一点背景:

由于LSM框架不会导出其符号,因此我必须对如何将TPE检查插入正在运行的内核进行创作.我写了一个find_symbol_address()函数,它给了我所需的任何函数的地址,并且它工作得非常好.我可以调用这样的函数:

int (*my_printk)(const char *fmt, ...);
my_printk = find_symbol_address("printk");
(*my_printk)("Hello, world!\n");
Run Code Online (Sandbox Code Playgroud)

它工作正常.我使用此方法来定位security_file_mmap,security_file_mprotectsecurity_bprm_check函数.

然后我用asm跳转到我的函数来覆盖这些函数来进行TPE检查.问题是,当前加载的LSM将不再执行它对该函数的挂钩的代码,因为它已被完全劫持.

这是我做的一个例子:

int tpe_security_bprm_check(struct linux_binprm *bprm) {

    int ret = 0;

    if (bprm->file) {
            ret = tpe_allow_file(bprm->file);
            if (IS_ERR(ret))
                    goto out;
    }

#if WRAP_SYSCALLS
    stop_my_code(&cs_security_bprm_check);

    ret = cs_security_bprm_check.ptr(bprm);

    start_my_code(&cs_security_bprm_check);
#endif

    out:

    return ret;
}
Run Code Online (Sandbox Code Playgroud)

注意#if WRAP_SYSCALLS部分之间的部分(默认情况下定义为0).如果设置为1,则调用LSM的钩子,因为我将原始代码写回asm跳转并调用该函数,但是我遇到了一个带有"无效操作码"的偶尔内核OOPS:

invalid opcode: 0000 [#1] SMP 
RIP: 0010:[<ffffffff8117b006>]  [<ffffffff8117b006>] security_bprm_check+0x6/0x310
Run Code Online (Sandbox Code Playgroud)

我不知道问题是什么.我尝试了几种不同类型的锁定方法(详情请参见start/stop_my_code的内部)无济于事.要触发内核OOPS,请编写一个简单的bash while循环,无休止地启动后台"ls"命令.大约一分钟后,它就会发生.

我在RHEL6内核上测试它,也适用于Ubuntu …

linux kernel wrapper

11
推荐指数
1
解决办法
2273
查看次数

我如何安静C编译器关于函数指针需要任意数量的参数?

我有一个函数指针struct,它在运行时动态设置为我的代码中不同位置的另一个函数的地址.它在我的头文件中定义如下:

    void *(*run)();
Run Code Online (Sandbox Code Playgroud)

在编译期间,我收到以下警告:

    warning: function declaration isn't a prototype
Run Code Online (Sandbox Code Playgroud)

这个警告是良性的,因为指针在我的代码中的许多地方用来调用它指向的函数,一切正常.但是,我真的想沉默警告.

如果我改成它:

    void *(*run)(void);
Run Code Online (Sandbox Code Playgroud)

我使用它时会出现编译错误,因为使用指针的各种函数具有不同数量的参数,并且说void在括号内部告诉编译器它不接受任何参数.

我不能使用va_list或类似的任何东西,因为这只是指向另一个函数的指针,我使用单个指针,因为它保持代码干净和简单.

我可以通过将此添加到我的编译器标志来使警告静音:

    -Wno-strict-prototypes
Run Code Online (Sandbox Code Playgroud)

但是如果可以避免,我宁愿不用标志来禁用编译器警告.

所以我的问题是:我如何在代码中注释这个函数指针,使编译器满意它接受任意数量的任何类型的参数这一事实?

代码完美无缺.我只想让警告消失.

c pointers function compiler-warnings

5
推荐指数
1
解决办法
1576
查看次数

在64位拱上投射指向整数问题警告的指针

我正在编写一个使用导出符号的linux内核模块 open_exec

struct file *open_exec(const char *name)
Run Code Online (Sandbox Code Playgroud)

它返回一个指针,我可以检查IS_ERR宏的错误:

if (IS_ERR(file))
    return file;
Run Code Online (Sandbox Code Playgroud)

在编译期间,我收到此警告:

warning: return makes integer from pointer without a cast
Run Code Online (Sandbox Code Playgroud)

这是因为我的函数返回一个整数.如果我尝试施放它:

return (int) file;
Run Code Online (Sandbox Code Playgroud)

我没有在我的32位机器上收到警告,但我在64位机器上发出警告:

warning: cast from pointer to integer of different size
Run Code Online (Sandbox Code Playgroud)

这是因为sizeofint和指针在32位上是相同的,但它们在64位机器上是不同的.

无论是否投射,代码似乎都有效.我只是想摆脱警告.

如何正确地转换指向整数的指针并获得我期望的值,同时没有得到编译器警告?我期望的值本质include/asm-generic/errno-base.h上是linux内核代码库中列出的整数.

因为我只是看指针就好像它是一个整数,如果IS_ERR()是真的,我可以肯定它实际上只保留一个整数值.

c pointers kernel-module compiler-warnings linux-kernel

4
推荐指数
1
解决办法
3037
查看次数

在linux内核中遍历进程树

我在内核模块中有以下代码,它在进程树中向上打印进程名称和uid直到init进程:

// recursivly walk the task's parent until we reach init

void parent_task_walk(struct task_struct *task) {

    struct task_struct *parent;
    char filename[MAX_FILE_LEN];

    if (task && task->mm) {

        parent = get_task_parent(task);

        printk("%s (uid:%d)", exe_from_mm(task->mm, filename, MAX_FILE_LEN),
            get_task_uid(task));

        if (parent && task->pid != 1) {
            printk(", ");
            parent_task_walk(parent);
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

注意:我使用了一些引用真实内核函数的宏,因为这是针对内核模块跨越多个版本的.源代码在此文件中:https://github.com/cormander/tpe-lkm/blob/319e1e29ea23055cca1c0a3bce3c865def14d3d2/core.c#L61

输出最终看起来像这样:

/bin/bash (uid:500), /usr/sbin/sshd (uid:500), /usr/sbin/sshd (uid:0), /usr/sbin/sshd (uid:0), /sbin/init (uid:0)

这是一个递归函数.可以想象,当你启动200个bash shell然后触发事件时,事情会变得很糟糕.我不确定究竟发生了什么,但机器冻结了.内核耗尽了我假设的堆栈空间,去了OOM,然后自己开枪?

我想知道处理这种情况的最佳方法是什么.我看到几个选项:

1)在N个进程后停止遍历进程树

2)在一些字符数组(最终将被打印)已满后停止行走

3)使用a goto而不是递归函数,但仍然遵守选项#1和#2的新规则

4)使用一些你将为我阐述的非递归方法

这发生在内核空间,所以不是最好客的环境.任何人都可以指出最好的方法吗?

recursion kernel kernel-module linux-kernel

1
推荐指数
1
解决办法
3192
查看次数