diff options
author | JaeMan Park <jaeman@google.com> | 2021-07-19 15:32:08 +0900 |
---|---|---|
committer | JaeMan Park <jaeman@google.com> | 2021-07-22 05:32:03 +0000 |
commit | 476eb906a5f7258cbc6381428d24ad1f4abe70bc (patch) | |
tree | 2977d4d6ea81aaadd5ccca1c6b8427d39a87e403 /wmediumd | |
parent | 7c677eb28f4bf5b4ce76467b3b180143a601d00c (diff) | |
download | wmediumd-476eb906a5f7258cbc6381428d24ad1f4abe70bc.tar.gz |
Fix assertion failure at usfstl_vhost_user_read_msg
Assertion USFSTL_ASSERT_EQ(hdr->size, (uint32_t)len, "%u")
at usfstl_vhost_user_read_msg can fail because socket
buffer can contain longer than one vhost user message, and
msghdr passed to recvmsg function specifies that recvmsg can
read more than message size if possible. Changed to msghdr
specify exact message size to prevent reading more than expected.
Bug: 194023816
Test: lunch aosp_cf_x86_64_phone-userdebug &&
m PRODUCT_ENFORCE_MAC80211_HWSIM=true droid wmediumd &&
wmediumd -u /tmp/vhost_server_mac80211 -c $ANDROID_BUILD_TOP/external/wmediumd/tests/cuttlefish.cfg
and then, execute
launch_cvd --vhost-user-mac80211-hwsim=/tmp/vhost_server_mac80211
Check assertion 'hdr->size == (uint32_t)len' of vhost.c at wmediumd
does not failes.
Change-Id: I576cd19eed738bf4b2d34c28aeef03be4abd96f8
Diffstat (limited to 'wmediumd')
-rw-r--r-- | wmediumd/lib/vhost.c | 12 |
1 files changed, 10 insertions, 2 deletions
diff --git a/wmediumd/lib/vhost.c b/wmediumd/lib/vhost.c index 9d46441..1a85140 100644 --- a/wmediumd/lib/vhost.c +++ b/wmediumd/lib/vhost.c @@ -172,6 +172,8 @@ static int usfstl_vhost_user_read_msg(int fd, struct msghdr *msghdr) size_t i; size_t maxlen = 0; ssize_t len; + ssize_t prev_datalen; + size_t prev_iovlen; USFSTL_ASSERT(msghdr->msg_iovlen >= 1); USFSTL_ASSERT(msghdr->msg_iov[0].iov_len >= sizeof(*hdr)); @@ -196,18 +198,24 @@ static int usfstl_vhost_user_read_msg(int fd, struct msghdr *msghdr) if (!hdr->size) return 0; + prev_iovlen = msghdr->msg_iovlen; + msghdr->msg_iovlen = 1; + msghdr->msg_control = NULL; msghdr->msg_controllen = 0; msghdr->msg_iov[0].iov_base += sizeof(*hdr); - msghdr->msg_iov[0].iov_len -= sizeof(*hdr); + prev_datalen = msghdr->msg_iov[0].iov_len; + msghdr->msg_iov[0].iov_len = hdr->size; len = recvmsg(fd, msghdr, 0); /* restore just in case the user needs it */ msghdr->msg_iov[0].iov_base -= sizeof(*hdr); - msghdr->msg_iov[0].iov_len += sizeof(*hdr); + msghdr->msg_iov[0].iov_len = prev_datalen; msghdr->msg_control = hdr2.msg_control; msghdr->msg_controllen = hdr2.msg_controllen; + msghdr->msg_iovlen = prev_iovlen; + if (len < 0) return -errno; if (len == 0) |