buffer overflow in dns.c pointed out by Matus Harvan, also strncpy cleanups

This commit is contained in:
Bjorn Andersson 2007-08-26 15:47:32 +00:00
parent b0c6924a8e
commit 488412d4e6
6 changed files with 27 additions and 21 deletions

View File

@ -28,6 +28,8 @@
#define MAX(a,b) ((a)>(b)?(a):(b)) #define MAX(a,b) ((a)>(b)?(a):(b))
#endif #endif
#define QUERY_NAME_SIZE 256
struct packet struct packet
{ {
int len; /* Total packet length */ int len; /* Total packet length */
@ -37,7 +39,7 @@ struct packet
}; };
struct query { struct query {
char name[258]; char name[QUERY_NAME_SIZE];
short type; short type;
short id; short id;
struct sockaddr from; struct sockaddr from;

View File

@ -61,7 +61,7 @@ dns_encode(char *buf, size_t buflen, struct query *q, qr_t qr, char *data, size_
name = 0xc000 | ((p - buf) & 0x3fff); name = 0xc000 | ((p - buf) & 0x3fff);
putname(&p, 256, q->name); putname(&p, sizeof(q->name), q->name);
putshort(&p, q->type); putshort(&p, q->type);
putshort(&p, C_IN); putshort(&p, C_IN);
@ -78,7 +78,7 @@ dns_encode(char *buf, size_t buflen, struct query *q, qr_t qr, char *data, size_
header->qdcount = htons(1); header->qdcount = htons(1);
header->arcount = htons(1); header->arcount = htons(1);
putname(&p, 256, data); putname(&p, datalen, data);
putshort(&p, q->type); putshort(&p, q->type);
putshort(&p, C_IN); putshort(&p, C_IN);
@ -101,11 +101,11 @@ dns_encode(char *buf, size_t buflen, struct query *q, qr_t qr, char *data, size_
int int
dns_decode(char *buf, size_t buflen, struct query *q, qr_t qr, char *packet, size_t packetlen) dns_decode(char *buf, size_t buflen, struct query *q, qr_t qr, char *packet, size_t packetlen)
{ {
char name[QUERY_NAME_SIZE];
char rdata[4*1024]; char rdata[4*1024];
HEADER *header; HEADER *header;
short qdcount; short qdcount;
short ancount; short ancount;
char name[255];
uint32_t ttl; uint32_t ttl;
short class; short class;
short type; short type;
@ -189,8 +189,8 @@ dns_decode(char *buf, size_t buflen, struct query *q, qr_t qr, char *packet, siz
return -1; return -1;
} }
readname(packet, packetlen, &data, name, sizeof(name) -1); readname(packet, packetlen, &data, name, sizeof(name) - 1);
name[256] = 0; name[sizeof(name)-1] = '\0';
readshort(packet, &data, &type); readshort(packet, &data, &type);
readshort(packet, &data, &class); readshort(packet, &data, &class);
@ -199,7 +199,8 @@ dns_decode(char *buf, size_t buflen, struct query *q, qr_t qr, char *packet, siz
break; break;
} }
strncpy(q->name, name, 257); strncpy(q->name, name, sizeof(q->name));
q->name[sizeof(q->name) - 1] = '\0';
q->type = type; q->type = type;
q->id = id; q->id = id;

View File

@ -654,8 +654,8 @@ main(int argc, char **argv)
device = optarg; device = optarg;
break; break;
case 'P': case 'P':
strncpy(password, optarg, 32); strncpy(password, optarg, sizeof(password));
password[32] = 0; password[sizeof(password)-1] = 0;
/* XXX: find better way of cleaning up ps(1) */ /* XXX: find better way of cleaning up ps(1) */
memset(optarg, 0, strlen(optarg)); memset(optarg, 0, strlen(optarg));

View File

@ -495,8 +495,8 @@ main(int argc, char **argv)
} }
break; break;
case 'P': case 'P':
strncpy(password, optarg, 32); strncpy(password, optarg, sizeof(password));
password[32] = 0; password[sizeof(password)-1] = 0;
/* XXX: find better way of cleaning up ps(1) */ /* XXX: find better way of cleaning up ps(1) */
memset(optarg, 0, strlen(optarg)); memset(optarg, 0, strlen(optarg));

View File

@ -58,7 +58,9 @@ open_tun(const char *tun_device)
if (tun_device != NULL) { if (tun_device != NULL) {
strncpy(ifreq.ifr_name, tun_device, IFNAMSIZ); strncpy(ifreq.ifr_name, tun_device, IFNAMSIZ);
ifreq.ifr_name[IFNAMSIZ-1] = '\0';
strncpy(if_name, tun_device, sizeof(if_name)); strncpy(if_name, tun_device, sizeof(if_name));
if_name[sizeof(if_name)-1] = '\0';
if (ioctl(tun_fd, TUNSETIFF, (void *) &ifreq) != -1) { if (ioctl(tun_fd, TUNSETIFF, (void *) &ifreq) != -1) {
printf("Opened %s\n", ifreq.ifr_name); printf("Opened %s\n", ifreq.ifr_name);
@ -102,6 +104,7 @@ open_tun(const char *tun_device)
if (tun_device != NULL) { if (tun_device != NULL) {
snprintf(tun_name, sizeof(tun_name), "/dev/%s", tun_device); snprintf(tun_name, sizeof(tun_name), "/dev/%s", tun_device);
strncpy(if_name, tun_device, sizeof(if_name)); strncpy(if_name, tun_device, sizeof(if_name));
if_name[sizeof(if_name)-1] = '\0';
if ((tun_fd = open(tun_name, O_RDWR)) < 0) { if ((tun_fd = open(tun_name, O_RDWR)) < 0) {
warn("open_tun: %s: %s", tun_name, strerror(errno)); warn("open_tun: %s: %s", tun_name, strerror(errno));
@ -140,7 +143,7 @@ close_tun(int tun_fd)
} }
int int
write_tun(int tun_fd, char *data, int len) write_tun(int tun_fd, char *data, size_t len)
{ {
#if defined (FREEBSD) || defined (DARWIN) || defined(NETBSD) #if defined (FREEBSD) || defined (DARWIN) || defined(NETBSD)
data += 4; data += 4;
@ -166,8 +169,8 @@ write_tun(int tun_fd, char *data, int len)
return 0; return 0;
} }
int ssize_t
read_tun(int tun_fd, char *buf, int len) read_tun(int tun_fd, char *buf, size_t len)
{ {
#if defined (FREEBSD) || defined (DARWIN) || defined(NETBSD) #if defined (FREEBSD) || defined (DARWIN) || defined(NETBSD)
/* FreeBSD/Darwin/NetBSD has no header */ /* FreeBSD/Darwin/NetBSD has no header */
@ -213,20 +216,20 @@ tun_setip(const char *ip)
} }
int int
tun_setmtu(const int mtu) tun_setmtu(const size_t mtu)
{ {
char cmdline[512]; char cmdline[512];
if (mtu > 200 && mtu < 1500) { if (mtu > 200 && mtu < 1500) {
snprintf(cmdline, sizeof(cmdline), snprintf(cmdline, sizeof(cmdline),
"/sbin/ifconfig %s mtu %d", "/sbin/ifconfig %s mtu %ld",
if_name, if_name,
mtu); mtu);
printf("Setting MTU of %s to %d\n", if_name, mtu); printf("Setting MTU of %s to %ld\n", if_name, mtu);
return system(cmdline); return system(cmdline);
} else { } else {
warn("MTU out of range: %d\n", mtu); warn("MTU out of range: %ld\n", mtu);
} }
return 1; return 1;

View File

@ -19,9 +19,9 @@
int open_tun(const char *); int open_tun(const char *);
void close_tun(int); void close_tun(int);
int write_tun(int, char *, int); int write_tun(int, char *, size_t);
int read_tun(int, char *, int); ssize_t read_tun(int, char *, size_t);
int tun_setip(const char *); int tun_setip(const char *);
int tun_setmtu(const int); int tun_setmtu(const size_t);
#endif /* _TUN_H_ */ #endif /* _TUN_H_ */