summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIlya Maximets <i.maximets@ovn.org>2022-06-24 14:55:56 +0200
committerIlya Maximets <i.maximets@ovn.org>2022-06-24 23:52:29 +0200
commite4f75b330fe99e3680c65223d0223a389babddc1 (patch)
treebf3b0f6627b57d834a692ea8abbc74178b9cc480
parentf5a714b30edb3dedd8723e494a7815cf69a9e4af (diff)
downloadopenvswitch-e4f75b330fe99e3680c65223d0223a389babddc1.tar.gz
odp-util: Fix unaligned access to tunnel id.
SUMMARY: UndefinedBehaviorSanitizer: lib/odp-util.c:3436:32: runtime error: load of misaligned address 0x624000489424 for type 'const ovs_be64' (aka 'const unsigned long'), which requires 8 byte alignment 0x624000489424: note: pointer points here 0c 00 00 00 ff ff ff ff ff ff ff ff 08 00 01 00 ... ^ 0 0x9b13a2 in format_be64 lib/odp-util.c:3436:32 1 0x9b13a2 in format_odp_tun_attr lib/odp-util.c:3942:13 2 0x9b13a2 in format_odp_key_attr__ lib/odp-util.c:4221:9 3 0x9ae7a2 in odp_flow_format lib/odp-util.c:4606:17 4 0xee5037 in format_dpif_flow lib/dpctl.c:862:5 5 0xed69ed in dpctl_dump_flows lib/dpctl.c:1142:13 6 0xed32b3 in dpctl_unixctl_handler lib/dpctl.c:3035:17 7 0xc7c80b in process_command lib/unixctl.c:310:13 8 0xc7c80b in run_connection lib/unixctl.c:344:17 9 0xc7c80b in unixctl_server_run lib/unixctl.c:395:21 10 0x59a9a4 in main vswitchd/ovs-vswitchd.c:130:9 11 0x7fee2803acf2 in __libc_start_main (/lib64/libc.so.6+0x3acf2) 12 0x47e60d in _start (vswitchd/ovs-vswitchd+0x47e60d) Tunnel id mask in the flow key is only 4 bytes aligned, so has to be accessed with appropriate unaligned read function. Acked-by: Dumitru Ceara <dceara@redhat.com> Acked-by: Aaron Conole <aconole@redhat.com> Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
-rw-r--r--lib/odp-util.c10
1 files changed, 5 insertions, 5 deletions
diff --git a/lib/odp-util.c b/lib/odp-util.c
index 0df892132..fa6287f6d 100644
--- a/lib/odp-util.c
+++ b/lib/odp-util.c
@@ -3341,16 +3341,16 @@ format_eth(struct ds *ds, const char *name, const struct eth_addr key,
static void
format_be64(struct ds *ds, const char *name, ovs_be64 key,
- const ovs_be64 *mask, bool verbose)
+ const ovs_32aligned_be64 *mask_, bool verbose)
{
- bool mask_empty = mask && !*mask;
+ ovs_be64 mask = mask_ ? get_32aligned_be64(mask_) : htonll(0);
- if (verbose || !mask_empty) {
- bool mask_full = !mask || *mask == OVS_BE64_MAX;
+ if (verbose || mask) {
+ bool mask_full = !mask_ || mask == OVS_BE64_MAX;
ds_put_format(ds, "%s=0x%"PRIx64, name, ntohll(key));
if (!mask_full) { /* Partially masked. */
- ds_put_format(ds, "/%#"PRIx64, ntohll(*mask));
+ ds_put_format(ds, "/%#"PRIx64, ntohll(mask));
}
ds_put_char(ds, ',');
}