From patchwork Mon Feb 4 11:28:34 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jaroslav Kysela X-Patchwork-Id: 10795453 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 52B66746 for ; Mon, 4 Feb 2019 11:36:22 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3C7FE2AAD8 for ; Mon, 4 Feb 2019 11:36:22 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 30DEA2AB7B; Mon, 4 Feb 2019 11:36:22 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.7 required=2.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A101A2AF11 for ; Mon, 4 Feb 2019 11:36:20 +0000 (UTC) Received: from alsa0.perex.cz (localhost [127.0.0.1]) by alsa0.perex.cz (Postfix) with ESMTP id EE9C3267567; Mon, 4 Feb 2019 12:29:15 +0100 (CET) X-Original-To: alsa-devel@alsa-project.org Delivered-To: alsa-devel@alsa-project.org Received: by alsa0.perex.cz (Postfix, from userid 1000) id C3A58267564; Mon, 4 Feb 2019 12:29:13 +0100 (CET) Received: from mail1.perex.cz (mail1.perex.cz [77.48.224.245]) by alsa0.perex.cz (Postfix) with ESMTP id 3136426751A for ; Mon, 4 Feb 2019 12:29:12 +0100 (CET) Received: from mail1.perex.cz (localhost [127.0.0.1]) by smtp1.perex.cz (Perex's E-mail Delivery System) with ESMTP id 029F1A0058; Mon, 4 Feb 2019 12:29:12 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp1.perex.cz 029F1A0058 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=perex.cz; s=default; t=1549279752; bh=GxfuVv3n2a5QGMnis76FlnwrDw0v7bnqxTFQZ8424QI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=plen3SHte/e0YvOG4pxv3RMzCxMAiqgqIvKa9mLvmDFaia6YJyTK9yGKlOcpyGQ6K iP/RM0MwP0A4jeSedymuz2mKf9d8M3FL0e9vavRL7neG5NJfc4sDmerHV7OV4d0LZj fJtcXJO6xzVS/0rV7BVXhkO8F++0XOH3oYeS92aM= Received: from p50.perex-int.cz (unknown [192.168.100.94]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) (Authenticated sender: perex) by mail1.perex.cz (Perex's E-mail Delivery System) with ESMTPSA; Mon, 4 Feb 2019 12:29:03 +0100 (CET) From: Jaroslav Kysela To: ALSA development Date: Mon, 4 Feb 2019 12:28:34 +0100 Message-Id: <20190204112834.27083-4-perex@perex.cz> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20190204112834.27083-1-perex@perex.cz> References: <20190204112834.27083-1-perex@perex.cz> Cc: Baolin Wang , Takashi Iwai , Phil Burk , Zach Riggle , Mark Brown , Leo Yan Subject: [alsa-devel] [PATCH 3/3] ALSA: pcm: implement the mmap buffer mode for the anonymous dup X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.14 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: , MIME-Version: 1.0 Errors-To: alsa-devel-bounces@alsa-project.org Sender: alsa-devel-bounces@alsa-project.org X-Virus-Scanned: ClamAV using ClamSMTP Android requires to allow the passing an anonymous inode file descriptor with the restricted functionality - only the mmap operation for the DMA sound buffer (anon_inode:snd-pcm-buffer). Android uses this access mode for the direct EXCLUSIVE sound device access by applications. This requirement is for the proper SELinux audit. Signed-off-by: Jaroslav Kysela Reviewed-by: Takashi Iwai --- include/sound/pcm.h | 2 ++ include/uapi/sound/asound.h | 3 +++ sound/core/pcm_native.c | 34 +++++++++++++++++++++++++++++++--- 3 files changed, 36 insertions(+), 3 deletions(-) diff --git a/include/sound/pcm.h b/include/sound/pcm.h index b79ffaa0241d..55b95476d15e 100644 --- a/include/sound/pcm.h +++ b/include/sound/pcm.h @@ -227,6 +227,7 @@ struct snd_pcm_ops { struct snd_pcm_file { struct snd_pcm_substream *substream; int no_compat_mmap; + unsigned int perm; /* file descriptor permissions */ unsigned int user_pversion; /* supported protocol version */ }; @@ -537,6 +538,7 @@ struct snd_pcm { * Registering */ +extern const struct file_operations snd_pcm_f_op_buffer; extern const struct file_operations snd_pcm_f_ops[2]; int snd_pcm_new(struct snd_card *card, const char *id, int device, diff --git a/include/uapi/sound/asound.h b/include/uapi/sound/asound.h index ebc17d5a3490..b0270d07cf4e 100644 --- a/include/uapi/sound/asound.h +++ b/include/uapi/sound/asound.h @@ -571,6 +571,9 @@ enum { #define SNDRV_CHMAP_PHASE_INVERSE (0x01 << 16) #define SNDRV_CHMAP_DRIVER_SPEC (0x02 << 16) +#define SNDRV_PCM_PERM_MODE_FULL 0 /* full access - no restrictions */ +#define SNDRV_PCM_PERM_MODE_BUFFER 1 /* allow to export only sound buffer through mmap */ + #define SNDRV_PCM_IOCTL_PVERSION _IOR('A', 0x00, int) #define SNDRV_PCM_IOCTL_INFO _IOR('A', 0x01, struct snd_pcm_info) #define SNDRV_PCM_IOCTL_TSTAMP _IOW('A', 0x02, int) diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index ffc6b32973ba..2722c99d9f41 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c @@ -2502,6 +2502,7 @@ static int snd_pcm_open_file(struct file *file, return -ENOMEM; } pcm_file->substream = substream; + pcm_file->perm = 0; if (substream->ref_count == 1) substream->pcm_release = pcm_release_private; file->private_data = pcm_file; @@ -2894,17 +2895,30 @@ static int snd_pcm_anonymous_dup(struct file *file, int fd, err, perm, flags; struct file *nfile; struct snd_pcm *pcm = substream->pcm; + struct snd_pcm_file *pcm_file; + const char *aname; + const struct file_operations *f_op; if (get_user(perm, arg)) return -EFAULT; - if (perm < 0) - return -EPERM; + switch (perm) { + case SNDRV_PCM_PERM_MODE_FULL: + aname = "snd-pcm"; + f_op = file->f_op; + break; + case SNDRV_PCM_PERM_MODE_BUFFER: + aname = "snd-pcm-buf"; + f_op = &snd_pcm_f_op_buffer; + break; + default: + return -EINVAL; + } flags = file->f_flags & (O_ACCMODE | O_NONBLOCK); flags |= O_APPEND | O_CLOEXEC; fd = get_unused_fd_flags(flags); if (fd < 0) return fd; - nfile = anon_inode_getfile("snd-pcm", file->f_op, NULL, flags); + nfile = anon_inode_getfile(aname, f_op, NULL, flags); if (IS_ERR(nfile)) { put_unused_fd(fd); return PTR_ERR(nfile); @@ -2922,6 +2936,8 @@ static int snd_pcm_anonymous_dup(struct file *file, err = snd_pcm_open_file(nfile, substream->pcm, substream->stream, substream->number); if (err >= 0) { + pcm_file = nfile->private_data; + pcm_file->perm = perm; put_user(fd, arg); return 0; } @@ -3305,6 +3321,8 @@ static int snd_pcm_mmap_status(struct snd_pcm_substream *substream, struct file if (pcm_file->user_pversion < SNDRV_PROTOCOL_VERSION(2, 0, 14) && (pcm_file->substream->runtime->hw.info & SNDRV_PCM_INFO_SYNC_APPLPTR)) return -ENXIO; + if (pcm_file->perm != SNDRV_PCM_PERM_MODE_FULL) + return -EPERM; if (!(area->vm_flags & VM_READ)) return -EINVAL; size = area->vm_end - area->vm_start; @@ -3350,6 +3368,8 @@ static int snd_pcm_mmap_control(struct snd_pcm_substream *substream, struct file */ if (pcm_file->substream->runtime->hw.info & SNDRV_PCM_INFO_SYNC_APPLPTR) return -ENXIO; + if (pcm_file->perm != SNDRV_PCM_PERM_MODE_FULL) + return -EPERM; if (!(area->vm_flags & VM_READ)) return -EINVAL; size = area->vm_end - area->vm_start; @@ -3726,6 +3746,14 @@ static unsigned long snd_pcm_get_unmapped_area(struct file *file, * Register section */ +const struct file_operations snd_pcm_f_op_buffer = { + .owner = THIS_MODULE, + .release = snd_pcm_release, + .llseek = no_llseek, + .mmap = snd_pcm_mmap, + .get_unmapped_area = snd_pcm_get_unmapped_area +}; + const struct file_operations snd_pcm_f_ops[2] = { { .owner = THIS_MODULE,