From owner-freebsd-geom@freebsd.org Thu Apr 19 21:17:15 2018 Return-Path: Delivered-To: freebsd-geom@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 5FD33FA3510 for ; Thu, 19 Apr 2018 21:17:15 +0000 (UTC) (envelope-from markjdb@gmail.com) Received: from mail-it0-x229.google.com (mail-it0-x229.google.com [IPv6:2607:f8b0:4001:c0b::229]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (Client CN "smtp.gmail.com", Issuer "Google Internet Authority G2" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id E4FF4824A6 for ; Thu, 19 Apr 2018 21:17:14 +0000 (UTC) (envelope-from markjdb@gmail.com) Received: by mail-it0-x229.google.com with SMTP id 186-v6so124329itu.0 for ; Thu, 19 Apr 2018 14:17:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:date:from:to:subject:message-id:mime-version :content-disposition:user-agent; bh=Qe5VqviW02I9Qkn5mZMA+XLjLazunASz0V7hqU9HM4k=; b=cpY0jOWFMmA16YLtTaZ1/37zUX69oB2YZJyQPXH3U3KYAWj9aQZPTPHYkN5GHkxEzW tpfrSA+7SyPzCKOap9OsaJjsvjEGMG+nWtyjiX1lAydw33E0RTJ/nckCtMAEHk4pQKoL MbfU20STz6FXudfNCx6PA3grsrBiT4KsIR5Yuqm/h/av2ztKPoHWt4tODUrffLfo5sSI urR2o4Hy1XeZUT3g6loVPLGu9lMMM2aQDXW7NW+wCgZ9J91VEEXXyEcR+eo3IhoYFFyP yOy+vBy8FpPrMSdYj2z+YrjKX4nDoZ6CyMelGeasUQs9MrBf6u/J7FydkLORDYcdhAS3 OsQA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:date:from:to:subject:message-id :mime-version:content-disposition:user-agent; bh=Qe5VqviW02I9Qkn5mZMA+XLjLazunASz0V7hqU9HM4k=; b=DICmbRNBE/lqVpC6wREy39Uh1GoXpIMt/LCzPFC8cYeGf5Yir8Tc7nLvCKkTh6BHPV im2roN4aJFOFXXjHJ4naxVRxFOPhnhn6ORKc+JrB6IriSZz9n3vlhPcJcHp9n+lTKQgr spooo6d8hY0PJK4sc73Sm1y94TDQGUN5wyKJTulVFvYzdbwLMbecTvuL/xhktIcSpB6d EQSsjP6Q57zA+KKrd0vTw5XhYvpZGVn0lthi1bNt0O5sATcRBjqzCEZch0R8F0vikjEN yGrJl/k2Mvl3h/HtNa3SSgsVG9Qrt7x4jAQrT9n+lVwJPD9MSuKpbPr4GaQ1+eOLKb3R WyRQ== X-Gm-Message-State: ALQs6tB7+zwiCkqOVgUbme7EK+yWoraESOjkz5vLGUOJYH2YME7sS98a Hr14uib//06WQfKiuJeNnXtC9Q== X-Google-Smtp-Source: AB8JxZoWTix5LzCyRvF3KMJBPtuO5xw2qWSnWSeO4/Uq2qGM2jfQsjEog2kDlfDOEl2OhH69hWA1dg== X-Received: by 2002:a24:5bd5:: with SMTP id g204-v6mr421025itb.55.1524172634082; Thu, 19 Apr 2018 14:17:14 -0700 (PDT) Received: from raichu (toroon0560w-lp130-04-184-145-252-74.dsl.bell.ca. [184.145.252.74]) by smtp.gmail.com with ESMTPSA id u98-v6sm2285421iou.79.2018.04.19.14.17.13 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 19 Apr 2018 14:17:13 -0700 (PDT) Sender: Mark Johnston Date: Thu, 19 Apr 2018 17:17:09 -0400 From: Mark Johnston To: freebsd-geom@freebsd.org Subject: racy dumpconf interface Message-ID: <20180419211709.GA12902@raichu> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.9.4 (2018-02-28) X-BeenThere: freebsd-geom@freebsd.org X-Mailman-Version: 2.1.25 Precedence: list List-Id: GEOM-specific discussions and implementations List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 19 Apr 2018 21:17:15 -0000 Hi, Currently, when fetching a snapshot of the mesh we call the class' dumpconf method once for each consumer: 254 LIST_FOREACH(cp2, &gp->consumer, consumer) { 255 if (cp != NULL && cp != cp2) 256 continue; 257 g_conf_consumer(sb, cp2); /* calls dumpconf */ 258 } Some dumpconf implementations (such as gmirror's) drop the topology lock to acquire an internal lock which comes first in the lock order. The problem with this is that cp2 may be freed while the topology lock is dropped. The problem doesn't really affect g_geom and g_provider pointers because they are freed only by the g_event thread (I think), which is also the thread which calls g_conf_geom(). This is not true of consumers, however, so it's possible to hit a use-after-free in the list traversal pasted above. One solution for gmirror's case is to simply avoid acquiring the softc lock when fetching a snapshot of the consumer. The topology lock is sufficient to ensure that cp->private doesn't get freed in the middle of the dumpconf invocation. However, this of course means that we may record an inconsistent snapshot of the disk's info. Another solution would be to fetch info for all consumers in a single call to dumpconf. This way the consumer list of a given GEOM may be traversed safely after dropping and reacquiring the topology lock. However, this would probably involve changing the dumpconf interface (or adding a "dumpconf_consumers" class method). Does anyone have any thoughts or preferences on this matter?