With the previous patches in place, a netns nf_hook_list might be empty, even if e.g. init_net performs filtering. Thus change nf_hook_thresh to check the hook_list as well before initializing hook_state and calling nf_hook_slow(). We still make use of static keys; if no netfilter modules are loaded list is guaranteed to be empty.
Unified · Split
| @@ -141,22 +141,6 @@ void nf_unregister_sockopt(struct nf_sockopt_ops *reg); · 140 unmodified lines | ||
| 141 | 141 | |
| 142 | 142 | #ifdef HAVE_JUMP_LABEL |
| 143 | 143 | extern struct static_key nf_hooks_needed[NFPROTO_NUMPROTO][NF_MAX_HOOKS]; |
| 144 | − | |
| 145 | −static inline bool nf_hook_list_active(struct list_head *hook_list, | |
| 146 | − u_int8_t pf, unsigned int hook) | |
| 147 | −{ | |
| 148 | − if (__builtin_constant_p(pf) && | |
| 149 | − __builtin_constant_p(hook)) | |
| 150 | − return static_key_false(&nf_hooks_needed[pf][hook]); | |
| 151 | − | |
| 152 | − return !list_empty(hook_list); | |
| 153 | −} | |
| 154 | −#else | |
| 155 | −static inline bool nf_hook_list_active(struct list_head *hook_list, | |
| 156 | − u_int8_t pf, unsigned int hook) | |
| 157 | −{ | |
| 158 | − return !list_empty(hook_list); | |
| 159 | −} | |
| 160 | 144 | #endif |
| 161 | 145 | |
| 162 | 146 | int nf_hook_slow(struct sk_buff *skb, struct nf_hook_state *state); |
| @@ -177,9 +161,18 @@ static inline int nf_hook_thresh(u_int8_t pf, unsigned int hook, · 14 unmodified lines | ||
| 177 | 161 | int (*okfn)(struct net *, struct sock *, struct sk_buff *), |
| 178 | 162 | int thresh) |
| 179 | 163 | { |
| 180 | − struct list_head *hook_list = &net->nf.hooks[pf][hook]; | |
| 164 | + struct list_head *hook_list; | |
| 165 | + | |
| 166 | +#ifdef HAVE_JUMP_LABEL | |
| 167 | + if (__builtin_constant_p(pf) && | |
| 168 | + __builtin_constant_p(hook) && | |
| 169 | + !static_key_false(&nf_hooks_needed[pf][hook])) | |
| 170 | + return 1; | |
| 171 | +#endif | |
| 172 | + | |
| 173 | + hook_list = &net->nf.hooks[pf][hook]; | |
| 181 | 174 | |
| 182 | − if (nf_hook_list_active(hook_list, pf, hook)) { | |
| 175 | + if (!list_empty(hook_list)) { | |
| 183 | 176 | struct nf_hook_state state; |
| 184 | 177 | |
| 185 | 178 | nf_hook_state_init(&state, hook_list, hook, thresh, |