learn: Avoid 1-byte buffer underrun in learn_format().
authorBen Pfaff <blp@nicira.com>
Thu, 1 Dec 2011 16:33:55 +0000 (08:33 -0800)
committerBen Pfaff <blp@nicira.com>
Thu, 1 Dec 2011 16:33:55 +0000 (08:33 -0800)
Reported-and-tested-by: Jari Sundell <sundell.software@gmail.com>
lib/learn.c

index 19a0e009044d8284dc821312f0edfa8eb0e5098e..9d97cb35cdfd28747ec066f5600d7f8de6df9ab3 100644 (file)
@@ -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);