On Wed, Nov 2, 2022 at 2:33 PM Dumitru Ceara <[email protected]> wrote:

> This avoids misaligned accesses as flagged by UBSan when running CoPP
> system tests:
>
>   controller/pinctrl.c:7129:28: runtime error: member access within
> misaligned address 0x61b0000627be for type 'const struct bfd_msg', which
> requires 4 byte alignment
>   0x61b0000627be: note: pointer points here
>    00 20 d3 d4 20 60  05 18 a8 99 e7 7b 92 1d  36 73 00 0f 42 40 00 0f  42
> 40 00 00 00 00 00 00  00 03
>                ^
>       #0 0x621b8f in pinctrl_check_bfd_msg
> /root/ovn/controller/pinctrl.c:7129:28
>       #1 0x621b8f in pinctrl_handle_bfd_msg
> /root/ovn/controller/pinctrl.c:7183:10
>       #2 0x621b8f in process_packet_in
> /root/ovn/controller/pinctrl.c:3320:9
>       #3 0x621b8f in pinctrl_recv /root/ovn/controller/pinctrl.c:3386:9
>       #4 0x621b8f in pinctrl_handler /root/ovn/controller/pinctrl.c:3481:17
>       #5 0xa2d89a in ovsthread_wrapper
> /root/ovn/ovs/lib/ovs-thread.c:422:12
>       #6 0x7fcb598081ce in start_thread (/lib64/libpthread.so.0+0x81ce)
>       #7 0x7fcb58439dd2 in clone (/lib64/libc.so.6+0x39dd2)
>
> Fixes: 117203584d98 ("controller: introduce BFD tx path in
> ovn-controller.")
> Reported-by: Ilya Maximets <[email protected]>
> Signed-off-by: Dumitru Ceara <[email protected]>
> ---
>  controller/pinctrl.c | 26 ++++++++++++++------------
>  lib/ovn-l7.h         | 10 +++++-----
>  2 files changed, 19 insertions(+), 17 deletions(-)
>
> diff --git a/controller/pinctrl.c b/controller/pinctrl.c
> index 8859cb080d..9913d5ae12 100644
> --- a/controller/pinctrl.c
> +++ b/controller/pinctrl.c
> @@ -6890,13 +6890,14 @@ pinctrl_find_bfd_monitor_entry_by_port(char *ip,
> uint16_t port)
>  }
>
>  static struct bfd_entry *
> -pinctrl_find_bfd_monitor_entry_by_disc(char *ip, ovs_be32 disc)
> +pinctrl_find_bfd_monitor_entry_by_disc(const char *ip,
> +                                       const ovs_16aligned_be32 *disc)
>  {
>      struct bfd_entry *ret = NULL, *entry;
>
>      HMAP_FOR_EACH_WITH_HASH (entry, node, hash_string(ip, 0),
>                               &bfd_monitor_map) {
> -        if (entry->local_disc == disc) {
> +        if (entry->local_disc == get_16aligned_be32(disc)) {
>              ret = entry;
>              break;
>          }
> @@ -6955,11 +6956,11 @@ bfd_monitor_put_bfd_msg(struct bfd_entry *entry,
> struct dp_packet *packet,
>      msg->length = BFD_PACKET_LEN;
>      msg->flags = final ? BFD_FLAG_FINAL : 0;
>      msg->flags |= entry->state << 6;
> -    msg->my_disc = entry->local_disc;
> -    msg->your_disc = entry->remote_disc;
> +    put_16aligned_be32(&msg->my_disc, entry->local_disc);
> +    put_16aligned_be32(&msg->your_disc, entry->remote_disc);
>      /* min_tx and min_rx are in us - RFC 5880 page 9 */
> -    msg->min_tx = htonl(entry->local_min_tx * 1000);
> -    msg->min_rx = htonl(entry->local_min_rx * 1000);
> +    put_16aligned_be32(&msg->min_tx, htonl(entry->local_min_tx * 1000));
> +    put_16aligned_be32(&msg->min_rx, htonl(entry->local_min_rx * 1000));
>
>      if (!IN6_IS_ADDR_V4MAPPED(&entry->ip_src)) {
>          /* IPv6 needs UDP checksum calculated */
> @@ -7154,7 +7155,7 @@ pinctrl_check_bfd_msg(const struct flow *ip_flow,
> struct dp_packet *pkt_in)
>          return false;
>      }
>
> -    if (!msg->my_disc) {
> +    if (!get_16aligned_be32(&msg->my_disc)) {
>          VLOG_DBG_RL(&rl, "BFD action: my_disc not set");
>          return false;
>      }
> @@ -7165,7 +7166,8 @@ pinctrl_check_bfd_msg(const struct flow *ip_flow,
> struct dp_packet *pkt_in)
>      }
>
>      enum bfd_state peer_state = msg->flags >> 6;
> -    if (peer_state >= BFD_STATE_INIT && !msg->your_disc) {
> +    if (peer_state >= BFD_STATE_INIT
> +        && !get_16aligned_be32(&msg->your_disc)) {
>          VLOG_DBG_RL(&rl,
>                      "BFD action: remote state is %s and your_disc is not
> set",
>                      bfd_get_status(peer_state));
> @@ -7193,7 +7195,7 @@ pinctrl_handle_bfd_msg(struct rconn *swconn, const
> struct flow *ip_flow,
>
>      const struct bfd_msg *msg = dp_packet_get_udp_payload(pkt_in);
>      struct bfd_entry *entry =
> -        pinctrl_find_bfd_monitor_entry_by_disc(ip_src, msg->your_disc);
> +        pinctrl_find_bfd_monitor_entry_by_disc(ip_src, &msg->your_disc);
>
>      if (!entry) {
>          free(ip_src);
> @@ -7201,9 +7203,9 @@ pinctrl_handle_bfd_msg(struct rconn *swconn, const
> struct flow *ip_flow,
>      }
>
>      bool change_state = false;
> -    entry->remote_disc = msg->my_disc;
> -    uint32_t remote_min_tx = ntohl(msg->min_tx) / 1000;
> -    entry->remote_min_rx = ntohl(msg->min_rx) / 1000;
> +    entry->remote_disc = get_16aligned_be32(&msg->my_disc);
> +    uint32_t remote_min_tx = ntohl(get_16aligned_be32(&msg->min_tx)) /
> 1000;
> +    entry->remote_min_rx = ntohl(get_16aligned_be32(&msg->min_rx)) / 1000;
>      entry->detection_timeout = msg->mult * MAX(remote_min_tx,
>                                                 entry->local_min_rx);
>
> diff --git a/lib/ovn-l7.h b/lib/ovn-l7.h
> index b03b945d89..2b20bc380a 100644
> --- a/lib/ovn-l7.h
> +++ b/lib/ovn-l7.h
> @@ -37,11 +37,11 @@ struct bfd_msg {
>      uint8_t flags;
>      uint8_t mult;
>      uint8_t length;
> -    ovs_be32 my_disc;
> -    ovs_be32 your_disc;
> -    ovs_be32 min_tx;
> -    ovs_be32 min_rx;
> -    ovs_be32 min_rx_echo;
> +    ovs_16aligned_be32 my_disc;
> +    ovs_16aligned_be32 your_disc;
> +    ovs_16aligned_be32 min_tx;
> +    ovs_16aligned_be32 min_rx;
> +    ovs_16aligned_be32 min_rx_echo;
>  };
>  BUILD_ASSERT_DECL(BFD_PACKET_LEN == sizeof(struct bfd_msg));
>
> --
> 2.31.1
>
> _______________________________________________
> dev mailing list
> [email protected]
> https://mail.openvswitch.org/mailman/listinfo/ovs-dev
>
>
It would be nice to make the ovs bfd struct public so it can be reused also
in ovn.
However, that takes some time, this is good, thanks.

Acked-by: Ales Musil <[email protected]>

-- 

Ales Musil

Senior Software Engineer - OVN Core

Red Hat EMEA <https://www.redhat.com>

[email protected]    IM: amusil
<https://red.ht/sig>
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to