Skip to content

Commit

Permalink
hamradio: use ndo_siocdevprivate
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Arnd Bergmann authored and David S. Miller committed Jul 27, 2021
1 parent ebb4a91 commit 25ec92f
Show file tree
Hide file tree
Showing 10 changed files with 65 additions and 61 deletions.
9 changes: 5 additions & 4 deletions drivers/net/hamradio/baycom_epp.c
Original file line number Diff line number Diff line change
Expand Up @@ -1005,15 +1005,16 @@ static int baycom_setmode(struct baycom_state *bc, const char *modestr)

/* --------------------------------------------------------------------- */

static int baycom_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
static int baycom_siocdevprivate(struct net_device *dev, struct ifreq *ifr,
void __user *data, int cmd)
{
struct baycom_state *bc = netdev_priv(dev);
struct hdlcdrv_ioctl hi;

if (cmd != SIOCDEVPRIVATE)
return -ENOIOCTLCMD;

if (copy_from_user(&hi, ifr->ifr_data, sizeof(hi)))
if (copy_from_user(&hi, data, sizeof(hi)))
return -EFAULT;
switch (hi.cmd) {
default:
Expand Down Expand Up @@ -1104,7 +1105,7 @@ static int baycom_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
return HDLCDRV_PARMASK_IOBASE;

}
if (copy_to_user(ifr->ifr_data, &hi, sizeof(hi)))
if (copy_to_user(data, &hi, sizeof(hi)))
return -EFAULT;
return 0;
}
Expand All @@ -1114,7 +1115,7 @@ static int baycom_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
static const struct net_device_ops baycom_netdev_ops = {
.ndo_open = epp_open,
.ndo_stop = epp_close,
.ndo_do_ioctl = baycom_ioctl,
.ndo_siocdevprivate = baycom_siocdevprivate,
.ndo_start_xmit = baycom_send_packet,
.ndo_set_mac_address = baycom_set_mac_address,
};
Expand Down
12 changes: 6 additions & 6 deletions drivers/net/hamradio/baycom_par.c
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,7 @@ static int par96_close(struct net_device *dev)
* ===================== hdlcdrv driver interface =========================
*/

static int baycom_ioctl(struct net_device *dev, struct ifreq *ifr,
static int baycom_ioctl(struct net_device *dev, void __user *data,
struct hdlcdrv_ioctl *hi, int cmd);

/* --------------------------------------------------------------------- */
Expand Down Expand Up @@ -408,7 +408,7 @@ static int baycom_setmode(struct baycom_state *bc, const char *modestr)

/* --------------------------------------------------------------------- */

static int baycom_ioctl(struct net_device *dev, struct ifreq *ifr,
static int baycom_ioctl(struct net_device *dev, void __user *data,
struct hdlcdrv_ioctl *hi, int cmd)
{
struct baycom_state *bc;
Expand All @@ -428,7 +428,7 @@ static int baycom_ioctl(struct net_device *dev, struct ifreq *ifr,

case HDLCDRVCTL_GETMODE:
strcpy(hi->data.modename, bc->options ? "par96" : "picpar");
if (copy_to_user(ifr->ifr_data, hi, sizeof(struct hdlcdrv_ioctl)))
if (copy_to_user(data, hi, sizeof(struct hdlcdrv_ioctl)))
return -EFAULT;
return 0;

Expand All @@ -440,7 +440,7 @@ static int baycom_ioctl(struct net_device *dev, struct ifreq *ifr,

case HDLCDRVCTL_MODELIST:
strcpy(hi->data.modename, "par96,picpar");
if (copy_to_user(ifr->ifr_data, hi, sizeof(struct hdlcdrv_ioctl)))
if (copy_to_user(data, hi, sizeof(struct hdlcdrv_ioctl)))
return -EFAULT;
return 0;

Expand All @@ -449,7 +449,7 @@ static int baycom_ioctl(struct net_device *dev, struct ifreq *ifr,

}

if (copy_from_user(&bi, ifr->ifr_data, sizeof(bi)))
if (copy_from_user(&bi, data, sizeof(bi)))
return -EFAULT;
switch (bi.cmd) {
default:
Expand All @@ -464,7 +464,7 @@ static int baycom_ioctl(struct net_device *dev, struct ifreq *ifr,
#endif /* BAYCOM_DEBUG */

}
if (copy_to_user(ifr->ifr_data, &bi, sizeof(bi)))
if (copy_to_user(data, &bi, sizeof(bi)))
return -EFAULT;
return 0;

Expand Down
12 changes: 6 additions & 6 deletions drivers/net/hamradio/baycom_ser_fdx.c
Original file line number Diff line number Diff line change
Expand Up @@ -462,7 +462,7 @@ static int ser12_close(struct net_device *dev)

/* --------------------------------------------------------------------- */

static int baycom_ioctl(struct net_device *dev, struct ifreq *ifr,
static int baycom_ioctl(struct net_device *dev, void __user *data,
struct hdlcdrv_ioctl *hi, int cmd);

/* --------------------------------------------------------------------- */
Expand Down Expand Up @@ -497,7 +497,7 @@ static int baycom_setmode(struct baycom_state *bc, const char *modestr)

/* --------------------------------------------------------------------- */

static int baycom_ioctl(struct net_device *dev, struct ifreq *ifr,
static int baycom_ioctl(struct net_device *dev, void __user *data,
struct hdlcdrv_ioctl *hi, int cmd)
{
struct baycom_state *bc;
Expand All @@ -519,7 +519,7 @@ static int baycom_ioctl(struct net_device *dev, struct ifreq *ifr,
sprintf(hi->data.modename, "ser%u", bc->baud / 100);
if (bc->opt_dcd <= 0)
strcat(hi->data.modename, (!bc->opt_dcd) ? "*" : "+");
if (copy_to_user(ifr->ifr_data, hi, sizeof(struct hdlcdrv_ioctl)))
if (copy_to_user(data, hi, sizeof(struct hdlcdrv_ioctl)))
return -EFAULT;
return 0;

Expand All @@ -531,7 +531,7 @@ static int baycom_ioctl(struct net_device *dev, struct ifreq *ifr,

case HDLCDRVCTL_MODELIST:
strcpy(hi->data.modename, "ser12,ser3,ser24");
if (copy_to_user(ifr->ifr_data, hi, sizeof(struct hdlcdrv_ioctl)))
if (copy_to_user(data, hi, sizeof(struct hdlcdrv_ioctl)))
return -EFAULT;
return 0;

Expand All @@ -540,7 +540,7 @@ static int baycom_ioctl(struct net_device *dev, struct ifreq *ifr,

}

if (copy_from_user(&bi, ifr->ifr_data, sizeof(bi)))
if (copy_from_user(&bi, data, sizeof(bi)))
return -EFAULT;
switch (bi.cmd) {
default:
Expand All @@ -555,7 +555,7 @@ static int baycom_ioctl(struct net_device *dev, struct ifreq *ifr,
#endif /* BAYCOM_DEBUG */

}
if (copy_to_user(ifr->ifr_data, &bi, sizeof(bi)))
if (copy_to_user(data, &bi, sizeof(bi)))
return -EFAULT;
return 0;

Expand Down
12 changes: 6 additions & 6 deletions drivers/net/hamradio/baycom_ser_hdx.c
Original file line number Diff line number Diff line change
Expand Up @@ -521,7 +521,7 @@ static int ser12_close(struct net_device *dev)

/* --------------------------------------------------------------------- */

static int baycom_ioctl(struct net_device *dev, struct ifreq *ifr,
static int baycom_ioctl(struct net_device *dev, void __user *data,
struct hdlcdrv_ioctl *hi, int cmd);

/* --------------------------------------------------------------------- */
Expand Down Expand Up @@ -551,7 +551,7 @@ static int baycom_setmode(struct baycom_state *bc, const char *modestr)

/* --------------------------------------------------------------------- */

static int baycom_ioctl(struct net_device *dev, struct ifreq *ifr,
static int baycom_ioctl(struct net_device *dev, void __user *data,
struct hdlcdrv_ioctl *hi, int cmd)
{
struct baycom_state *bc;
Expand All @@ -573,7 +573,7 @@ static int baycom_ioctl(struct net_device *dev, struct ifreq *ifr,
strcpy(hi->data.modename, "ser12");
if (bc->opt_dcd <= 0)
strcat(hi->data.modename, (!bc->opt_dcd) ? "*" : (bc->opt_dcd == -2) ? "@" : "+");
if (copy_to_user(ifr->ifr_data, hi, sizeof(struct hdlcdrv_ioctl)))
if (copy_to_user(data, hi, sizeof(struct hdlcdrv_ioctl)))
return -EFAULT;
return 0;

Expand All @@ -585,7 +585,7 @@ static int baycom_ioctl(struct net_device *dev, struct ifreq *ifr,

case HDLCDRVCTL_MODELIST:
strcpy(hi->data.modename, "ser12");
if (copy_to_user(ifr->ifr_data, hi, sizeof(struct hdlcdrv_ioctl)))
if (copy_to_user(data, hi, sizeof(struct hdlcdrv_ioctl)))
return -EFAULT;
return 0;

Expand All @@ -594,7 +594,7 @@ static int baycom_ioctl(struct net_device *dev, struct ifreq *ifr,

}

if (copy_from_user(&bi, ifr->ifr_data, sizeof(bi)))
if (copy_from_user(&bi, data, sizeof(bi)))
return -EFAULT;
switch (bi.cmd) {
default:
Expand All @@ -609,7 +609,7 @@ static int baycom_ioctl(struct net_device *dev, struct ifreq *ifr,
#endif /* BAYCOM_DEBUG */

}
if (copy_to_user(ifr->ifr_data, &bi, sizeof(bi)))
if (copy_to_user(data, &bi, sizeof(bi)))
return -EFAULT;
return 0;

Expand Down
9 changes: 5 additions & 4 deletions drivers/net/hamradio/bpqether.c
Original file line number Diff line number Diff line change
Expand Up @@ -314,9 +314,10 @@ static int bpq_set_mac_address(struct net_device *dev, void *addr)
* source ethernet address (broadcast
* or multicast: accept all)
*/
static int bpq_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
static int bpq_siocdevprivate(struct net_device *dev, struct ifreq *ifr,
void __user *data, int cmd)
{
struct bpq_ethaddr __user *ethaddr = ifr->ifr_data;
struct bpq_ethaddr __user *ethaddr = data;
struct bpqdev *bpq = netdev_priv(dev);
struct bpq_req req;

Expand All @@ -325,7 +326,7 @@ static int bpq_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)

switch (cmd) {
case SIOCSBPQETHOPT:
if (copy_from_user(&req, ifr->ifr_data, sizeof(struct bpq_req)))
if (copy_from_user(&req, data, sizeof(struct bpq_req)))
return -EFAULT;
switch (req.cmd) {
case SIOCGBPQETHPARAM:
Expand Down Expand Up @@ -448,7 +449,7 @@ static const struct net_device_ops bpq_netdev_ops = {
.ndo_stop = bpq_close,
.ndo_start_xmit = bpq_xmit,
.ndo_set_mac_address = bpq_set_mac_address,
.ndo_do_ioctl = bpq_ioctl,
.ndo_siocdevprivate = bpq_siocdevprivate,
};

static void bpq_setup(struct net_device *dev)
Expand Down
18 changes: 8 additions & 10 deletions drivers/net/hamradio/dmascc.c
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,8 @@ static int read_scc_data(struct scc_priv *priv);

static int scc_open(struct net_device *dev);
static int scc_close(struct net_device *dev);
static int scc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);
static int scc_siocdevprivate(struct net_device *dev, struct ifreq *ifr,
void __user *data, int cmd);
static int scc_send_packet(struct sk_buff *skb, struct net_device *dev);
static int scc_set_mac_address(struct net_device *dev, void *sa);

Expand Down Expand Up @@ -432,7 +433,7 @@ static const struct net_device_ops scc_netdev_ops = {
.ndo_open = scc_open,
.ndo_stop = scc_close,
.ndo_start_xmit = scc_send_packet,
.ndo_do_ioctl = scc_ioctl,
.ndo_siocdevprivate = scc_siocdevprivate,
.ndo_set_mac_address = scc_set_mac_address,
};

Expand Down Expand Up @@ -881,29 +882,26 @@ static int scc_close(struct net_device *dev)
}


static int scc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
static int scc_siocdevprivate(struct net_device *dev, struct ifreq *ifr, void __user *data, int cmd)
{
struct scc_priv *priv = dev->ml_priv;

switch (cmd) {
case SIOCGSCCPARAM:
if (copy_to_user
(ifr->ifr_data, &priv->param,
sizeof(struct scc_param)))
if (copy_to_user(data, &priv->param, sizeof(struct scc_param)))
return -EFAULT;
return 0;
case SIOCSSCCPARAM:
if (!capable(CAP_NET_ADMIN))
return -EPERM;
if (netif_running(dev))
return -EAGAIN;
if (copy_from_user
(&priv->param, ifr->ifr_data,
sizeof(struct scc_param)))
if (copy_from_user(&priv->param, data,
sizeof(struct scc_param)))
return -EFAULT;
return 0;
default:
return -EINVAL;
return -EOPNOTSUPP;
}
}

Expand Down
20 changes: 11 additions & 9 deletions drivers/net/hamradio/hdlcdrv.c
Original file line number Diff line number Diff line change
Expand Up @@ -483,23 +483,25 @@ static int hdlcdrv_close(struct net_device *dev)

/* --------------------------------------------------------------------- */

static int hdlcdrv_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
static int hdlcdrv_siocdevprivate(struct net_device *dev, struct ifreq *ifr,
void __user *data, int cmd)
{
struct hdlcdrv_state *s = netdev_priv(dev);
struct hdlcdrv_ioctl bi;

if (cmd != SIOCDEVPRIVATE) {
if (s->ops && s->ops->ioctl)
return s->ops->ioctl(dev, ifr, &bi, cmd);
if (cmd != SIOCDEVPRIVATE)
return -ENOIOCTLCMD;
}
if (copy_from_user(&bi, ifr->ifr_data, sizeof(bi)))

if (in_compat_syscall()) /* to be implemented */
return -ENOIOCTLCMD;

if (copy_from_user(&bi, data, sizeof(bi)))
return -EFAULT;

switch (bi.cmd) {
default:
if (s->ops && s->ops->ioctl)
return s->ops->ioctl(dev, ifr, &bi, cmd);
return s->ops->ioctl(dev, data, &bi, cmd);
return -ENOIOCTLCMD;

case HDLCDRVCTL_GETCHANNELPAR:
Expand Down Expand Up @@ -605,7 +607,7 @@ static int hdlcdrv_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
break;

}
if (copy_to_user(ifr->ifr_data, &bi, sizeof(bi)))
if (copy_to_user(data, &bi, sizeof(bi)))
return -EFAULT;
return 0;

Expand All @@ -617,7 +619,7 @@ static const struct net_device_ops hdlcdrv_netdev = {
.ndo_open = hdlcdrv_open,
.ndo_stop = hdlcdrv_close,
.ndo_start_xmit = hdlcdrv_send_packet,
.ndo_do_ioctl = hdlcdrv_ioctl,
.ndo_siocdevprivate = hdlcdrv_siocdevprivate,
.ndo_set_mac_address = hdlcdrv_set_mac_address,
};

Expand Down
13 changes: 8 additions & 5 deletions drivers/net/hamradio/scc.c
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,8 @@ static int scc_net_close(struct net_device *dev);
static void scc_net_rx(struct scc_channel *scc, struct sk_buff *skb);
static netdev_tx_t scc_net_tx(struct sk_buff *skb,
struct net_device *dev);
static int scc_net_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);
static int scc_net_siocdevprivate(struct net_device *dev, struct ifreq *ifr,
void __user *data, int cmd);
static int scc_net_set_mac_address(struct net_device *dev, void *addr);
static struct net_device_stats * scc_net_get_stats(struct net_device *dev);

Expand Down Expand Up @@ -1550,7 +1551,7 @@ static const struct net_device_ops scc_netdev_ops = {
.ndo_start_xmit = scc_net_tx,
.ndo_set_mac_address = scc_net_set_mac_address,
.ndo_get_stats = scc_net_get_stats,
.ndo_do_ioctl = scc_net_ioctl,
.ndo_siocdevprivate = scc_net_siocdevprivate,
};

/* ----> Initialize device <----- */
Expand Down Expand Up @@ -1703,7 +1704,8 @@ static netdev_tx_t scc_net_tx(struct sk_buff *skb, struct net_device *dev)
* SIOCSCCCAL - send calib. pattern arg: (struct scc_calibrate *) arg
*/

static int scc_net_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
static int scc_net_siocdevprivate(struct net_device *dev,
struct ifreq *ifr, void __user *arg, int cmd)
{
struct scc_kiss_cmd kiss_cmd;
struct scc_mem_config memcfg;
Expand All @@ -1712,8 +1714,6 @@ static int scc_net_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
struct scc_channel *scc = (struct scc_channel *) dev->ml_priv;
int chan;
unsigned char device_name[IFNAMSIZ];
void __user *arg = ifr->ifr_data;


if (!Driver_Initialized)
{
Expand All @@ -1722,6 +1722,9 @@ static int scc_net_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
int found = 1;

if (!capable(CAP_SYS_RAWIO)) return -EPERM;
if (in_compat_syscall())
return -EOPNOTSUPP;

if (!arg) return -EFAULT;

if (Nchips >= SCC_MAXCHIPS)
Expand Down
Loading

0 comments on commit 25ec92f

Please sign in to comment.