402 Star 1.4K Fork 1.3K

GVPopenEuler / kernel

 / 详情

【openEuler 1.0-LTS】nfsd创建delegation异常与删除delegation并发触发UAF

已完成
任务
创建于  
2024-03-18 14:56

评论 (3)

Hi li-lingfeng3, welcome to the openEuler Community.
I'm the Bot here serving you. You can find the instructions on how to interact with me at Here.
If you have any questions, please contact the SIG: Kernel, and any of the maintainers.

Li Lingfeng 创建了任务
openeuler-ci-bot 添加了
 
sig/Kernel
标签
展开全部操作日志

社区讨论:
https://lore.kernel.org/all/20201011075913.GA8065@eldamar.lan/#t

问题场景为 nfs4_set_delegation() 异常流程与 nfsd4_cb_recall_prepare() 流程并发,导致已被释放的 nfs4_delegation 被插入 del_recall_lru 链表后继续访问

修复补丁: 548ec0805c39 "nfsd: fix use-after-free due to delegation race"

// 分配释放 delegation ———— 正常流程
nfs4_open_delegation
 // set delegation
 nfs4_set_delegation
  alloc_init_deleg
   delegstateid
    nfs4_alloc_stid
     kmem_cache_zalloc // 从 deleg_slab 中分配 nfs4_stid
                       // nfs4_stid 是 nfs4_delegation 的第一个成员,
                       // 指向nfs4_stid的指针即指向nfs4_delegation的指针
     refcount_set(&stid->sc_count, 1) // 初始化 nfs4_stid 计数
  hash_delegation_locked // 没有冲突则执行
   refcount_inc(&dp->dl_stid.sc_count) // 增加 nfs4_stid 计数
   list_add(&dp->dl_perfile, &fp->fi_delegations)
 nfs4_put_stid
  refcount_dec_and_lock(&s->sc_count, &clp->cl_lock) // 减少 nfs4_stid 计数


// 分配释放 delegation ———— 异常流程
nfs4_open_delegation
 nfs4_set_delegation
  alloc_init_deleg
   delegstateid
    nfs4_alloc_stid
     kmem_cache_zalloc
     refcount_set(&stid->sc_count, 1) // 初始化 nfs4_stid 计数
  fp->fi_had_conflict // 有冲突
  nfs4_put_stid
   refcount_dec_and_lock(&s->sc_count, &clp->cl_lock) // 减少 nfs4_stid 计数
   sc_free // 若 nfs4_stid 计数减为0,则释放 nfs4_stid 即 nfs4_delegation
  put_deleg_file
   --fp->fi_delegees // fp->fi_delegees 减为0


// 分配 delegation 后,释放 delegation 前加入链表 del_recall_lru
// recall
nfsd4_run_cb
 queue_work(callback_wq, &cb->cb_work)

nfsd4_run_cb_work
 cb->cb_ops->prepare

nfsd4_cb_recall_prepare
 // 修复补丁: 在将 delegation 添加到 del_recall_lru 链表前增加 delegation_hashed() 判断
 // 如果 dp->dl_perfile 非空,说明在 nfs4_set_delegation() 流程中已经执行了 hash_delegation_locked()
 // 进一步说明 nfs4_stid(nfs4_delegation) 没有释放,可以插入链表
 list_add_tail(&dp->dl_recall_lru, &nn->del_recall_lru)
异常栈分析:

[7416735.513815] WARNING: CPU: 5 PID: 150353 at fs/nfsd/nfs4state.c:4741 laundromat_main+0x210/0x600 [nfsd]
1) WARNING
// delegation 加入 del_recall_lru 链表(dl_recall_lru),未加入 fi_delegations 链表(dl_perfile)
laundromat_main
 nfs4_laundromat
  list_for_each_safe(pos, next, &nn->del_recall_lru)
   WARN_ON(!unhash_delegation_locked(dp))
    // dp->dl_perfile 为空,unhash_delegation_locked 返回 false,触发 WARNING


[7416735.513904] list_del corruption. prev->next should be ffff8df5d2b8d3f0, but was ffffa4d7de533e50
[7416735.513913] WARNING: CPU: 5 PID: 150353 at lib/list_debug.c:53 __list_del_entry_valid+0x79/0x90
2) WARNING
// 待删除的 delegation 的前置结点的后置结点不是该 delegation
// 当前 delegation 已不在原链表中
1. 基于基本问题场景,delegation 被加入 del_recall_lru 的同时,已经被释放
2. 原 delegation 所在内存区域重新分配并初始化
3. 新的 dp->dl_perfile 插入 fi_delegations 链表与原 del_recall_lru 链表中的 delegation 删除并发(新旧两个 delegation 使用同一块内存,但对应不同的文件,无法按预期通过 fp->fi_lock 防止并发)
laundromat_main
 nfs4_laundromat
  list_for_each_safe(pos, next, &nn->del_recall_lru)
   unhash_delegation_locked
    list_del_init // &dp->dl_perfile
     __list_del_entry
      __list_del_entry_valid


[7416735.514198] WARNING: CPU: 5 PID: 150353 at fs/nfsd/nfs4state.c:899 destroy_unhashed_deleg+0x75/0x80 [nfsd]
3) WARNING
laundromat_main
 nfs4_laundromat
  revoke_delegation
   destroy_unhashed_deleg
    nfs4_unlock_deleg_lease
     WARN_ON_ONCE(!fp->fi_delegees) // fp->fi_delegees 已减为0


[7416735.514257] BUG: unable to handle kernel NULL pointer dereference at 0000000000000028
destroy_unhashed_deleg
4) BUG
laundromat_main
 nfs4_laundromat
  revoke_delegation
   destroy_unhashed_deleg
    nfs4_put_stid // dp->dl_stid 作为 delegation 内嵌成员,所在的内存区域已释放(通过kmem_cache_zalloc()重新分配并初始化成0?),解析该地址触发空指针解引用

登录 后才可以发表评论

状态
负责人
项目
里程碑
Pull Requests
关联的 Pull Requests 被合并后可能会关闭此 issue
分支
开始日期   -   截止日期
-
置顶选项
优先级
预计工期 (小时)
参与者(2)
5329419 openeuler ci bot 1632792936
C
1
https://gitee.com/openeuler/kernel.git
git@gitee.com:openeuler/kernel.git
openeuler
kernel
kernel

搜索帮助