Received: by 2002:ac0:a5a7:0:0:0:0:0 with SMTP id m36-v6csp5948467imm; Mon, 23 Jul 2018 08:46:08 -0700 (PDT) X-Google-Smtp-Source: AAOMgpd1tWpz6HRCs2cjCSSN13uQlDLxVBzl4yQwoCuI7CZL1vQnL3EAahfR1+Rf/HHyFqOi+7Mb X-Received: by 2002:a62:ac12:: with SMTP id v18-v6mr13553669pfe.126.1532360768536; Mon, 23 Jul 2018 08:46:08 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1532360768; cv=none; d=google.com; s=arc-20160816; b=jjcr7gXazGCMl/5VwBZFRRBnEEVgx9iHWk4+8hEdsHjjj8ehh6CarpOLflVt9Kvsev U5z3o2PHemVg3lluiqKSTIi487Xf/TGGCYvYlyQx0qdQ7oxJe8VJ+hgV0xSW7G0WmN7N nyXRT+9KAgIIiQFDXKtNxCLY49AwLBlDcLb7eO/msTgdxmwzwldTHFX7Xz2eUa7qp3HF V8xJGPDllAE+vuJ2f8SmA0RtbSSfS/bshU+9i5pKiHgVq6Vayok0bEndD4rUCAx9myj4 Wl+M15IYW58yCwDXw07wQT8RhtIhp7yXS//O6+GMTwB8vj6Lw/f1vMgNP8Y/c5rfd0Sq RRUQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:message-id:date:subject:cc:to:from :dkim-signature:arc-authentication-results; bh=S2vp7wIiLTtVes09q9AhvVh/4crBSVkDyIIaM012ufg=; b=peFi5dUSISpcIJ+Bqf+qCTub4lyaRo5JDo6a3gSrCCxeFkxwHhcEkqeGL+0H0y7pJy ojHQB3LILIAda7vUUI6o3OqaIocCC6/x766KE8cTjyICLO1pnCF2bsSb5UJUmkqOm4LB cxg396RAgYQ3E0ju8qWfzGPTPZVSp3OSItj8Dq3neJNsthPUFFnI4KgleNmHOKiS9cJ+ uMxiclbRa5kbE3TkJMZbI0W02lv4IY07f/VGOdiYJuV84fowL+4ixvXFKzrre29VXMHm /lkJagRjemIyvRgB6kwMRfneS/7wIdX6Rd9oysmqOnkJKu6TxAsXexHRwK5fp/ev/v4d zw8w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=pktWMPqk; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id l33-v6si8259208pld.514.2018.07.23.08.45.53; Mon, 23 Jul 2018 08:46:08 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=pktWMPqk; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2388719AbeGWQqB (ORCPT + 99 others); Mon, 23 Jul 2018 12:46:01 -0400 Received: from mail-lj1-f196.google.com ([209.85.208.196]:32996 "EHLO mail-lj1-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2388068AbeGWQqB (ORCPT ); Mon, 23 Jul 2018 12:46:01 -0400 Received: by mail-lj1-f196.google.com with SMTP id s12-v6so956469ljj.0; Mon, 23 Jul 2018 08:44:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id; bh=S2vp7wIiLTtVes09q9AhvVh/4crBSVkDyIIaM012ufg=; b=pktWMPqkJctUPA7Xl7V2saDPz9eIVEhA9332kwZA5OzcSCpO15CTlWDK+NuiL8HK6C oEZ//Tmxv7GCd6W1re2em9CDw7reVXPOof1/zjyieGSZZooyWb03Bo76XSYsr7IallmR 8ZN/ZNAlQ5UNXa1jEVnjpf/mAKqi70927aLCRl2kMvG6ZNyYRTn7Xfriaj/zKxxOqLQu HyHE8WYZiF8YR79tiqcRfwCeKenzWC45gzaolSQzWpj6gc7GcP0r+mNE5d3+t7WUb8Jv yoJRvMb+XlpSmY4Tcu5PVxGVzC9SNEdMNCUeltM7yhZKAoeNjEf3Rea4FhdLOpmhHYJj SM4Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=S2vp7wIiLTtVes09q9AhvVh/4crBSVkDyIIaM012ufg=; b=U2G0r0S1nHGD9y1nQmxPbI4B9Y2BZGAa/PW48YzbipoBLwk7+N+v6wN2FvdDUt/Khp jSnc7QI3sCPVzywgB0BXOhMhgsg+fk7AuMsGdjK1YtFJUBGNl+xdAmEa5sUMB6eo/B+o IRWxBe5oju9kOIYjNxFi7y+XCNWvu2ORuHhf1BFSkP0eFssqdwkx9cOjFa1DXT/OOil2 KBNnibYmOZYG6xBGB+S/kcdcS03+UfRh+6JP0ORV/+Z2nDSoi0yk+cVOBkrsBrAIp44F auH1amG1jPUTZPcvknb2da6S82/HNyA+R75nc5KxtF8vFt1QfaEhYuLCNjWiBQzgUtnW RiXQ== X-Gm-Message-State: AOUpUlHu7KrhCccHzlGJXLX9vf2VNfucUpbIrPDwoyzxoOXtklLvCSlq 4/YNzUgpr4n33GA42Y+j2TE= X-Received: by 2002:a2e:4103:: with SMTP id o3-v6mr8993428lja.3.1532360651062; Mon, 23 Jul 2018 08:44:11 -0700 (PDT) Received: from debian-tom.lan ([2001:2012:22e:1b00:f2e2:9015:9262:3fde]) by smtp.gmail.com with ESMTPSA id t8-v6sm717345lfd.2.2018.07.23.08.44.09 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 23 Jul 2018 08:44:10 -0700 (PDT) From: Tomas Bortoli To: ericvh@gmail.com, rminnich@sandia.gov, lucho@ionkov.net Cc: asmadeus@codewreck.org, davem@davemloft.net, v9fs-developer@lists.sourceforge.net, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, syzkaller@googlegroups.com, Tomas Bortoli Subject: [PATCH] 9p: validate PDU length Date: Mon, 23 Jul 2018 17:44:04 +0200 Message-Id: <20180723154404.2406-1-tomasbortoli@gmail.com> X-Mailer: git-send-email 2.11.0 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org This commit adds length check for the PDU size. The size contained in the header has to match the actual size, except for TCP (trans_fd.c) where actual length is not known ahead and the header's length will be checked only against the validity range. Signed-off-by: Tomas Bortoli Reported-by: syzbot+65c6b72f284a39d416b4@syzkaller.appspotmail.com --- net/9p/client.c | 25 ++++++++++++++++--------- net/9p/trans_fd.c | 5 ++++- net/9p/trans_rdma.c | 1 + net/9p/trans_virtio.c | 4 +++- 4 files changed, 24 insertions(+), 11 deletions(-) diff --git a/net/9p/client.c b/net/9p/client.c index 18c5271910dc..92240ccf476b 100644 --- a/net/9p/client.c +++ b/net/9p/client.c @@ -477,20 +477,11 @@ p9_parse_header(struct p9_fcall *pdu, int32_t *size, int8_t *type, int16_t *tag, int err; pdu->offset = 0; - if (pdu->size == 0) - pdu->size = 7; err = p9pdu_readf(pdu, 0, "dbw", &r_size, &r_type, &r_tag); if (err) goto rewind_and_exit; - pdu->size = r_size; - pdu->id = r_type; - pdu->tag = r_tag; - - p9_debug(P9_DEBUG_9P, "<<< size=%d type: %d tag: %d\n", - pdu->size, pdu->id, pdu->tag); - if (type) *type = r_type; if (tag) @@ -498,6 +489,16 @@ p9_parse_header(struct p9_fcall *pdu, int32_t *size, int8_t *type, int16_t *tag, if (size) *size = r_size; + if (pdu->size != r_size || r_size < 7) { + err = -EINVAL; + goto rewind_and_exit; + } + + pdu->id = r_type; + pdu->tag = r_tag; + + p9_debug(P9_DEBUG_9P, "<<< size=%d type: %d tag: %d\n", + pdu->size, pdu->id, pdu->tag); rewind_and_exit: if (rewind) @@ -524,6 +525,12 @@ static int p9_check_errors(struct p9_client *c, struct p9_req_t *req) int ecode; err = p9_parse_header(req->rc, NULL, &type, NULL, 0); + if (req->rc->size >= c->msize) { + p9_debug(P9_DEBUG_ERROR, + "requested packet size too big: %d\n", + req->rc->size); + return -EIO; + } /* * dump the response from server * This should be after check errors which poplulate pdu_fcall. diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c index 588bf88c3305..65533c437b7f 100644 --- a/net/9p/trans_fd.c +++ b/net/9p/trans_fd.c @@ -324,7 +324,9 @@ static void p9_read_work(struct work_struct *work) if ((!m->req) && (m->rc.offset == m->rc.capacity)) { p9_debug(P9_DEBUG_TRANS, "got new header\n"); - err = p9_parse_header(&m->rc, NULL, NULL, NULL, 0); + /* Header size */ + m->rc.size = 7; + err = p9_parse_header(&m->rc, &m->rc.size, NULL, NULL, 0); if (err) { p9_debug(P9_DEBUG_ERROR, "error parsing header: %d\n", err); @@ -369,6 +371,7 @@ static void p9_read_work(struct work_struct *work) */ if ((m->req) && (m->rc.offset == m->rc.capacity)) { p9_debug(P9_DEBUG_TRANS, "got new packet\n"); + m->req->rc->size = m->rc.offset; spin_lock(&m->client->lock); if (m->req->status != REQ_STATUS_ERROR) status = REQ_STATUS_RCVD; diff --git a/net/9p/trans_rdma.c b/net/9p/trans_rdma.c index 3d414acb7015..2649b2ebf961 100644 --- a/net/9p/trans_rdma.c +++ b/net/9p/trans_rdma.c @@ -320,6 +320,7 @@ recv_done(struct ib_cq *cq, struct ib_wc *wc) if (wc->status != IB_WC_SUCCESS) goto err_out; + c->rc->size = wc->byte_len; err = p9_parse_header(c->rc, NULL, NULL, &tag, 1); if (err) goto err_out; diff --git a/net/9p/trans_virtio.c b/net/9p/trans_virtio.c index 05006cbb3361..fc6dc9ca86a4 100644 --- a/net/9p/trans_virtio.c +++ b/net/9p/trans_virtio.c @@ -159,8 +159,10 @@ static void req_done(struct virtqueue *vq) spin_unlock_irqrestore(&chan->lock, flags); /* Wakeup if anyone waiting for VirtIO ring space. */ wake_up(chan->vc_wq); - if (len) + if (len) { + req->rc->size = len; p9_client_cb(chan->client, req, REQ_STATUS_RCVD); + } } } -- 2.11.0