CVE-2023-4015[TODO]


环境搭建

version: v6.4.0

commit: 6995e2de6891c724bfeb2db33d7b87775f913ad1

config: defconfig +

CONFIG_USER_NS=y
CONFIG_SECURITY_SELINUX_DISABLE=y
# for debug
CONFIG_KALLSYMS=y
CONFIG_KALLSYMS_ALL=y
CONFIG_DEBUG_INFO_DWARF4=y
# for msg_msg copy
CONFIG_CHECKPOINT_RESTORE=y
# for syzkaller image
CONFIG_CONFIGFS_FS=y
CONFIG_SECURITYFS=y

CONFIG_SLAB_FREELIST_RANDOM=n
CONFIG_SLAB_FREELIST_HARDENED=n
CONFIG_SHUFFLE_PAGE_ALLOCATOR=n
CONFIG_HARDENED_USERCOPY=n
CONFIG_FORTIFY_SOURCE=n
CONFIG_STATIC_USERMODEHELPER=n
CONFIG_DEBUG_INFO_NONE=n
CONFIG_RANDOMIZE_BASE=n

CONFIG_DEBUG_INFO=y #调试

CONFIG_NETFILTER=y
CONFIG_NF_TABLES=y

make CFLAGS_KERNEL="-g" CFLAGS_MODULE="-g" -j144

immediate-expr

先看其init:

1748518426967

1748518395957

1748518293485

漏洞成因

https://elixir.bootlin.com/linux/v6.4/source/net/netfilter/nf_tables_api.c#L3920

nf_tables_newrule函数中,添加一个rule,同时给rule添加expr,如果添加immediate类型的expr后,在添加其他expr时遇到错误,走到err_release_rule的错误处理:

1748517270911

1748517529929

nft_rule_expr_deactive

会首先调用nft_rule_expr_deactive函数,起作用时调用rule中每一个expr的deactive函数进行析构:

1748517302746

对于immediate类型的rule而言,其deactivate函数是nft_immediate_deactivate:https://elixir.bootlin.com/linux/v6.4/source/net/netfilter/nft_immediate.c#L128

1748517610092

rule有immediate类型的expr,该expr又关联chain,chain又有多个rule,此时就是把这个chain的所有rule的expr给解除掉;

nf_tables_unbind_chain的作用是在commit_list中找本chain所在的那个trans,找到后对trans进行如下设置:

(((struct nft_trans_rule *)trans->data)->bound) = false;

fallthrough会是switch继续走下一个case,调用nft_deactive_next函数,该函数的作用是:

chain->genmask = (1 << READ_ONCE(net->nft.gencurksor));

可能此时chain在commit_llist中就不活跃了?🤔

总结来看,expr一般都会和其他结构有关联,比如lookup会和set产生关联,而这里的immediate会和chain产生关联,而deactive的作用就是让产生关联的对象失效;

nf_tables_rule_destroy

nf_tables_rule_destroy函数的作用是依次调用rule的所有expr的destroy函数,expr的destroy就是减少关联对象(这里是chain)的引用计数,并在引用计数为0的情况下将其释放,处理完这些之后释放掉rule(expr内嵌在rule里边,所以不需要专门释放):

1748518672444

1748518687942

1748518709166

1748518797553

在批处理中间的iov的时候,如果err==0,会继续处理下一个iov,直到全都成功之后调用ss->commit;

如果出现错误,要是err == -EAGAIN,会给status加一个NFNL_BATCH_REPLAY标记,然后直接走ss->abort,如果有NFNL_BATCH_REPLAY标记就replay重新执行,否则就直接结束了;

总结

nfnetlink_rcv_batch:
begin...
nc->call ==> nf_tables_newrule
err_release_rule:
nft_rule_expr_deactive{
调用每一个expr的deactivate函数,对于immediate类型来说就是
}
nf_tables_rule_destroy{

}
end...
ss->abort
//......
case NFT_MSG_NEWRULE:


POC

参考

https://github.com/google/security-research/blob/master/pocs/linux/kernelctf/CVE-2023-4015_lts/docs/vulnerability.md

https://github.com/google/security-research/blob/master/pocs/linux/kernelctf/CVE-2023-4015_lts/docs/exploit.md


文章作者: q1ming
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 q1ming !
  目录