@@ -452,6 +452,76 @@ static unsigned int joydev_poll(struct file *file, poll_table *wait)
452
452
(joydev -> exist ? 0 : (POLLHUP | POLLERR ));
453
453
}
454
454
455
+ static int joydev_handle_JSIOCSAXMAP (struct joydev * joydev ,
456
+ void __user * argp , size_t len )
457
+ {
458
+ __u8 * abspam ;
459
+ int i ;
460
+ int retval = 0 ;
461
+
462
+ len = min (len , sizeof (joydev -> abspam ));
463
+
464
+ /* Validate the map. */
465
+ abspam = kmalloc (len , GFP_KERNEL );
466
+ if (!abspam )
467
+ return - ENOMEM ;
468
+
469
+ if (copy_from_user (abspam , argp , len )) {
470
+ retval = - EFAULT ;
471
+ goto out ;
472
+ }
473
+
474
+ for (i = 0 ; i < joydev -> nabs ; i ++ ) {
475
+ if (abspam [i ] > ABS_MAX ) {
476
+ retval = - EINVAL ;
477
+ goto out ;
478
+ }
479
+ }
480
+
481
+ memcpy (joydev -> abspam , abspam , len );
482
+
483
+ out :
484
+ kfree (abspam );
485
+ return retval ;
486
+ }
487
+
488
+ static int joydev_handle_JSIOCSBTNMAP (struct joydev * joydev ,
489
+ void __user * argp , size_t len )
490
+ {
491
+ __u16 * keypam ;
492
+ int i ;
493
+ int retval = 0 ;
494
+
495
+ len = min (len , sizeof (joydev -> keypam ));
496
+
497
+ /* Validate the map. */
498
+ keypam = kmalloc (len , GFP_KERNEL );
499
+ if (!keypam )
500
+ return - ENOMEM ;
501
+
502
+ if (copy_from_user (keypam , argp , len )) {
503
+ retval = - EFAULT ;
504
+ goto out ;
505
+ }
506
+
507
+ for (i = 0 ; i < joydev -> nkey ; i ++ ) {
508
+ if (keypam [i ] > KEY_MAX || keypam [i ] < BTN_MISC ) {
509
+ retval = - EINVAL ;
510
+ goto out ;
511
+ }
512
+ }
513
+
514
+ memcpy (joydev -> keypam , keypam , len );
515
+
516
+ for (i = 0 ; i < joydev -> nkey ; i ++ )
517
+ joydev -> keymap [keypam [i ] - BTN_MISC ] = i ;
518
+
519
+ out :
520
+ kfree (keypam );
521
+ return retval ;
522
+ }
523
+
524
+
455
525
static int joydev_ioctl_common (struct joydev * joydev ,
456
526
unsigned int cmd , void __user * argp )
457
527
{
@@ -512,46 +582,18 @@ static int joydev_ioctl_common(struct joydev *joydev,
512
582
switch (cmd & ~IOCSIZE_MASK ) {
513
583
514
584
case (JSIOCSAXMAP & ~IOCSIZE_MASK ):
515
- len = min_t (size_t , _IOC_SIZE (cmd ), sizeof (joydev -> abspam ));
516
- /*
517
- * FIXME: we should not copy into our axis map before
518
- * validating the data.
519
- */
520
- if (copy_from_user (joydev -> abspam , argp , len ))
521
- return - EFAULT ;
522
-
523
- for (i = 0 ; i < joydev -> nabs ; i ++ ) {
524
- if (joydev -> abspam [i ] > ABS_MAX )
525
- return - EINVAL ;
526
- joydev -> absmap [joydev -> abspam [i ]] = i ;
527
- }
528
- return 0 ;
585
+ return joydev_handle_JSIOCSAXMAP (joydev , argp , _IOC_SIZE (cmd ));
529
586
530
587
case (JSIOCGAXMAP & ~IOCSIZE_MASK ):
531
588
len = min_t (size_t , _IOC_SIZE (cmd ), sizeof (joydev -> abspam ));
532
- return copy_to_user (argp , joydev -> abspam , len ) ? - EFAULT : 0 ;
589
+ return copy_to_user (argp , joydev -> abspam , len ) ? - EFAULT : len ;
533
590
534
591
case (JSIOCSBTNMAP & ~IOCSIZE_MASK ):
535
- len = min_t (size_t , _IOC_SIZE (cmd ), sizeof (joydev -> keypam ));
536
- /*
537
- * FIXME: we should not copy into our keymap before
538
- * validating the data.
539
- */
540
- if (copy_from_user (joydev -> keypam , argp , len ))
541
- return - EFAULT ;
542
-
543
- for (i = 0 ; i < joydev -> nkey ; i ++ ) {
544
- if (joydev -> keypam [i ] > KEY_MAX ||
545
- joydev -> keypam [i ] < BTN_MISC )
546
- return - EINVAL ;
547
- joydev -> keymap [joydev -> keypam [i ] - BTN_MISC ] = i ;
548
- }
549
-
550
- return 0 ;
592
+ return joydev_handle_JSIOCSBTNMAP (joydev , argp , _IOC_SIZE (cmd ));
551
593
552
594
case (JSIOCGBTNMAP & ~IOCSIZE_MASK ):
553
595
len = min_t (size_t , _IOC_SIZE (cmd ), sizeof (joydev -> keypam ));
554
- return copy_to_user (argp , joydev -> keypam , len ) ? - EFAULT : 0 ;
596
+ return copy_to_user (argp , joydev -> keypam , len ) ? - EFAULT : len ;
555
597
556
598
case JSIOCGNAME (0 ):
557
599
name = dev -> name ;
0 commit comments