Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

hamradio: use ndo_siocdevprivate

hamradio uses a set of private ioctls that do seem to work
correctly in compat mode, as they only rely on the ifr_data
pointer.

Move them over to the ndo_siocdevprivate callback as a cleanup.

Cc: Thomas Sailer <t.sailer@alumni.ethz.ch>
Cc: Joerg Reuter <jreuter@yaina.de>
Cc: Jean-Paul Roubelat <jpr@f6fbb.org>
Cc: linux-hams@vger.kernel.org
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Arnd Bergmann and committed by
David S. Miller
25ec92fb ebb4a911

+65 -61
+5 -4
drivers/net/hamradio/baycom_epp.c
··· 1005 1005 1006 1006 /* --------------------------------------------------------------------- */ 1007 1007 1008 - static int baycom_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) 1008 + static int baycom_siocdevprivate(struct net_device *dev, struct ifreq *ifr, 1009 + void __user *data, int cmd) 1009 1010 { 1010 1011 struct baycom_state *bc = netdev_priv(dev); 1011 1012 struct hdlcdrv_ioctl hi; ··· 1014 1013 if (cmd != SIOCDEVPRIVATE) 1015 1014 return -ENOIOCTLCMD; 1016 1015 1017 - if (copy_from_user(&hi, ifr->ifr_data, sizeof(hi))) 1016 + if (copy_from_user(&hi, data, sizeof(hi))) 1018 1017 return -EFAULT; 1019 1018 switch (hi.cmd) { 1020 1019 default: ··· 1105 1104 return HDLCDRV_PARMASK_IOBASE; 1106 1105 1107 1106 } 1108 - if (copy_to_user(ifr->ifr_data, &hi, sizeof(hi))) 1107 + if (copy_to_user(data, &hi, sizeof(hi))) 1109 1108 return -EFAULT; 1110 1109 return 0; 1111 1110 } ··· 1115 1114 static const struct net_device_ops baycom_netdev_ops = { 1116 1115 .ndo_open = epp_open, 1117 1116 .ndo_stop = epp_close, 1118 - .ndo_do_ioctl = baycom_ioctl, 1117 + .ndo_siocdevprivate = baycom_siocdevprivate, 1119 1118 .ndo_start_xmit = baycom_send_packet, 1120 1119 .ndo_set_mac_address = baycom_set_mac_address, 1121 1120 };
+6 -6
drivers/net/hamradio/baycom_par.c
··· 380 380 * ===================== hdlcdrv driver interface ========================= 381 381 */ 382 382 383 - static int baycom_ioctl(struct net_device *dev, struct ifreq *ifr, 383 + static int baycom_ioctl(struct net_device *dev, void __user *data, 384 384 struct hdlcdrv_ioctl *hi, int cmd); 385 385 386 386 /* --------------------------------------------------------------------- */ ··· 408 408 409 409 /* --------------------------------------------------------------------- */ 410 410 411 - static int baycom_ioctl(struct net_device *dev, struct ifreq *ifr, 411 + static int baycom_ioctl(struct net_device *dev, void __user *data, 412 412 struct hdlcdrv_ioctl *hi, int cmd) 413 413 { 414 414 struct baycom_state *bc; ··· 428 428 429 429 case HDLCDRVCTL_GETMODE: 430 430 strcpy(hi->data.modename, bc->options ? "par96" : "picpar"); 431 - if (copy_to_user(ifr->ifr_data, hi, sizeof(struct hdlcdrv_ioctl))) 431 + if (copy_to_user(data, hi, sizeof(struct hdlcdrv_ioctl))) 432 432 return -EFAULT; 433 433 return 0; 434 434 ··· 440 440 441 441 case HDLCDRVCTL_MODELIST: 442 442 strcpy(hi->data.modename, "par96,picpar"); 443 - if (copy_to_user(ifr->ifr_data, hi, sizeof(struct hdlcdrv_ioctl))) 443 + if (copy_to_user(data, hi, sizeof(struct hdlcdrv_ioctl))) 444 444 return -EFAULT; 445 445 return 0; 446 446 ··· 449 449 450 450 } 451 451 452 - if (copy_from_user(&bi, ifr->ifr_data, sizeof(bi))) 452 + if (copy_from_user(&bi, data, sizeof(bi))) 453 453 return -EFAULT; 454 454 switch (bi.cmd) { 455 455 default: ··· 464 464 #endif /* BAYCOM_DEBUG */ 465 465 466 466 } 467 - if (copy_to_user(ifr->ifr_data, &bi, sizeof(bi))) 467 + if (copy_to_user(data, &bi, sizeof(bi))) 468 468 return -EFAULT; 469 469 return 0; 470 470
+6 -6
drivers/net/hamradio/baycom_ser_fdx.c
··· 462 462 463 463 /* --------------------------------------------------------------------- */ 464 464 465 - static int baycom_ioctl(struct net_device *dev, struct ifreq *ifr, 465 + static int baycom_ioctl(struct net_device *dev, void __user *data, 466 466 struct hdlcdrv_ioctl *hi, int cmd); 467 467 468 468 /* --------------------------------------------------------------------- */ ··· 497 497 498 498 /* --------------------------------------------------------------------- */ 499 499 500 - static int baycom_ioctl(struct net_device *dev, struct ifreq *ifr, 500 + static int baycom_ioctl(struct net_device *dev, void __user *data, 501 501 struct hdlcdrv_ioctl *hi, int cmd) 502 502 { 503 503 struct baycom_state *bc; ··· 519 519 sprintf(hi->data.modename, "ser%u", bc->baud / 100); 520 520 if (bc->opt_dcd <= 0) 521 521 strcat(hi->data.modename, (!bc->opt_dcd) ? "*" : "+"); 522 - if (copy_to_user(ifr->ifr_data, hi, sizeof(struct hdlcdrv_ioctl))) 522 + if (copy_to_user(data, hi, sizeof(struct hdlcdrv_ioctl))) 523 523 return -EFAULT; 524 524 return 0; 525 525 ··· 531 531 532 532 case HDLCDRVCTL_MODELIST: 533 533 strcpy(hi->data.modename, "ser12,ser3,ser24"); 534 - if (copy_to_user(ifr->ifr_data, hi, sizeof(struct hdlcdrv_ioctl))) 534 + if (copy_to_user(data, hi, sizeof(struct hdlcdrv_ioctl))) 535 535 return -EFAULT; 536 536 return 0; 537 537 ··· 540 540 541 541 } 542 542 543 - if (copy_from_user(&bi, ifr->ifr_data, sizeof(bi))) 543 + if (copy_from_user(&bi, data, sizeof(bi))) 544 544 return -EFAULT; 545 545 switch (bi.cmd) { 546 546 default: ··· 555 555 #endif /* BAYCOM_DEBUG */ 556 556 557 557 } 558 - if (copy_to_user(ifr->ifr_data, &bi, sizeof(bi))) 558 + if (copy_to_user(data, &bi, sizeof(bi))) 559 559 return -EFAULT; 560 560 return 0; 561 561
+6 -6
drivers/net/hamradio/baycom_ser_hdx.c
··· 521 521 522 522 /* --------------------------------------------------------------------- */ 523 523 524 - static int baycom_ioctl(struct net_device *dev, struct ifreq *ifr, 524 + static int baycom_ioctl(struct net_device *dev, void __user *data, 525 525 struct hdlcdrv_ioctl *hi, int cmd); 526 526 527 527 /* --------------------------------------------------------------------- */ ··· 551 551 552 552 /* --------------------------------------------------------------------- */ 553 553 554 - static int baycom_ioctl(struct net_device *dev, struct ifreq *ifr, 554 + static int baycom_ioctl(struct net_device *dev, void __user *data, 555 555 struct hdlcdrv_ioctl *hi, int cmd) 556 556 { 557 557 struct baycom_state *bc; ··· 573 573 strcpy(hi->data.modename, "ser12"); 574 574 if (bc->opt_dcd <= 0) 575 575 strcat(hi->data.modename, (!bc->opt_dcd) ? "*" : (bc->opt_dcd == -2) ? "@" : "+"); 576 - if (copy_to_user(ifr->ifr_data, hi, sizeof(struct hdlcdrv_ioctl))) 576 + if (copy_to_user(data, hi, sizeof(struct hdlcdrv_ioctl))) 577 577 return -EFAULT; 578 578 return 0; 579 579 ··· 585 585 586 586 case HDLCDRVCTL_MODELIST: 587 587 strcpy(hi->data.modename, "ser12"); 588 - if (copy_to_user(ifr->ifr_data, hi, sizeof(struct hdlcdrv_ioctl))) 588 + if (copy_to_user(data, hi, sizeof(struct hdlcdrv_ioctl))) 589 589 return -EFAULT; 590 590 return 0; 591 591 ··· 594 594 595 595 } 596 596 597 - if (copy_from_user(&bi, ifr->ifr_data, sizeof(bi))) 597 + if (copy_from_user(&bi, data, sizeof(bi))) 598 598 return -EFAULT; 599 599 switch (bi.cmd) { 600 600 default: ··· 609 609 #endif /* BAYCOM_DEBUG */ 610 610 611 611 } 612 - if (copy_to_user(ifr->ifr_data, &bi, sizeof(bi))) 612 + if (copy_to_user(data, &bi, sizeof(bi))) 613 613 return -EFAULT; 614 614 return 0; 615 615
+5 -4
drivers/net/hamradio/bpqether.c
··· 314 314 * source ethernet address (broadcast 315 315 * or multicast: accept all) 316 316 */ 317 - static int bpq_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) 317 + static int bpq_siocdevprivate(struct net_device *dev, struct ifreq *ifr, 318 + void __user *data, int cmd) 318 319 { 319 - struct bpq_ethaddr __user *ethaddr = ifr->ifr_data; 320 + struct bpq_ethaddr __user *ethaddr = data; 320 321 struct bpqdev *bpq = netdev_priv(dev); 321 322 struct bpq_req req; 322 323 ··· 326 325 327 326 switch (cmd) { 328 327 case SIOCSBPQETHOPT: 329 - if (copy_from_user(&req, ifr->ifr_data, sizeof(struct bpq_req))) 328 + if (copy_from_user(&req, data, sizeof(struct bpq_req))) 330 329 return -EFAULT; 331 330 switch (req.cmd) { 332 331 case SIOCGBPQETHPARAM: ··· 449 448 .ndo_stop = bpq_close, 450 449 .ndo_start_xmit = bpq_xmit, 451 450 .ndo_set_mac_address = bpq_set_mac_address, 452 - .ndo_do_ioctl = bpq_ioctl, 451 + .ndo_siocdevprivate = bpq_siocdevprivate, 453 452 }; 454 453 455 454 static void bpq_setup(struct net_device *dev)
+8 -10
drivers/net/hamradio/dmascc.c
··· 225 225 226 226 static int scc_open(struct net_device *dev); 227 227 static int scc_close(struct net_device *dev); 228 - static int scc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); 228 + static int scc_siocdevprivate(struct net_device *dev, struct ifreq *ifr, 229 + void __user *data, int cmd); 229 230 static int scc_send_packet(struct sk_buff *skb, struct net_device *dev); 230 231 static int scc_set_mac_address(struct net_device *dev, void *sa); 231 232 ··· 433 432 .ndo_open = scc_open, 434 433 .ndo_stop = scc_close, 435 434 .ndo_start_xmit = scc_send_packet, 436 - .ndo_do_ioctl = scc_ioctl, 435 + .ndo_siocdevprivate = scc_siocdevprivate, 437 436 .ndo_set_mac_address = scc_set_mac_address, 438 437 }; 439 438 ··· 882 881 } 883 882 884 883 885 - static int scc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) 884 + static int scc_siocdevprivate(struct net_device *dev, struct ifreq *ifr, void __user *data, int cmd) 886 885 { 887 886 struct scc_priv *priv = dev->ml_priv; 888 887 889 888 switch (cmd) { 890 889 case SIOCGSCCPARAM: 891 - if (copy_to_user 892 - (ifr->ifr_data, &priv->param, 893 - sizeof(struct scc_param))) 890 + if (copy_to_user(data, &priv->param, sizeof(struct scc_param))) 894 891 return -EFAULT; 895 892 return 0; 896 893 case SIOCSSCCPARAM: ··· 896 897 return -EPERM; 897 898 if (netif_running(dev)) 898 899 return -EAGAIN; 899 - if (copy_from_user 900 - (&priv->param, ifr->ifr_data, 901 - sizeof(struct scc_param))) 900 + if (copy_from_user(&priv->param, data, 901 + sizeof(struct scc_param))) 902 902 return -EFAULT; 903 903 return 0; 904 904 default: 905 - return -EINVAL; 905 + return -EOPNOTSUPP; 906 906 } 907 907 } 908 908
+11 -9
drivers/net/hamradio/hdlcdrv.c
··· 483 483 484 484 /* --------------------------------------------------------------------- */ 485 485 486 - static int hdlcdrv_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) 486 + static int hdlcdrv_siocdevprivate(struct net_device *dev, struct ifreq *ifr, 487 + void __user *data, int cmd) 487 488 { 488 489 struct hdlcdrv_state *s = netdev_priv(dev); 489 490 struct hdlcdrv_ioctl bi; 490 491 491 - if (cmd != SIOCDEVPRIVATE) { 492 - if (s->ops && s->ops->ioctl) 493 - return s->ops->ioctl(dev, ifr, &bi, cmd); 492 + if (cmd != SIOCDEVPRIVATE) 494 493 return -ENOIOCTLCMD; 495 - } 496 - if (copy_from_user(&bi, ifr->ifr_data, sizeof(bi))) 494 + 495 + if (in_compat_syscall()) /* to be implemented */ 496 + return -ENOIOCTLCMD; 497 + 498 + if (copy_from_user(&bi, data, sizeof(bi))) 497 499 return -EFAULT; 498 500 499 501 switch (bi.cmd) { 500 502 default: 501 503 if (s->ops && s->ops->ioctl) 502 - return s->ops->ioctl(dev, ifr, &bi, cmd); 504 + return s->ops->ioctl(dev, data, &bi, cmd); 503 505 return -ENOIOCTLCMD; 504 506 505 507 case HDLCDRVCTL_GETCHANNELPAR: ··· 607 605 break; 608 606 609 607 } 610 - if (copy_to_user(ifr->ifr_data, &bi, sizeof(bi))) 608 + if (copy_to_user(data, &bi, sizeof(bi))) 611 609 return -EFAULT; 612 610 return 0; 613 611 ··· 619 617 .ndo_open = hdlcdrv_open, 620 618 .ndo_stop = hdlcdrv_close, 621 619 .ndo_start_xmit = hdlcdrv_send_packet, 622 - .ndo_do_ioctl = hdlcdrv_ioctl, 620 + .ndo_siocdevprivate = hdlcdrv_siocdevprivate, 623 621 .ndo_set_mac_address = hdlcdrv_set_mac_address, 624 622 }; 625 623
+8 -5
drivers/net/hamradio/scc.c
··· 210 210 static void scc_net_rx(struct scc_channel *scc, struct sk_buff *skb); 211 211 static netdev_tx_t scc_net_tx(struct sk_buff *skb, 212 212 struct net_device *dev); 213 - static int scc_net_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); 213 + static int scc_net_siocdevprivate(struct net_device *dev, struct ifreq *ifr, 214 + void __user *data, int cmd); 214 215 static int scc_net_set_mac_address(struct net_device *dev, void *addr); 215 216 static struct net_device_stats * scc_net_get_stats(struct net_device *dev); 216 217 ··· 1551 1550 .ndo_start_xmit = scc_net_tx, 1552 1551 .ndo_set_mac_address = scc_net_set_mac_address, 1553 1552 .ndo_get_stats = scc_net_get_stats, 1554 - .ndo_do_ioctl = scc_net_ioctl, 1553 + .ndo_siocdevprivate = scc_net_siocdevprivate, 1555 1554 }; 1556 1555 1557 1556 /* ----> Initialize device <----- */ ··· 1704 1703 * SIOCSCCCAL - send calib. pattern arg: (struct scc_calibrate *) arg 1705 1704 */ 1706 1705 1707 - static int scc_net_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) 1706 + static int scc_net_siocdevprivate(struct net_device *dev, 1707 + struct ifreq *ifr, void __user *arg, int cmd) 1708 1708 { 1709 1709 struct scc_kiss_cmd kiss_cmd; 1710 1710 struct scc_mem_config memcfg; ··· 1714 1712 struct scc_channel *scc = (struct scc_channel *) dev->ml_priv; 1715 1713 int chan; 1716 1714 unsigned char device_name[IFNAMSIZ]; 1717 - void __user *arg = ifr->ifr_data; 1718 - 1719 1715 1720 1716 if (!Driver_Initialized) 1721 1717 { ··· 1722 1722 int found = 1; 1723 1723 1724 1724 if (!capable(CAP_SYS_RAWIO)) return -EPERM; 1725 + if (in_compat_syscall()) 1726 + return -EOPNOTSUPP; 1727 + 1725 1728 if (!arg) return -EFAULT; 1726 1729 1727 1730 if (Nchips >= SCC_MAXCHIPS)
+9 -10
drivers/net/hamradio/yam.c
··· 920 920 921 921 /* --------------------------------------------------------------------- */ 922 922 923 - static int yam_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) 923 + static int yam_siocdevprivate(struct net_device *dev, struct ifreq *ifr, void __user *data, int cmd) 924 924 { 925 925 struct yam_port *yp = netdev_priv(dev); 926 926 struct yamdrv_ioctl_cfg yi; 927 927 struct yamdrv_ioctl_mcs *ym; 928 928 int ioctl_cmd; 929 929 930 - if (copy_from_user(&ioctl_cmd, ifr->ifr_data, sizeof(int))) 931 - return -EFAULT; 930 + if (copy_from_user(&ioctl_cmd, data, sizeof(int))) 931 + return -EFAULT; 932 932 933 933 if (yp->magic != YAM_MAGIC) 934 934 return -EINVAL; ··· 947 947 case SIOCYAMSMCS: 948 948 if (netif_running(dev)) 949 949 return -EINVAL; /* Cannot change this parameter when up */ 950 - ym = memdup_user(ifr->ifr_data, 951 - sizeof(struct yamdrv_ioctl_mcs)); 950 + ym = memdup_user(data, sizeof(struct yamdrv_ioctl_mcs)); 952 951 if (IS_ERR(ym)) 953 952 return PTR_ERR(ym); 954 953 if (ym->cmd != SIOCYAMSMCS) ··· 964 965 case SIOCYAMSCFG: 965 966 if (!capable(CAP_SYS_RAWIO)) 966 967 return -EPERM; 967 - if (copy_from_user(&yi, ifr->ifr_data, sizeof(struct yamdrv_ioctl_cfg))) 968 - return -EFAULT; 968 + if (copy_from_user(&yi, data, sizeof(struct yamdrv_ioctl_cfg))) 969 + return -EFAULT; 969 970 970 971 if (yi.cmd != SIOCYAMSCFG) 971 972 return -EINVAL; ··· 1044 1045 yi.cfg.txtail = yp->txtail; 1045 1046 yi.cfg.persist = yp->pers; 1046 1047 yi.cfg.slottime = yp->slot; 1047 - if (copy_to_user(ifr->ifr_data, &yi, sizeof(struct yamdrv_ioctl_cfg))) 1048 - return -EFAULT; 1048 + if (copy_to_user(data, &yi, sizeof(struct yamdrv_ioctl_cfg))) 1049 + return -EFAULT; 1049 1050 break; 1050 1051 1051 1052 default: ··· 1073 1074 .ndo_open = yam_open, 1074 1075 .ndo_stop = yam_close, 1075 1076 .ndo_start_xmit = yam_send_packet, 1076 - .ndo_do_ioctl = yam_ioctl, 1077 + .ndo_siocdevprivate = yam_siocdevprivate, 1077 1078 .ndo_set_mac_address = yam_set_mac_address, 1078 1079 }; 1079 1080
+1 -1
include/linux/hdlcdrv.h
··· 79 79 */ 80 80 int (*open)(struct net_device *); 81 81 int (*close)(struct net_device *); 82 - int (*ioctl)(struct net_device *, struct ifreq *, 82 + int (*ioctl)(struct net_device *, void __user *, 83 83 struct hdlcdrv_ioctl *, int); 84 84 }; 85 85