Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932116AbbGASoj (ORCPT ); Wed, 1 Jul 2015 14:44:39 -0400 Received: from zeniv.linux.org.uk ([195.92.253.2]:47212 "EHLO ZenIV.linux.org.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932080AbbGASoO (ORCPT ); Wed, 1 Jul 2015 14:44:14 -0400 Date: Wed, 1 Jul 2015 19:44:08 +0100 From: Al Viro To: Andrey Ryabinin Cc: Linus Torvalds , linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org Subject: Re: [git pull] vfs part 2 Message-ID: <20150701184408.GF17109@ZenIV.linux.org.uk> References: <20150415181406.GL889@ZenIV.linux.org.uk> <5538C66F.4050404@samsung.com> <20150621211213.GA18732@ZenIV.linux.org.uk> <5587F943.3040006@samsung.com> <20150701062752.GC17109@ZenIV.linux.org.uk> <55939BE3.6040902@samsung.com> <20150701082753.GD17109@ZenIV.linux.org.uk> <5593A7A0.6050400@samsung.com> <20150701085507.GE17109@ZenIV.linux.org.uk> <5593CE37.4070307@samsung.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <5593CE37.4070307@samsung.com> User-Agent: Mutt/1.5.21 (2010-09-15) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 3436 Lines: 81 On Wed, Jul 01, 2015 at 02:25:43PM +0300, Andrey Ryabinin wrote: > I've attached gdb instead. > So, after message "bogus RWRITE: 93 -> 4096" > I've got this: > > (gdb) p *req->rc > $11 = {size = 11, id = 119 'w', tag = 3, offset = 11, capacity = 8192, sdata = 0xffff8802347b8020 "\v"} > (gdb) p *req->tc > $12 = {size = 116, id = 118 'v', tag = 3, offset = 0, capacity = 8192, sdata = 0xffff88023479c020 "t"} *grumble* Request: id = P9_TWRITE, tag = 3. Response: id = P9_RWRITE, tag = 3. Size of request is reasonable: it should be 32bit request size + 8bit id (TWRITE) + 16bit tag + 32bit fid + 64bit offset + 32bit count + payload, i.e. 23 + payload size. 23 + 93 == 116, which is what we have there. Success response is 32bit request size + 8bit id (RWRITE) + 16bit tag + 32bit count, i.e. 11 bytes and that seems to be what we are getting here. That would appear to exclude the possibility of bogus request - even if we had somehow ended up with count == 4096 in TWRITE arguments, server wouldn't have anywhere to get that much data from and either the things are *really* badly fucked on server, or it should've replied with RERROR. To exclude it completely we could check 4 bytes at req->tc->sdata + 19 (that's where count is), but I don't believe that this is where the problem is. The thing is, looking through qemu hw/9pfs/virtio-9p.c:v9fs_write() and the stuff it calls, I don't see any way for that kind of crap to happen there... Just in case - after the do-while loop in qemu v9fs_write(), just prior to offset = 7; err = pdu_marshal(pdu, offset, "d", total); if (err < 0) { goto out; } could you slap something like if (total > count) *(char *)0 = 0; and see if it dumps core on your test? Or use some more humane form of debugging - it's been a while since I last ran qemu under gdb and I'd need more coffee to bring that memory up... Mismatched reply could also be a possibility, but only if we end up with sending more than one request with the same tag without waiting for response for the first one. The reason why I don't want to let it go just with the "cap count with rsize in a couple of places in net/9p/client.c" (which we'll definitely need - we can't assume that server is sane, not compromised, etc.) is that it smells like a symptom of something very fishy and I'd prefer to get to the root of that thing... Oh, lovely - I do see one bug in there that could've lead to bogosities around the request lifetimes, but it's more recent than 3.19, so we have something else going on. In any case, the patch below is needed to fix a fuckup introduced in 4.0 - getting truncated RWRITE packet from server (as in "badly malformed response", not "short write") ends up with double-free. Almost certainly not what we are hitting here, though. diff --git a/net/9p/client.c b/net/9p/client.c index 6f4c4c8..ca3b342 100644 --- a/net/9p/client.c +++ b/net/9p/client.c @@ -1647,6 +1647,7 @@ p9_client_write(struct p9_fid *fid, u64 offset, struct iov_iter *from, int *err) if (*err) { trace_9p_protocol_dump(clnt, req->rc); p9_free_req(clnt, req); + break; } p9_debug(P9_DEBUG_9P, "<<< RWRITE count %d\n", count); -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/