From patchwork Mon Jan 13 10:58:41 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ilya Dryomov X-Patchwork-Id: 3474501 Return-Path: X-Original-To: patchwork-ceph-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 4C3269F2E9 for ; Mon, 13 Jan 2014 10:59:47 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 3723E200FE for ; Mon, 13 Jan 2014 10:59:46 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 360632010E for ; Mon, 13 Jan 2014 10:59:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751394AbaAMK7o (ORCPT ); Mon, 13 Jan 2014 05:59:44 -0500 Received: from mail-ee0-f41.google.com ([74.125.83.41]:41990 "EHLO mail-ee0-f41.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751355AbaAMK7m (ORCPT ); Mon, 13 Jan 2014 05:59:42 -0500 Received: by mail-ee0-f41.google.com with SMTP id e49so1380695eek.0 for ; Mon, 13 Jan 2014 02:59:41 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=qqGTANfU/h57a2I2r8w4L26amP0XDNLkQoGtA79DtIk=; b=i/Dx9LGZDO5b9v7gn5sfuQL+2hodVyhhAgFUqgVlGvjBU7wJOPXRQuK3XN7rjlwYpj W56iuGnRd3STz1uwYgn61YRKbVtkXGJNKzHWs7c/mwkJhp49sTyI/rvv6C38czVPMsw1 /Lwd75/JVyIZR+E9YP4Me7sh11cUErsPUhrofcPzR3e6gMXZvLVuy065cVzljUZFqhek QzfVgptVbXVuDuWkSkVW2K7eJCUvzkhcxeuXBMfmCJdTWayInVI8yZImPMrA4TtEfr24 c9+1FMIZK8pu+fCdPorjXMU/uQPqablS2myYy+cF9JMSua6q9hSKxkblQ7x+F4AvhGFK UY0w== X-Gm-Message-State: ALoCoQn7Yfvk5H8SC/hgHDqsfFMcjQvgScKxHvkka72gsMkqeG/DoNGUDnUO0gS+cl1eByoB33zj X-Received: by 10.14.122.5 with SMTP id s5mr26813817eeh.28.1389610781608; Mon, 13 Jan 2014 02:59:41 -0800 (PST) Received: from localhost ([109.110.66.199]) by mx.google.com with ESMTPSA id w4sm18499920eef.20.2014.01.13.02.59.40 for (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Mon, 13 Jan 2014 02:59:41 -0800 (PST) From: Ilya Dryomov To: ceph-devel@vger.kernel.org Cc: ilya.dryomov@inktank.com Subject: [PATCH 3/3] libceph: fix preallocation check in get_reply() Date: Mon, 13 Jan 2014 12:58:41 +0200 Message-Id: <1389610721-5280-4-git-send-email-ilya.dryomov@inktank.com> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1389610721-5280-1-git-send-email-ilya.dryomov@inktank.com> References: <1389610721-5280-1-git-send-email-ilya.dryomov@inktank.com> Sender: ceph-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: ceph-devel@vger.kernel.org X-Spam-Status: No, score=-7.0 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The check that makes sure that we have enough memory allocated to read in the entire header of the message in question is currently busted. It compares front_len of the incoming message with iov_len field of ceph_msg::front structure, which is used primarily to indicate the amount of data already read in, and not the size of the allocated buffer. Under certain conditions (e.g. a short read from a socket followed by that socket's shutdown and owning ceph_connection reset) this results in a warning similar to [85688.975866] libceph: get_reply front 198 > preallocated 122 (4#0) and, through another bug, leads to forever hung tasks and forced reboots. Fix this by comparing front_len with front_alloc_len field of struct ceph_msg, which stores the actual size of the buffer. Fixes: http://tracker.ceph.com/issues/5425 Signed-off-by: Ilya Dryomov Reviewed-by: Sage Weil --- net/ceph/messenger.c | 3 +-- net/ceph/osd_client.c | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c index 331f8e4c8a75..c4238e85989a 100644 --- a/net/ceph/messenger.c +++ b/net/ceph/messenger.c @@ -3131,7 +3131,6 @@ struct ceph_msg *ceph_msg_new(int type, int front_len, gfp_t flags, INIT_LIST_HEAD(&m->data); /* front */ - m->front_alloc_len = front_len; if (front_len) { if (front_len > PAGE_CACHE_SIZE) { m->front.iov_base = __vmalloc(front_len, flags, @@ -3148,7 +3147,7 @@ struct ceph_msg *ceph_msg_new(int type, int front_len, gfp_t flags, } else { m->front.iov_base = NULL; } - m->front.iov_len = front_len; + m->front_alloc_len = m->front.iov_len = front_len; dout("ceph_msg_new %p front %d\n", m, front_len); return m; diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c index bf1b418cc06d..600d3dc0fb66 100644 --- a/net/ceph/osd_client.c +++ b/net/ceph/osd_client.c @@ -2532,9 +2532,9 @@ static struct ceph_msg *get_reply(struct ceph_connection *con, goto out; } - if (front_len > req->r_reply->front.iov_len) { + if (front_len > req->r_reply->front_alloc_len) { pr_warning("get_reply front %d > preallocated %d (%u#%llu)\n", - front_len, (int)req->r_reply->front.iov_len, + front_len, req->r_reply->front_alloc_len, (unsigned int)con->peer_name.type, le64_to_cpu(con->peer_name.num)); m = ceph_msg_new(CEPH_MSG_OSD_OPREPLY, front_len, GFP_NOFS,