Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

netfilter: pptp: attach nat extension when needed

make sure nat extension gets added if the master conntrack is subject to
NAT. This will be required once the nat core stops adding it by default.

Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>

authored by

Florian Westphal and committed by
Pablo Neira Ayuso
2fe7c321 ff459018

+31 -6
+21 -4
net/ipv4/netfilter/nf_nat_pptp.c
··· 49 49 const struct nf_ct_pptp_master *ct_pptp_info; 50 50 const struct nf_nat_pptp *nat_pptp_info; 51 51 struct nf_nat_range range; 52 + struct nf_conn_nat *nat; 52 53 54 + nat = nf_ct_nat_ext_add(ct); 55 + if (WARN_ON_ONCE(!nat)) 56 + return; 57 + 58 + nat_pptp_info = &nat->help.nat_pptp_info; 53 59 ct_pptp_info = nfct_help_data(master); 54 - nat_pptp_info = &nfct_nat(master)->help.nat_pptp_info; 55 60 56 61 /* And here goes the grand finale of corrosion... */ 57 62 if (exp->dir == IP_CT_DIR_ORIGINAL) { ··· 125 120 126 121 { 127 122 struct nf_ct_pptp_master *ct_pptp_info; 123 + struct nf_conn_nat *nat = nfct_nat(ct); 128 124 struct nf_nat_pptp *nat_pptp_info; 129 125 u_int16_t msg; 130 126 __be16 new_callid; 131 127 unsigned int cid_off; 132 128 129 + if (WARN_ON_ONCE(!nat)) 130 + return NF_DROP; 131 + 132 + nat_pptp_info = &nat->help.nat_pptp_info; 133 133 ct_pptp_info = nfct_help_data(ct); 134 - nat_pptp_info = &nfct_nat(ct)->help.nat_pptp_info; 135 134 136 135 new_callid = ct_pptp_info->pns_call_id; 137 136 ··· 200 191 struct nf_conntrack_expect *expect_reply) 201 192 { 202 193 const struct nf_conn *ct = expect_orig->master; 194 + struct nf_conn_nat *nat = nfct_nat(ct); 203 195 struct nf_ct_pptp_master *ct_pptp_info; 204 196 struct nf_nat_pptp *nat_pptp_info; 205 197 198 + if (WARN_ON_ONCE(!nat)) 199 + return; 200 + 201 + nat_pptp_info = &nat->help.nat_pptp_info; 206 202 ct_pptp_info = nfct_help_data(ct); 207 - nat_pptp_info = &nfct_nat(ct)->help.nat_pptp_info; 208 203 209 204 /* save original PAC call ID in nat_info */ 210 205 nat_pptp_info->pac_call_id = ct_pptp_info->pac_call_id; ··· 236 223 union pptp_ctrl_union *pptpReq) 237 224 { 238 225 const struct nf_nat_pptp *nat_pptp_info; 226 + struct nf_conn_nat *nat = nfct_nat(ct); 239 227 u_int16_t msg; 240 228 __be16 new_pcid; 241 229 unsigned int pcid_off; 242 230 243 - nat_pptp_info = &nfct_nat(ct)->help.nat_pptp_info; 231 + if (WARN_ON_ONCE(!nat)) 232 + return NF_DROP; 233 + 234 + nat_pptp_info = &nat->help.nat_pptp_info; 244 235 new_pcid = nat_pptp_info->pns_call_id; 245 236 246 237 switch (msg = ntohs(ctlh->messageType)) {
+10 -2
net/netfilter/nf_conntrack_pptp.c
··· 263 263 goto out_put_both; 264 264 } 265 265 266 - static inline int 266 + static int 267 267 pptp_inbound_pkt(struct sk_buff *skb, unsigned int protoff, 268 268 struct PptpControlHeader *ctlh, 269 269 union pptp_ctrl_union *pptpReq, ··· 391 391 return NF_ACCEPT; 392 392 } 393 393 394 - static inline int 394 + static int 395 395 pptp_outbound_pkt(struct sk_buff *skb, unsigned int protoff, 396 396 struct PptpControlHeader *ctlh, 397 397 union pptp_ctrl_union *pptpReq, ··· 523 523 int ret; 524 524 u_int16_t msg; 525 525 526 + #if IS_ENABLED(CONFIG_NF_NAT) 527 + if (!nf_ct_is_confirmed(ct) && (ct->status & IPS_NAT_MASK)) { 528 + struct nf_conn_nat *nat = nf_ct_ext_find(ct, NF_CT_EXT_NAT); 529 + 530 + if (!nat && !nf_ct_ext_add(ct, NF_CT_EXT_NAT, GFP_ATOMIC)) 531 + return NF_DROP; 532 + } 533 + #endif 526 534 /* don't do any tracking before tcp handshake complete */ 527 535 if (ctinfo != IP_CT_ESTABLISHED && ctinfo != IP_CT_ESTABLISHED_REPLY) 528 536 return NF_ACCEPT;