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