ipaddr_to_string is used in many places including runtime logging.
Handling its memory allocation is annoyingly fiddly. Indeed there is
at least one possible memory leak, which represents a potential denial
of service bug.
None of the callers keep the answers for any length of time.
So make it return the next one of a series of round-robin buffers,
instead, and remove all the freeing at all the call sites.
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
+#define IPADDR_NBUFS_SHIFT 4
+#define IPADDR_NBUFS (1 << IPADDR_NBUFS_SHIFT)
+#define IPADDR_BUFLEN 20
+
+static char *ipaddr_getbuf(void)
+{
+ static int ipaddr_bufnum;
+ static char ipaddr_bufs[IPADDR_NBUFS][IPADDR_BUFLEN];
+
+ ipaddr_bufnum++;
+ ipaddr_bufnum &= IPADDR_NBUFS-1;
+ return ipaddr_bufs[ipaddr_bufnum];
+}
+
/* The string buffer must be at least 16 bytes long */
string_t ipaddr_to_string(uint32_t addr)
{
uint8_t a,b,c,d;
string_t s;
/* The string buffer must be at least 16 bytes long */
string_t ipaddr_to_string(uint32_t addr)
{
uint8_t a,b,c,d;
string_t s;
- s=safe_malloc(16,"ipaddr_to_string");
a=addr>>24;
b=addr>>16;
c=addr>>8;
a=addr>>24;
b=addr>>16;
c=addr>>8;
d=ipaddr_to_string(dest);
Message(M_ERR,"%s: dropping %s->%s, client not registered\n",
st->name,s,d);
d=ipaddr_to_string(dest);
Message(M_ERR,"%s: dropping %s->%s, client not registered\n",
st->name,s,d);
d=ipaddr_to_string(dest);
Message(M_DEBUG,"%s: don't know where to deliver packet "
"(s=%s, d=%s)\n", st->name, s, d);
d=ipaddr_to_string(dest);
Message(M_DEBUG,"%s: don't know where to deliver packet "
"(s=%s, d=%s)\n", st->name, s, d);
netlink_icmp_simple(st,sender,buf,ICMP_TYPE_UNREACHABLE,
ICMP_CODE_NET_UNREACHABLE, icmp_noinfo);
BUF_FREE(buf);
netlink_icmp_simple(st,sender,buf,ICMP_TYPE_UNREACHABLE,
ICMP_CODE_NET_UNREACHABLE, icmp_noinfo);
BUF_FREE(buf);
with destination network administratively prohibited */
Message(M_NOTICE,"%s: denied forwarding for packet (s=%s, d=%s)\n",
st->name,s,d);
with destination network administratively prohibited */
Message(M_NOTICE,"%s: denied forwarding for packet (s=%s, d=%s)\n",
st->name,s,d);
netlink_icmp_simple(st,sender,buf,ICMP_TYPE_UNREACHABLE,
ICMP_CODE_NET_PROHIBITED, icmp_noinfo);
netlink_icmp_simple(st,sender,buf,ICMP_TYPE_UNREACHABLE,
ICMP_CODE_NET_PROHIBITED, icmp_noinfo);
d=ipaddr_to_string(dest);
Message(M_WARNING,"%s: packet from tunnel %s with bad "
"source address (s=%s,d=%s)\n",st->name,sender->name,s,d);
d=ipaddr_to_string(dest);
Message(M_WARNING,"%s: packet from tunnel %s with bad "
"source address (s=%s,d=%s)\n",st->name,sender->name,s,d);
d=ipaddr_to_string(dest);
Message(M_WARNING,"%s: outgoing packet with bad source address "
"(s=%s,d=%s)\n",st->name,s,d);
d=ipaddr_to_string(dest);
Message(M_WARNING,"%s: outgoing packet with bad source address "
"(s=%s,d=%s)\n",st->name,s,d);
net=ipaddr_to_string(st->secnet_address);
Message(c,"%s: point-to-point (remote end is %s); routes: ",
st->name, net);
net=ipaddr_to_string(st->secnet_address);
Message(c,"%s: point-to-point (remote end is %s); routes: ",
st->name, net);
netlink_output_subnets(st,c,st->clients->subnets);
Message(c,"\n");
} else {
netlink_output_subnets(st,c,st->clients->subnets);
Message(c,"\n");
} else {
net=ipaddr_to_string(st->secnet_address);
Message(c,"%s/32 -> netlink \"%s\" (use %d)\n",
net,st->name,st->localcount);
net=ipaddr_to_string(st->secnet_address);
Message(c,"%s/32 -> netlink \"%s\" (use %d)\n",
net,st->name,st->localcount);
for (i=0; i<st->subnets->entries; i++) {
net=subnet_to_string(st->subnets->list[i]);
Message(c,"%s ",net);
for (i=0; i<st->subnets->entries; i++) {
net=subnet_to_string(st->subnets->list[i]);
Message(c,"%s ",net);
fatal("tun_set_route: unsupported route command type");
break;
}
fatal("tun_set_route: unsupported route command type");
break;
}
- free(network); free(mask);
if (st->route_type==TUN_CONFIG_IOCTL) {
close(fd);
}
if (st->route_type==TUN_CONFIG_IOCTL) {
close(fd);
}