mirror of
https://github.com/yarrick/iodine.git
synced 2024-11-26 07:51:27 +00:00
Add packet length parameter on readname, add tests
This commit is contained in:
parent
4a4aaa5bb4
commit
aeae642fd8
10
dns.c
10
dns.c
|
@ -309,12 +309,12 @@ dns_parse_reply(char *outbuf, int buflen, char *packet, int packetlen)
|
||||||
rlen = 0;
|
rlen = 0;
|
||||||
|
|
||||||
if(qdcount == 1) {
|
if(qdcount == 1) {
|
||||||
readname(packet, &data, name, sizeof(name));
|
readname(packet, packetlen, &data, name, sizeof(name));
|
||||||
readshort(packet, &data, &type);
|
readshort(packet, &data, &type);
|
||||||
readshort(packet, &data, &class);
|
readshort(packet, &data, &class);
|
||||||
}
|
}
|
||||||
if(ancount == 1) {
|
if(ancount == 1) {
|
||||||
readname(packet, &data, name, sizeof(name));
|
readname(packet, packetlen, &data, name, sizeof(name));
|
||||||
readshort(packet, &data, &type);
|
readshort(packet, &data, &type);
|
||||||
readshort(packet, &data, &class);
|
readshort(packet, &data, &class);
|
||||||
readlong(packet, &data, &ttl);
|
readlong(packet, &data, &ttl);
|
||||||
|
@ -455,7 +455,7 @@ dnsd_read(int fd, struct query *q, char *buf, int buflen)
|
||||||
qdcount = ntohs(header->qdcount);
|
qdcount = ntohs(header->qdcount);
|
||||||
|
|
||||||
if(qdcount == 1) {
|
if(qdcount == 1) {
|
||||||
readname(packet, &data, name, sizeof(name) -1);
|
readname(packet, r, &data, name, sizeof(name) -1);
|
||||||
name[256] = 0;
|
name[256] = 0;
|
||||||
readshort(packet, &data, &type);
|
readshort(packet, &data, &type);
|
||||||
readshort(packet, &data, &class);
|
readshort(packet, &data, &class);
|
||||||
|
@ -469,9 +469,11 @@ dnsd_read(int fd, struct query *q, char *buf, int buflen)
|
||||||
rv = decodepacket(name, buf, buflen);
|
rv = decodepacket(name, buf, buflen);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else if (r < 0) { // Error
|
||||||
perror("recvfrom");
|
perror("recvfrom");
|
||||||
rv = 0;
|
rv = 0;
|
||||||
|
} else { // Packet too small to be dns protocol
|
||||||
|
rv = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
|
|
|
@ -111,7 +111,7 @@ tunnel(int tun_fd, int dns_fd)
|
||||||
}
|
}
|
||||||
if(FD_ISSET(dns_fd, &fds)) {
|
if(FD_ISSET(dns_fd, &fds)) {
|
||||||
read = dnsd_read(dns_fd, &q, in, sizeof(in));
|
read = dnsd_read(dns_fd, &q, in, sizeof(in));
|
||||||
if (read < 0)
|
if (read <= 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if(in[0] == 'H' || in[0] == 'h') {
|
if(in[0] == 'H' || in[0] == 'h') {
|
||||||
|
|
22
read.c
22
read.c
|
@ -15,14 +15,16 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
static int
|
static int
|
||||||
readname_loop(char *packet, char **src, char *dst, size_t length, size_t loop)
|
readname_loop(char *packet, int packetlen, char **src, char *dst, size_t length, size_t loop)
|
||||||
{
|
{
|
||||||
char *dummy;
|
char *dummy;
|
||||||
char *s;
|
char *s;
|
||||||
char *d;
|
char *d;
|
||||||
int len;
|
int len;
|
||||||
|
unsigned offset;
|
||||||
char c;
|
char c;
|
||||||
|
|
||||||
if (loop <= 0)
|
if (loop <= 0)
|
||||||
|
@ -36,8 +38,18 @@ readname_loop(char *packet, char **src, char *dst, size_t length, size_t loop)
|
||||||
|
|
||||||
/* is this a compressed label? */
|
/* is this a compressed label? */
|
||||||
if((c & 0xc0) == 0xc0) {
|
if((c & 0xc0) == 0xc0) {
|
||||||
dummy = packet + (((s[-1] & 0x3f) << 8) | s[0]);
|
offset = (((s[-1] & 0x3f) << 8) | s[0]);
|
||||||
len += readname_loop(packet, &dummy, d, length - len, loop - 1);
|
if (offset > packetlen) {
|
||||||
|
if (len == 0) {
|
||||||
|
// Bad jump first in packet
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
// Bad jump after some data
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dummy = packet + offset;
|
||||||
|
len += readname_loop(packet, packetlen, &dummy, d, length - len, loop - 1);
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,9 +77,9 @@ end:
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
readname(char *packet, char **src, char *dst, size_t length)
|
readname(char *packet, int packetlen, char **src, char *dst, size_t length)
|
||||||
{
|
{
|
||||||
return readname_loop(packet, src, dst, length, 10);
|
return readname_loop(packet, packetlen, src, dst, length, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|
2
read.h
2
read.h
|
@ -17,7 +17,7 @@
|
||||||
#ifndef _READ_H_
|
#ifndef _READ_H_
|
||||||
#define _READ_H_
|
#define _READ_H_
|
||||||
|
|
||||||
int readname(char *, char **, char *, size_t);
|
int readname(char *, int, char **, char *, size_t);
|
||||||
int readshort(char *, char **, short *);
|
int readshort(char *, char **, short *);
|
||||||
int readlong(char *, char **, long *);
|
int readlong(char *, char **, long *);
|
||||||
int readdata(char *, char **, char *, size_t);
|
int readdata(char *, char **, char *, size_t);
|
||||||
|
|
36
test.c
36
test.c
|
@ -129,6 +129,13 @@ test_readname()
|
||||||
char onejump[] =
|
char onejump[] =
|
||||||
"AA\x81\x80\x00\x01\x00\x00\x00\x00\x00\x00"
|
"AA\x81\x80\x00\x01\x00\x00\x00\x00\x00\x00"
|
||||||
"\x02hh\xc0\x15\x00\x01\x00\x01\x05zBCDE\x00";
|
"\x02hh\xc0\x15\x00\x01\x00\x01\x05zBCDE\x00";
|
||||||
|
char badjump[] = {
|
||||||
|
'A', 'A', 0x81, 0x80, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0xfe, 0xcc, 0x00, 0x01, 0x00, 0x01 };
|
||||||
|
char badjump2[] = {
|
||||||
|
'A', 'A', 0x81, 0x80, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x02, 'B', 'A', 0xfe, 0xcc, 0x00, 0x01, 0x00, 0x01 };
|
||||||
|
char *jumper;
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
char *data;
|
char *data;
|
||||||
int rv;
|
int rv;
|
||||||
|
@ -139,26 +146,47 @@ test_readname()
|
||||||
bzero(buf, sizeof(buf));
|
bzero(buf, sizeof(buf));
|
||||||
data = emptyloop + sizeof(HEADER);
|
data = emptyloop + sizeof(HEADER);
|
||||||
buf[1023] = 'A';
|
buf[1023] = 'A';
|
||||||
rv = readname(emptyloop, &data, buf, 1023);
|
rv = readname(emptyloop, sizeof(emptyloop), &data, buf, 1023);
|
||||||
assert(buf[1023] == 'A');
|
assert(buf[1023] == 'A');
|
||||||
|
|
||||||
bzero(buf, sizeof(buf));
|
bzero(buf, sizeof(buf));
|
||||||
data = infloop + sizeof(HEADER);
|
data = infloop + sizeof(HEADER);
|
||||||
buf[4] = '\a';
|
buf[4] = '\a';
|
||||||
rv = readname(infloop, &data, buf, 4);
|
rv = readname(infloop, sizeof(infloop), &data, buf, 4);
|
||||||
assert(buf[4] == '\a');
|
assert(buf[4] == '\a');
|
||||||
|
|
||||||
bzero(buf, sizeof(buf));
|
bzero(buf, sizeof(buf));
|
||||||
data = longname + sizeof(HEADER);
|
data = longname + sizeof(HEADER);
|
||||||
buf[256] = '\a';
|
buf[256] = '\a';
|
||||||
rv = readname(longname, &data, buf, 256);
|
rv = readname(longname, sizeof(longname), &data, buf, 256);
|
||||||
assert(buf[256] == '\a');
|
assert(buf[256] == '\a');
|
||||||
|
|
||||||
bzero(buf, sizeof(buf));
|
bzero(buf, sizeof(buf));
|
||||||
data = onejump + sizeof(HEADER);
|
data = onejump + sizeof(HEADER);
|
||||||
rv = readname(onejump, &data, buf, 256);
|
rv = readname(onejump, sizeof(onejump), &data, buf, 256);
|
||||||
assert(rv == 9);
|
assert(rv == 9);
|
||||||
|
|
||||||
|
// These two tests use malloc to fail with segfault if jump is executed
|
||||||
|
bzero(buf, sizeof(buf));
|
||||||
|
jumper = malloc(sizeof(badjump));
|
||||||
|
if (jumper) {
|
||||||
|
memcpy(jumper, badjump, sizeof(badjump));
|
||||||
|
data = jumper + sizeof(HEADER);
|
||||||
|
rv = readname(jumper, sizeof(badjump), &data, buf, 256);
|
||||||
|
assert(rv == 0);
|
||||||
|
}
|
||||||
|
free(jumper);
|
||||||
|
|
||||||
|
bzero(buf, sizeof(buf));
|
||||||
|
jumper = malloc(sizeof(badjump2));
|
||||||
|
if (jumper) {
|
||||||
|
memcpy(jumper, badjump2, sizeof(badjump2));
|
||||||
|
data = jumper + sizeof(HEADER);
|
||||||
|
rv = readname(jumper, sizeof(badjump2), &data, buf, 256);
|
||||||
|
assert(rv == 4);
|
||||||
|
}
|
||||||
|
free(jumper);
|
||||||
|
|
||||||
printf("OK\n");
|
printf("OK\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue