diff options
author | Ben Pfaff <blp@nicira.com> | 2011-12-01 08:33:55 -0800 |
---|---|---|
committer | Ben Pfaff <blp@nicira.com> | 2011-12-01 08:37:00 -0800 |
commit | a4767f4164df0db47734416ead0710038f04354f (patch) | |
tree | efcc470521fc23cdfe0f3af1b0562cfa23a4e4fa | |
parent | 99553eeac5c6a422a7622ea8be801e8636699753 (diff) | |
download | openvswitch-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.c | 11 |
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); |