mirror of
https://github.com/tbsdtv/linux_media.git
synced 2025-07-23 04:33:26 +02:00
Merge tag 'net-next-5.15' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next
Pull networking updates from Jakub Kicinski: "Core: - Enable memcg accounting for various networking objects. BPF: - Introduce bpf timers. - Add perf link and opaque bpf_cookie which the program can read out again, to be used in libbpf-based USDT library. - Add bpf_task_pt_regs() helper to access user space pt_regs in kprobes, to help user space stack unwinding. - Add support for UNIX sockets for BPF sockmap. - Extend BPF iterator support for UNIX domain sockets. - Allow BPF TCP congestion control progs and bpf iterators to call bpf_setsockopt(), e.g. to switch to another congestion control algorithm. Protocols: - Support IOAM Pre-allocated Trace with IPv6. - Support Management Component Transport Protocol. - bridge: multicast: add vlan support. - netfilter: add hooks for the SRv6 lightweight tunnel driver. - tcp: - enable mid-stream window clamping (by user space or BPF) - allow data-less, empty-cookie SYN with TFO_SERVER_COOKIE_NOT_REQD - more accurate DSACK processing for RACK-TLP - mptcp: - add full mesh path manager option - add partial support for MP_FAIL - improve use of backup subflows - optimize option processing - af_unix: add OOB notification support. - ipv6: add IFLA_INET6_RA_MTU to expose MTU value advertised by the router. - mac80211: Target Wake Time support in AP mode. - can: j1939: extend UAPI to notify about RX status. Driver APIs: - Add page frag support in page pool API. - Many improvements to the DSA (distributed switch) APIs. - ethtool: extend IRQ coalesce uAPI with timer reset modes. - devlink: control which auxiliary devices are created. - Support CAN PHYs via the generic PHY subsystem. - Proper cross-chip support for tag_8021q. - Allow TX forwarding for the software bridge data path to be offloaded to capable devices. Drivers: - veth: more flexible channels number configuration. - openvswitch: introduce per-cpu upcall dispatch. - Add internet mix (IMIX) mode to pktgen. - Transparently handle XDP operations in the bonding driver. - Add LiteETH network driver. - Renesas (ravb): - support Gigabit Ethernet IP - NXP Ethernet switch (sja1105): - fast aging support - support for "H" switch topologies - traffic termination for ports under VLAN-aware bridge - Intel 1G Ethernet - support getcrosststamp() with PCIe PTM (Precision Time Measurement) for better time sync - support Credit-Based Shaper (CBS) offload, enabling HW traffic prioritization and bandwidth reservation - Broadcom Ethernet (bnxt) - support pulse-per-second output - support larger Rx rings - Mellanox Ethernet (mlx5) - support ethtool RSS contexts and MQPRIO channel mode - support LAG offload with bridging - support devlink rate limit API - support packet sampling on tunnels - Huawei Ethernet (hns3): - basic devlink support - add extended IRQ coalescing support - report extended link state - Netronome Ethernet (nfp): - add conntrack offload support - Broadcom WiFi (brcmfmac): - add WPA3 Personal with FT to supported cipher suites - support 43752 SDIO device - Intel WiFi (iwlwifi): - support scanning hidden 6GHz networks - support for a new hardware family (Bz) - Xen pv driver: - harden netfront against malicious backends - Qualcomm mobile - ipa: refactor power management and enable automatic suspend - mhi: move MBIM to WWAN subsystem interfaces Refactor: - Ambient BPF run context and cgroup storage cleanup. - Compat rework for ndo_ioctl. Old code removal: - prism54 remove the obsoleted driver, deprecated by the p54 driver. - wan: remove sbni/granch driver" * tag 'net-next-5.15' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next: (1715 commits) net: Add depends on OF_NET for LiteX's LiteETH ipv6: seg6: remove duplicated include net: hns3: remove unnecessary spaces net: hns3: add some required spaces net: hns3: clean up a type mismatch warning net: hns3: refine function hns3_set_default_feature() ipv6: remove duplicated 'net/lwtunnel.h' include net: w5100: check return value after calling platform_get_resource() net/mlxbf_gige: Make use of devm_platform_ioremap_resourcexxx() net: mdio: mscc-miim: Make use of the helper function devm_platform_ioremap_resource() net: mdio-ipq4019: Make use of devm_platform_ioremap_resource() fou: remove sparse errors ipv4: fix endianness issue in inet_rtm_getroute_build_skb() octeontx2-af: Set proper errorcode for IPv4 checksum errors octeontx2-af: Fix static code analyzer reported issues octeontx2-af: Fix mailbox errors in nix_rss_flowkey_cfg octeontx2-af: Fix loop in free and unmap counter af_unix: fix potential NULL deref in unix_dgram_connect() dpaa2-eth: Replace strlcpy with strscpy octeontx2-af: Use NDC TX for transmit packet data ...
This commit is contained in:
386
net/socket.c
386
net/socket.c
@@ -212,6 +212,7 @@ static const char * const pf_family_names[] = {
|
||||
[PF_QIPCRTR] = "PF_QIPCRTR",
|
||||
[PF_SMC] = "PF_SMC",
|
||||
[PF_XDP] = "PF_XDP",
|
||||
[PF_MCTP] = "PF_MCTP",
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -1064,9 +1065,13 @@ static ssize_t sock_write_iter(struct kiocb *iocb, struct iov_iter *from)
|
||||
*/
|
||||
|
||||
static DEFINE_MUTEX(br_ioctl_mutex);
|
||||
static int (*br_ioctl_hook) (struct net *, unsigned int cmd, void __user *arg);
|
||||
static int (*br_ioctl_hook)(struct net *net, struct net_bridge *br,
|
||||
unsigned int cmd, struct ifreq *ifr,
|
||||
void __user *uarg);
|
||||
|
||||
void brioctl_set(int (*hook) (struct net *, unsigned int, void __user *))
|
||||
void brioctl_set(int (*hook)(struct net *net, struct net_bridge *br,
|
||||
unsigned int cmd, struct ifreq *ifr,
|
||||
void __user *uarg))
|
||||
{
|
||||
mutex_lock(&br_ioctl_mutex);
|
||||
br_ioctl_hook = hook;
|
||||
@@ -1074,6 +1079,22 @@ void brioctl_set(int (*hook) (struct net *, unsigned int, void __user *))
|
||||
}
|
||||
EXPORT_SYMBOL(brioctl_set);
|
||||
|
||||
int br_ioctl_call(struct net *net, struct net_bridge *br, unsigned int cmd,
|
||||
struct ifreq *ifr, void __user *uarg)
|
||||
{
|
||||
int err = -ENOPKG;
|
||||
|
||||
if (!br_ioctl_hook)
|
||||
request_module("bridge");
|
||||
|
||||
mutex_lock(&br_ioctl_mutex);
|
||||
if (br_ioctl_hook)
|
||||
err = br_ioctl_hook(net, br, cmd, ifr, uarg);
|
||||
mutex_unlock(&br_ioctl_mutex);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static DEFINE_MUTEX(vlan_ioctl_mutex);
|
||||
static int (*vlan_ioctl_hook) (struct net *, void __user *arg);
|
||||
|
||||
@@ -1088,8 +1109,11 @@ EXPORT_SYMBOL(vlan_ioctl_set);
|
||||
static long sock_do_ioctl(struct net *net, struct socket *sock,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
struct ifreq ifr;
|
||||
bool need_copyout;
|
||||
int err;
|
||||
void __user *argp = (void __user *)arg;
|
||||
void __user *data;
|
||||
|
||||
err = sock->ops->ioctl(sock, cmd, arg);
|
||||
|
||||
@@ -1100,25 +1124,16 @@ static long sock_do_ioctl(struct net *net, struct socket *sock,
|
||||
if (err != -ENOIOCTLCMD)
|
||||
return err;
|
||||
|
||||
if (cmd == SIOCGIFCONF) {
|
||||
struct ifconf ifc;
|
||||
if (copy_from_user(&ifc, argp, sizeof(struct ifconf)))
|
||||
if (!is_socket_ioctl_cmd(cmd))
|
||||
return -ENOTTY;
|
||||
|
||||
if (get_user_ifreq(&ifr, &data, argp))
|
||||
return -EFAULT;
|
||||
err = dev_ioctl(net, cmd, &ifr, data, &need_copyout);
|
||||
if (!err && need_copyout)
|
||||
if (put_user_ifreq(&ifr, argp))
|
||||
return -EFAULT;
|
||||
rtnl_lock();
|
||||
err = dev_ifconf(net, &ifc, sizeof(struct ifreq));
|
||||
rtnl_unlock();
|
||||
if (!err && copy_to_user(argp, &ifc, sizeof(struct ifconf)))
|
||||
err = -EFAULT;
|
||||
} else {
|
||||
struct ifreq ifr;
|
||||
bool need_copyout;
|
||||
if (copy_from_user(&ifr, argp, sizeof(struct ifreq)))
|
||||
return -EFAULT;
|
||||
err = dev_ioctl(net, cmd, &ifr, &need_copyout);
|
||||
if (!err && need_copyout)
|
||||
if (copy_to_user(argp, &ifr, sizeof(struct ifreq)))
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -1140,12 +1155,13 @@ static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg)
|
||||
net = sock_net(sk);
|
||||
if (unlikely(cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15))) {
|
||||
struct ifreq ifr;
|
||||
void __user *data;
|
||||
bool need_copyout;
|
||||
if (copy_from_user(&ifr, argp, sizeof(struct ifreq)))
|
||||
if (get_user_ifreq(&ifr, &data, argp))
|
||||
return -EFAULT;
|
||||
err = dev_ioctl(net, cmd, &ifr, &need_copyout);
|
||||
err = dev_ioctl(net, cmd, &ifr, data, &need_copyout);
|
||||
if (!err && need_copyout)
|
||||
if (copy_to_user(argp, &ifr, sizeof(struct ifreq)))
|
||||
if (put_user_ifreq(&ifr, argp))
|
||||
return -EFAULT;
|
||||
} else
|
||||
#ifdef CONFIG_WEXT_CORE
|
||||
@@ -1170,14 +1186,7 @@ static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg)
|
||||
case SIOCSIFBR:
|
||||
case SIOCBRADDBR:
|
||||
case SIOCBRDELBR:
|
||||
err = -ENOPKG;
|
||||
if (!br_ioctl_hook)
|
||||
request_module("bridge");
|
||||
|
||||
mutex_lock(&br_ioctl_mutex);
|
||||
if (br_ioctl_hook)
|
||||
err = br_ioctl_hook(net, cmd, argp);
|
||||
mutex_unlock(&br_ioctl_mutex);
|
||||
err = br_ioctl_call(net, NULL, cmd, NULL, argp);
|
||||
break;
|
||||
case SIOCGIFVLAN:
|
||||
case SIOCSIFVLAN:
|
||||
@@ -1217,6 +1226,11 @@ static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg)
|
||||
cmd == SIOCGSTAMP_NEW,
|
||||
false);
|
||||
break;
|
||||
|
||||
case SIOCGIFCONF:
|
||||
err = dev_ifconf(net, argp);
|
||||
break;
|
||||
|
||||
default:
|
||||
err = sock_do_ioctl(net, sock, cmd, arg);
|
||||
break;
|
||||
@@ -3129,154 +3143,55 @@ void socket_seq_show(struct seq_file *seq)
|
||||
}
|
||||
#endif /* CONFIG_PROC_FS */
|
||||
|
||||
/* Handle the fact that while struct ifreq has the same *layout* on
|
||||
* 32/64 for everything but ifreq::ifru_ifmap and ifreq::ifru_data,
|
||||
* which are handled elsewhere, it still has different *size* due to
|
||||
* ifreq::ifru_ifmap (which is 16 bytes on 32 bit, 24 bytes on 64-bit,
|
||||
* resulting in struct ifreq being 32 and 40 bytes respectively).
|
||||
* As a result, if the struct happens to be at the end of a page and
|
||||
* the next page isn't readable/writable, we get a fault. To prevent
|
||||
* that, copy back and forth to the full size.
|
||||
*/
|
||||
int get_user_ifreq(struct ifreq *ifr, void __user **ifrdata, void __user *arg)
|
||||
{
|
||||
if (in_compat_syscall()) {
|
||||
struct compat_ifreq *ifr32 = (struct compat_ifreq *)ifr;
|
||||
|
||||
memset(ifr, 0, sizeof(*ifr));
|
||||
if (copy_from_user(ifr32, arg, sizeof(*ifr32)))
|
||||
return -EFAULT;
|
||||
|
||||
if (ifrdata)
|
||||
*ifrdata = compat_ptr(ifr32->ifr_data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (copy_from_user(ifr, arg, sizeof(*ifr)))
|
||||
return -EFAULT;
|
||||
|
||||
if (ifrdata)
|
||||
*ifrdata = ifr->ifr_data;
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(get_user_ifreq);
|
||||
|
||||
int put_user_ifreq(struct ifreq *ifr, void __user *arg)
|
||||
{
|
||||
size_t size = sizeof(*ifr);
|
||||
|
||||
if (in_compat_syscall())
|
||||
size = sizeof(struct compat_ifreq);
|
||||
|
||||
if (copy_to_user(arg, ifr, size))
|
||||
return -EFAULT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(put_user_ifreq);
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
static int compat_dev_ifconf(struct net *net, struct compat_ifconf __user *uifc32)
|
||||
{
|
||||
struct compat_ifconf ifc32;
|
||||
struct ifconf ifc;
|
||||
int err;
|
||||
|
||||
if (copy_from_user(&ifc32, uifc32, sizeof(struct compat_ifconf)))
|
||||
return -EFAULT;
|
||||
|
||||
ifc.ifc_len = ifc32.ifc_len;
|
||||
ifc.ifc_req = compat_ptr(ifc32.ifcbuf);
|
||||
|
||||
rtnl_lock();
|
||||
err = dev_ifconf(net, &ifc, sizeof(struct compat_ifreq));
|
||||
rtnl_unlock();
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
ifc32.ifc_len = ifc.ifc_len;
|
||||
if (copy_to_user(uifc32, &ifc32, sizeof(struct compat_ifconf)))
|
||||
return -EFAULT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ethtool_ioctl(struct net *net, struct compat_ifreq __user *ifr32)
|
||||
{
|
||||
struct compat_ethtool_rxnfc __user *compat_rxnfc;
|
||||
bool convert_in = false, convert_out = false;
|
||||
size_t buf_size = 0;
|
||||
struct ethtool_rxnfc __user *rxnfc = NULL;
|
||||
struct ifreq ifr;
|
||||
u32 rule_cnt = 0, actual_rule_cnt;
|
||||
u32 ethcmd;
|
||||
u32 data;
|
||||
int ret;
|
||||
|
||||
if (get_user(data, &ifr32->ifr_ifru.ifru_data))
|
||||
return -EFAULT;
|
||||
|
||||
compat_rxnfc = compat_ptr(data);
|
||||
|
||||
if (get_user(ethcmd, &compat_rxnfc->cmd))
|
||||
return -EFAULT;
|
||||
|
||||
/* Most ethtool structures are defined without padding.
|
||||
* Unfortunately struct ethtool_rxnfc is an exception.
|
||||
*/
|
||||
switch (ethcmd) {
|
||||
default:
|
||||
break;
|
||||
case ETHTOOL_GRXCLSRLALL:
|
||||
/* Buffer size is variable */
|
||||
if (get_user(rule_cnt, &compat_rxnfc->rule_cnt))
|
||||
return -EFAULT;
|
||||
if (rule_cnt > KMALLOC_MAX_SIZE / sizeof(u32))
|
||||
return -ENOMEM;
|
||||
buf_size += rule_cnt * sizeof(u32);
|
||||
fallthrough;
|
||||
case ETHTOOL_GRXRINGS:
|
||||
case ETHTOOL_GRXCLSRLCNT:
|
||||
case ETHTOOL_GRXCLSRULE:
|
||||
case ETHTOOL_SRXCLSRLINS:
|
||||
convert_out = true;
|
||||
fallthrough;
|
||||
case ETHTOOL_SRXCLSRLDEL:
|
||||
buf_size += sizeof(struct ethtool_rxnfc);
|
||||
convert_in = true;
|
||||
rxnfc = compat_alloc_user_space(buf_size);
|
||||
break;
|
||||
}
|
||||
|
||||
if (copy_from_user(&ifr.ifr_name, &ifr32->ifr_name, IFNAMSIZ))
|
||||
return -EFAULT;
|
||||
|
||||
ifr.ifr_data = convert_in ? rxnfc : (void __user *)compat_rxnfc;
|
||||
|
||||
if (convert_in) {
|
||||
/* We expect there to be holes between fs.m_ext and
|
||||
* fs.ring_cookie and at the end of fs, but nowhere else.
|
||||
*/
|
||||
BUILD_BUG_ON(offsetof(struct compat_ethtool_rxnfc, fs.m_ext) +
|
||||
sizeof(compat_rxnfc->fs.m_ext) !=
|
||||
offsetof(struct ethtool_rxnfc, fs.m_ext) +
|
||||
sizeof(rxnfc->fs.m_ext));
|
||||
BUILD_BUG_ON(
|
||||
offsetof(struct compat_ethtool_rxnfc, fs.location) -
|
||||
offsetof(struct compat_ethtool_rxnfc, fs.ring_cookie) !=
|
||||
offsetof(struct ethtool_rxnfc, fs.location) -
|
||||
offsetof(struct ethtool_rxnfc, fs.ring_cookie));
|
||||
|
||||
if (copy_in_user(rxnfc, compat_rxnfc,
|
||||
(void __user *)(&rxnfc->fs.m_ext + 1) -
|
||||
(void __user *)rxnfc) ||
|
||||
copy_in_user(&rxnfc->fs.ring_cookie,
|
||||
&compat_rxnfc->fs.ring_cookie,
|
||||
(void __user *)(&rxnfc->fs.location + 1) -
|
||||
(void __user *)&rxnfc->fs.ring_cookie))
|
||||
return -EFAULT;
|
||||
if (ethcmd == ETHTOOL_GRXCLSRLALL) {
|
||||
if (put_user(rule_cnt, &rxnfc->rule_cnt))
|
||||
return -EFAULT;
|
||||
} else if (copy_in_user(&rxnfc->rule_cnt,
|
||||
&compat_rxnfc->rule_cnt,
|
||||
sizeof(rxnfc->rule_cnt)))
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
ret = dev_ioctl(net, SIOCETHTOOL, &ifr, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (convert_out) {
|
||||
if (copy_in_user(compat_rxnfc, rxnfc,
|
||||
(const void __user *)(&rxnfc->fs.m_ext + 1) -
|
||||
(const void __user *)rxnfc) ||
|
||||
copy_in_user(&compat_rxnfc->fs.ring_cookie,
|
||||
&rxnfc->fs.ring_cookie,
|
||||
(const void __user *)(&rxnfc->fs.location + 1) -
|
||||
(const void __user *)&rxnfc->fs.ring_cookie) ||
|
||||
copy_in_user(&compat_rxnfc->rule_cnt, &rxnfc->rule_cnt,
|
||||
sizeof(rxnfc->rule_cnt)))
|
||||
return -EFAULT;
|
||||
|
||||
if (ethcmd == ETHTOOL_GRXCLSRLALL) {
|
||||
/* As an optimisation, we only copy the actual
|
||||
* number of rules that the underlying
|
||||
* function returned. Since Mallory might
|
||||
* change the rule count in user memory, we
|
||||
* check that it is less than the rule count
|
||||
* originally given (as the user buffer size),
|
||||
* which has been range-checked.
|
||||
*/
|
||||
if (get_user(actual_rule_cnt, &rxnfc->rule_cnt))
|
||||
return -EFAULT;
|
||||
if (actual_rule_cnt < rule_cnt)
|
||||
rule_cnt = actual_rule_cnt;
|
||||
if (copy_in_user(&compat_rxnfc->rule_locs[0],
|
||||
&rxnfc->rule_locs[0],
|
||||
rule_cnt * sizeof(u32)))
|
||||
return -EFAULT;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int compat_siocwandev(struct net *net, struct compat_ifreq __user *uifr32)
|
||||
{
|
||||
compat_uptr_t uptr32;
|
||||
@@ -3284,7 +3199,7 @@ static int compat_siocwandev(struct net *net, struct compat_ifreq __user *uifr32
|
||||
void __user *saved;
|
||||
int err;
|
||||
|
||||
if (copy_from_user(&ifr, uifr32, sizeof(struct compat_ifreq)))
|
||||
if (get_user_ifreq(&ifr, NULL, uifr32))
|
||||
return -EFAULT;
|
||||
|
||||
if (get_user(uptr32, &uifr32->ifr_settings.ifs_ifsu))
|
||||
@@ -3293,10 +3208,10 @@ static int compat_siocwandev(struct net *net, struct compat_ifreq __user *uifr32
|
||||
saved = ifr.ifr_settings.ifs_ifsu.raw_hdlc;
|
||||
ifr.ifr_settings.ifs_ifsu.raw_hdlc = compat_ptr(uptr32);
|
||||
|
||||
err = dev_ioctl(net, SIOCWANDEV, &ifr, NULL);
|
||||
err = dev_ioctl(net, SIOCWANDEV, &ifr, NULL, NULL);
|
||||
if (!err) {
|
||||
ifr.ifr_settings.ifs_ifsu.raw_hdlc = saved;
|
||||
if (copy_to_user(uifr32, &ifr, sizeof(struct compat_ifreq)))
|
||||
if (put_user_ifreq(&ifr, uifr32))
|
||||
err = -EFAULT;
|
||||
}
|
||||
return err;
|
||||
@@ -3307,97 +3222,15 @@ static int compat_ifr_data_ioctl(struct net *net, unsigned int cmd,
|
||||
struct compat_ifreq __user *u_ifreq32)
|
||||
{
|
||||
struct ifreq ifreq;
|
||||
u32 data32;
|
||||
void __user *data;
|
||||
|
||||
if (copy_from_user(ifreq.ifr_name, u_ifreq32->ifr_name, IFNAMSIZ))
|
||||
if (!is_socket_ioctl_cmd(cmd))
|
||||
return -ENOTTY;
|
||||
if (get_user_ifreq(&ifreq, &data, u_ifreq32))
|
||||
return -EFAULT;
|
||||
if (get_user(data32, &u_ifreq32->ifr_data))
|
||||
return -EFAULT;
|
||||
ifreq.ifr_data = compat_ptr(data32);
|
||||
ifreq.ifr_data = data;
|
||||
|
||||
return dev_ioctl(net, cmd, &ifreq, NULL);
|
||||
}
|
||||
|
||||
static int compat_ifreq_ioctl(struct net *net, struct socket *sock,
|
||||
unsigned int cmd,
|
||||
struct compat_ifreq __user *uifr32)
|
||||
{
|
||||
struct ifreq __user *uifr;
|
||||
int err;
|
||||
|
||||
/* Handle the fact that while struct ifreq has the same *layout* on
|
||||
* 32/64 for everything but ifreq::ifru_ifmap and ifreq::ifru_data,
|
||||
* which are handled elsewhere, it still has different *size* due to
|
||||
* ifreq::ifru_ifmap (which is 16 bytes on 32 bit, 24 bytes on 64-bit,
|
||||
* resulting in struct ifreq being 32 and 40 bytes respectively).
|
||||
* As a result, if the struct happens to be at the end of a page and
|
||||
* the next page isn't readable/writable, we get a fault. To prevent
|
||||
* that, copy back and forth to the full size.
|
||||
*/
|
||||
|
||||
uifr = compat_alloc_user_space(sizeof(*uifr));
|
||||
if (copy_in_user(uifr, uifr32, sizeof(*uifr32)))
|
||||
return -EFAULT;
|
||||
|
||||
err = sock_do_ioctl(net, sock, cmd, (unsigned long)uifr);
|
||||
|
||||
if (!err) {
|
||||
switch (cmd) {
|
||||
case SIOCGIFFLAGS:
|
||||
case SIOCGIFMETRIC:
|
||||
case SIOCGIFMTU:
|
||||
case SIOCGIFMEM:
|
||||
case SIOCGIFHWADDR:
|
||||
case SIOCGIFINDEX:
|
||||
case SIOCGIFADDR:
|
||||
case SIOCGIFBRDADDR:
|
||||
case SIOCGIFDSTADDR:
|
||||
case SIOCGIFNETMASK:
|
||||
case SIOCGIFPFLAGS:
|
||||
case SIOCGIFTXQLEN:
|
||||
case SIOCGMIIPHY:
|
||||
case SIOCGMIIREG:
|
||||
case SIOCGIFNAME:
|
||||
if (copy_in_user(uifr32, uifr, sizeof(*uifr32)))
|
||||
err = -EFAULT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
static int compat_sioc_ifmap(struct net *net, unsigned int cmd,
|
||||
struct compat_ifreq __user *uifr32)
|
||||
{
|
||||
struct ifreq ifr;
|
||||
struct compat_ifmap __user *uifmap32;
|
||||
int err;
|
||||
|
||||
uifmap32 = &uifr32->ifr_ifru.ifru_map;
|
||||
err = copy_from_user(&ifr, uifr32, sizeof(ifr.ifr_name));
|
||||
err |= get_user(ifr.ifr_map.mem_start, &uifmap32->mem_start);
|
||||
err |= get_user(ifr.ifr_map.mem_end, &uifmap32->mem_end);
|
||||
err |= get_user(ifr.ifr_map.base_addr, &uifmap32->base_addr);
|
||||
err |= get_user(ifr.ifr_map.irq, &uifmap32->irq);
|
||||
err |= get_user(ifr.ifr_map.dma, &uifmap32->dma);
|
||||
err |= get_user(ifr.ifr_map.port, &uifmap32->port);
|
||||
if (err)
|
||||
return -EFAULT;
|
||||
|
||||
err = dev_ioctl(net, cmd, &ifr, NULL);
|
||||
|
||||
if (cmd == SIOCGIFMAP && !err) {
|
||||
err = copy_to_user(uifr32, &ifr, sizeof(ifr.ifr_name));
|
||||
err |= put_user(ifr.ifr_map.mem_start, &uifmap32->mem_start);
|
||||
err |= put_user(ifr.ifr_map.mem_end, &uifmap32->mem_end);
|
||||
err |= put_user(ifr.ifr_map.base_addr, &uifmap32->base_addr);
|
||||
err |= put_user(ifr.ifr_map.irq, &uifmap32->irq);
|
||||
err |= put_user(ifr.ifr_map.dma, &uifmap32->dma);
|
||||
err |= put_user(ifr.ifr_map.port, &uifmap32->port);
|
||||
if (err)
|
||||
err = -EFAULT;
|
||||
}
|
||||
return err;
|
||||
return dev_ioctl(net, cmd, &ifreq, data, NULL);
|
||||
}
|
||||
|
||||
/* Since old style bridge ioctl's endup using SIOCDEVPRIVATE
|
||||
@@ -3423,21 +3256,14 @@ static int compat_sock_ioctl_trans(struct file *file, struct socket *sock,
|
||||
struct net *net = sock_net(sk);
|
||||
|
||||
if (cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15))
|
||||
return compat_ifr_data_ioctl(net, cmd, argp);
|
||||
return sock_ioctl(file, cmd, (unsigned long)argp);
|
||||
|
||||
switch (cmd) {
|
||||
case SIOCSIFBR:
|
||||
case SIOCGIFBR:
|
||||
return old_bridge_ioctl(argp);
|
||||
case SIOCGIFCONF:
|
||||
return compat_dev_ifconf(net, argp);
|
||||
case SIOCETHTOOL:
|
||||
return ethtool_ioctl(net, argp);
|
||||
case SIOCWANDEV:
|
||||
return compat_siocwandev(net, argp);
|
||||
case SIOCGIFMAP:
|
||||
case SIOCSIFMAP:
|
||||
return compat_sioc_ifmap(net, cmd, argp);
|
||||
case SIOCGSTAMP_OLD:
|
||||
case SIOCGSTAMPNS_OLD:
|
||||
if (!sock->ops->gettstamp)
|
||||
@@ -3445,6 +3271,7 @@ static int compat_sock_ioctl_trans(struct file *file, struct socket *sock,
|
||||
return sock->ops->gettstamp(sock, argp, cmd == SIOCGSTAMP_OLD,
|
||||
!COMPAT_USE_64BIT_TIME);
|
||||
|
||||
case SIOCETHTOOL:
|
||||
case SIOCBONDSLAVEINFOQUERY:
|
||||
case SIOCBONDINFOQUERY:
|
||||
case SIOCSHWTSTAMP:
|
||||
@@ -3462,10 +3289,13 @@ static int compat_sock_ioctl_trans(struct file *file, struct socket *sock,
|
||||
case SIOCGSKNS:
|
||||
case SIOCGSTAMP_NEW:
|
||||
case SIOCGSTAMPNS_NEW:
|
||||
case SIOCGIFCONF:
|
||||
return sock_ioctl(file, cmd, arg);
|
||||
|
||||
case SIOCGIFFLAGS:
|
||||
case SIOCSIFFLAGS:
|
||||
case SIOCGIFMAP:
|
||||
case SIOCSIFMAP:
|
||||
case SIOCGIFMETRIC:
|
||||
case SIOCSIFMETRIC:
|
||||
case SIOCGIFMTU:
|
||||
@@ -3502,8 +3332,6 @@ static int compat_sock_ioctl_trans(struct file *file, struct socket *sock,
|
||||
case SIOCBONDRELEASE:
|
||||
case SIOCBONDSETHWADDR:
|
||||
case SIOCBONDCHANGEACTIVE:
|
||||
return compat_ifreq_ioctl(net, sock, cmd, argp);
|
||||
|
||||
case SIOCSARP:
|
||||
case SIOCGARP:
|
||||
case SIOCDARP:
|
||||
|
Reference in New Issue
Block a user