• Linux内核中各种鉴权 Hello


    一、编译阶段

    1. BUILD_BUG 系列

    主要定义在 include/linux/build_bug.h 文件中,若编译期发现不合法就报错并中止编译。

    (1) BUILD_BUG_ON(condition)

    #define BUILD_BUG_ON(condition) BUILD_BUG_ON_MSG(condition, "BUILD_BUG_ON failed: " #condition)

    若条件为真就报错并中止编译,但需要在使用文件的顶行 #define __OPTIMIZE__ 才会生效。相关的还有:

    /* 条件cond为真就编译报错且打印msg指定的信息 */
    #define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg)
    
    /* 只要代码被编译住了,就报错 */
    #define BUILD_BUG() BUILD_BUG_ON_MSG(1, "BUILD_BUG failed")

    (2) BUILD_BUG_ON_ZERO(e)

    #define BUILD_BUG_ON_ZERO(e) ((int)(sizeof(struct { int:(-!!(e)); })))

    若条件e为真,则强制编译报错。这个没有什么依赖,可以直接拿来使用。

    (3) 若常量表达式n不是2的次方,强制编译报错。也是依赖于 #define __OPTIMIZE__ 才会生效。

    #define __BUILD_BUG_ON_NOT_POWER_OF_2(n)    BUILD_BUG_ON(((n) & ((n) - 1)) != 0)
    #define BUILD_BUG_ON_NOT_POWER_OF_2(n)    BUILD_BUG_ON((n) == 0 || (((n) & ((n) - 1)) != 0))

    二、运行阶段-锁相关

    1. lockdep_assert_held(),判断执行当前函数时指定spin_lock是否处于锁定状态。需要使能 CONFIG_LOCKDEP 宏才起作用,默认不使能。

    lockdep_assert_held(&spin_lock);
    
    //使用举例:
    __assign_cfs_rq_runtime
      lockdep_assert_held(&cfs_b->lock);

    除了此函数外,还有一些列相关函数:

    lockdep_assert_irqs_enabled(); //需要使能 CONFIG_PROVE_LOCKING 
    lockdep_assert_irqs_enabled()
    lockdep_assert_in_irq()
    lockdep_assert_preemption_enabled()
    lockdep_assert_preemption_disabled()
    lockdep_assert_in_softirq()

    使用举例:

    static void __unqueue_futex(struct futex_q *q)
    {
        if (WARN_ON_SMP(!q->lock_ptr) || WARN_ON(plist_node_empty(&q->list)))
            return;
        lockdep_assert_held(q->lock_ptr);
        ...
    }

    三、运行阶段-判断上下文

    1. assert当前是否关中断的

    lockdep_assert_irqs_disabled(); //include/linux/lockdep.h 需要使能 CONFIG_PROVE_LOCKING

    四、运行阶段-BUG_ON()系列

    1. 主要定义在 include/asm-generic/bug.h 中,若执行时发现条件不满足,就直接panic.

    BUG(); //直接panic打印栈回溯
    BUG_ON(condition) //若条件为真,则BUG()
    
    WARN(condition, format...)
    WARN_ONCE(condition, format...)
    
    WARN_ON(condition);
    WARN_ON_ONCE(condition);
    
    WARN_TAINT(condition, taint, format...)
    WARN_TAINT_ONCE(condition, taint, format...)

    BUG() 是通过brk中断来触发栈回溯的

    [ 1167.217429] sh: Call trace:
    [ 1167.217448] sh:  dump_backtrace.cfi_jt+0x0/0x8
    [ 1167.217465] sh:  show_stack+0x1c/0x2c
    [ 1167.217482] sh:  dump_stack_lvl+0xc4/0x140
    [ 1167.217494] sh:  dump_stack+0x1c/0x2c
    [ 1167.217586] sh:  mrdump_common_die+0x2c4/0x3a8 [mrdump]
    [ 1167.217668] sh:  ipanic_die+0x24/0x38 [mrdump]
    [ 1167.217690] sh:  notify_die+0x8c/0x118
    [ 1167.217705] sh:  __die+0x80/0x240
    [ 1167.217718] sh:  die+0x6c/0x108
    [ 1167.217733] sh:  bug_handler+0x48/0xf4
    [ 1167.217747] sh:  brk_handler+0x9c/0x17c
    [ 1167.217762] sh:  do_debug_exception+0xe0/0x1d8
    [ 1167.217777] sh:  el1_dbg+0x38/0x58
    [ 1167.217792] sh:  el1_sync_handler+0x40/0x8c
    [ 1167.217804] sh:  el1_sync+0x8c/0x140  //BUG()会触发brk中断然后导致栈回溯
    [ 1167.217863] sh:  proc_my_test_write+0x35c/0x3e8 [my_test] //在这里面加 BUG() 并触发

    五、运行阶段-合法地址检测

    1. access_ok

    检验一块内存是否是有效的用户空间地址。对系统调用传下来的地址必须进行检查。

    // arch/arm64/include/asm/uaccess.h
    
    /*
     * Test whether a block of memory is a valid user space address.
     * Returns 1 if the range is valid, 0 otherwise.
     *
     * This is equivalent to the following test:
     * (u65)addr + (u65)size <= (u65)TASK_SIZE_MAX
     */
    #define access_ok(addr, size)    __range_ok(addr, size)
  • 相关阅读:
    金蝶K3 账套复制
    silverlight控件如何自适应
    一个使用Jquery写的一个鼠标拖动效果
    如何使用C#开发“类ActiveX组件”
    一个非科班出身程序员的成长历程
    Ubuntu 12.04下LAMP安装配置
    Abp vue项目找不到模块“./app.vue”
    google的分析(analytics)js代码分析以及重写
    javascript实现类似google和msn space的拖拽
    Lucene.Net, SQL Server 2008全文检索, Like模糊查询的一点心得
  • 原文地址:https://www.cnblogs.com/hellokitty2/p/16461422.html
Copyright © 2020-2023  润新知