From patchwork Fri Apr 1 12:29:31 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Amadeusz_S=C5=82awi=C5=84ski?= X-Patchwork-Id: 556236 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 84C2EC433EF for ; Fri, 1 Apr 2022 12:34:53 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 15E481A26; Fri, 1 Apr 2022 14:34:01 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 15E481A26 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1648816491; bh=TlMmRfo9CM306+Ibn6L82q3WygN+pjH2WFjmGAcBfec=; h=From:To:Subject:Date:Cc:List-Id:List-Unsubscribe:List-Archive: List-Post:List-Help:List-Subscribe:From; b=bNZZoTBw2uE33/ttbzd3BaNu+MmjVMuyp8p60JuBsNzO0GTptT+GhFWIjHzT1ZyDB LCDrHE/Lpo8YgOKQ+ePsEfVBNpJAHI9+F9mOU2APWPpCZaTJQPkW482pNkUL3BuMO8 8JvDtMAV72MTZbrZoxBU8IVBpc5asicW3TxnMWLY= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 9A86DF8020D; Fri, 1 Apr 2022 14:34:00 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 9A750F80279; Fri, 1 Apr 2022 14:33:58 +0200 (CEST) Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id C4554F80109 for ; Fri, 1 Apr 2022 14:33:48 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz C4554F80109 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="hSQrHUXk" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1648816432; x=1680352432; h=from:to:cc:subject:date:message-id:mime-version: content-transfer-encoding; bh=TlMmRfo9CM306+Ibn6L82q3WygN+pjH2WFjmGAcBfec=; b=hSQrHUXktPqJ5OV93jXmNINAYXP/TvuRf2IhKVrJBEVUlMXEQTZwyp8k 1170K24NxbEiccf9LI/ElN+ypsA26myK42fudb4/LI5AsJErlbT5uowiE lHWu8mNzcTtl1f7s+Jo1J30vREVla55YnldeW72/8yEx0fyW3+GSGyage W6G/nRJLAOc0aEP80Tzzah8sxGsKAagovJSGhfnjcLuMthuk9MoeoJGh+ ebmAeE1iXMgv4EvgDbh6nFYHtA4hlPzcxoMjLg9XfwIAX1aVyrEMl6nyo 9sdeGJ3s26PkgfTv6OK8jaxFdooIOCFzC50mWRfONonVDt6PtQL147tP9 A==; X-IronPort-AV: E=McAfee;i="6200,9189,10303"; a="285056800" X-IronPort-AV: E=Sophos;i="5.90,227,1643702400"; d="scan'208";a="285056800" Received: from orsmga006.jf.intel.com ([10.7.209.51]) by fmsmga101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 01 Apr 2022 05:29:33 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.90,227,1643702400"; d="scan'208";a="522761794" Received: from dev2 (HELO DEV2.igk.intel.com) ([10.237.148.94]) by orsmga006.jf.intel.com with ESMTP; 01 Apr 2022 05:29:31 -0700 From: =?utf-8?q?Amadeusz_S=C5=82awi=C5=84ski?= To: Takashi Iwai Subject: [PATCH] ALSA: jack: Access input_dev under mutex Date: Fri, 1 Apr 2022 14:29:31 +0200 Message-Id: <20220401122931.4181700-1-amadeuszx.slawinski@linux.intel.com> X-Mailer: git-send-email 2.25.1 MIME-Version: 1.0 Cc: alsa-devel@alsa-project.org, =?utf-8?q?Amadeusz_S=C5=82awi=C5=84ski?= X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" It is possible when using ASoC that input_dev is unregistered while calling snd_jack_report, which causes NULL pointer dereference. In order to prevent this serialize access to input_dev using mutex lock. Signed-off-by: Amadeusz Sławiński --- include/sound/jack.h | 1 + sound/core/jack.c | 37 ++++++++++++++++++++++++++++++------- 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/include/sound/jack.h b/include/sound/jack.h index 1181f536557e..1ed90e2109e9 100644 --- a/include/sound/jack.h +++ b/include/sound/jack.h @@ -62,6 +62,7 @@ struct snd_jack { const char *id; #ifdef CONFIG_SND_JACK_INPUT_DEV struct input_dev *input_dev; + struct mutex input_dev_lock; int registered; int type; char name[100]; diff --git a/sound/core/jack.c b/sound/core/jack.c index d1e3055f2b6a..58b9ebf5e7e1 100644 --- a/sound/core/jack.c +++ b/sound/core/jack.c @@ -42,8 +42,11 @@ static int snd_jack_dev_disconnect(struct snd_device *device) #ifdef CONFIG_SND_JACK_INPUT_DEV struct snd_jack *jack = device->device_data; - if (!jack->input_dev) + mutex_lock(&jack->input_dev_lock); + if (!jack->input_dev) { + mutex_unlock(&jack->input_dev_lock); return 0; + } /* If the input device is registered with the input subsystem * then we need to use a different deallocator. */ @@ -52,6 +55,7 @@ static int snd_jack_dev_disconnect(struct snd_device *device) else input_free_device(jack->input_dev); jack->input_dev = NULL; + mutex_unlock(&jack->input_dev_lock); #endif /* CONFIG_SND_JACK_INPUT_DEV */ return 0; } @@ -90,8 +94,11 @@ static int snd_jack_dev_register(struct snd_device *device) snprintf(jack->name, sizeof(jack->name), "%s %s", card->shortname, jack->id); - if (!jack->input_dev) + mutex_lock(&jack->input_dev_lock); + if (!jack->input_dev) { + mutex_unlock(&jack->input_dev_lock); return 0; + } jack->input_dev->name = jack->name; @@ -116,6 +123,7 @@ static int snd_jack_dev_register(struct snd_device *device) if (err == 0) jack->registered = 1; + mutex_unlock(&jack->input_dev_lock); return err; } #endif /* CONFIG_SND_JACK_INPUT_DEV */ @@ -517,11 +525,15 @@ int snd_jack_new(struct snd_card *card, const char *id, int type, return -ENOMEM; } - /* don't creat input device for phantom jack */ - if (!phantom_jack) { #ifdef CONFIG_SND_JACK_INPUT_DEV + mutex_init(&jack->input_dev_lock); + + /* don't create input device for phantom jack */ + if (!phantom_jack) { int i; + mutex_lock(&jack->input_dev_lock); + jack->input_dev = input_allocate_device(); if (jack->input_dev == NULL) { err = -ENOMEM; @@ -537,8 +549,9 @@ int snd_jack_new(struct snd_card *card, const char *id, int type, input_set_capability(jack->input_dev, EV_SW, jack_switch_types[i]); -#endif /* CONFIG_SND_JACK_INPUT_DEV */ + mutex_unlock(&jack->input_dev_lock); } +#endif /* CONFIG_SND_JACK_INPUT_DEV */ err = snd_device_new(card, SNDRV_DEV_JACK, jack, &ops); if (err < 0) @@ -556,7 +569,9 @@ int snd_jack_new(struct snd_card *card, const char *id, int type, fail_input: #ifdef CONFIG_SND_JACK_INPUT_DEV + mutex_lock(&jack->input_dev_lock); input_free_device(jack->input_dev); + mutex_unlock(&jack->input_dev_lock); #endif kfree(jack->id); kfree(jack); @@ -578,10 +593,14 @@ EXPORT_SYMBOL(snd_jack_new); void snd_jack_set_parent(struct snd_jack *jack, struct device *parent) { WARN_ON(jack->registered); - if (!jack->input_dev) + mutex_lock(&jack->input_dev_lock); + if (!jack->input_dev) { + mutex_unlock(&jack->input_dev_lock); return; + } jack->input_dev->dev.parent = parent; + mutex_unlock(&jack->input_dev_lock); } EXPORT_SYMBOL(snd_jack_set_parent); @@ -654,8 +673,11 @@ void snd_jack_report(struct snd_jack *jack, int status) status & jack_kctl->mask_bits); #ifdef CONFIG_SND_JACK_INPUT_DEV - if (!jack->input_dev) + mutex_lock(&jack->input_dev_lock); + if (!jack->input_dev) { + mutex_unlock(&jack->input_dev_lock); return; + } for (i = 0; i < ARRAY_SIZE(jack->key); i++) { int testbit = ((SND_JACK_BTN_0 >> i) & ~mask_bits); @@ -675,6 +697,7 @@ void snd_jack_report(struct snd_jack *jack, int status) } input_sync(jack->input_dev); + mutex_unlock(&jack->input_dev_lock); #endif /* CONFIG_SND_JACK_INPUT_DEV */ } EXPORT_SYMBOL(snd_jack_report);