2003-03-02 Havoc Pennington <hp@pobox.com>

* test/break-loader.c (randomly_set_extreme_ints): add test that
	sets really huge and small integers

	* dbus/dbus-marshal.c (_dbus_marshal_validate_arg): add check
	that length of boolean array fits in the string, and that
	string has room for boolean value in single-bool case.

	* dbus/dbus-message-builder.c (_dbus_message_data_load): add
	optional value to "ALIGN" command which is what to fill the
	alignment with.

	* test/data/valid-messages/no-padding.message: add regression
	test for the message padding problem
This commit is contained in:
Havoc Pennington 2003-03-02 17:34:30 +00:00
parent 7584a7bdcc
commit f7d96bdf80
8 changed files with 167 additions and 5 deletions

View file

@ -1,3 +1,19 @@
2003-03-02 Havoc Pennington <hp@pobox.com>
* test/break-loader.c (randomly_set_extreme_ints): add test that
sets really huge and small integers
* dbus/dbus-marshal.c (_dbus_marshal_validate_arg): add check
that length of boolean array fits in the string, and that
string has room for boolean value in single-bool case.
* dbus/dbus-message-builder.c (_dbus_message_data_load): add
optional value to "ALIGN" command which is what to fill the
alignment with.
* test/data/valid-messages/no-padding.message: add regression
test for the message padding problem
2003-03-02 Havoc Pennington <hp@pobox.com>
* dbus/dbus-message.c (decode_header_data): fix to always init

View file

@ -115,6 +115,7 @@ char* _dbus_strdup (const char *str);
#define _DBUS_INT_MIN (-_DBUS_INT_MAX - 1)
#define _DBUS_INT_MAX 2147483647
#define _DBUS_UINT_MAX 0xffffffff
#define _DBUS_MAX_SUN_PATH_LENGTH 99
#define _DBUS_ONE_KILOBYTE 1024
#define _DBUS_ONE_MEGABYTE 1024 * _DBUS_ONE_KILOBYTE

View file

@ -997,7 +997,9 @@ _dbus_marshal_get_arg_end_pos (const DBusString *str,
* Demarshals and validates a length; returns < 0 if the validation
* fails. The length is required to be small enough that
* len*sizeof(double) will not overflow, and small enough to fit in a
* signed integer.
* signed integer. DOES NOT check whether the length points
* beyond the end of the string, because it doesn't know the
* size of array elements.
*
* @param str the string
* @param byte_order the byte order
@ -1012,6 +1014,8 @@ demarshal_and_validate_len (const DBusString *str,
{
int align_4 = _DBUS_ALIGN_VALUE (pos, 4);
unsigned int len;
_dbus_assert (new_pos != NULL);
if ((align_4 + 4) >= _dbus_string_get_length (str))
{
@ -1116,6 +1120,12 @@ _dbus_marshal_validate_arg (const DBusString *str,
{
unsigned char c;
if (2 > _dbus_string_get_length (str) - pos)
{
_dbus_verbose ("no room for boolean value\n");
return FALSE;
}
c = _dbus_string_get_byte (str, pos + 1);
if (c != 0 && c != 1)
@ -1184,6 +1194,12 @@ _dbus_marshal_validate_arg (const DBusString *str,
if (len < 0)
return FALSE;
if (len > _dbus_string_get_length (str) - pos)
{
_dbus_verbose ("boolean array length outside length of the message\n");
return FALSE;
}
i = 0;
while (i < len)
{

View file

@ -334,6 +334,12 @@ _dbus_message_data_load (DBusString *dest,
_dbus_string_free (&file);
return FALSE;
}
{
const char *s;
_dbus_string_get_const_data (filename, &s);
_dbus_verbose ("Loading %s\n", s);
}
if ((result = _dbus_file_get_contents (&file, filename)) != DBUS_RESULT_SUCCESS)
{
@ -439,24 +445,47 @@ _dbus_message_data_load (DBusString *dest,
"ALIGN"))
{
long val;
int end;
int orig_len;
_dbus_string_delete_first_word (&line);
if (!_dbus_string_parse_int (&line, 0, &val, NULL))
if (!_dbus_string_parse_int (&line, 0, &val, &end))
{
_dbus_warn ("Failed to parse integer\n");
goto parse_failed;
}
if (val > 16)
if (val > 8)
{
_dbus_warn ("Aligning to %ld boundary is crack\n",
val);
goto parse_failed;
}
orig_len = _dbus_string_get_length (dest);
if (!_dbus_string_align_length (dest, val))
goto parse_failed;
if (_dbus_string_parse_int (&line, end, &val, NULL))
{
/* If there's an optional second int argument,
* fill in align padding with that value
*/
if (val < 0 || val > 255)
{
_dbus_warn ("can't fill align padding with %ld, must be a byte value\n", val);
goto parse_failed;
}
end = orig_len;
while (end < _dbus_string_get_length (dest))
{
_dbus_string_set_byte (dest, end, val);
++end;
}
}
}
else if (_dbus_string_starts_with_c_str (&line, "UNALIGN"))
{

View file

@ -334,6 +334,67 @@ randomly_modify_length (const DBusString *orig_data,
(unsigned) (orig + delta));
}
static void
randomly_set_extreme_ints (const DBusString *orig_data,
DBusString *mutated)
{
int i;
int byte_order;
const char *d;
dbus_uint32_t orig;
static int which = 0;
unsigned int extreme_ints[] = {
_DBUS_INT_MAX,
_DBUS_UINT_MAX,
_DBUS_INT_MAX - 1,
_DBUS_UINT_MAX - 1,
_DBUS_INT_MAX - 2,
_DBUS_UINT_MAX - 2,
(unsigned int) (_DBUS_INT_MAX + 1),
(unsigned int) (_DBUS_UINT_MAX + 1),
_DBUS_INT_MAX + 2,
_DBUS_UINT_MAX + 2,
0, 1, 2, 3,
(unsigned int) -1,
(unsigned int) -2,
(unsigned int) -3
};
if (orig_data != mutated)
{
_dbus_string_set_length (mutated, 0);
if (!_dbus_string_copy (orig_data, 0, mutated, 0))
_dbus_assert_not_reached ("out of mem");
}
if (_dbus_string_get_length (mutated) < 12)
return;
_dbus_string_get_const_data (mutated, &d);
if (!(*d == DBUS_LITTLE_ENDIAN ||
*d == DBUS_BIG_ENDIAN))
return;
byte_order = *d;
i = random_int_in_range (4, _dbus_string_get_length (mutated) - 8);
i = _DBUS_ALIGN_VALUE (i, 4);
orig = _dbus_demarshal_uint32 (mutated, byte_order, i, NULL);
which = random_int_in_range (0, _DBUS_N_ELEMENTS (extreme_ints));
_dbus_assert (which >= 0);
_dbus_assert (which < _DBUS_N_ELEMENTS (extreme_ints));
_dbus_marshal_set_uint32 (mutated, byte_order, i,
extreme_ints[which]);
}
static int times_we_did_each_thing[6] = { 0, };
static void
randomly_do_n_things (const DBusString *orig_data,
DBusString *mutated,
@ -347,7 +408,8 @@ randomly_do_n_things (const DBusString *orig_data,
randomly_change_one_byte,
randomly_add_one_byte,
randomly_remove_one_byte,
randomly_modify_length
randomly_modify_length,
randomly_set_extreme_ints
};
_dbus_string_set_length (mutated, 0);
@ -363,6 +425,7 @@ randomly_do_n_things (const DBusString *orig_data,
which = random_int_in_range (0, _DBUS_N_ELEMENTS (functions));
(* functions[which]) (mutated, mutated);
times_we_did_each_thing[which] += 1;
++i;
}
@ -432,6 +495,15 @@ find_breaks_based_on (const DBusString *filename,
++i;
}
i = 0;
while (i < 50)
{
randomly_set_extreme_ints (&orig_data, &mutated);
try_mutated_data (&mutated);
++i;
}
i = 0;
while (i < 15)
@ -588,6 +660,15 @@ main (int argc,
return 1;
}
printf (" did %d random mutations: %d %d %d %d %d %d\n",
_DBUS_N_ELEMENTS (times_we_did_each_thing),
times_we_did_each_thing[0],
times_we_did_each_thing[1],
times_we_did_each_thing[2],
times_we_did_each_thing[3],
times_we_did_each_thing[4],
times_we_did_each_thing[5]);
printf ("Found %d failures with seed %u stored in %s\n",
failures_this_iteration, seed, failure_dir_c);

View file

@ -0,0 +1,19 @@
## Message with no header padding
## VALID_HEADER includes a LENGTH Header and LENGTH Body
VALID_HEADER
## this byte array is filled with zeros to the natural length
## of the header
FIELD_NAME unkn
TYPE BYTE_ARRAY
ALIGN 4
LENGTH ThisByteArray
START_LENGTH ThisByteArray
BYTE 1
ALIGN 8 1
END_LENGTH ThisByteArray
END_LENGTH Header
START_LENGTH Body
END_LENGTH Body