root/sound/core/rawmidi_compat.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. snd_rawmidi_ioctl_params_compat
  2. snd_rawmidi_ioctl_status_compat
  3. snd_rawmidi_ioctl_status_x32
  4. snd_rawmidi_ioctl_compat

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  *   32bit -> 64bit ioctl wrapper for raw MIDI API
   4  *   Copyright (c) by Takashi Iwai <tiwai@suse.de>
   5  */
   6 
   7 /* This file included from rawmidi.c */
   8 
   9 #include <linux/compat.h>
  10 
  11 struct snd_rawmidi_params32 {
  12         s32 stream;
  13         u32 buffer_size;
  14         u32 avail_min;
  15         unsigned int no_active_sensing; /* avoid bit-field */
  16         unsigned char reserved[16];
  17 } __attribute__((packed));
  18 
  19 static int snd_rawmidi_ioctl_params_compat(struct snd_rawmidi_file *rfile,
  20                                            struct snd_rawmidi_params32 __user *src)
  21 {
  22         struct snd_rawmidi_params params;
  23         unsigned int val;
  24 
  25         if (get_user(params.stream, &src->stream) ||
  26             get_user(params.buffer_size, &src->buffer_size) ||
  27             get_user(params.avail_min, &src->avail_min) ||
  28             get_user(val, &src->no_active_sensing))
  29                 return -EFAULT;
  30         params.no_active_sensing = val;
  31         switch (params.stream) {
  32         case SNDRV_RAWMIDI_STREAM_OUTPUT:
  33                 if (!rfile->output)
  34                         return -EINVAL;
  35                 return snd_rawmidi_output_params(rfile->output, &params);
  36         case SNDRV_RAWMIDI_STREAM_INPUT:
  37                 if (!rfile->input)
  38                         return -EINVAL;
  39                 return snd_rawmidi_input_params(rfile->input, &params);
  40         }
  41         return -EINVAL;
  42 }
  43 
  44 struct snd_rawmidi_status32 {
  45         s32 stream;
  46         struct compat_timespec tstamp;
  47         u32 avail;
  48         u32 xruns;
  49         unsigned char reserved[16];
  50 } __attribute__((packed));
  51 
  52 static int snd_rawmidi_ioctl_status_compat(struct snd_rawmidi_file *rfile,
  53                                            struct snd_rawmidi_status32 __user *src)
  54 {
  55         int err;
  56         struct snd_rawmidi_status status;
  57 
  58         if (get_user(status.stream, &src->stream))
  59                 return -EFAULT;
  60 
  61         switch (status.stream) {
  62         case SNDRV_RAWMIDI_STREAM_OUTPUT:
  63                 if (!rfile->output)
  64                         return -EINVAL;
  65                 err = snd_rawmidi_output_status(rfile->output, &status);
  66                 break;
  67         case SNDRV_RAWMIDI_STREAM_INPUT:
  68                 if (!rfile->input)
  69                         return -EINVAL;
  70                 err = snd_rawmidi_input_status(rfile->input, &status);
  71                 break;
  72         default:
  73                 return -EINVAL;
  74         }
  75         if (err < 0)
  76                 return err;
  77 
  78         if (compat_put_timespec(&status.tstamp, &src->tstamp) ||
  79             put_user(status.avail, &src->avail) ||
  80             put_user(status.xruns, &src->xruns))
  81                 return -EFAULT;
  82 
  83         return 0;
  84 }
  85 
  86 #ifdef CONFIG_X86_X32
  87 /* X32 ABI has 64bit timespec and 64bit alignment */
  88 struct snd_rawmidi_status_x32 {
  89         s32 stream;
  90         u32 rsvd; /* alignment */
  91         struct timespec tstamp;
  92         u32 avail;
  93         u32 xruns;
  94         unsigned char reserved[16];
  95 } __attribute__((packed));
  96 
  97 #define put_timespec(src, dst) copy_to_user(dst, src, sizeof(*dst))
  98 
  99 static int snd_rawmidi_ioctl_status_x32(struct snd_rawmidi_file *rfile,
 100                                         struct snd_rawmidi_status_x32 __user *src)
 101 {
 102         int err;
 103         struct snd_rawmidi_status status;
 104 
 105         if (get_user(status.stream, &src->stream))
 106                 return -EFAULT;
 107 
 108         switch (status.stream) {
 109         case SNDRV_RAWMIDI_STREAM_OUTPUT:
 110                 if (!rfile->output)
 111                         return -EINVAL;
 112                 err = snd_rawmidi_output_status(rfile->output, &status);
 113                 break;
 114         case SNDRV_RAWMIDI_STREAM_INPUT:
 115                 if (!rfile->input)
 116                         return -EINVAL;
 117                 err = snd_rawmidi_input_status(rfile->input, &status);
 118                 break;
 119         default:
 120                 return -EINVAL;
 121         }
 122         if (err < 0)
 123                 return err;
 124 
 125         if (put_timespec(&status.tstamp, &src->tstamp) ||
 126             put_user(status.avail, &src->avail) ||
 127             put_user(status.xruns, &src->xruns))
 128                 return -EFAULT;
 129 
 130         return 0;
 131 }
 132 #endif /* CONFIG_X86_X32 */
 133 
 134 enum {
 135         SNDRV_RAWMIDI_IOCTL_PARAMS32 = _IOWR('W', 0x10, struct snd_rawmidi_params32),
 136         SNDRV_RAWMIDI_IOCTL_STATUS32 = _IOWR('W', 0x20, struct snd_rawmidi_status32),
 137 #ifdef CONFIG_X86_X32
 138         SNDRV_RAWMIDI_IOCTL_STATUS_X32 = _IOWR('W', 0x20, struct snd_rawmidi_status_x32),
 139 #endif /* CONFIG_X86_X32 */
 140 };
 141 
 142 static long snd_rawmidi_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg)
 143 {
 144         struct snd_rawmidi_file *rfile;
 145         void __user *argp = compat_ptr(arg);
 146 
 147         rfile = file->private_data;
 148         switch (cmd) {
 149         case SNDRV_RAWMIDI_IOCTL_PVERSION:
 150         case SNDRV_RAWMIDI_IOCTL_INFO:
 151         case SNDRV_RAWMIDI_IOCTL_DROP:
 152         case SNDRV_RAWMIDI_IOCTL_DRAIN:
 153                 return snd_rawmidi_ioctl(file, cmd, (unsigned long)argp);
 154         case SNDRV_RAWMIDI_IOCTL_PARAMS32:
 155                 return snd_rawmidi_ioctl_params_compat(rfile, argp);
 156         case SNDRV_RAWMIDI_IOCTL_STATUS32:
 157                 return snd_rawmidi_ioctl_status_compat(rfile, argp);
 158 #ifdef CONFIG_X86_X32
 159         case SNDRV_RAWMIDI_IOCTL_STATUS_X32:
 160                 return snd_rawmidi_ioctl_status_x32(rfile, argp);
 161 #endif /* CONFIG_X86_X32 */
 162         }
 163         return -ENOIOCTLCMD;
 164 }

/* [<][>][^][v][top][bottom][index][help] */