Skip to content

Commit b8ded73

Browse files
committed
Do bounds checking and length checking.
Don't run past the end of the captured data, and don't run past the end of the packet (i.e., don't make the length variable go negative).
1 parent a65d127 commit b8ded73

File tree

1 file changed

+155
-120
lines changed

1 file changed

+155
-120
lines changed

print-geonet.c

+155-120
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@
4141
Sub-part 1: Media-Independent Functionality
4242
*/
4343

44+
#define GEONET_ADDR_LEN 8
45+
4446
static const struct tok msg_type_values[] = {
4547
{ 0, "CAM" },
4648
{ 1, "DENM" },
@@ -56,16 +58,12 @@ static const struct tok msg_type_values[] = {
5658
};
5759

5860
static void
59-
print_btp_body(const u_char *bp, u_int length)
61+
print_btp_body(const u_char *bp)
6062
{
6163
int version;
6264
int msg_type;
6365
const char *msg_type_str;
6466

65-
if (length <= 2) {
66-
return;
67-
}
68-
6967
/* Assuming ItsDpuHeader */
7068
version = bp[0];
7169
msg_type = bp[1];
@@ -82,8 +80,9 @@ print_btp(const u_char *bp)
8280
printf("; BTP Dst:%u Src:%u", dest, src);
8381
}
8482

85-
static void
86-
print_long_pos_vector(const u_char *bp)
83+
static int
84+
print_long_pos_vector(netdissect_options *ndo,
85+
const u_char *bp)
8786
{
8887
int i;
8988
u_int32_t lat, lon;
@@ -95,10 +94,13 @@ print_long_pos_vector(const u_char *bp)
9594
}
9695
printf(" ");
9796

97+
if (!ND_TTEST2(*(bp+12), 8))
98+
return (-1);
9899
lat = EXTRACT_32BITS(bp+12);
99100
printf("lat:%d ", lat);
100101
lon = EXTRACT_32BITS(bp+16);
101102
printf("lon:%d", lon);
103+
return (0);
102104
}
103105

104106

@@ -109,137 +111,170 @@ print_long_pos_vector(const u_char *bp)
109111
void
110112
geonet_print(netdissect_options *ndo, const u_char *eth, const u_char *bp, u_int length)
111113
{
114+
int version;
115+
int next_hdr;
116+
int hdr_type;
117+
int hdr_subtype;
118+
u_int16_t payload_length;
119+
int hop_limit;
120+
const char *next_hdr_txt = "Unknown";
121+
const char *hdr_type_txt = "Unknown";
122+
int hdr_size = -1;
123+
112124
printf("GeoNet src:%s; ", etheraddr_string(eth+6));
113125

114-
if (length >= 36) {
115-
/* Process Common Header */
116-
int version = bp[0] >> 4;
117-
int next_hdr = bp[0] & 0x0f;
118-
int hdr_type = bp[1] >> 4;
119-
int hdr_subtype = bp[1] & 0x0f;
120-
u_int16_t payload_length = EXTRACT_16BITS(bp+4);
121-
int hop_limit = bp[7];
122-
const char *next_hdr_txt = "Unknown";
123-
const char *hdr_type_txt = "Unknown";
124-
int hdr_size = -1;
126+
/* Process Common Header */
127+
if (length < 36)
128+
goto malformed;
129+
130+
ND_TCHECK2(*bp, 7);
131+
version = bp[0] >> 4;
132+
next_hdr = bp[0] & 0x0f;
133+
hdr_type = bp[1] >> 4;
134+
hdr_subtype = bp[1] & 0x0f;
135+
payload_length = EXTRACT_16BITS(bp+4);
136+
hop_limit = bp[7];
125137

126-
switch (next_hdr) {
127-
case 0: next_hdr_txt = "Any"; break;
128-
case 1: next_hdr_txt = "BTP-A"; break;
129-
case 2: next_hdr_txt = "BTP-B"; break;
130-
case 3: next_hdr_txt = "IPv6"; break;
131-
}
138+
switch (next_hdr) {
139+
case 0: next_hdr_txt = "Any"; break;
140+
case 1: next_hdr_txt = "BTP-A"; break;
141+
case 2: next_hdr_txt = "BTP-B"; break;
142+
case 3: next_hdr_txt = "IPv6"; break;
143+
}
132144

133-
switch (hdr_type) {
134-
case 0: hdr_type_txt = "Any"; break;
135-
case 1: hdr_type_txt = "Beacon"; break;
136-
case 2: hdr_type_txt = "GeoUnicast"; break;
137-
case 3: switch (hdr_subtype) {
138-
case 0: hdr_type_txt = "GeoAnycastCircle"; break;
139-
case 1: hdr_type_txt = "GeoAnycastRect"; break;
140-
case 2: hdr_type_txt = "GeoAnycastElipse"; break;
141-
}
142-
break;
143-
case 4: switch (hdr_subtype) {
144-
case 0: hdr_type_txt = "GeoBroadcastCircle"; break;
145-
case 1: hdr_type_txt = "GeoBroadcastRect"; break;
146-
case 2: hdr_type_txt = "GeoBroadcastElipse"; break;
147-
}
148-
break;
149-
case 5: switch (hdr_subtype) {
150-
case 0: hdr_type_txt = "TopoScopeBcast-SH"; break;
151-
case 1: hdr_type_txt = "TopoScopeBcast-MH"; break;
152-
}
153-
break;
154-
case 6: switch (hdr_subtype) {
155-
case 0: hdr_type_txt = "LocService-Request"; break;
156-
case 1: hdr_type_txt = "LocService-Reply"; break;
157-
}
158-
break;
159-
}
145+
switch (hdr_type) {
146+
case 0: hdr_type_txt = "Any"; break;
147+
case 1: hdr_type_txt = "Beacon"; break;
148+
case 2: hdr_type_txt = "GeoUnicast"; break;
149+
case 3: switch (hdr_subtype) {
150+
case 0: hdr_type_txt = "GeoAnycastCircle"; break;
151+
case 1: hdr_type_txt = "GeoAnycastRect"; break;
152+
case 2: hdr_type_txt = "GeoAnycastElipse"; break;
153+
}
154+
break;
155+
case 4: switch (hdr_subtype) {
156+
case 0: hdr_type_txt = "GeoBroadcastCircle"; break;
157+
case 1: hdr_type_txt = "GeoBroadcastRect"; break;
158+
case 2: hdr_type_txt = "GeoBroadcastElipse"; break;
159+
}
160+
break;
161+
case 5: switch (hdr_subtype) {
162+
case 0: hdr_type_txt = "TopoScopeBcast-SH"; break;
163+
case 1: hdr_type_txt = "TopoScopeBcast-MH"; break;
164+
}
165+
break;
166+
case 6: switch (hdr_subtype) {
167+
case 0: hdr_type_txt = "LocService-Request"; break;
168+
case 1: hdr_type_txt = "LocService-Reply"; break;
169+
}
170+
break;
171+
}
160172

161-
printf("v:%d ", version);
162-
printf("NH:%d-%s ", next_hdr, next_hdr_txt);
163-
printf("HT:%d-%d-%s ", hdr_type, hdr_subtype, hdr_type_txt);
164-
printf("HopLim:%d ", hop_limit);
165-
printf("Payload:%d ", payload_length);
166-
print_long_pos_vector(bp + 8);
173+
printf("v:%d ", version);
174+
printf("NH:%d-%s ", next_hdr, next_hdr_txt);
175+
printf("HT:%d-%d-%s ", hdr_type, hdr_subtype, hdr_type_txt);
176+
printf("HopLim:%d ", hop_limit);
177+
printf("Payload:%d ", payload_length);
178+
if (print_long_pos_vector(ndo, bp + 8) == -1)
179+
goto trunc;
167180

168-
/* Skip Common Header */
169-
length -= 36;
170-
bp += 36;
181+
/* Skip Common Header */
182+
length -= 36;
183+
bp += 36;
171184

172-
/* Process Extended Headers */
173-
switch (hdr_type) {
185+
/* Process Extended Headers */
186+
switch (hdr_type) {
187+
case 0: /* Any */
188+
hdr_size = 0;
189+
break;
190+
case 1: /* Beacon */
191+
hdr_size = 0;
192+
break;
193+
case 2: /* GeoUnicast */
194+
break;
195+
case 3: switch (hdr_subtype) {
196+
case 0: /* GeoAnycastCircle */
197+
break;
198+
case 1: /* GeoAnycastRect */
199+
break;
200+
case 2: /* GeoAnycastElipse */
201+
break;
202+
}
203+
break;
204+
case 4: switch (hdr_subtype) {
205+
case 0: /* GeoBroadcastCircle */
206+
break;
207+
case 1: /* GeoBroadcastRect */
208+
break;
209+
case 2: /* GeoBroadcastElipse */
210+
break;
211+
}
212+
break;
213+
case 5: switch (hdr_subtype) {
214+
case 0: /* TopoScopeBcast-SH */
215+
hdr_size = 0;
216+
break;
217+
case 1: /* TopoScopeBcast-MH */
218+
hdr_size = 68 - 36;
219+
break;
220+
}
221+
break;
222+
case 6: switch (hdr_subtype) {
223+
case 0: /* LocService-Request */
224+
break;
225+
case 1: /* LocService-Reply */
226+
break;
227+
}
228+
break;
229+
}
230+
231+
/* Skip Extended headers */
232+
if (hdr_size >= 0) {
233+
if (length < (u_int)hdr_size)
234+
goto malformed;
235+
ND_TCHECK2(*bp, hdr_size);
236+
length -= hdr_size;
237+
bp += hdr_size;
238+
switch (next_hdr) {
174239
case 0: /* Any */
175-
hdr_size = 0;
176-
break;
177-
case 1: /* Beacon */
178-
hdr_size = 0;
179-
break;
180-
case 2: /* GeoUnicast */
181240
break;
182-
case 3: switch (hdr_subtype) {
183-
case 0: /* GeoAnycastCircle */
184-
break;
185-
case 1: /* GeoAnycastRect */
186-
break;
187-
case 2: /* GeoAnycastElipse */
188-
break;
241+
case 1:
242+
case 2: /* BTP A/B */
243+
if (length < 4)
244+
goto malformed;
245+
ND_TCHECK2(*bp, 4);
246+
print_btp(bp);
247+
length -= 4;
248+
bp += 4;
249+
if (length >= 2) {
250+
/*
251+
* XXX - did print_btp_body()
252+
* return if length < 2
253+
* because this is optional,
254+
* or was that just not
255+
* reporting genuine errors?
256+
*/
257+
ND_TCHECK2(*bp, 2);
258+
print_btp_body(bp);
189259
}
190260
break;
191-
case 4: switch (hdr_subtype) {
192-
case 0: /* GeoBroadcastCircle */
193-
break;
194-
case 1: /* GeoBroadcastRect */
195-
break;
196-
case 2: /* GeoBroadcastElipse */
197-
break;
198-
}
199-
break;
200-
case 5: switch (hdr_subtype) {
201-
case 0: /* TopoScopeBcast-SH */
202-
hdr_size = 0;
203-
break;
204-
case 1: /* TopoScopeBcast-MH */
205-
hdr_size = 68 - 36;
206-
break;
207-
}
208-
break;
209-
case 6: switch (hdr_subtype) {
210-
case 0: /* LocService-Request */
211-
break;
212-
case 1: /* LocService-Reply */
213-
break;
214-
}
261+
case 3: /* IPv6 */
215262
break;
216263
}
217-
218-
/* Skip Extended headers */
219-
if (hdr_size >= 0) {
220-
length -= hdr_size;
221-
bp += hdr_size;
222-
switch (next_hdr) {
223-
case 0: /* Any */
224-
break;
225-
case 1:
226-
case 2: /* BTP A/B */
227-
print_btp(bp);
228-
length -= 4;
229-
bp += 4;
230-
print_btp_body(bp, length);
231-
break;
232-
case 3: /* IPv6 */
233-
break;
234-
}
235-
}
236-
} else {
237-
printf("Malformed (small) ");
238264
}
239265

240266
/* Print user data part */
241267
if (ndo->ndo_vflag)
242268
default_print(bp, length);
269+
return;
270+
271+
malformed:
272+
printf(" Malformed (small) ");
273+
/* XXX - print the remaining data as hex? */
274+
return;
275+
276+
trunc:
277+
printf("[|geonet]");
243278
}
244279

245280

0 commit comments

Comments
 (0)