check option length when processing TCP options.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20774 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Hugo Santos 2007-04-20 19:04:08 +00:00
parent 89fe2e175e
commit 530017c6c9

View File

@ -236,49 +236,49 @@ process_options(tcp_segment_header &segment, net_buffer *buffer, int32 size)
uint8 optionsBuffer[32];
if (gBufferModule->direct_access(buffer, sizeof(tcp_header), size,
(void **)&option) != B_OK) {
if (size > 32) {
dprintf("options too large to take into account (%ld bytes)\n", size);
return;
}
if (size > 32)
panic("UNIMPLEMENTED: TCP option processing across data nodes");
gBufferModule->read(buffer, sizeof(tcp_header), optionsBuffer, size);
option = (tcp_option *)optionsBuffer;
}
while (size > 0) {
uint32 length = 1;
int32 length = -1;
switch (option->kind) {
case TCP_OPTION_END:
case TCP_OPTION_NOP:
length = 1;
break;
case TCP_OPTION_MAX_SEGMENT_SIZE:
segment.max_segment_size = ntohs(option->max_segment_size);
length = 4;
if (option->length == 4 && (size - 4) >= 0)
segment.max_segment_size = ntohs(option->max_segment_size);
break;
case TCP_OPTION_WINDOW_SHIFT:
segment.has_window_shift = true;
segment.window_shift = option->window_shift;
length = 3;
if (option->length == 3 && (size - 3) >= 0) {
segment.has_window_shift = true;
segment.window_shift = option->window_shift;
}
break;
case TCP_OPTION_TIMESTAMP:
segment.has_timestamps = true;
segment.TSval = option->timestamp.TSval;
segment.TSecr = ntohl(option->timestamp.TSecr);
length = 10;
if (option->length == 10 && (size - 10) >= 0) {
segment.has_timestamps = true;
segment.TSval = option->timestamp.TSval;
segment.TSecr = ntohl(option->timestamp.TSecr);
}
break;
}
default:
length = option->length;
// make sure we don't end up in an endless loop
if (length == 0)
return;
if (length < 0) {
length = option->length;
if (length == 0)
break;
}
size -= length;
option = (tcp_option *)((uint8 *)option + length);
}
// TODO: check if options are valid!
}