ALSA: Avoid using timespec for struct snd_pcm_status
authorBaolin Wang <baolin.wang@linaro.org>
Tue, 24 Apr 2018 12:06:11 +0000 (20:06 +0800)
committerArnd Bergmann <arnd@arndb.de>
Wed, 11 Dec 2019 21:06:15 +0000 (22:06 +0100)
commit3ddee7f88aaf2dee38f7016ac8fd48dd9fdb43e3
treebd68506d27a4db945608bd80a7350dc5c3fa5716
parenta4e7dd35b9dac21fa7b33e8788b51c7fbc7a49f1
ALSA: Avoid using timespec for struct snd_pcm_status

The struct snd_pcm_status will use 'timespec' type variables to record
timestamp, which is not year 2038 safe on 32bits system.

Userspace will use SNDRV_PCM_IOCTL_STATUS and SNDRV_PCM_IOCTL_STATUS_EXT
as commands to issue ioctl() to fill the 'snd_pcm_status' structure in
userspace. The command number is always defined through _IOR/_IOW/IORW,
so when userspace changes the definition of 'struct timespec' to use
64-bit types, the command number also changes.

Thus in the kernel, we now need to define two versions of each such ioctl
and corresponding ioctl commands to handle 32bit time_t and 64bit time_t
in native mode:
struct snd_pcm_status32 {
......

s32 trigger_tstamp_sec;
s32 trigger_tstamp_nsec;

......

s32 audio_tstamp_sec;
s32 audio_tstamp_nsec;

......
};

struct snd_pcm_status64 {
......

s32 trigger_tstamp_sec;
s32 trigger_tstamp_nsec;

......

s32 audio_tstamp_sec;
s32 audio_tstamp_nsec;

......
};

Moreover in compat file, we renamed or introduced new structures to handle
32bit/64bit time_t in compatible mode. The 'struct snd_pcm_status32' and
snd_pcm_status_user32() are used to handle 32bit time_t in compat mode.
'struct compat_snd_pcm_status64' and snd_pcm_status_user_compat64() are used
to handle 64bit time_t.

The implicit padding before timespec is made explicit to avoid incompatible
structure layout between 32-bit and 64-bit x86 due to the different
alignment requirements, and the snd_pcm_status structure is now hidden
from the kernel to avoid relying on the timespec definitio definitionn

Finally we can replace SNDRV_PCM_IOCTL_STATUS and SNDRV_PCM_IOCTL_STATUS_EXT
with new commands and introduce new functions to fill new 'struct snd_pcm_status64'
instead of using unsafe 'struct snd_pcm_status'. Then in future, the new
commands can be matched when userspace changes 'timespec' to 64bit type
to make a size change of 'struct snd_pcm_status'. 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 <baolin.wang@linaro.org>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
include/sound/pcm.h
include/uapi/sound/asound.h
sound/core/pcm.c
sound/core/pcm_compat.c
sound/core/pcm_native.c