]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
msg/msg_types: entity_addrvec_t: fix decode on big-endian hosts 36814/head
authorUlrich Weigand <ulrich.weigand@de.ibm.com>
Fri, 3 Jul 2020 13:47:00 +0000 (15:47 +0200)
committerNathan Cutler <ncutler@suse.com>
Fri, 25 Sep 2020 14:09:38 +0000 (16:09 +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>
(cherry picked from commit 31da17378b712542e915adbf4084e0212b8bb615)

src/msg/msg_types.cc

index 62ca036e225907a4baf3894b883767be96a361b3..76b9585b394e3602b80b87ba88ae6664d88136a0 100644 (file)
@@ -317,7 +317,21 @@ void entity_addrvec_t::decode(bufferlist::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();