From patchwork Thu Sep 21 06:18:06 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "\(Exiting\) Baolin Wang" X-Patchwork-Id: 113193 Delivered-To: patch@linaro.org Received: by 10.140.106.117 with SMTP id d108csp1641382qgf; Wed, 20 Sep 2017 23:18:57 -0700 (PDT) X-Received: by 10.84.142.101 with SMTP id 92mr4441758plw.254.1505974737091; Wed, 20 Sep 2017 23:18:57 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1505974737; cv=none; d=google.com; s=arc-20160816; b=Sup2dGuD+O1BCWVSZQ8c+wfQMCrgGAmBgv6pCAhpjOkv0GF/pOHXvZjYTYkTVfSSU1 8y6RryJJ+pf+JU1/RggHpv7kPcodzBouRWsah9gj28ZFoUaSer9UvgL6s1odpSvArLGw DGkkGlwkgbvSNFGknKIPbnayPJVzpymi6wAhbQ43Ba00XaEZlQJdz7IYtwBwwJvW6ZFe 1+32bUmt7Hp50A6AN2TtdnovY93taoB3yfTzcm4X4DWFVnsjHek5Qkpe4VXTVSl1vUf1 F/drDsApw3zXUylJar01iT2sf/x1+8C/BPECiBMBWnGpQPWjL3I9zW7+k1zFep0lrZVj zx3A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:references :in-reply-to:message-id:date:subject:cc:to:from:dkim-signature :arc-authentication-results; bh=g6oiF0QJV4h1lC6MykkeYZWwX0nJ+y0ULmxPNv2l5dw=; b=SZ5mJOSl/vFvfmZgTtCp1T1rFbU22ayXgw9bklV6kA4G4lv9q/6yadUjN/MYhu7cHV JS0LjqJeUHPgyxhtbtg/sPhTi7PwvIRadwMND9xcRIS3huzm1Viowgsms83CryQpjsH8 vFX+TxXBEEQam0VWZB/kl+BuW6HnsJBRZQHXTzDVEEMBGxkG6yGvcsngWrhpCNrl6Wa9 PFPiVmnI8ryMWmrOVCSpGXOU7L8lfLm7cLqxCfzxNChEcYWg27bbsvAShyYCZYkdpAvN IVEwfsj5WZnbSSHsKwnL+D8vCtdtLGS/r2mbJ970QtUep8WJhUH+R1StGmnRjhoPJUaD YlUw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=GovqIGIB; 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=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id h90si568406plb.279.2017.09.20.23.18.56; Wed, 20 Sep 2017 23:18:57 -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=@linaro.org header.s=google header.b=GovqIGIB; 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=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751801AbdIUGSy (ORCPT + 26 others); Thu, 21 Sep 2017 02:18:54 -0400 Received: from mail-pf0-f178.google.com ([209.85.192.178]:50639 "EHLO mail-pf0-f178.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751743AbdIUGSu (ORCPT ); Thu, 21 Sep 2017 02:18:50 -0400 Received: by mail-pf0-f178.google.com with SMTP id m63so2748006pfk.7 for ; Wed, 20 Sep 2017 23:18:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :in-reply-to:references; bh=g6oiF0QJV4h1lC6MykkeYZWwX0nJ+y0ULmxPNv2l5dw=; b=GovqIGIBfdW4vCCnvqQCryRJ9ygOZzkPJZ1jn6ciNEDqKzgbUS9/8GbALRkdr0XG4g RRim6sok2K0bIU5xvFGhF2m4dQD5pfxOW2YCQ3Yj+KqfbRwLnn3bNFGiiEVnXLh5CsXR FXrwBXjaSfde3yeacOkoDg8vNnGH5ENjs7hXw= 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:in-reply-to :references:in-reply-to:references; bh=g6oiF0QJV4h1lC6MykkeYZWwX0nJ+y0ULmxPNv2l5dw=; b=ArPvLsSbc0riJGkXrZmglA7m7dYxeZSks4DijIMYTAu4tjmex2vCDOYMcjB2vVS4Dy mRegoRqke13TPrNEj7IRbP1glvBPZSZGZGAbJsK3MIlZUwWNH+3RvuPH59La9NKvgV69 jiQcuSIw0Bj/+V+yq+UpvKylUzXwdm9CTrvCaGdEiJbgYXyYmoD/wKXEYQxEido6Ew8v uc3tgEtXMe9the7RhQTNo4vZ6Y0UMtp67x8Jm1fXgUX8RA+7mt8Mhn59mnlcXzy75JhC mKI/u0vLIHIJdCk0IvXQrDgsn5ioUii9LhsFAr74AlbK4jWg39PnAq+gltSXBTocKF7c dT5A== X-Gm-Message-State: AHPjjUhLl1kE5EFfBzMEhqD4zWXJs4wMbxU3WpoEGZw2tJFUawjWDBRe QRz/xn9FHgSzLkCLXJHFP0MYlA== X-Google-Smtp-Source: AOwi7QBtpLrGmq6pHdtGGMokAwyQCSr8zFLbtQZV8XRVRVpzOxNMFb9m+r4fo6mtyNlsjVp+SuhYtw== X-Received: by 10.98.48.195 with SMTP id w186mr4603666pfw.213.1505974729758; Wed, 20 Sep 2017 23:18:49 -0700 (PDT) Received: from baolinwangubtpc.spreadtrum.com ([117.18.48.82]) by smtp.gmail.com with ESMTPSA id q23sm1037773pfk.182.2017.09.20.23.18.44 (version=TLS1 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 20 Sep 2017 23:18:49 -0700 (PDT) From: Baolin Wang To: perex@perex.cz, tiwai@suse.com Cc: lgirdwood@gmail.com, mingo@kernel.org, o-takashi@sakamocchi.jp, elfring@users.sourceforge.net, dan.carpenter@oracle.com, jeeja.kp@intel.com, vinod.koul@intel.com, dharageswari.r@intel.com, guneshwor.o.singh@intel.com, bhumirks@gmail.com, gudishax.kranthikumar@intel.com, naveen.m@intel.com, hardik.t.shah@intel.com, arvind.yadav.cs@gmail.com, fabf@skynet.be, arnd@arndb.de, broonie@kernel.org, deepa.kernel@gmail.com, baolin.wang@linaro.org, alsa-devel@alsa-project.org, linux-kernel@vger.kernel.org Subject: [RFC PATCH 4/7] sound: core: Avoid using timespec for struct snd_rawmidi_status Date: Thu, 21 Sep 2017 14:18:06 +0800 Message-Id: X-Mailer: git-send-email 1.7.9.5 In-Reply-To: References: In-Reply-To: References: Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The struct snd_rawmidi_status will use 'timespec' type variables to record timestamp, which is not year 2038 safe on 32bits system. Thus we introduced 'struct snd_rawmidi_status32' and 'struct snd_rawmidi_status64' to handle 32bit time_t and 64bit time_t in native mode, which replace timespec with s64 type. In compat mode, we renamed or introduced new structures to handle 32bit/64bit time_t in compatible mode. 'struct compat_snd_rawmidi_status32' and snd_rawmidi_ioctl_status_compat() are used to handle 32bit time_t in compat mode. 'struct compat_snd_rawmidi_status64' and snd_rawmidi_ioctl_status_compat64() are used to handle 64bit time_t with 64bit alignment. 'struct compat_snd_rawmidi_status64_x86_32' and snd_rawmidi_ioctl_status_compat64_x86_32() are used to handle 64bit time_t with 32bit alignment. When glibc changes time_t to 64-bit, any recompiled program will issue ioctl commands that the kernel does not understand without this patch. Signed-off-by: Baolin Wang --- sound/core/rawmidi.c | 74 ++++++++++++++++++++++++++++++++--- sound/core/rawmidi_compat.c | 90 ++++++++++++++++++++++++++++++++----------- 2 files changed, 135 insertions(+), 29 deletions(-) -- 1.7.9.5 diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c index b3b353d..7afb1a4 100644 --- a/sound/core/rawmidi.c +++ b/sound/core/rawmidi.c @@ -63,6 +63,28 @@ #define rmidi_dbg(rmidi, fmt, args...) \ dev_dbg(&(rmidi)->dev, fmt, ##args) +#if __BITS_PER_LONG == 32 +struct snd_rawmidi_status32 { + int stream; + struct { s32 tv_sec; s32 tv_nsec; } tstamp; /* Timestamp */ + size_t avail; /* available bytes */ + size_t xruns; /* count of overruns since last status (in bytes) */ + unsigned char reserved[16]; /* reserved for future use */ +}; + +#define SNDRV_RAWMIDI_IOCTL_STATUS32 _IOWR('W', 0x20, struct snd_rawmidi_status32) +#endif + +struct snd_rawmidi_status64 { + int stream; + struct { s64 tv_sec; s64 tv_nsec; } tstamp; /* Timestamp */ + size_t avail; /* available bytes */ + size_t xruns; /* count of overruns since last status (in bytes) */ + unsigned char reserved[16]; /* reserved for future use */ +}; + +#define SNDRV_RAWMIDI_IOCTL_STATUS64 _IOWR('W', 0x20, struct snd_rawmidi_status64) + static struct snd_rawmidi *snd_rawmidi_search(struct snd_card *card, int device) { struct snd_rawmidi *rawmidi; @@ -680,7 +702,7 @@ int snd_rawmidi_input_params(struct snd_rawmidi_substream *substream, EXPORT_SYMBOL(snd_rawmidi_input_params); static int snd_rawmidi_output_status(struct snd_rawmidi_substream *substream, - struct snd_rawmidi_status * status) + struct snd_rawmidi_status64 * status) { struct snd_rawmidi_runtime *runtime = substream->runtime; @@ -693,7 +715,7 @@ static int snd_rawmidi_output_status(struct snd_rawmidi_substream *substream, } static int snd_rawmidi_input_status(struct snd_rawmidi_substream *substream, - struct snd_rawmidi_status * status) + struct snd_rawmidi_status64 * status) { struct snd_rawmidi_runtime *runtime = substream->runtime; @@ -751,11 +773,50 @@ static long snd_rawmidi_ioctl(struct file *file, unsigned int cmd, unsigned long return -EINVAL; } } - case SNDRV_RAWMIDI_IOCTL_STATUS: +#if __BITS_PER_LONG == 32 + case SNDRV_RAWMIDI_IOCTL_STATUS32: + { + int err = 0; + struct snd_rawmidi_status32 __user *status = argp; + struct snd_rawmidi_status32 status32; + struct snd_rawmidi_status64 status64; + + if (copy_from_user(&status32, argp, + sizeof(struct snd_rawmidi_status32))) + return -EFAULT; + switch (status32.stream) { + case SNDRV_RAWMIDI_STREAM_OUTPUT: + if (rfile->output == NULL) + return -EINVAL; + err = snd_rawmidi_output_status(rfile->output, &status64); + break; + case SNDRV_RAWMIDI_STREAM_INPUT: + if (rfile->input == NULL) + return -EINVAL; + err = snd_rawmidi_input_status(rfile->input, &status64); + break; + default: + return -EINVAL; + } + if (err < 0) + return err; + + if (put_user(status64.stream, &status->stream) || + put_user(status64.tstamp.tv_sec, &status->tstamp.tv_sec) || + put_user(status64.tstamp.tv_nsec, &status->tstamp.tv_nsec) || + put_user(status64.avail, &status->avail) || + put_user(status64.xruns, &status->xruns)) + return -EFAULT; + return 0; + } +#endif + case SNDRV_RAWMIDI_IOCTL_STATUS64: { int err = 0; - struct snd_rawmidi_status status; - if (copy_from_user(&status, argp, sizeof(struct snd_rawmidi_status))) + struct snd_rawmidi_status64 status; + + if (copy_from_user(&status, argp, + sizeof(struct snd_rawmidi_status64))) return -EFAULT; switch (status.stream) { case SNDRV_RAWMIDI_STREAM_OUTPUT: @@ -773,7 +834,8 @@ static long snd_rawmidi_ioctl(struct file *file, unsigned int cmd, unsigned long } if (err < 0) return err; - if (copy_to_user(argp, &status, sizeof(struct snd_rawmidi_status))) + if (copy_to_user(argp, &status, + sizeof(struct snd_rawmidi_status64))) return -EFAULT; return 0; } diff --git a/sound/core/rawmidi_compat.c b/sound/core/rawmidi_compat.c index f69764d..4b5a612 100644 --- a/sound/core/rawmidi_compat.c +++ b/sound/core/rawmidi_compat.c @@ -53,7 +53,7 @@ static int snd_rawmidi_ioctl_params_compat(struct snd_rawmidi_file *rfile, return -EINVAL; } -struct snd_rawmidi_status32 { +struct compat_snd_rawmidi_status32 { s32 stream; struct compat_timespec tstamp; u32 avail; @@ -62,10 +62,10 @@ struct snd_rawmidi_status32 { } __attribute__((packed)); static int snd_rawmidi_ioctl_status_compat(struct snd_rawmidi_file *rfile, - struct snd_rawmidi_status32 __user *src) + struct compat_snd_rawmidi_status32 __user *src) { int err; - struct snd_rawmidi_status status; + struct snd_rawmidi_status64 status; if (rfile->output == NULL) return -EINVAL; @@ -85,7 +85,8 @@ static int snd_rawmidi_ioctl_status_compat(struct snd_rawmidi_file *rfile, if (err < 0) return err; - if (compat_put_timespec(&status.tstamp, &src->tstamp) || + if (put_user(status.tstamp.tv_sec, &src->tstamp.tv_sec) || + put_user(status.tstamp.tv_nsec, &src->tstamp.tv_nsec) || put_user(status.avail, &src->avail) || put_user(status.xruns, &src->xruns)) return -EFAULT; @@ -93,24 +94,63 @@ static int snd_rawmidi_ioctl_status_compat(struct snd_rawmidi_file *rfile, return 0; } -#ifdef CONFIG_X86_X32 -/* X32 ABI has 64bit timespec and 64bit alignment */ -struct snd_rawmidi_status_x32 { +struct compat_snd_rawmidi_status64 { s32 stream; u32 rsvd; /* alignment */ - struct timespec tstamp; + struct { s64 tv_sec; s64 tv_nsec; } tstamp; u32 avail; u32 xruns; unsigned char reserved[16]; } __attribute__((packed)); -#define put_timespec(src, dst) copy_to_user(dst, src, sizeof(*dst)) +static int snd_rawmidi_ioctl_status_compat64(struct snd_rawmidi_file *rfile, + struct compat_snd_rawmidi_status64 __user *src) +{ + int err; + struct snd_rawmidi_status64 status; + + if (rfile->output == NULL) + return -EINVAL; + if (get_user(status.stream, &src->stream)) + return -EFAULT; + + switch (status.stream) { + case SNDRV_RAWMIDI_STREAM_OUTPUT: + err = snd_rawmidi_output_status(rfile->output, &status); + break; + case SNDRV_RAWMIDI_STREAM_INPUT: + err = snd_rawmidi_input_status(rfile->input, &status); + break; + default: + return -EINVAL; + } + if (err < 0) + return err; + + if (put_user(status.tstamp.tv_sec, &src->tstamp.tv_sec) || + put_user(status.tstamp.tv_nsec, &src->tstamp.tv_nsec) || + put_user(status.avail, &src->avail) || + put_user(status.xruns, &src->xruns)) + return -EFAULT; + + return 0; +} + +#ifdef IA32_EMULATION +struct compat_snd_rawmidi_status64_x86_32 { + s32 stream; + struct { s64 tv_sec; s64 tv_nsec; } tstamp; + u32 avail; + u32 xruns; + unsigned char reserved[16]; +} __attribute__((packed)); -static int snd_rawmidi_ioctl_status_x32(struct snd_rawmidi_file *rfile, - struct snd_rawmidi_status_x32 __user *src) +static int +snd_rawmidi_ioctl_status_compat64_x86_32(struct snd_rawmidi_file *rfile, + struct compat_snd_rawmidi_status64_x86_32 __user *src) { int err; - struct snd_rawmidi_status status; + struct snd_rawmidi_status64 status; if (rfile->output == NULL) return -EINVAL; @@ -130,21 +170,23 @@ static int snd_rawmidi_ioctl_status_x32(struct snd_rawmidi_file *rfile, if (err < 0) return err; - if (put_timespec(&status.tstamp, &src->tstamp) || + if (put_user(status.tstamp.tv_sec, &src->tstamp.tv_sec) || + put_user(status.tstamp.tv_nsec, &src->tstamp.tv_nsec) || put_user(status.avail, &src->avail) || put_user(status.xruns, &src->xruns)) return -EFAULT; return 0; } -#endif /* CONFIG_X86_X32 */ +#endif enum { SNDRV_RAWMIDI_IOCTL_PARAMS32 = _IOWR('W', 0x10, struct snd_rawmidi_params32), - SNDRV_RAWMIDI_IOCTL_STATUS32 = _IOWR('W', 0x20, struct snd_rawmidi_status32), -#ifdef CONFIG_X86_X32 - SNDRV_RAWMIDI_IOCTL_STATUS_X32 = _IOWR('W', 0x20, struct snd_rawmidi_status_x32), -#endif /* CONFIG_X86_X32 */ + SNDRV_RAWMIDI_IOCTL_STATUS_COMPAT32 = _IOWR('W', 0x20, struct compat_snd_rawmidi_status32), + SNDRV_RAWMIDI_IOCTL_STATUS_COMPAT64 = _IOWR('W', 0x20, struct compat_snd_rawmidi_status64), +#ifdef IA32_EMULATION + SNDRV_RAWMIDI_IOCTL_STATUS_COMPAT64_X86_32 = _IOWR('W', 0x20, struct compat_snd_rawmidi_status64_x86_32), +#endif }; static long snd_rawmidi_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg) @@ -161,12 +203,14 @@ static long snd_rawmidi_ioctl_compat(struct file *file, unsigned int cmd, unsign return snd_rawmidi_ioctl(file, cmd, (unsigned long)argp); case SNDRV_RAWMIDI_IOCTL_PARAMS32: return snd_rawmidi_ioctl_params_compat(rfile, argp); - case SNDRV_RAWMIDI_IOCTL_STATUS32: + case SNDRV_RAWMIDI_IOCTL_STATUS_COMPAT32: return snd_rawmidi_ioctl_status_compat(rfile, argp); -#ifdef CONFIG_X86_X32 - case SNDRV_RAWMIDI_IOCTL_STATUS_X32: - return snd_rawmidi_ioctl_status_x32(rfile, argp); -#endif /* CONFIG_X86_X32 */ + case SNDRV_RAWMIDI_IOCTL_STATUS_COMPAT64: + return snd_rawmidi_ioctl_status_compat64(rfile, argp); +#ifdef IA32_EMULATION + case SNDRV_RAWMIDI_IOCTL_STATUS_COMPAT64_X86_32: + return snd_rawmidi_ioctl_status_compat64_x86_32(rfile, argp); +#endif } return -ENOIOCTLCMD; }