diff options
| author | Patrick McHardy <kaber@trash.net> | 2010-04-08 07:35:47 -0400 |
|---|---|---|
| committer | Patrick McHardy <kaber@trash.net> | 2010-04-08 07:35:47 -0400 |
| commit | 3d91c1a848c812e0e66e7e57f076667822cb460e (patch) | |
| tree | cd5c6a16e0f48f99045e032a4ceb8946ec9d7ef0 | |
| parent | 02e4eb75912a5c8babccc1acdc9cc913989be04e (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>
| -rw-r--r-- | net/netfilter/ipvs/ip_vs_proto.c | 28 | ||||
| -rw-r--r-- | net/netfilter/ipvs/ip_vs_proto_ah_esp.c | 14 |
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 | ||
