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:
commit
41a56822e3
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
12
hw/9pfs/9p.c
12
hw/9pfs/9p.c
@ -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) {
|
||||||
|
Loading…
Reference in New Issue
Block a user