summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2017-12-21 10:20:35 -0500
committerNick Mathewson <nickm@torproject.org>2017-12-21 10:20:35 -0500
commit2a7cad957263f5faed3a0b9de8b15d9794a5541c (patch)
treee70f71e4195d90dd7600cfcb73860395afc20beb
parentc2b64ad0968f040e2b5ecb426d3520a02acb5cc7 (diff)
parent885ba513ff709eb86a71c7daf7c23aafab4862a8 (diff)
downloadtor-2a7cad957263f5faed3a0b9de8b15d9794a5541c.tar.gz
tor-2a7cad957263f5faed3a0b9de8b15d9794a5541c.zip
Merge branch 'maint-0.3.2' into release-0.3.2
-rw-r--r--changes/bug246656
-rw-r--r--src/or/scheduler_kist.c22
2 files changed, 17 insertions, 11 deletions
diff --git a/changes/bug24665 b/changes/bug24665
new file mode 100644
index 0000000000..f950d9dd01
--- /dev/null
+++ b/changes/bug24665
@@ -0,0 +1,6 @@
+ o Major bugfixes (KIST, scheduler):
+ - The KIST scheduler did not correctly account for data already enqueued
+ in each connection's send socket buffer, particularly in cases when the
+ TCP/IP congestion window was reduced between scheduler calls. This
+ situation lead to excessive per-connection buffering in the kernel, and
+ a potential memory DoS. Fixes bug 24665; bugfix on 0.3.2.1-alpha.
diff --git a/src/or/scheduler_kist.c b/src/or/scheduler_kist.c
index 9acd89b37f..a50be345b0 100644
--- a/src/or/scheduler_kist.c
+++ b/src/or/scheduler_kist.c
@@ -266,8 +266,7 @@ update_socket_info_impl, (socket_table_ent_t *ent))
/* These values from the kernel are uint32_t, they will always fit into a
* int64_t tcp_space variable but if the congestion window cwnd is smaller
- * than the unacked packets, the remaining TCP space is set to 0 so we don't
- * write more on this channel. */
+ * than the unacked packets, the remaining TCP space is set to 0. */
if (ent->cwnd >= ent->unacked) {
tcp_space = (ent->cwnd - ent->unacked) * (int64_t)(ent->mss);
} else {
@@ -276,20 +275,21 @@ update_socket_info_impl, (socket_table_ent_t *ent))
/* The clamp_double_to_int64 makes sure the first part fits into an int64_t.
* In fact, if sock_buf_size_factor is still forced to be >= 0 in config.c,
- * then it will be positive for sure. Then we subtract a uint32_t. At worst
- * we end up negative, but then we just set extra_space to 0 in the sanity
- * check.*/
+ * then it will be positive for sure. Then we subtract a uint32_t. Getting a
+ * negative value is OK, see after how it is being handled. */
extra_space =
clamp_double_to_int64(
(ent->cwnd * (int64_t)ent->mss) * sock_buf_size_factor) -
ent->notsent;
- if (extra_space < 0) {
- extra_space = 0;
+ if ((tcp_space + extra_space) < 0) {
+ /* This means that the "notsent" queue is just too big so we shouldn't put
+ * more in the kernel for now. */
+ ent->limit = 0;
+ } else {
+ /* Adding two positive int64_t together will always fit in an uint64_t.
+ * And we know this will always be positive. */
+ ent->limit = (uint64_t)tcp_space + (uint64_t)extra_space;
}
-
- /* Finally we set the limit. Adding two positive int64_t together will always
- * fit in an uint64_t. */
- ent->limit = (uint64_t)tcp_space + (uint64_t)extra_space;
return;
#else /* !(defined(HAVE_KIST_SUPPORT)) */