diff --git a/ChangeLog b/ChangeLog index 12eb30428..45a51220d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -10,6 +10,7 @@ * fix uTP edge case where udp socket buffer fills up * fix nagle implementation in uTP + * fix potential packet allocation alignment issue in utp * make 'close_redudnant_connections' cover more cases * set_piece_deadline() also unfilters the piece (if its priority is 0) * add work-around for bug in windows vista and earlier in GetOverlappedResult diff --git a/include/libtorrent/string_util.hpp b/include/libtorrent/string_util.hpp index d10bf7cd8..3ed17ff5d 100644 --- a/include/libtorrent/string_util.hpp +++ b/include/libtorrent/string_util.hpp @@ -54,6 +54,10 @@ namespace libtorrent // in strict ansi mode char* allocate_string_copy(char const* str); + // returns p + x such that the pointer is 8 bytes aligned + // x cannot be greater than 7 + void* align_pointer(void* p); + } #endif diff --git a/src/string_util.cpp b/src/string_util.cpp index bed6afa15..d21cbc71a 100644 --- a/src/string_util.cpp +++ b/src/string_util.cpp @@ -130,5 +130,18 @@ namespace libtorrent return tmp; } + // 8-byte align pointer + void* align_pointer(void* p) + { + int offset = uintptr_t(p) & 0x7; + // if we're already aligned, don't do anything + if (offset == 0) return p; + + // offset is how far passed the last aligned address + // we are. We need to go forward to the next aligned + // one. Since aligned addresses are 8 bytes apart, add + // 8 - offset. + return static_cast(p) + (8 - offset); + } } diff --git a/src/utp_stream.cpp b/src/utp_stream.cpp index d8088e2e0..ef8f18b6e 100644 --- a/src/utp_stream.cpp +++ b/src/utp_stream.cpp @@ -1682,9 +1682,11 @@ bool utp_socket_impl::send_pkt(int flags) stack_alloced = true; #endif TORRENT_ASSERT(force); - // TODO: 3 this alloca() statement won't necessarily produce - // correctly aligned memory. do something about that - p = (packet*)TORRENT_ALLOCA(char, sizeof(packet) + packet_size); + // this alloca() statement won't necessarily produce + // correctly aligned memory. That's why we ask for 7 more bytes + // and adjust our pointer to be aligned later + p = (packet*)TORRENT_ALLOCA(char, sizeof(packet) + packet_size + 7); + p = (packet*)align_pointer(p); UTP_LOGV("%8p: allocating %d bytes on the stack\n", this, packet_size); p->allocated = packet_size; }