ubifs: Fix memory leak from c->sup_node
[linux-2.6-microblaze.git] / block / compat_ioctl.c
1 // SPDX-License-Identifier: GPL-2.0
2 #include <linux/blkdev.h>
3 #include <linux/blkpg.h>
4 #include <linux/blktrace_api.h>
5 #include <linux/cdrom.h>
6 #include <linux/compat.h>
7 #include <linux/elevator.h>
8 #include <linux/hdreg.h>
9 #include <linux/pr.h>
10 #include <linux/slab.h>
11 #include <linux/syscalls.h>
12 #include <linux/types.h>
13 #include <linux/uaccess.h>
14
15 static int compat_put_ushort(unsigned long arg, unsigned short val)
16 {
17         return put_user(val, (unsigned short __user *)compat_ptr(arg));
18 }
19
20 static int compat_put_int(unsigned long arg, int val)
21 {
22         return put_user(val, (compat_int_t __user *)compat_ptr(arg));
23 }
24
25 static int compat_put_uint(unsigned long arg, unsigned int val)
26 {
27         return put_user(val, (compat_uint_t __user *)compat_ptr(arg));
28 }
29
30 static int compat_put_long(unsigned long arg, long val)
31 {
32         return put_user(val, (compat_long_t __user *)compat_ptr(arg));
33 }
34
35 static int compat_put_ulong(unsigned long arg, compat_ulong_t val)
36 {
37         return put_user(val, (compat_ulong_t __user *)compat_ptr(arg));
38 }
39
40 static int compat_put_u64(unsigned long arg, u64 val)
41 {
42         return put_user(val, (compat_u64 __user *)compat_ptr(arg));
43 }
44
45 struct compat_hd_geometry {
46         unsigned char heads;
47         unsigned char sectors;
48         unsigned short cylinders;
49         u32 start;
50 };
51
52 static int compat_hdio_getgeo(struct gendisk *disk, struct block_device *bdev,
53                         struct compat_hd_geometry __user *ugeo)
54 {
55         struct hd_geometry geo;
56         int ret;
57
58         if (!ugeo)
59                 return -EINVAL;
60         if (!disk->fops->getgeo)
61                 return -ENOTTY;
62
63         memset(&geo, 0, sizeof(geo));
64         /*
65          * We need to set the startsect first, the driver may
66          * want to override it.
67          */
68         geo.start = get_start_sect(bdev);
69         ret = disk->fops->getgeo(bdev, &geo);
70         if (ret)
71                 return ret;
72
73         ret = copy_to_user(ugeo, &geo, 4);
74         ret |= put_user(geo.start, &ugeo->start);
75         if (ret)
76                 ret = -EFAULT;
77
78         return ret;
79 }
80
81 static int compat_hdio_ioctl(struct block_device *bdev, fmode_t mode,
82                 unsigned int cmd, unsigned long arg)
83 {
84         unsigned long __user *p;
85         int error;
86
87         p = compat_alloc_user_space(sizeof(unsigned long));
88         error = __blkdev_driver_ioctl(bdev, mode,
89                                 cmd, (unsigned long)p);
90         if (error == 0) {
91                 unsigned int __user *uvp = compat_ptr(arg);
92                 unsigned long v;
93                 if (get_user(v, p) || put_user(v, uvp))
94                         error = -EFAULT;
95         }
96         return error;
97 }
98
99 struct compat_cdrom_read_audio {
100         union cdrom_addr        addr;
101         u8                      addr_format;
102         compat_int_t            nframes;
103         compat_caddr_t          buf;
104 };
105
106 struct compat_cdrom_generic_command {
107         unsigned char   cmd[CDROM_PACKET_SIZE];
108         compat_caddr_t  buffer;
109         compat_uint_t   buflen;
110         compat_int_t    stat;
111         compat_caddr_t  sense;
112         unsigned char   data_direction;
113         compat_int_t    quiet;
114         compat_int_t    timeout;
115         compat_caddr_t  reserved[1];
116 };
117
118 static int compat_cdrom_read_audio(struct block_device *bdev, fmode_t mode,
119                 unsigned int cmd, unsigned long arg)
120 {
121         struct cdrom_read_audio __user *cdread_audio;
122         struct compat_cdrom_read_audio __user *cdread_audio32;
123         __u32 data;
124         void __user *datap;
125
126         cdread_audio = compat_alloc_user_space(sizeof(*cdread_audio));
127         cdread_audio32 = compat_ptr(arg);
128
129         if (copy_in_user(&cdread_audio->addr,
130                          &cdread_audio32->addr,
131                          (sizeof(*cdread_audio32) -
132                           sizeof(compat_caddr_t))))
133                 return -EFAULT;
134
135         if (get_user(data, &cdread_audio32->buf))
136                 return -EFAULT;
137         datap = compat_ptr(data);
138         if (put_user(datap, &cdread_audio->buf))
139                 return -EFAULT;
140
141         return __blkdev_driver_ioctl(bdev, mode, cmd,
142                         (unsigned long)cdread_audio);
143 }
144
145 static int compat_cdrom_generic_command(struct block_device *bdev, fmode_t mode,
146                 unsigned int cmd, unsigned long arg)
147 {
148         struct cdrom_generic_command __user *cgc;
149         struct compat_cdrom_generic_command __user *cgc32;
150         u32 data;
151         unsigned char dir;
152         int itmp;
153
154         cgc = compat_alloc_user_space(sizeof(*cgc));
155         cgc32 = compat_ptr(arg);
156
157         if (copy_in_user(&cgc->cmd, &cgc32->cmd, sizeof(cgc->cmd)) ||
158             get_user(data, &cgc32->buffer) ||
159             put_user(compat_ptr(data), &cgc->buffer) ||
160             copy_in_user(&cgc->buflen, &cgc32->buflen,
161                          (sizeof(unsigned int) + sizeof(int))) ||
162             get_user(data, &cgc32->sense) ||
163             put_user(compat_ptr(data), &cgc->sense) ||
164             get_user(dir, &cgc32->data_direction) ||
165             put_user(dir, &cgc->data_direction) ||
166             get_user(itmp, &cgc32->quiet) ||
167             put_user(itmp, &cgc->quiet) ||
168             get_user(itmp, &cgc32->timeout) ||
169             put_user(itmp, &cgc->timeout) ||
170             get_user(data, &cgc32->reserved[0]) ||
171             put_user(compat_ptr(data), &cgc->reserved[0]))
172                 return -EFAULT;
173
174         return __blkdev_driver_ioctl(bdev, mode, cmd, (unsigned long)cgc);
175 }
176
177 struct compat_blkpg_ioctl_arg {
178         compat_int_t op;
179         compat_int_t flags;
180         compat_int_t datalen;
181         compat_caddr_t data;
182 };
183
184 static int compat_blkpg_ioctl(struct block_device *bdev, fmode_t mode,
185                 unsigned int cmd, struct compat_blkpg_ioctl_arg __user *ua32)
186 {
187         struct blkpg_ioctl_arg __user *a = compat_alloc_user_space(sizeof(*a));
188         compat_caddr_t udata;
189         compat_int_t n;
190         int err;
191
192         err = get_user(n, &ua32->op);
193         err |= put_user(n, &a->op);
194         err |= get_user(n, &ua32->flags);
195         err |= put_user(n, &a->flags);
196         err |= get_user(n, &ua32->datalen);
197         err |= put_user(n, &a->datalen);
198         err |= get_user(udata, &ua32->data);
199         err |= put_user(compat_ptr(udata), &a->data);
200         if (err)
201                 return err;
202
203         return blkdev_ioctl(bdev, mode, cmd, (unsigned long)a);
204 }
205
206 #define BLKBSZGET_32            _IOR(0x12, 112, int)
207 #define BLKBSZSET_32            _IOW(0x12, 113, int)
208 #define BLKGETSIZE64_32         _IOR(0x12, 114, int)
209
210 static int compat_blkdev_driver_ioctl(struct block_device *bdev, fmode_t mode,
211                         unsigned cmd, unsigned long arg)
212 {
213         switch (cmd) {
214         case HDIO_GET_UNMASKINTR:
215         case HDIO_GET_MULTCOUNT:
216         case HDIO_GET_KEEPSETTINGS:
217         case HDIO_GET_32BIT:
218         case HDIO_GET_NOWERR:
219         case HDIO_GET_DMA:
220         case HDIO_GET_NICE:
221         case HDIO_GET_WCACHE:
222         case HDIO_GET_ACOUSTIC:
223         case HDIO_GET_ADDRESS:
224         case HDIO_GET_BUSSTATE:
225                 return compat_hdio_ioctl(bdev, mode, cmd, arg);
226         case CDROMREADAUDIO:
227                 return compat_cdrom_read_audio(bdev, mode, cmd, arg);
228         case CDROM_SEND_PACKET:
229                 return compat_cdrom_generic_command(bdev, mode, cmd, arg);
230
231         /*
232          * No handler required for the ones below, we just need to
233          * convert arg to a 64 bit pointer.
234          */
235         case BLKSECTSET:
236         /*
237          * 0x03 -- HD/IDE ioctl's used by hdparm and friends.
238          *         Some need translations, these do not.
239          */
240         case HDIO_GET_IDENTITY:
241         case HDIO_DRIVE_TASK:
242         case HDIO_DRIVE_CMD:
243         /* 0x330 is reserved -- it used to be HDIO_GETGEO_BIG */
244         case 0x330:
245         /* CDROM stuff */
246         case CDROMPAUSE:
247         case CDROMRESUME:
248         case CDROMPLAYMSF:
249         case CDROMPLAYTRKIND:
250         case CDROMREADTOCHDR:
251         case CDROMREADTOCENTRY:
252         case CDROMSTOP:
253         case CDROMSTART:
254         case CDROMEJECT:
255         case CDROMVOLCTRL:
256         case CDROMSUBCHNL:
257         case CDROMMULTISESSION:
258         case CDROM_GET_MCN:
259         case CDROMRESET:
260         case CDROMVOLREAD:
261         case CDROMSEEK:
262         case CDROMPLAYBLK:
263         case CDROMCLOSETRAY:
264         case CDROM_DISC_STATUS:
265         case CDROM_CHANGER_NSLOTS:
266         case CDROM_GET_CAPABILITY:
267         /* Ignore cdrom.h about these next 5 ioctls, they absolutely do
268          * not take a struct cdrom_read, instead they take a struct cdrom_msf
269          * which is compatible.
270          */
271         case CDROMREADMODE2:
272         case CDROMREADMODE1:
273         case CDROMREADRAW:
274         case CDROMREADCOOKED:
275         case CDROMREADALL:
276         /* DVD ioctls */
277         case DVD_READ_STRUCT:
278         case DVD_WRITE_STRUCT:
279         case DVD_AUTH:
280                 arg = (unsigned long)compat_ptr(arg);
281         /* These intepret arg as an unsigned long, not as a pointer,
282          * so we must not do compat_ptr() conversion. */
283         case HDIO_SET_MULTCOUNT:
284         case HDIO_SET_UNMASKINTR:
285         case HDIO_SET_KEEPSETTINGS:
286         case HDIO_SET_32BIT:
287         case HDIO_SET_NOWERR:
288         case HDIO_SET_DMA:
289         case HDIO_SET_PIO_MODE:
290         case HDIO_SET_NICE:
291         case HDIO_SET_WCACHE:
292         case HDIO_SET_ACOUSTIC:
293         case HDIO_SET_BUSSTATE:
294         case HDIO_SET_ADDRESS:
295         case CDROMEJECT_SW:
296         case CDROM_SET_OPTIONS:
297         case CDROM_CLEAR_OPTIONS:
298         case CDROM_SELECT_SPEED:
299         case CDROM_SELECT_DISC:
300         case CDROM_MEDIA_CHANGED:
301         case CDROM_DRIVE_STATUS:
302         case CDROM_LOCKDOOR:
303         case CDROM_DEBUG:
304                 break;
305         default:
306                 /* unknown ioctl number */
307                 return -ENOIOCTLCMD;
308         }
309
310         return __blkdev_driver_ioctl(bdev, mode, cmd, arg);
311 }
312
313 /* Most of the generic ioctls are handled in the normal fallback path.
314    This assumes the blkdev's low level compat_ioctl always returns
315    ENOIOCTLCMD for unknown ioctls. */
316 long compat_blkdev_ioctl(struct file *file, unsigned cmd, unsigned long arg)
317 {
318         int ret = -ENOIOCTLCMD;
319         struct inode *inode = file->f_mapping->host;
320         struct block_device *bdev = inode->i_bdev;
321         struct gendisk *disk = bdev->bd_disk;
322         fmode_t mode = file->f_mode;
323         loff_t size;
324         unsigned int max_sectors;
325
326         /*
327          * O_NDELAY can be altered using fcntl(.., F_SETFL, ..), so we have
328          * to updated it before every ioctl.
329          */
330         if (file->f_flags & O_NDELAY)
331                 mode |= FMODE_NDELAY;
332         else
333                 mode &= ~FMODE_NDELAY;
334
335         switch (cmd) {
336         case HDIO_GETGEO:
337                 return compat_hdio_getgeo(disk, bdev, compat_ptr(arg));
338         case BLKPBSZGET:
339                 return compat_put_uint(arg, bdev_physical_block_size(bdev));
340         case BLKIOMIN:
341                 return compat_put_uint(arg, bdev_io_min(bdev));
342         case BLKIOOPT:
343                 return compat_put_uint(arg, bdev_io_opt(bdev));
344         case BLKALIGNOFF:
345                 return compat_put_int(arg, bdev_alignment_offset(bdev));
346         case BLKDISCARDZEROES:
347                 return compat_put_uint(arg, 0);
348         case BLKFLSBUF:
349         case BLKROSET:
350         case BLKDISCARD:
351         case BLKSECDISCARD:
352         case BLKZEROOUT:
353         /*
354          * the ones below are implemented in blkdev_locked_ioctl,
355          * but we call blkdev_ioctl, which gets the lock for us
356          */
357         case BLKRRPART:
358         case BLKREPORTZONE:
359         case BLKRESETZONE:
360         case BLKOPENZONE:
361         case BLKCLOSEZONE:
362         case BLKFINISHZONE:
363         case BLKGETZONESZ:
364         case BLKGETNRZONES:
365                 return blkdev_ioctl(bdev, mode, cmd,
366                                 (unsigned long)compat_ptr(arg));
367         case BLKBSZSET_32:
368                 return blkdev_ioctl(bdev, mode, BLKBSZSET,
369                                 (unsigned long)compat_ptr(arg));
370         case BLKPG:
371                 return compat_blkpg_ioctl(bdev, mode, cmd, compat_ptr(arg));
372         case BLKRAGET:
373         case BLKFRAGET:
374                 if (!arg)
375                         return -EINVAL;
376                 return compat_put_long(arg,
377                                (bdev->bd_bdi->ra_pages * PAGE_SIZE) / 512);
378         case BLKROGET: /* compatible */
379                 return compat_put_int(arg, bdev_read_only(bdev) != 0);
380         case BLKBSZGET_32: /* get the logical block size (cf. BLKSSZGET) */
381                 return compat_put_int(arg, block_size(bdev));
382         case BLKSSZGET: /* get block device hardware sector size */
383                 return compat_put_int(arg, bdev_logical_block_size(bdev));
384         case BLKSECTGET:
385                 max_sectors = min_t(unsigned int, USHRT_MAX,
386                                     queue_max_sectors(bdev_get_queue(bdev)));
387                 return compat_put_ushort(arg, max_sectors);
388         case BLKROTATIONAL:
389                 return compat_put_ushort(arg,
390                                          !blk_queue_nonrot(bdev_get_queue(bdev)));
391         case BLKRASET: /* compatible, but no compat_ptr (!) */
392         case BLKFRASET:
393                 if (!capable(CAP_SYS_ADMIN))
394                         return -EACCES;
395                 bdev->bd_bdi->ra_pages = (arg * 512) / PAGE_SIZE;
396                 return 0;
397         case BLKGETSIZE:
398                 size = i_size_read(bdev->bd_inode);
399                 if ((size >> 9) > ~0UL)
400                         return -EFBIG;
401                 return compat_put_ulong(arg, size >> 9);
402
403         case BLKGETSIZE64_32:
404                 return compat_put_u64(arg, i_size_read(bdev->bd_inode));
405
406         case BLKTRACESETUP32:
407         case BLKTRACESTART: /* compatible */
408         case BLKTRACESTOP:  /* compatible */
409         case BLKTRACETEARDOWN: /* compatible */
410                 ret = blk_trace_ioctl(bdev, cmd, compat_ptr(arg));
411                 return ret;
412         case IOC_PR_REGISTER:
413         case IOC_PR_RESERVE:
414         case IOC_PR_RELEASE:
415         case IOC_PR_PREEMPT:
416         case IOC_PR_PREEMPT_ABORT:
417         case IOC_PR_CLEAR:
418                 return blkdev_ioctl(bdev, mode, cmd,
419                                 (unsigned long)compat_ptr(arg));
420         default:
421                 if (disk->fops->compat_ioctl)
422                         ret = disk->fops->compat_ioctl(bdev, mode, cmd, arg);
423                 if (ret == -ENOIOCTLCMD)
424                         ret = compat_blkdev_driver_ioctl(bdev, mode, cmd, arg);
425                 return ret;
426         }
427 }