From patchwork Wed Oct 24 23:20:29 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sage Weil X-Patchwork-Id: 1641041 Return-Path: X-Original-To: patchwork-ceph-devel@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork1.kernel.org (Postfix) with ESMTP id A2F6C3FD4E for ; Wed, 24 Oct 2012 23:19:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754002Ab2JXXTl (ORCPT ); Wed, 24 Oct 2012 19:19:41 -0400 Received: from cobra.newdream.net ([66.33.216.30]:53582 "EHLO cobra.newdream.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751333Ab2JXXTk (ORCPT ); Wed, 24 Oct 2012 19:19:40 -0400 Received: from fatty.ops.newdream.net (unknown [38.122.20.226]) by cobra.newdream.net (Postfix) with ESMTPA id 6595F8004B; Wed, 24 Oct 2012 16:19:40 -0700 (PDT) From: Sage Weil To: ceph-devel@vger.kernel.org Cc: Sage Weil Subject: [PATCH] libceph: avoid NULL kref_put when osd reset races with alloc_msg Date: Wed, 24 Oct 2012 16:20:29 -0700 Message-Id: <1351120829-12219-1-git-send-email-sage@inktank.com> X-Mailer: git-send-email 1.7.9 Sender: ceph-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: ceph-devel@vger.kernel.org The ceph_on_in_msg_alloc() method drops con->mutex while it allocates a message. If that races with a timeout that resends a zillion messages and resets the connection, and the ->alloc_msg() method returns a NULL message, it will call ceph_msg_put(NULL) and BUG. Fix by only calling put if msg is non-NULL. Fixes http://tracker.newdream.net/issues/3142 Signed-off-by: Sage Weil Reviewed-by: Alex Elder --- net/ceph/messenger.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c index 66f6f56..1041114 100644 --- a/net/ceph/messenger.c +++ b/net/ceph/messenger.c @@ -2742,7 +2742,8 @@ static int ceph_con_in_msg_alloc(struct ceph_connection *con, int *skip) msg = con->ops->alloc_msg(con, hdr, skip); mutex_lock(&con->mutex); if (con->state != CON_STATE_OPEN) { - ceph_msg_put(msg); + if (msg) + ceph_msg_put(msg); return -EAGAIN; } con->in_msg = msg;