summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorBen Pfaff <blp@nicira.com>2014-04-04 19:26:22 -0700
committerBen Pfaff <blp@nicira.com>2014-04-05 10:46:26 -0700
commitdea241f172b64958f6b917bc3971253c5dc010c0 (patch)
tree07f22845ee6d4ea519bb8fdd674f5c88f1089f67 /lib
parent5fa008d4618856aa44189cc98f71a7b3c5233652 (diff)
downloadopenvswitch-dea241f172b64958f6b917bc3971253c5dc010c0.tar.gz
ofp-print: Fix misaligned data access in ofp_print_error_msg().
The body of an OpenFlow error message often contains an inner OpenFlow message, and when it does, the inner message starts at an odd multiple of 4 bytes from the beginning of the outer message. That means that, on RISC systems, accessing the inner message directly causes a bus error. This commit fixes the problem in a way that should make it difficult to recur. This fixes the failure of tests 643, 645, and 651 on sparc seen here: https://buildd.debian.org/status/fetch.php?pkg=openvswitch&arch=sparc&ver=2.1.0%2Bgit20140325-1&stamp=1396438624 Signed-off-by: Ben Pfaff <blp@nicira.com> Acked-by: Jarno Rajahalme <jrajahalme@nicira.com>
Diffstat (limited to 'lib')
-rw-r--r--lib/ofp-errors.c11
-rw-r--r--lib/ofp-print.c1
2 files changed, 8 insertions, 4 deletions
diff --git a/lib/ofp-errors.c b/lib/ofp-errors.c
index d1e4dbf98..bd4e43a4e 100644
--- a/lib/ofp-errors.c
+++ b/lib/ofp-errors.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2013 Nicira, Inc.
+ * Copyright (c) 2012, 2013, 2014 Nicira, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -272,8 +272,10 @@ ofperr_get_code(enum ofperr error, enum ofp_version version)
/* Tries to decode 'oh', which should be an OpenFlow OFPT_ERROR message.
* Returns an OFPERR_* constant on success, 0 on failure.
*
- * If 'payload' is nonnull, on success '*payload' is initialized to the
- * error's payload, and on failure it is cleared. */
+ * If 'payload' is nonnull, on success '*payload' is initialized with a copy of
+ * the error's payload (copying is required because the payload is not properly
+ * aligned). The caller must free the payload (with ofpbuf_uninit()) when it
+ * is no longer needed. On failure, '*payload' is cleared. */
enum ofperr
ofperr_decode_msg(const struct ofp_header *oh, struct ofpbuf *payload)
{
@@ -323,7 +325,8 @@ ofperr_decode_msg(const struct ofp_header *oh, struct ofpbuf *payload)
/* Translate the error type and code into an ofperr. */
error = ofperr_decode(oh->version, vendor, type, code);
if (error && payload) {
- ofpbuf_use_const(payload, ofpbuf_data(&b), ofpbuf_size(&b));
+ ofpbuf_init(payload, ofpbuf_size(&b));
+ ofpbuf_push(payload, ofpbuf_data(&b), ofpbuf_size(&b));
}
return error;
}
diff --git a/lib/ofp-print.c b/lib/ofp-print.c
index 60e2148fc..02f3db035 100644
--- a/lib/ofp-print.c
+++ b/lib/ofp-print.c
@@ -1368,6 +1368,7 @@ ofp_print_error_msg(struct ds *string, const struct ofp_header *oh)
ds_put_cstr(string, s);
free(s);
}
+ ofpbuf_uninit(&payload);
}
static void