Received: by 10.192.165.148 with SMTP id m20csp4729571imm; Tue, 24 Apr 2018 07:32:14 -0700 (PDT) X-Google-Smtp-Source: AB8JxZp+I71rqzEDq/sNP9d5CD/45OLDRfQ4BZndoJoPXG23guQC1vjke4VI6pRDnic7NU7qmSqT X-Received: by 2002:a17:902:d886:: with SMTP id b6-v6mr2052048plz.278.1524580334797; Tue, 24 Apr 2018 07:32:14 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1524580334; cv=none; d=google.com; s=arc-20160816; b=RqFvOuPgFqgeNoggGdK42mnWBUEw6nTOl6EhxqzSLtQXXWOu/0Q46vwTxmm+ELDU+p O+Dj6u7gRCLPN5ApNlrQ3heZ+GoQ+snnblChWJuNp+EKa5p5Ftk8waBDm5oiDdH4IHnU 2B+FqXrMl4WB/KgCTWhK+fYJiveFAltuDs3JZzfaLGwht2TJdYPLtyne6likIOXrg3sz o48wpQbXr6uu3IN+1YF36KnzG/XchtVUoa1meCeGPlH+SaB9jzGVKQCxxcHN1/5F/Cyl 843HdMWhdAeNUwj+C3Y8D1frbbpQKhKWpv3TB+TDzEItfH7/S7uN9VLSfpAL2w2wn9xm iqrQ== 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=h7INzNzbQTb1Sna5LcKBNSOpvNhnJbSqOVTEwH2gvAA=; b=viJa6SGG4lGwF1fCF6K05PVACvHmdKoUePc3uEeT5bLQoEd4em4rkFmsEtfLY1Z69s gJtCBt2H+pPiR2HEETr0X8WxhCFLiN7CTAFhRwYWqNbWBV9O3cRsL09OATB5V1n1vKOj HNfLc+r42MoFMAFvY3sRBefpAiqD6TMOJBozMOsfjnsg17+Ek5io3Elf4GP/C1i6DjyX 5M+6UcURlTOCsK7Hq4l4OfGsPK7BP08n9aa/TjSxQ3+SVCHpfZ9zu8QOG8DId5awIu+3 iaFbpPRPUDFfbh2D87ZByLj9SvTGjRjj8w/kJ44PGM2GX+xpD5fe4r1jOjIp2dLd6naV SEHg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=BRTtPees; 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 l22si9567505pgn.74.2018.04.24.07.32.00; Tue, 24 Apr 2018 07:32:14 -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=BRTtPees; 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 S1756590AbeDXMIu (ORCPT + 99 others); Tue, 24 Apr 2018 08:08:50 -0400 Received: from mail-pf0-f194.google.com ([209.85.192.194]:38351 "EHLO mail-pf0-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932588AbeDXMHj (ORCPT ); Tue, 24 Apr 2018 08:07:39 -0400 Received: by mail-pf0-f194.google.com with SMTP id o76so7374960pfi.5 for ; Tue, 24 Apr 2018 05:07:39 -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=h7INzNzbQTb1Sna5LcKBNSOpvNhnJbSqOVTEwH2gvAA=; b=BRTtPeesZb8fIbBTNuVPnpx971pAHSZnuGOXAs8gv/EaG+sFjQK+MvOsyTnXKiYEi1 XCLjwfgqPDrjVB3XryB8OXG3lo7399+2xgIYGsgoWjpDW8+/E0ujHFQwHVoetGi6cEjg rO+EjSRlJI2mIeh2MPMV5XY8vnc0JaMKld4cM= 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=h7INzNzbQTb1Sna5LcKBNSOpvNhnJbSqOVTEwH2gvAA=; b=SXCeYPpCX7ImAesswQ13Qg+8uf5inE+vR4ToUyaolocq+VWXrt26EcoAolFwMh981+ I1sfXoY7oh+/St1XaxDrTKu+VX/kLOwEaWobt9IwDV0ShVxfl7C+75nb48uLJLF2fQFE 9a/rb+ZhL/7ZDYOSaCoroeQ/z/4v5G+wT8ol/VagHuuqbUAEmZXLgPg5gW7qn+7QfUbP Qaw2lge8PNzustfwbtcJJiT0CGAoXIK9uo3SC6xSG8f82+zC0XPE5+eCkCOvrJSCxbSf fvxbUuDwFwffCMMZvYTsPeMD1U87GNkUgH2HPqAuT/p2DsCrEYMpWnnvcreAaWVoveFj lR/g== X-Gm-Message-State: ALQs6tCpjZGCYrPN7AK4PpVkZQz7GjPYBoEXYz6d0+IlYNoBUsZj4tHT wPugOQ/bKLBxg0/e17UQg3txDw== X-Received: by 10.101.72.1 with SMTP id h1mr18174188pgs.96.1524571659032; Tue, 24 Apr 2018 05:07:39 -0700 (PDT) Received: from baolinwangubtpc.spreadtrum.com ([117.18.48.82]) by smtp.gmail.com with ESMTPSA id c7sm46350567pfg.81.2018.04.24.05.07.34 (version=TLS1 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 24 Apr 2018 05:07:38 -0700 (PDT) From: Baolin Wang To: perex@perex.cz, tiwai@suse.com, arnd@arndb.de Cc: baolin.wang@linaro.org, lgirdwood@gmail.com, broonie@kernel.org, o-takashi@sakamocchi.jp, mingo@kernel.org, elfring@users.sourceforge.net, dan.carpenter@oracle.com, jeeja.kp@intel.com, vinod.koul@intel.com, guneshwor.o.singh@intel.com, subhransu.s.prusty@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, alsa-devel@alsa-project.org, linux-kernel@vger.kernel.org Subject: [PATCH 5/8] ALSA: Avoid using timespec for struct snd_rawmidi_status Date: Tue, 24 Apr 2018 20:06:12 +0800 Message-Id: <4b52b5726f66313347519c7e11168f1d0f9b2143.1524570852.git.baolin.wang@linaro.org> 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. The 'struct snd_rawmidi_status32' and snd_rawmidi_ioctl_status32() are used to handle 32bit time_t in compat mode. 'struct compat_snd_rawmidi_status64' is used to handle 64bit time_t. 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 --- include/uapi/sound/asound.h | 1 + sound/core/rawmidi.c | 131 ++++++++++++++++++++++++++++++++++--------- sound/core/rawmidi_compat.c | 87 ++++++++-------------------- 3 files changed, 126 insertions(+), 93 deletions(-) diff --git a/include/uapi/sound/asound.h b/include/uapi/sound/asound.h index c9afde4..fad66ad 100644 --- a/include/uapi/sound/asound.h +++ b/include/uapi/sound/asound.h @@ -650,6 +650,7 @@ struct snd_rawmidi_params { struct snd_rawmidi_status { int stream; + unsigned char pad1[sizeof(time_t) - sizeof(int)]; struct timespec tstamp; /* Timestamp */ size_t avail; /* available bytes */ size_t xruns; /* count of overruns since last status (in bytes) */ diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c index 69616d0..421b899 100644 --- a/sound/core/rawmidi.c +++ b/sound/core/rawmidi.c @@ -63,6 +63,29 @@ #define rmidi_dbg(rmidi, fmt, args...) \ dev_dbg(&(rmidi)->dev, fmt, ##args) +struct snd_rawmidi_status32 { + s32 stream; + s32 tstamp_sec; /* Timestamp */ + s32 tstamp_nsec; + u32 avail; /* available bytes */ + u32 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) + +struct snd_rawmidi_status64 { + int stream; + u8 rsvd[sizeof(time_t) - sizeof(int)]; /* alignment */ + s64 tstamp_sec; /* Timestamp */ + s64 tstamp_nsec; + 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; @@ -689,7 +712,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; @@ -702,7 +725,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; @@ -716,6 +739,80 @@ static int snd_rawmidi_input_status(struct snd_rawmidi_substream *substream, return 0; } +static int snd_rawmidi_ioctl_status32(struct snd_rawmidi_file *rfile, + struct snd_rawmidi_status32 __user *argp) +{ + 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; + + status32 = (struct snd_rawmidi_status32) { + .stream = status64.stream, + .tstamp_sec = status64.tstamp_sec, + .tstamp_nsec = status64.tstamp_nsec, + .avail = status64.avail, + .xruns = status64.xruns, + }; + + if (copy_to_user(status, &status32, sizeof(*status))) + return -EFAULT; + + return 0; +} + +static int snd_rawmidi_ioctl_status64(struct snd_rawmidi_file *rfile, + struct snd_rawmidi_status64 __user *argp) +{ + int err = 0; + 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: + if (rfile->output == NULL) + return -EINVAL; + err = snd_rawmidi_output_status(rfile->output, &status); + break; + case SNDRV_RAWMIDI_STREAM_INPUT: + if (rfile->input == NULL) + return -EINVAL; + err = snd_rawmidi_input_status(rfile->input, &status); + break; + default: + return -EINVAL; + } + if (err < 0) + return err; + if (copy_to_user(argp, &status, + sizeof(struct snd_rawmidi_status64))) + return -EFAULT; + return 0; +} + static long snd_rawmidi_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { struct snd_rawmidi_file *rfile; @@ -760,32 +857,10 @@ static long snd_rawmidi_ioctl(struct file *file, unsigned int cmd, unsigned long return -EINVAL; } } - case SNDRV_RAWMIDI_IOCTL_STATUS: - { - int err = 0; - struct snd_rawmidi_status status; - if (copy_from_user(&status, argp, sizeof(struct snd_rawmidi_status))) - return -EFAULT; - switch (status.stream) { - case SNDRV_RAWMIDI_STREAM_OUTPUT: - if (rfile->output == NULL) - return -EINVAL; - err = snd_rawmidi_output_status(rfile->output, &status); - break; - case SNDRV_RAWMIDI_STREAM_INPUT: - if (rfile->input == NULL) - return -EINVAL; - err = snd_rawmidi_input_status(rfile->input, &status); - break; - default: - return -EINVAL; - } - if (err < 0) - return err; - if (copy_to_user(argp, &status, sizeof(struct snd_rawmidi_status))) - return -EFAULT; - return 0; - } + case SNDRV_RAWMIDI_IOCTL_STATUS32: + return snd_rawmidi_ioctl_status32(rfile, argp); + case SNDRV_RAWMIDI_IOCTL_STATUS64: + return snd_rawmidi_ioctl_status64(rfile, argp); case SNDRV_RAWMIDI_IOCTL_DROP: { int val; diff --git a/sound/core/rawmidi_compat.c b/sound/core/rawmidi_compat.c index e30e30b..c817441 100644 --- a/sound/core/rawmidi_compat.c +++ b/sound/core/rawmidi_compat.c @@ -55,19 +55,22 @@ static int snd_rawmidi_ioctl_params_compat(struct snd_rawmidi_file *rfile, return -EINVAL; } -struct snd_rawmidi_status32 { +struct compat_snd_rawmidi_status64 { s32 stream; - struct compat_timespec tstamp; + u8 rsvd[sizeof(time_t) - sizeof(s32)]; /* alignment */ + s64 tstamp_sec; + s64 tstamp_nsec; u32 avail; u32 xruns; unsigned char reserved[16]; } __attribute__((packed)); -static int snd_rawmidi_ioctl_status_compat(struct snd_rawmidi_file *rfile, - struct snd_rawmidi_status32 __user *src) +static int snd_rawmidi_ioctl_status_compat64(struct snd_rawmidi_file *rfile, + struct compat_snd_rawmidi_status64 __user *src) { int err; - struct snd_rawmidi_status status; + struct snd_rawmidi_status64 status; + struct compat_snd_rawmidi_status64 compat_status; if (get_user(status.stream, &src->stream)) return -EFAULT; @@ -89,68 +92,24 @@ 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) || - put_user(status.avail, &src->avail) || - put_user(status.xruns, &src->xruns)) - return -EFAULT; - - return 0; -} - -#ifdef CONFIG_X86_X32 -/* X32 ABI has 64bit timespec and 64bit alignment */ -struct snd_rawmidi_status_x32 { - s32 stream; - u32 rsvd; /* alignment */ - struct timespec 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_x32(struct snd_rawmidi_file *rfile, - struct snd_rawmidi_status_x32 __user *src) -{ - int err; - struct snd_rawmidi_status status; - - if (get_user(status.stream, &src->stream)) - return -EFAULT; - - switch (status.stream) { - case SNDRV_RAWMIDI_STREAM_OUTPUT: - if (!rfile->output) - return -EINVAL; - err = snd_rawmidi_output_status(rfile->output, &status); - break; - case SNDRV_RAWMIDI_STREAM_INPUT: - if (!rfile->input) - return -EINVAL; - err = snd_rawmidi_input_status(rfile->input, &status); - break; - default: - return -EINVAL; - } - if (err < 0) - return err; + compat_status = (struct compat_snd_rawmidi_status64) { + .stream = status.stream, + .tstamp_sec = status.tstamp_sec, + .tstamp_nsec = status.tstamp_nsec, + .avail = status.avail, + .xruns = status.xruns, + }; - if (put_timespec(&status.tstamp, &src->tstamp) || - put_user(status.avail, &src->avail) || - put_user(status.xruns, &src->xruns)) + if (copy_to_user(src, &compat_status, sizeof(*src))) return -EFAULT; return 0; } -#endif /* CONFIG_X86_X32 */ 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 snd_rawmidi_status32), + SNDRV_RAWMIDI_IOCTL_STATUS_COMPAT64 = _IOWR('W', 0x20, struct compat_snd_rawmidi_status64), }; static long snd_rawmidi_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg) @@ -167,12 +126,10 @@ 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: - 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_COMPAT32: + return snd_rawmidi_ioctl_status32(rfile, argp); + case SNDRV_RAWMIDI_IOCTL_STATUS_COMPAT64: + return snd_rawmidi_ioctl_status_compat64(rfile, argp); } return -ENOIOCTLCMD; } -- 1.7.9.5