On Sat, Dec 02, 2000 at 10:53:05PM +0100, Arkadiusz Miskiewicz wrote:
> Program received signal SIGSEGV, Segmentation fault.
> 0x0806e16a in print_attr_string (data=0x8140912 "\005", length=4294967294,
> attr_code=30)
"rad_attr->len - 2" is passed as the "length" argument.
4294967294+2 = 2^32, so "rad_attr->len" was probably zero.
It shouldn't try to print the attribute if the length is less than or
equal to 2.
Furthermore, the routines that print the attribute shouldn't assume that
the length *after* subtracting the 2 bytes for the type and length will
necessarily be correct for the attribute being printed.
I noticed some other problems when adding those checks as well.
Here's a patch - can you try it on any of the capture files that had a
problem?
Index: print-radius.c
===================================================================
RCS file: /tcpdump/master/tcpdump/print-radius.c,v
retrieving revision 1.3
diff -c -r1.3 print-radius.c
*** print-radius.c 2000/10/10 05:14:35 1.3
--- print-radius.c 2000/12/03 09:01:10
***************
*** 470,475 ****
--- 470,481 ----
u_int8_t tag;
u_int32_t timeout;
+ if (length != 4)
+ {
+ printf("{length %u != 4}", length);
+ return;
+ }
+
TCHECK2(data[0],4);
/* This attribute has standard values */
if (attr_type[attr_code].siz_subtypes)
***************
*** 577,582 ****
--- 583,594 ----
static void
print_attr_address(register u_char *data, u_int length, u_short attr_code )
{
+ if (length != 4)
+ {
+ printf("{length %u != 4}", length);
+ return;
+ }
+
TCHECK2(data[0],4);
switch(attr_code)
***************
*** 615,625 ****
static void print_attr_time(register u_char *data, u_int length, u_short attr_code)
{
time_t attr_time;
TCHECK2(data[0],4);
attr_time = EXTRACT_32BITS(data);
! printf("{%.24s}", ctime(&attr_time));
return;
trunc:
--- 627,647 ----
static void print_attr_time(register u_char *data, u_int length, u_short attr_code)
{
time_t attr_time;
+ char string[26];
+
+ if (length != 4)
+ {
+ printf("{length %u != 4}", length);
+ return;
+ }
TCHECK2(data[0],4);
attr_time = EXTRACT_32BITS(data);
! strcpy(string, ctime(&attr_time));
! /* Get rid of the newline */
! string[24] = '\0';
! printf("{%.24s}", string);
return;
trunc:
***************
*** 636,678 ****
/***********************************/
static void print_attr_strange(register u_char *data, u_int length, u_short
attr_code)
{
! u_short len_data = 8;
switch(attr_code)
{
case ARAP_PASS:
printf("{User_challenge[");
TCHECK2(data[0],8);
PRINT_HEX(len_data, data);
printf("] User_resp[");
TCHECK2(data[0],8);
PRINT_HEX(len_data, data);
printf("]}");
break;
case ARAP_FEATURES:
if (*data)
printf("{User_can_change_pass");
else
printf("{User_cant_change_pass");
- TCHECK2(data[0],1);
data++;
printf(" Min_pass_len[%d]",*data);
printf(" Pass_created_at[");
! TCHECK2(data[0],8);
PRINT_HEX(len_data, data);
printf("] Pass_expired_in[");
! TCHECK2(data[0],8);
PRINT_HEX(len_data, data);
printf("] Current_time[");
! TCHECK2(data[0],8);
PRINT_HEX(len_data, data);
printf("]}");
break;
case ARAP_CHALLENGE_RESP:
printf("{");
TCHECK2(data[0],8);
PRINT_HEX(len_data, data);
printf("}");
break;
--- 658,723 ----
/***********************************/
static void print_attr_strange(register u_char *data, u_int length, u_short
attr_code)
{
! u_short len_data;
switch(attr_code)
{
case ARAP_PASS:
+ if (length != 16)
+ {
+ printf("{length %u != 16}", length);
+ return;
+ }
printf("{User_challenge[");
TCHECK2(data[0],8);
+ len_data = 8;
PRINT_HEX(len_data, data);
printf("] User_resp[");
TCHECK2(data[0],8);
+ len_data = 8;
PRINT_HEX(len_data, data);
printf("]}");
break;
case ARAP_FEATURES:
+ if (length != 14)
+ {
+ printf("{length %u != 14}", length);
+ return;
+ }
+ TCHECK2(data[0],1);
if (*data)
printf("{User_can_change_pass");
else
printf("{User_cant_change_pass");
data++;
+ TCHECK2(data[0],1);
printf(" Min_pass_len[%d]",*data);
+ data++;
printf(" Pass_created_at[");
! TCHECK2(data[0],4);
! len_data = 4;
PRINT_HEX(len_data, data);
printf("] Pass_expired_in[");
! TCHECK2(data[0],4);
! len_data = 4;
PRINT_HEX(len_data, data);
printf("] Current_time[");
! len_data = 4;
! TCHECK2(data[0],4);
PRINT_HEX(len_data, data);
printf("]}");
break;
case ARAP_CHALLENGE_RESP:
+ if (length < 8)
+ {
+ printf("{length %u != 8}", length);
+ return;
+ }
printf("{");
TCHECK2(data[0],8);
+ len_data = 8;
PRINT_HEX(len_data, data);
printf("}");
break;
***************
*** 706,714 ****
{
printf(" %s",attr_type[rad_attr->type].name);
! if ( attr_type[rad_attr->type].print_func )
! (*attr_type[rad_attr->type].print_func)( ((u_char *)(rad_attr+1)),
rad_attr->len - 2, rad_attr->type);
}
}
else
--- 751,763 ----
{
printf(" %s",attr_type[rad_attr->type].name);
! if (rad_attr->len > 2)
! {
! if ( attr_type[rad_attr->type].print_func )
! (*attr_type[rad_attr->type].print_func)(
! ((u_char *)(rad_attr+1)),
rad_attr->len - 2, rad_attr->type);
+ }
}
}
else