This pull request fixes a potential QEMU hang in 9pfs and two issues

reported by Coverity.
 -----BEGIN PGP SIGNATURE-----
 
 iEYEABECAAYFAljQ+SYACgkQAvw66wEB28J8ZwCgku9iE4sYZdkMxGdtyo1vVZkV
 Fy4AnRDKY62QCJSewzHa6k0qX+UEKZP1
 =ARLp
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/gkurz/tags/for-upstream' into staging

This pull request fixes a potential QEMU hang in 9pfs and two issues
reported by Coverity.

# gpg: Signature made Tue 21 Mar 2017 09:57:58 GMT
# gpg:                using DSA key 0x02FC3AEB0101DBC2
# gpg: Good signature from "Greg Kurz <groug@kaod.org>"
# gpg:                 aka "Greg Kurz <groug@free.fr>"
# gpg:                 aka "Greg Kurz <gkurz@linux.vnet.ibm.com>"
# gpg:                 aka "Gregory Kurz (Groug) <groug@free.fr>"
# gpg:                 aka "[jpeg image of size 3330]"
# gpg: WARNING: This key is not certified with a trusted signature!
# gpg:          There is no indication that the signature belongs to the owner.
# Primary key fingerprint: 2BD4 3B44 535E C0A7 9894  DBA2 02FC 3AEB 0101 DBC2

* remotes/gkurz/tags/for-upstream:
  9pfs: proxy: assert if unmarshal fails
  9pfs: don't try to flush self and avoid QEMU hang on reset

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2017-03-21 14:32:51 +00:00
commit 41a56822e3
2 changed files with 19 additions and 15 deletions

View File

@ -165,7 +165,8 @@ static int v9fs_receive_response(V9fsProxy *proxy, int type,
return retval; return retval;
} }
reply->iov_len = PROXY_HDR_SZ; reply->iov_len = PROXY_HDR_SZ;
proxy_unmarshal(reply, 0, "dd", &header.type, &header.size); retval = proxy_unmarshal(reply, 0, "dd", &header.type, &header.size);
assert(retval == 4 * 2);
/* /*
* if response size > PROXY_MAX_IO_SZ, read the response but ignore it and * if response size > PROXY_MAX_IO_SZ, read the response but ignore it and
* return -ENOBUFS * return -ENOBUFS
@ -194,9 +195,7 @@ static int v9fs_receive_response(V9fsProxy *proxy, int type,
if (header.type == T_ERROR) { if (header.type == T_ERROR) {
int ret; int ret;
ret = proxy_unmarshal(reply, PROXY_HDR_SZ, "d", status); ret = proxy_unmarshal(reply, PROXY_HDR_SZ, "d", status);
if (ret < 0) { assert(ret == 4);
*status = ret;
}
return 0; return 0;
} }
@ -213,6 +212,7 @@ static int v9fs_receive_response(V9fsProxy *proxy, int type,
&prstat.st_atim_sec, &prstat.st_atim_nsec, &prstat.st_atim_sec, &prstat.st_atim_nsec,
&prstat.st_mtim_sec, &prstat.st_mtim_nsec, &prstat.st_mtim_sec, &prstat.st_mtim_nsec,
&prstat.st_ctim_sec, &prstat.st_ctim_nsec); &prstat.st_ctim_sec, &prstat.st_ctim_nsec);
assert(retval == 8 * 3 + 4 * 3 + 8 * 10);
prstat_to_stat(response, &prstat); prstat_to_stat(response, &prstat);
break; break;
} }
@ -225,6 +225,7 @@ static int v9fs_receive_response(V9fsProxy *proxy, int type,
&prstfs.f_files, &prstfs.f_ffree, &prstfs.f_files, &prstfs.f_ffree,
&prstfs.f_fsid[0], &prstfs.f_fsid[1], &prstfs.f_fsid[0], &prstfs.f_fsid[1],
&prstfs.f_namelen, &prstfs.f_frsize); &prstfs.f_namelen, &prstfs.f_frsize);
assert(retval == 8 * 11);
prstatfs_to_statfs(response, &prstfs); prstatfs_to_statfs(response, &prstfs);
break; break;
} }
@ -246,7 +247,8 @@ static int v9fs_receive_response(V9fsProxy *proxy, int type,
break; break;
} }
case T_GETVERSION: case T_GETVERSION:
proxy_unmarshal(reply, PROXY_HDR_SZ, "q", response); retval = proxy_unmarshal(reply, PROXY_HDR_SZ, "q", response);
assert(retval == 8);
break; break;
default: default:
return -1; return -1;
@ -274,18 +276,16 @@ static int v9fs_receive_status(V9fsProxy *proxy,
return retval; return retval;
} }
reply->iov_len = PROXY_HDR_SZ; reply->iov_len = PROXY_HDR_SZ;
proxy_unmarshal(reply, 0, "dd", &header.type, &header.size); retval = proxy_unmarshal(reply, 0, "dd", &header.type, &header.size);
if (header.size != sizeof(int)) { assert(retval == 4 * 2);
*status = -ENOBUFS;
return 0;
}
retval = socket_read(proxy->sockfd, retval = socket_read(proxy->sockfd,
reply->iov_base + PROXY_HDR_SZ, header.size); reply->iov_base + PROXY_HDR_SZ, header.size);
if (retval < 0) { if (retval < 0) {
return retval; return retval;
} }
reply->iov_len += header.size; reply->iov_len += header.size;
proxy_unmarshal(reply, PROXY_HDR_SZ, "d", status); retval = proxy_unmarshal(reply, PROXY_HDR_SZ, "d", status);
assert(retval == 4);
return 0; return 0;
} }

View File

@ -2353,7 +2353,7 @@ static void coroutine_fn v9fs_flush(void *opaque)
ssize_t err; ssize_t err;
int16_t tag; int16_t tag;
size_t offset = 7; size_t offset = 7;
V9fsPDU *cancel_pdu; V9fsPDU *cancel_pdu = NULL;
V9fsPDU *pdu = opaque; V9fsPDU *pdu = opaque;
V9fsState *s = pdu->s; V9fsState *s = pdu->s;
@ -2364,9 +2364,13 @@ static void coroutine_fn v9fs_flush(void *opaque)
} }
trace_v9fs_flush(pdu->tag, pdu->id, tag); trace_v9fs_flush(pdu->tag, pdu->id, tag);
QLIST_FOREACH(cancel_pdu, &s->active_list, next) { if (pdu->tag == tag) {
if (cancel_pdu->tag == tag) { error_report("Warning: the guest sent a self-referencing 9P flush request");
break; } else {
QLIST_FOREACH(cancel_pdu, &s->active_list, next) {
if (cancel_pdu->tag == tag) {
break;
}
} }
} }
if (cancel_pdu) { if (cancel_pdu) {