Received: by 2002:a25:ad19:0:0:0:0:0 with SMTP id y25csp2399450ybi; Mon, 1 Jul 2019 11:19:54 -0700 (PDT) X-Google-Smtp-Source: APXvYqzAd7KwBOIyUzKC6bcd2fw+8RzUGW6LkzNdh7Lw+BCLyBwis5F8fU2U83sQk//w4MFvlcZZ X-Received: by 2002:a17:90a:1aa4:: with SMTP id p33mr680793pjp.27.1562005194730; Mon, 01 Jul 2019 11:19:54 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1562005194; cv=none; d=google.com; s=arc-20160816; b=x0Y24tKUjxYdSbuK3f87xSl7mdBV9cJFRRDJ3VQgNnVgiT8fSG8hsqjF7MtuKBQdOW mWywfyHYnZMGjYmUB2QcypAHcyvbrwhOxWIrWG60TjpEcU1LL3w5hpuWYIFsgMTFIy8z m6r4xEyWycZm2vIe0R47GF1J0Yd6KtLSoKQOJ/ooGBoNBVQXwFtxq2/FBXsu9XyV1tYH NiraS7jXIwW3aHn9bjn4/sTIvXXfV0ijxdX35BsY95AfGu07GJTmLUbuKM9BiGYA5MPZ FEp7gFYHSl78OKlg+SL0P+9eC08adcGyrWtJqc6NUG/Zm2yMqF5e9URXTVeBtJHLvkjQ wzpw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :message-id:date:subject:cc:to:from:dkim-signature; bh=SbjyLgOhtDSopoLbQRya8z6cDiEX3QnPAyeC6iTDsA0=; b=OOrXLbXHMIhRYG5LDOrq9B64FMk9ZnzuibcWw2RhiPBu+ffkl5WbdX4NENVE/3a+d5 HykQbnWdgxKKPQr471M8RKK/EqFa+vHLJJ7vTD9X+cYeSBqPZZCdC2EFuqXxRh9tib2G /hR7YCDYgrzvT+v7SyrA8HGp7tJmPRu3G9QQsq+OrVkScnlbILjYCHxMrvBLQyjumzxD we8Ebx58LfS/3TWKNEAdd22EvXZbG+8lXlZx8NtyvLluYpwja95va6xPCDIyn/qESdbP l8GeQ0otwTQ5OFEthQYu3G1wdMyKi+/Ljz6ueCvpZRBiH2qZVfHG33L/1czxP87I6WWL Oz/Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b=awfBR53c; 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=NONE dis=NONE) header.from=chromium.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id j62si11965423pfb.272.2019.07.01.11.18.58; Mon, 01 Jul 2019 11:19:54 -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=@chromium.org header.s=google header.b=awfBR53c; 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=NONE dis=NONE) header.from=chromium.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729543AbfGARar (ORCPT + 99 others); Mon, 1 Jul 2019 13:30:47 -0400 Received: from mail-pl1-f193.google.com ([209.85.214.193]:43908 "EHLO mail-pl1-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729002AbfGARar (ORCPT ); Mon, 1 Jul 2019 13:30:47 -0400 Received: by mail-pl1-f193.google.com with SMTP id cl9so7677761plb.10 for ; Mon, 01 Jul 2019 10:30:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=SbjyLgOhtDSopoLbQRya8z6cDiEX3QnPAyeC6iTDsA0=; b=awfBR53cYYeNdAmUC6qRCyNuCBq5Gn2U5ktWi0DUNSiBQWFot1XhV5VGK4sbk/MFwU ky2Sa+/a0NTwiIPa3hqvnAIkkzfBsqD7ZoJzBHJSfgMx1jdZDX8fSsuRzuqN7G8putue XmUQwpNoeWMI32y5wZq6n5r4jpu73EXLoMtdk= 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:mime-version :content-transfer-encoding; bh=SbjyLgOhtDSopoLbQRya8z6cDiEX3QnPAyeC6iTDsA0=; b=Q+rXfQMdn6W8LrQi56oa9GEmOHVSit8DNSNbnwrH8bgnXwTbK8ZcNWxXdYIdV2xGWx 9S6QsoFxdECYaPDGx8vQxnyUnIup4Ixg965r+P3V3m7vv+LAXJTqD0LhMmNr6K7f4TzN u24g4NJ7YvejsNNfEJs2tS9S+u1qILF+uaATu9VGVcqdzNvWbXHxJEoy/Z930h3YHo+9 uRTH3rWrbe6aitDEFJnHqZIbuLfK+wN3a6rWEMwPNp4ygIbnJ87I+16kQVILEjlK73Sh L0Fk/jlw4cdTyM5xPZYyhAbg+tlxKOocsszPJwi1d+aK1HAJRW2APcExYDVVf6iYdHE7 PUVg== X-Gm-Message-State: APjAAAW4QjFuKcXsYc43gqYy4Fc5BFO++SY/zEMXUck2rVEabYcKzeuW pHNvLdQGUw2zJ/9ofxfEzFLstA== X-Received: by 2002:a17:902:8d97:: with SMTP id v23mr3403051plo.157.1562002246821; Mon, 01 Jul 2019 10:30:46 -0700 (PDT) Received: from evgreen2.mtv.corp.google.com ([2620:15c:202:201:ffda:7716:9afc:1301]) by smtp.gmail.com with ESMTPSA id h11sm11791289pfn.170.2019.07.01.10.30.45 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 01 Jul 2019 10:30:45 -0700 (PDT) From: Evan Green To: Takashi Iwai Cc: Evan Green , Jaroslav Kysela , alsa-devel@alsa-project.org, =?UTF-8?q?Amadeusz=20S=C5=82awi=C5=84ski?= , linux-kernel@vger.kernel.org, Thomas Gleixner , Greg Kroah-Hartman Subject: [PATCH v3] ALSA: hda: Fix widget_mutex incomplete protection Date: Mon, 1 Jul 2019 10:30:30 -0700 Message-Id: <20190701173030.168346-1-evgreen@chromium.org> X-Mailer: git-send-email 2.20.1 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The widget_mutex was introduced to serialize callers to hda_widget_sysfs_{re}init. However, its protection of the sysfs widget array is incomplete. For example, it is acquired around the call to hda_widget_sysfs_reinit(), which actually creates the new array, but isn't still acquired when codec->num_nodes and codec->start_nid is updated. So the lock ensures one thread sets up the new array at a time, but doesn't ensure which thread's value will end up in codec->num_nodes. If a larger num_nodes wins but a smaller array was set up, the next call to refresh_widgets() will touch free memory as it iterates over codec->num_nodes that aren't there. The widget_lock really protects both the tree as well as codec->num_nodes, start_nid, and end_nid, so make sure it's held across that update. It should also be held during snd_hdac_get_sub_nodes(), so that a very old read from that function doesn't end up clobbering a later update. Fixes: ed180abba7f1 ("ALSA: hda: Fix race between creating and refreshing sysfs entries") Signed-off-by: Evan Green --- Changes in v3: - Moved locking back into callers (Takashi) - Combined update_widgets exit flow (Takashi) Changes in v2: - Introduced widget_mutex relocation sound/hda/hdac_device.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/sound/hda/hdac_device.c b/sound/hda/hdac_device.c index 6907dbefd08c..3842f9d34b7c 100644 --- a/sound/hda/hdac_device.c +++ b/sound/hda/hdac_device.c @@ -400,27 +400,33 @@ static void setup_fg_nodes(struct hdac_device *codec) int snd_hdac_refresh_widgets(struct hdac_device *codec, bool sysfs) { hda_nid_t start_nid; - int nums, err; + int nums, err = 0; + /* + * Serialize against multiple threads trying to update the sysfs + * widgets array. + */ + mutex_lock(&codec->widget_lock); nums = snd_hdac_get_sub_nodes(codec, codec->afg, &start_nid); if (!start_nid || nums <= 0 || nums >= 0xff) { dev_err(&codec->dev, "cannot read sub nodes for FG 0x%02x\n", codec->afg); - return -EINVAL; + err = -EINVAL; + goto unlock; } if (sysfs) { - mutex_lock(&codec->widget_lock); err = hda_widget_sysfs_reinit(codec, start_nid, nums); - mutex_unlock(&codec->widget_lock); if (err < 0) - return err; + goto unlock; } codec->num_nodes = nums; codec->start_nid = start_nid; codec->end_nid = start_nid + nums; - return 0; +unlock: + mutex_unlock(&codec->widget_lock); + return err; } EXPORT_SYMBOL_GPL(snd_hdac_refresh_widgets); -- 2.20.1