]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
msg/msg_types: entity_addrvec_t: fix decode on big-endian hosts 35920/head
authorUlrich Weigand <ulrich.weigand@de.ibm.com>
Fri, 3 Jul 2020 13:47:00 +0000 (15:47 +0200)
committerUlrich Weigand <ulrich.weigand@de.ibm.com>
Fri, 3 Jul 2020 13:47:00 +0000 (15:47 +0200)
When decoding an entity_addrvec_t with marker 1, we just have
a single (non-legacy) entity_addr_t.  This should be decoded
exactly the same as done by entity_addr_t::decode, but it
currently is not.  Specifically, the sa_family member of
the sockaddr is not converted from the on-wire little-endian
format to host byte order (as done by entity_addr_t::decode).

Fixed by using the same code as in entity_addr_t::decode.

Signed-off-by: Ulrich Weigand <ulrich.weigand@de.ibm.com>
src/msg/msg_types.cc

index 1f0c8242a8c2212072e549aced314e1529b03b8e..50a75cc86d0594d4edd34aa294b2373242d8822b 100644 (file)
@@ -309,7 +309,21 @@ void entity_addrvec_t::decode(ceph::buffer::list::const_iterator& bl)
     __u32 elen;
     decode(elen, bl);
     if (elen) {
-      bl.copy(elen, (char*)addr.get_sockaddr());
+      struct sockaddr *sa = (struct sockaddr *)addr.get_sockaddr();
+#if defined(__FreeBSD__) || defined(__APPLE__)
+      sa->sa_len = 0;
+#endif
+      uint16_t ss_family;
+      if (elen < sizeof(ss_family)) {
+        throw ceph::buffer::malformed_input("elen smaller than family len");
+      }
+      decode(ss_family, bl);
+      sa->sa_family = ss_family;
+      elen -= sizeof(ss_family);
+      if (elen > addr.get_sockaddr_len() - sizeof(sa->sa_family)) {
+        throw ceph::buffer::malformed_input("elen exceeds sockaddr len");
+      }
+      bl.copy(elen, sa->sa_data);
     }
     DECODE_FINISH(bl);
     v.clear();