环境搭建
version: v6.4.0
commit: 6995e2de6891c724bfeb2db33d7b87775f913ad1
config: defconfig +
CONFIG_USER_NS=y |
make CFLAGS_KERNEL="-g" CFLAGS_MODULE="-g" -j144 |
immediate-expr
先看其init:
漏洞成因
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的错误处理:
nft_rule_expr_deactive
会首先调用nft_rule_expr_deactive
函数,起作用时调用rule中每一个expr的deactive函数进行析构:
对于immediate类型的rule而言,其deactivate函数是nft_immediate_deactivate
:https://elixir.bootlin.com/linux/v6.4/source/net/netfilter/nft_immediate.c#L128
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里边,所以不需要专门释放):
在批处理中间的iov的时候,如果err==0,会继续处理下一个iov,直到全都成功之后调用ss->commit;
如果出现错误,要是err == -EAGAIN,会给status加一个NFNL_BATCH_REPLAY标记,然后直接走ss->abort,如果有NFNL_BATCH_REPLAY标记就replay重新执行,否则就直接结束了;
总结
nfnetlink_rcv_batch: |