From patchwork Tue Jun 13 04:51:14 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Pfaff X-Patchwork-Id: 774942 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3wmy5r2GWZz9s8H for ; Tue, 13 Jun 2017 14:51:28 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 740CCB7B; Tue, 13 Jun 2017 04:51:24 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id 42F8EB50 for ; Tue, 13 Jun 2017 04:51:23 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from relay2-d.mail.gandi.net (relay2-d.mail.gandi.net [217.70.183.194]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 90CA0140 for ; Tue, 13 Jun 2017 04:51:22 +0000 (UTC) Received: from mfilter1-d.gandi.net (mfilter1-d.gandi.net [217.70.178.130]) by relay2-d.mail.gandi.net (Postfix) with ESMTP id 63B40C5A5F; Tue, 13 Jun 2017 06:51:21 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at mfilter1-d.gandi.net Received: from relay2-d.mail.gandi.net ([IPv6:::ffff:217.70.183.194]) by mfilter1-d.gandi.net (mfilter1-d.gandi.net [::ffff:10.0.15.180]) (amavisd-new, port 10024) with ESMTP id wJolZs13G92g; Tue, 13 Jun 2017 06:51:20 +0200 (CEST) X-Originating-IP: 173.228.112.24 Received: from sigabrt.gateway.sonic.net (173-228-112-24.dsl.dynamic.fusionbroadband.com [173.228.112.24]) (Authenticated sender: blp@ovn.org) by relay2-d.mail.gandi.net (Postfix) with ESMTPSA id 165CEC5A43; Tue, 13 Jun 2017 06:51:17 +0200 (CEST) From: Ben Pfaff To: dev@openvswitch.org Date: Mon, 12 Jun 2017 21:51:14 -0700 Message-Id: <20170613045114.1511-1-blp@ovn.org> X-Mailer: git-send-email 2.10.2 X-Spam-Status: No, score=-2.6 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_LOW autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Cc: Ben Pfaff Subject: [ovs-dev] [PATCH] byte-order: Fix undefined behavior of BYTES_TO_BE32. X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org A left shift that would produce a result that is not representable by the type of the expression's result has "undefined behavior" according to the C language standard. Avoid this by casting values that could set the upper bit to unsigned types. Also document and convert a macro to a function. While we're at it, delete the unused macro BE16S_TO_BE32. Found via gcc's undefined behavior sanitizer. Reported-by: Lance Richardson Signed-off-by: Ben Pfaff Acked-by: Lance Richardson --- lib/byte-order.h | 21 +++++++++++++-------- lib/flow.c | 2 +- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/lib/byte-order.h b/lib/byte-order.h index e864658f9b59..b2a9082bbada 100644 --- a/lib/byte-order.h +++ b/lib/byte-order.h @@ -98,17 +98,22 @@ uint32_byteswap(uint32_t crc) { ((((ovs_be64) (VALUE)) & UINT64_C(0xff00000000000000)) >> 56)) #endif +/* Returns the ovs_be32 that you would get from: + * + * union { uint8_t b[4]; ovs_be32 be32; } x = { .b = { b0, b1, b2, b3 } }; + * return x.be32; + * + * but without the undefined behavior. */ +static inline ovs_be32 +bytes_to_be32(uint8_t b0, uint8_t b1, uint8_t b2, uint8_t b3) +{ #if WORDS_BIGENDIAN -#define BYTES_TO_BE32(B1, B2, B3, B4) \ - (OVS_FORCE ovs_be32)((uint32_t)(B1) << 24 | (B2) << 16 | (B3) << 8 | (B4)) -#define BE16S_TO_BE32(B1, B2) \ - (OVS_FORCE ovs_be32)((uint32_t)(B1) << 16 | (B2)) + uint32_t x = ((uint32_t) b0 << 24) | (b1 << 16) | (b2 << 8) | b3; #else -#define BYTES_TO_BE32(B1, B2, B3, B4) \ - (OVS_FORCE ovs_be32)((uint32_t)(B1) | (B2) << 8 | (B3) << 16 | (B4) << 24) -#define BE16S_TO_BE32(B1, B2) \ - (OVS_FORCE ovs_be32)((uint32_t)(B1) | (B2) << 16) + uint32_t x = ((uint32_t) b3 << 24) | (b2 << 16) | (b1 << 8) | b0; #endif + return (OVS_FORCE ovs_be32) x; +} /* These functions zero-extend big-endian values to longer ones, * or truncate long big-endian value to shorter ones. */ diff --git a/lib/flow.c b/lib/flow.c index 1f51b66e7b44..d73e796a2f45 100644 --- a/lib/flow.c +++ b/lib/flow.c @@ -823,7 +823,7 @@ miniflow_extract(struct dp_packet *packet, struct miniflow *dst) packet->l4_ofs = (char *)data - frame; miniflow_push_be32(mf, nw_frag, - BYTES_TO_BE32(nw_frag, nw_tos, nw_ttl, nw_proto)); + bytes_to_be32(nw_frag, nw_tos, nw_ttl, nw_proto)); if (OVS_LIKELY(!(nw_frag & FLOW_NW_FRAG_LATER))) { if (OVS_LIKELY(nw_proto == IPPROTO_TCP)) {