aboutsummaryrefslogtreecommitdiffstats
path: root/net/netfilter
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2010-04-08 07:35:47 -0400
committerPatrick McHardy <kaber@trash.net>2010-04-08 07:35:47 -0400
commit3d91c1a848c812e0e66e7e57f076667822cb460e (patch)
treecd5c6a16e0f48f99045e032a4ceb8946ec9d7ef0 /net/netfilter
parent02e4eb75912a5c8babccc1acdc9cc913989be04e (diff)
IPVS: fix potential stack overflow with overly long protocol names
When protocols use very long names, the sprintf calls might overflow the on-stack buffer. No protocol in the kernel does this however. Print the protocol name in the pr_debug statement directly to avoid this. Based on patch by Zhitong Wang <zhitong.wangzt@alibaba-inc.com> Acked-by: Simon Horman <horms@verge.net.au> Signed-off-by: Patrick McHardy <kaber@trash.net>
Diffstat (limited to 'net/netfilter')
-rw-r--r--net/netfilter/ipvs/ip_vs_proto.c28
-rw-r--r--net/netfilter/ipvs/ip_vs_proto_ah_esp.c14
2 files changed, 18 insertions, 24 deletions
diff --git a/net/netfilter/ipvs/ip_vs_proto.c b/net/netfilter/ipvs/ip_vs_proto.c
index 0e584553819d..27add971bb13 100644
--- a/net/netfilter/ipvs/ip_vs_proto.c
+++ b/net/netfilter/ipvs/ip_vs_proto.c
@@ -166,26 +166,24 @@ ip_vs_tcpudp_debug_packet_v4(struct ip_vs_protocol *pp,
166 166
167 ih = skb_header_pointer(skb, offset, sizeof(_iph), &_iph); 167 ih = skb_header_pointer(skb, offset, sizeof(_iph), &_iph);
168 if (ih == NULL) 168 if (ih == NULL)
169 sprintf(buf, "%s TRUNCATED", pp->name); 169 sprintf(buf, "TRUNCATED");
170 else if (ih->frag_off & htons(IP_OFFSET)) 170 else if (ih->frag_off & htons(IP_OFFSET))
171 sprintf(buf, "%s %pI4->%pI4 frag", 171 sprintf(buf, "%pI4->%pI4 frag", &ih->saddr, &ih->daddr);
172 pp->name, &ih->saddr, &ih->daddr);
173 else { 172 else {
174 __be16 _ports[2], *pptr 173 __be16 _ports[2], *pptr
175; 174;
176 pptr = skb_header_pointer(skb, offset + ih->ihl*4, 175 pptr = skb_header_pointer(skb, offset + ih->ihl*4,
177 sizeof(_ports), _ports); 176 sizeof(_ports), _ports);
178 if (pptr == NULL) 177 if (pptr == NULL)
179 sprintf(buf, "%s TRUNCATED %pI4->%pI4", 178 sprintf(buf, "TRUNCATED %pI4->%pI4",
180 pp->name, &ih->saddr, &ih->daddr); 179 &ih->saddr, &ih->daddr);
181 else 180 else
182 sprintf(buf, "%s %pI4:%u->%pI4:%u", 181 sprintf(buf, "%pI4:%u->%pI4:%u",
183 pp->name,
184 &ih->saddr, ntohs(pptr[0]), 182 &ih->saddr, ntohs(pptr[0]),
185 &ih->daddr, ntohs(pptr[1])); 183 &ih->daddr, ntohs(pptr[1]));
186 } 184 }
187 185
188 pr_debug("%s: %s\n", msg, buf); 186 pr_debug("%s: %s %s\n", msg, pp->name, buf);
189} 187}
190 188
191#ifdef CONFIG_IP_VS_IPV6 189#ifdef CONFIG_IP_VS_IPV6
@@ -200,26 +198,24 @@ ip_vs_tcpudp_debug_packet_v6(struct ip_vs_protocol *pp,
200 198
201 ih = skb_header_pointer(skb, offset, sizeof(_iph), &_iph); 199 ih = skb_header_pointer(skb, offset, sizeof(_iph), &_iph);
202 if (ih == NULL) 200 if (ih == NULL)
203 sprintf(buf, "%s TRUNCATED", pp->name); 201 sprintf(buf, "TRUNCATED");
204 else if (ih->nexthdr == IPPROTO_FRAGMENT) 202 else if (ih->nexthdr == IPPROTO_FRAGMENT)
205 sprintf(buf, "%s %pI6->%pI6 frag", 203 sprintf(buf, "%pI6->%pI6 frag", &ih->saddr, &ih->daddr);
206 pp->name, &ih->saddr, &ih->daddr);
207 else { 204 else {
208 __be16 _ports[2], *pptr; 205 __be16 _ports[2], *pptr;
209 206
210 pptr = skb_header_pointer(skb, offset + sizeof(struct ipv6hdr), 207 pptr = skb_header_pointer(skb, offset + sizeof(struct ipv6hdr),
211 sizeof(_ports), _ports); 208 sizeof(_ports), _ports);
212 if (pptr == NULL) 209 if (pptr == NULL)
213 sprintf(buf, "%s TRUNCATED %pI6->%pI6", 210 sprintf(buf, "TRUNCATED %pI6->%pI6",
214 pp->name, &ih->saddr, &ih->daddr); 211 &ih->saddr, &ih->daddr);
215 else 212 else
216 sprintf(buf, "%s %pI6:%u->%pI6:%u", 213 sprintf(buf, "%pI6:%u->%pI6:%u",
217 pp->name,
218 &ih->saddr, ntohs(pptr[0]), 214 &ih->saddr, ntohs(pptr[0]),
219 &ih->daddr, ntohs(pptr[1])); 215 &ih->daddr, ntohs(pptr[1]));
220 } 216 }
221 217
222 pr_debug("%s: %s\n", msg, buf); 218 pr_debug("%s: %s %s\n", msg, pp->name, buf);
223} 219}
224#endif 220#endif
225 221
diff --git a/net/netfilter/ipvs/ip_vs_proto_ah_esp.c b/net/netfilter/ipvs/ip_vs_proto_ah_esp.c
index c30b43c36cd7..1892dfc12fdd 100644
--- a/net/netfilter/ipvs/ip_vs_proto_ah_esp.c
+++ b/net/netfilter/ipvs/ip_vs_proto_ah_esp.c
@@ -136,12 +136,11 @@ ah_esp_debug_packet_v4(struct ip_vs_protocol *pp, const struct sk_buff *skb,
136 136
137 ih = skb_header_pointer(skb, offset, sizeof(_iph), &_iph); 137 ih = skb_header_pointer(skb, offset, sizeof(_iph), &_iph);
138 if (ih == NULL) 138 if (ih == NULL)
139 sprintf(buf, "%s TRUNCATED", pp->name); 139 sprintf(buf, "TRUNCATED");
140 else 140 else
141 sprintf(buf, "%s %pI4->%pI4", 141 sprintf(buf, "%pI4->%pI4", &ih->saddr, &ih->daddr);
142 pp->name, &ih->saddr, &ih->daddr);
143 142
144 pr_debug("%s: %s\n", msg, buf); 143 pr_debug("%s: %s %s\n", msg, pp->name, buf);
145} 144}
146 145
147#ifdef CONFIG_IP_VS_IPV6 146#ifdef CONFIG_IP_VS_IPV6
@@ -154,12 +153,11 @@ ah_esp_debug_packet_v6(struct ip_vs_protocol *pp, const struct sk_buff *skb,
154 153
155 ih = skb_header_pointer(skb, offset, sizeof(_iph), &_iph); 154 ih = skb_header_pointer(skb, offset, sizeof(_iph), &_iph);
156 if (ih == NULL) 155 if (ih == NULL)
157 sprintf(buf, "%s TRUNCATED", pp->name); 156 sprintf(buf, "TRUNCATED");
158 else 157 else
159 sprintf(buf, "%s %pI6->%pI6", 158 sprintf(buf, "%pI6->%pI6", &ih->saddr, &ih->daddr);
160 pp->name, &ih->saddr, &ih->daddr);
161 159
162 pr_debug("%s: %s\n", msg, buf); 160 pr_debug("%s: %s %s\n", msg, pp->name, buf);
163} 161}
164#endif 162#endif
165 163