Received: by 2002:a25:4158:0:0:0:0:0 with SMTP id o85csp518818yba; Mon, 1 Apr 2019 10:55:58 -0700 (PDT) X-Google-Smtp-Source: APXvYqzoOefrYQDaF50KMLcA/h8H+bJ9ducFtVJPfOOj/gxQo6F6abtwkz3DZ1mYJMnkwlA7mb66 X-Received: by 2002:a63:744b:: with SMTP id e11mr44150302pgn.327.1554141358199; Mon, 01 Apr 2019 10:55:58 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1554141358; cv=none; d=google.com; s=arc-20160816; b=QUIdStgh1VCM4Dk0NM56Vg8kd1ZTSssFeFqUKmMSYul5GKk7NvTQKjwkdp8Unv9Zu8 /Ty66ElW/7bBAoySiv2EbfnulE8awwqqsIu+sRd0lHAm9Pmco6oBbk2kAXQQzp6zcOrP CPfottPvEOekFauqUTMVtpn3bL8mrz8hUesU6lkDFT78CqshIh15JiHD2llYkZLmVlL0 l9hlEidXEIcfdSEYBwuM7uCC/n6Rhm+T2ugr8OnEzyxg8pKa598tJHRhKD7VhP6OOrr2 wGI/uXI7c1unP0f4uJXpu8y+2YJTa7QNFfZBR9UeQEKH+PAHt7MoCl91RH9m8XNPIs6N c1uA== 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 :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=0PyPcT3UAhte+qIKRqj6R3M8EmH3syUNHnGFqoWUGOE=; b=L786lC0TfV9yBK/F2MfKicvB/m+HRDUyIPlBsN1aXfGwUaChfjflrCswiJdoz32rNy ZOsGmH17eV/cITTmR/6mGg9Kd0bLFo7lyneDoVi8SpddljNiftSjEe946aEd5c/m/519 98ORlDfhmYUldDq0XDJCMh2xxMWxULO92Nmv0TggZN/2nIHx9vlxzac3X2VNyZ2YXBoA ZfxTVFJXJAtb75zU7Akjv6twEYOuDkVLY7StZiDargq8wun3XVBrlFsI4L9jEN1ycybN GDkO7TjKo6mHErUaX84F3sk7YQPKL/Vn8TSy9XisM5DQTYXDdwpNuUzTx2ZMQD03+qDE 1QXg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=jlFviOhe; 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 Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id o35si9438640pgb.551.2019.04.01.10.55.42; Mon, 01 Apr 2019 10:55:58 -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=@kernel.org header.s=default header.b=jlFviOhe; 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 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731423AbfDARX0 (ORCPT + 99 others); Mon, 1 Apr 2019 13:23:26 -0400 Received: from mail.kernel.org ([198.145.29.99]:53184 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1732098AbfDARXX (ORCPT ); Mon, 1 Apr 2019 13:23:23 -0400 Received: from localhost (83-86-89-107.cable.dynamic.v4.ziggo.nl [83.86.89.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 871C32133D; Mon, 1 Apr 2019 17:23:21 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1554139402; bh=+fIh9Xe46i1kTfAoqVBz7SqCEOJZwnLGkX6g1A/bpsQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=jlFviOhe0iQs3UZe/f2uA5plmGXmVI6eVZkEYt9FfAJ9sbZpfGdL3GMO4zFV5vJ1M moeQ1WiupiElTBTfB8Cz88Y8RSRkcmtBix5vBMpwJxpfDZjmFbAId5RWg2QRDdkGUj 97zK9A4wYCHJNVsyERFn0tRH4CjCUpmOR5rxiIIk= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, syzbot+d4503ae45b65c5bc1194@syzkaller.appspotmail.com, Takashi Iwai Subject: [PATCH 4.14 065/107] ALSA: pcm: Fix possible OOB access in PCM oss plugins Date: Mon, 1 Apr 2019 19:02:20 +0200 Message-Id: <20190401170051.586892106@linuxfoundation.org> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190401170045.246405031@linuxfoundation.org> References: <20190401170045.246405031@linuxfoundation.org> User-Agent: quilt/0.65 X-stable: review X-Patchwork-Hint: ignore MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 4.14-stable review patch. If anyone has any objections, please let me know. ------------------ From: Takashi Iwai commit ca0214ee2802dd47239a4e39fb21c5b00ef61b22 upstream. The PCM OSS emulation converts and transfers the data on the fly via "plugins". The data is converted over the dynamically allocated buffer for each plugin, and recently syzkaller caught OOB in this flow. Although the bisection by syzbot pointed out to the commit 65766ee0bf7f ("ALSA: oss: Use kvzalloc() for local buffer allocations"), this is merely a commit to replace vmalloc() with kvmalloc(), hence it can't be the cause. The further debug action revealed that this happens in the case where a slave PCM doesn't support only the stereo channels while the OSS stream is set up for a mono channel. Below is a brief explanation: At each OSS parameter change, the driver sets up the PCM hw_params again in snd_pcm_oss_change_params_lock(). This is also the place where plugins are created and local buffers are allocated. The problem is that the plugins are created before the final hw_params is determined. Namely, two snd_pcm_hw_param_near() calls for setting the period size and periods may influence on the final result of channels, rates, etc, too, while the current code has already created plugins beforehand with the premature values. So, the plugin believes that channels=1, while the actual I/O is with channels=2, which makes the driver reading/writing over the allocated buffer size. The fix is simply to move the plugin allocation code after the final hw_params call. Reported-by: syzbot+d4503ae45b65c5bc1194@syzkaller.appspotmail.com Cc: Signed-off-by: Takashi Iwai Signed-off-by: Greg Kroah-Hartman --- sound/core/oss/pcm_oss.c | 43 ++++++++++++++++++++++--------------------- 1 file changed, 22 insertions(+), 21 deletions(-) --- a/sound/core/oss/pcm_oss.c +++ b/sound/core/oss/pcm_oss.c @@ -940,6 +940,28 @@ static int snd_pcm_oss_change_params_loc oss_frame_size = snd_pcm_format_physical_width(params_format(params)) * params_channels(params) / 8; + err = snd_pcm_oss_period_size(substream, params, sparams); + if (err < 0) + goto failure; + + n = snd_pcm_plug_slave_size(substream, runtime->oss.period_bytes / oss_frame_size); + err = snd_pcm_hw_param_near(substream, sparams, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, n, NULL); + if (err < 0) + goto failure; + + err = snd_pcm_hw_param_near(substream, sparams, SNDRV_PCM_HW_PARAM_PERIODS, + runtime->oss.periods, NULL); + if (err < 0) + goto failure; + + snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DROP, NULL); + + err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_HW_PARAMS, sparams); + if (err < 0) { + pcm_dbg(substream->pcm, "HW_PARAMS failed: %i\n", err); + goto failure; + } + #ifdef CONFIG_SND_PCM_OSS_PLUGINS snd_pcm_oss_plugin_clear(substream); if (!direct) { @@ -974,27 +996,6 @@ static int snd_pcm_oss_change_params_loc } #endif - err = snd_pcm_oss_period_size(substream, params, sparams); - if (err < 0) - goto failure; - - n = snd_pcm_plug_slave_size(substream, runtime->oss.period_bytes / oss_frame_size); - err = snd_pcm_hw_param_near(substream, sparams, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, n, NULL); - if (err < 0) - goto failure; - - err = snd_pcm_hw_param_near(substream, sparams, SNDRV_PCM_HW_PARAM_PERIODS, - runtime->oss.periods, NULL); - if (err < 0) - goto failure; - - snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DROP, NULL); - - if ((err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_HW_PARAMS, sparams)) < 0) { - pcm_dbg(substream->pcm, "HW_PARAMS failed: %i\n", err); - goto failure; - } - if (runtime->oss.trigger) { sw_params->start_threshold = 1; } else {