From patchwork Wed May 18 07:01:00 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacek Luczak X-Patchwork-Id: 96133 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 10CC4B6F67 for ; Wed, 18 May 2011 17:01:07 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754541Ab1ERHBB (ORCPT ); Wed, 18 May 2011 03:01:01 -0400 Received: from mail-pv0-f174.google.com ([74.125.83.174]:51124 "EHLO mail-pv0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754316Ab1ERHBA (ORCPT ); Wed, 18 May 2011 03:01:00 -0400 Received: by pvg12 with SMTP id 12so577358pvg.19 for ; Wed, 18 May 2011 00:01:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:mime-version:date:message-id:subject:from:to :content-type; bh=QJ7I/s/LzO8ST+1tecv7O20RgZbZH04NFlcZ45bcucQ=; b=wJ7NudbUUfiM643AE90w0nK1X8NBDvsIROQbsnDosffFzRqNx3gnM1KsDGtcIzrm+m 24ODnC1juLVkMH0PJpt47NT2gk85qdexi1TmC26pqnTUOzWAL1dLKvBc8t50Ka90MXYb QRKWtm7Ro1c6TbnqUdpyZWmnbw3NhjXIy5ukQ= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:date:message-id:subject:from:to:content-type; b=BG1y4PIVvIlUGiBZgsj5K598eYL5WI/ih7Q8w402fAOsPN/3xavKEaWay6pkHiAHVc Bjf7eqakvvglJiBR8WVhIl4H+SwjqY+yNp9iT70NZ/wqK438roYCPALHf229a9DYL5Nd I5kaQ8xRC10hXsB1mwqvbbdjDkFlsAMXugFRc= MIME-Version: 1.0 Received: by 10.68.31.104 with SMTP id z8mr2617765pbh.220.1305702060050; Wed, 18 May 2011 00:01:00 -0700 (PDT) Received: by 10.68.48.199 with HTTP; Wed, 18 May 2011 00:01:00 -0700 (PDT) Date: Wed, 18 May 2011 09:01:00 +0200 Message-ID: Subject: [PATCH] SCTP: fix race between sctp_bind_addr_free() and sctp_bind_addr_conflict() From: Jacek Luczak To: netdev@vger.kernel.org Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org During the sctp_close() call, we do not use rcu primitives to destroy the address list attached to the endpoint. At the same time, we do the removal of addresses from this list before attempting to remove the socket from the port hash As a result, it is possible for another process to find the socket in the port hash that is in the process of being closed. It then proceeds to traverse the address list to find the conflict, only to have that address list suddenly disappear without rcu() critical section. This can result in a kernel crash with general protection fault or kernel NULL pointer dereference. Fix issue by closing address list removal inside RCU critical section. Signed-off-by: Jacek Luczak Acked-by: Vlad Yasevich --- bind_addr.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/net/sctp/bind_addr.c b/net/sctp/bind_addr.c index faf71d1..19d1329 100644 --- a/net/sctp/bind_addr.c +++ b/net/sctp/bind_addr.c @@ -155,8 +155,16 @@ static void sctp_bind_addr_clean(struct sctp_bind_addr *bp) /* Dispose of an SCTP_bind_addr structure */ void sctp_bind_addr_free(struct sctp_bind_addr *bp) { - /* Empty the bind address list. */ - sctp_bind_addr_clean(bp); + struct sctp_sockaddr_entry *addr; + + /* Empty the bind address list inside RCU section. */ + rcu_read_lock(); + list_for_each_entry_rcu(addr, &bp->address_list, list) { + list_del_rcu(&addr->list); + call_rcu(&addr->rcu, sctp_local_addr_free); + SCTP_DBG_OBJCNT_DEC(addr); + } + rcu_read_unlock(); if (bp->malloced) { kfree(bp);