summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Pfaff <blp@nicira.com>2011-12-01 08:33:55 -0800
committerBen Pfaff <blp@nicira.com>2011-12-01 08:37:00 -0800
commita4767f4164df0db47734416ead0710038f04354f (patch)
treeefcc470521fc23cdfe0f3af1b0562cfa23a4e4fa
parent99553eeac5c6a422a7622ea8be801e8636699753 (diff)
downloadopenvswitch-a4767f4164df0db47734416ead0710038f04354f.tar.gz
learn: Avoid 1-byte buffer underrun in learn_format().
Reported-and-tested-by: Jari Sundell <sundell.software@gmail.com>
-rw-r--r--lib/learn.c11
1 files changed, 11 insertions, 0 deletions
diff --git a/lib/learn.c b/lib/learn.c
index 9f95a1312..5926a2cd1 100644
--- a/lib/learn.c
+++ b/lib/learn.c
@@ -621,6 +621,17 @@ learn_format(const struct nx_action_learn *learn, struct ds *s)
union mf_value value;
uint8_t *bytes = (uint8_t *) &value;
+ if (src_value_bytes > dst_field->n_bytes) {
+ /* The destination field is an odd number of bytes, which
+ * got rounded up to a multiple of 2 to be put into the
+ * learning action. Skip over the leading byte, which
+ * should be zero anyway. Otherwise the memcpy() below
+ * will overrun the start of 'value'. */
+ int diff = src_value_bytes - dst_field->n_bytes;
+ src_value += diff;
+ src_value_bytes -= diff;
+ }
+
memset(&value, 0, sizeof value);
memcpy(&bytes[dst_field->n_bytes - src_value_bytes],
src_value, src_value_bytes);