mirror of
https://github.com/Fishwaldo/build.git
synced 2025-03-26 16:51:48 +00:00
953 lines
32 KiB
Diff
953 lines
32 KiB
Diff
diff --git a/Makefile b/Makefile
|
|
index 6dd1ffb..5adfadf 100644
|
|
--- a/Makefile
|
|
+++ b/Makefile
|
|
@@ -1,6 +1,6 @@
|
|
VERSION = 3
|
|
PATCHLEVEL = 4
|
|
-SUBLEVEL = 50
|
|
+SUBLEVEL = 51
|
|
EXTRAVERSION =
|
|
NAME = Saber-toothed Squirrel
|
|
|
|
diff --git a/arch/tile/lib/exports.c b/arch/tile/lib/exports.c
|
|
index 2a81d32..e51e5cd 100644
|
|
--- a/arch/tile/lib/exports.c
|
|
+++ b/arch/tile/lib/exports.c
|
|
@@ -90,4 +90,6 @@ uint64_t __ashrdi3(uint64_t, unsigned int);
|
|
EXPORT_SYMBOL(__ashrdi3);
|
|
uint64_t __ashldi3(uint64_t, unsigned int);
|
|
EXPORT_SYMBOL(__ashldi3);
|
|
+int __ffsdi2(uint64_t);
|
|
+EXPORT_SYMBOL(__ffsdi2);
|
|
#endif
|
|
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
|
|
index b27b452..3663e0b 100644
|
|
--- a/arch/x86/kvm/x86.c
|
|
+++ b/arch/x86/kvm/x86.c
|
|
@@ -555,8 +555,6 @@ int __kvm_set_xcr(struct kvm_vcpu *vcpu, u32 index, u64 xcr)
|
|
if (index != XCR_XFEATURE_ENABLED_MASK)
|
|
return 1;
|
|
xcr0 = xcr;
|
|
- if (kvm_x86_ops->get_cpl(vcpu) != 0)
|
|
- return 1;
|
|
if (!(xcr0 & XSTATE_FP))
|
|
return 1;
|
|
if ((xcr0 & XSTATE_YMM) && !(xcr0 & XSTATE_SSE))
|
|
@@ -570,7 +568,8 @@ int __kvm_set_xcr(struct kvm_vcpu *vcpu, u32 index, u64 xcr)
|
|
|
|
int kvm_set_xcr(struct kvm_vcpu *vcpu, u32 index, u64 xcr)
|
|
{
|
|
- if (__kvm_set_xcr(vcpu, index, xcr)) {
|
|
+ if (kvm_x86_ops->get_cpl(vcpu) != 0 ||
|
|
+ __kvm_set_xcr(vcpu, index, xcr)) {
|
|
kvm_inject_gp(vcpu, 0);
|
|
return 1;
|
|
}
|
|
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
|
|
index 7f1ea56..4c63665 100644
|
|
--- a/drivers/clk/clk.c
|
|
+++ b/drivers/clk/clk.c
|
|
@@ -1453,6 +1453,7 @@ int clk_notifier_unregister(struct clk *clk, struct notifier_block *nb)
|
|
/* XXX the notifier code should handle this better */
|
|
if (!cn->notifier_head.head) {
|
|
srcu_cleanup_notifier_head(&cn->notifier_head);
|
|
+ list_del(&cn->node);
|
|
kfree(cn);
|
|
}
|
|
|
|
diff --git a/drivers/input/touchscreen/cyttsp_core.c b/drivers/input/touchscreen/cyttsp_core.c
|
|
index f030d9e..3f505d5 100644
|
|
--- a/drivers/input/touchscreen/cyttsp_core.c
|
|
+++ b/drivers/input/touchscreen/cyttsp_core.c
|
|
@@ -133,7 +133,7 @@ static int cyttsp_exit_bl_mode(struct cyttsp *ts)
|
|
memcpy(bl_cmd, bl_command, sizeof(bl_command));
|
|
if (ts->pdata->bl_keys)
|
|
memcpy(&bl_cmd[sizeof(bl_command) - CY_NUM_BL_KEYS],
|
|
- ts->pdata->bl_keys, sizeof(bl_command));
|
|
+ ts->pdata->bl_keys, CY_NUM_BL_KEYS);
|
|
|
|
error = ttsp_write_block_data(ts, CY_REG_BASE,
|
|
sizeof(bl_cmd), bl_cmd);
|
|
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c
|
|
index 2e1f806..b6ed7e9 100644
|
|
--- a/drivers/net/bonding/bond_alb.c
|
|
+++ b/drivers/net/bonding/bond_alb.c
|
|
@@ -704,6 +704,12 @@ static struct slave *rlb_arp_xmit(struct sk_buff *skb, struct bonding *bond)
|
|
struct arp_pkt *arp = arp_pkt(skb);
|
|
struct slave *tx_slave = NULL;
|
|
|
|
+ /* Don't modify or load balance ARPs that do not originate locally
|
|
+ * (e.g.,arrive via a bridge).
|
|
+ */
|
|
+ if (!bond_slave_has_mac(bond, arp->mac_src))
|
|
+ return NULL;
|
|
+
|
|
if (arp->op_code == htons(ARPOP_REPLY)) {
|
|
/* the arp must be sent on the selected
|
|
* rx channel
|
|
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
|
|
index 4581aa5..51f1766 100644
|
|
--- a/drivers/net/bonding/bonding.h
|
|
+++ b/drivers/net/bonding/bonding.h
|
|
@@ -18,6 +18,7 @@
|
|
#include <linux/timer.h>
|
|
#include <linux/proc_fs.h>
|
|
#include <linux/if_bonding.h>
|
|
+#include <linux/etherdevice.h>
|
|
#include <linux/cpumask.h>
|
|
#include <linux/in6.h>
|
|
#include <linux/netpoll.h>
|
|
@@ -450,6 +451,18 @@ static inline void bond_destroy_proc_dir(struct bond_net *bn)
|
|
}
|
|
#endif
|
|
|
|
+static inline struct slave *bond_slave_has_mac(struct bonding *bond,
|
|
+ const u8 *mac)
|
|
+{
|
|
+ int i = 0;
|
|
+ struct slave *tmp;
|
|
+
|
|
+ bond_for_each_slave(bond, tmp, i)
|
|
+ if (!compare_ether_addr_64bits(mac, tmp->dev->dev_addr))
|
|
+ return tmp;
|
|
+
|
|
+ return NULL;
|
|
+}
|
|
|
|
/* exported from bond_main.c */
|
|
extern int bond_net_id;
|
|
diff --git a/drivers/net/ethernet/freescale/gianfar_ptp.c b/drivers/net/ethernet/freescale/gianfar_ptp.c
|
|
index ca2748a..8de54e5 100644
|
|
--- a/drivers/net/ethernet/freescale/gianfar_ptp.c
|
|
+++ b/drivers/net/ethernet/freescale/gianfar_ptp.c
|
|
@@ -520,6 +520,7 @@ static int gianfar_ptp_probe(struct platform_device *dev)
|
|
return 0;
|
|
|
|
no_clock:
|
|
+ iounmap(etsects->regs);
|
|
no_ioremap:
|
|
release_resource(etsects->rsrc);
|
|
no_resource:
|
|
diff --git a/drivers/net/ethernet/realtek/8139cp.c b/drivers/net/ethernet/realtek/8139cp.c
|
|
index b3287c0..4ce981c 100644
|
|
--- a/drivers/net/ethernet/realtek/8139cp.c
|
|
+++ b/drivers/net/ethernet/realtek/8139cp.c
|
|
@@ -1097,6 +1097,7 @@ static void cp_clean_rings (struct cp_private *cp)
|
|
cp->dev->stats.tx_dropped++;
|
|
}
|
|
}
|
|
+ netdev_reset_queue(cp->dev);
|
|
|
|
memset(cp->rx_ring, 0, sizeof(struct cp_desc) * CP_RX_RING_SIZE);
|
|
memset(cp->tx_ring, 0, sizeof(struct cp_desc) * CP_TX_RING_SIZE);
|
|
diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c
|
|
index cf20388..2a59e7a 100644
|
|
--- a/drivers/net/ethernet/realtek/r8169.c
|
|
+++ b/drivers/net/ethernet/realtek/r8169.c
|
|
@@ -5126,7 +5126,20 @@ err_out:
|
|
return -EIO;
|
|
}
|
|
|
|
-static inline void rtl8169_tso_csum(struct rtl8169_private *tp,
|
|
+static bool rtl_skb_pad(struct sk_buff *skb)
|
|
+{
|
|
+ if (skb_padto(skb, ETH_ZLEN))
|
|
+ return false;
|
|
+ skb_put(skb, ETH_ZLEN - skb->len);
|
|
+ return true;
|
|
+}
|
|
+
|
|
+static bool rtl_test_hw_pad_bug(struct rtl8169_private *tp, struct sk_buff *skb)
|
|
+{
|
|
+ return skb->len < ETH_ZLEN && tp->mac_version == RTL_GIGA_MAC_VER_34;
|
|
+}
|
|
+
|
|
+static inline bool rtl8169_tso_csum(struct rtl8169_private *tp,
|
|
struct sk_buff *skb, u32 *opts)
|
|
{
|
|
const struct rtl_tx_desc_info *info = tx_desc_info + tp->txd_version;
|
|
@@ -5139,13 +5152,20 @@ static inline void rtl8169_tso_csum(struct rtl8169_private *tp,
|
|
} else if (skb->ip_summed == CHECKSUM_PARTIAL) {
|
|
const struct iphdr *ip = ip_hdr(skb);
|
|
|
|
+ if (unlikely(rtl_test_hw_pad_bug(tp, skb)))
|
|
+ return skb_checksum_help(skb) == 0 && rtl_skb_pad(skb);
|
|
+
|
|
if (ip->protocol == IPPROTO_TCP)
|
|
opts[offset] |= info->checksum.tcp;
|
|
else if (ip->protocol == IPPROTO_UDP)
|
|
opts[offset] |= info->checksum.udp;
|
|
else
|
|
WARN_ON_ONCE(1);
|
|
+ } else {
|
|
+ if (unlikely(rtl_test_hw_pad_bug(tp, skb)))
|
|
+ return rtl_skb_pad(skb);
|
|
}
|
|
+ return true;
|
|
}
|
|
|
|
static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb,
|
|
@@ -5166,17 +5186,15 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb,
|
|
goto err_stop_0;
|
|
}
|
|
|
|
- /* 8168evl does not automatically pad to minimum length. */
|
|
- if (unlikely(tp->mac_version == RTL_GIGA_MAC_VER_34 &&
|
|
- skb->len < ETH_ZLEN)) {
|
|
- if (skb_padto(skb, ETH_ZLEN))
|
|
- goto err_update_stats;
|
|
- skb_put(skb, ETH_ZLEN - skb->len);
|
|
- }
|
|
-
|
|
if (unlikely(le32_to_cpu(txd->opts1) & DescOwn))
|
|
goto err_stop_0;
|
|
|
|
+ opts[1] = cpu_to_le32(rtl8169_tx_vlan_tag(tp, skb));
|
|
+ opts[0] = DescOwn;
|
|
+
|
|
+ if (!rtl8169_tso_csum(tp, skb, opts))
|
|
+ goto err_update_stats;
|
|
+
|
|
len = skb_headlen(skb);
|
|
mapping = dma_map_single(d, skb->data, len, DMA_TO_DEVICE);
|
|
if (unlikely(dma_mapping_error(d, mapping))) {
|
|
@@ -5188,11 +5206,6 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb,
|
|
tp->tx_skb[entry].len = len;
|
|
txd->addr = cpu_to_le64(mapping);
|
|
|
|
- opts[1] = cpu_to_le32(rtl8169_tx_vlan_tag(tp, skb));
|
|
- opts[0] = DescOwn;
|
|
-
|
|
- rtl8169_tso_csum(tp, skb, opts);
|
|
-
|
|
frags = rtl8169_xmit_frags(tp, skb, opts);
|
|
if (frags < 0)
|
|
goto err_dma_1;
|
|
diff --git a/drivers/net/team/team_mode_roundrobin.c b/drivers/net/team/team_mode_roundrobin.c
|
|
index a0e8f80..bf6a818 100644
|
|
--- a/drivers/net/team/team_mode_roundrobin.c
|
|
+++ b/drivers/net/team/team_mode_roundrobin.c
|
|
@@ -52,6 +52,8 @@ static bool rr_transmit(struct team *team, struct sk_buff *skb)
|
|
|
|
port_index = rr_priv(team)->sent_packets++ % team->port_count;
|
|
port = team_get_port_by_index_rcu(team, port_index);
|
|
+ if (unlikely(!port))
|
|
+ goto drop;
|
|
port = __get_first_port_up(team, port);
|
|
if (unlikely(!port))
|
|
goto drop;
|
|
diff --git a/drivers/target/iscsi/iscsi_target_erl0.c b/drivers/target/iscsi/iscsi_target_erl0.c
|
|
index 1ab0560..a7c4324 100644
|
|
--- a/drivers/target/iscsi/iscsi_target_erl0.c
|
|
+++ b/drivers/target/iscsi/iscsi_target_erl0.c
|
|
@@ -831,11 +831,11 @@ extern int iscsit_stop_time2retain_timer(struct iscsi_session *sess)
|
|
return 0;
|
|
|
|
sess->time2retain_timer_flags |= ISCSI_TF_STOP;
|
|
- spin_unlock_bh(&se_tpg->session_lock);
|
|
+ spin_unlock(&se_tpg->session_lock);
|
|
|
|
del_timer_sync(&sess->time2retain_timer);
|
|
|
|
- spin_lock_bh(&se_tpg->session_lock);
|
|
+ spin_lock(&se_tpg->session_lock);
|
|
sess->time2retain_timer_flags &= ~ISCSI_TF_RUNNING;
|
|
pr_debug("Stopped Time2Retain Timer for SID: %u\n",
|
|
sess->sid);
|
|
diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c
|
|
index 3377437..a39a08c 100644
|
|
--- a/drivers/usb/serial/ti_usb_3410_5052.c
|
|
+++ b/drivers/usb/serial/ti_usb_3410_5052.c
|
|
@@ -179,7 +179,8 @@ static struct usb_device_id ti_id_table_3410[15+TI_EXTRA_VID_PID_COUNT+1] = {
|
|
{ USB_DEVICE(IBM_VENDOR_ID, IBM_4543_PRODUCT_ID) },
|
|
{ USB_DEVICE(IBM_VENDOR_ID, IBM_454B_PRODUCT_ID) },
|
|
{ USB_DEVICE(IBM_VENDOR_ID, IBM_454C_PRODUCT_ID) },
|
|
- { USB_DEVICE(ABBOTT_VENDOR_ID, ABBOTT_PRODUCT_ID) },
|
|
+ { USB_DEVICE(ABBOTT_VENDOR_ID, ABBOTT_STEREO_PLUG_ID) },
|
|
+ { USB_DEVICE(ABBOTT_VENDOR_ID, ABBOTT_STRIP_PORT_ID) },
|
|
{ USB_DEVICE(TI_VENDOR_ID, FRI2_PRODUCT_ID) },
|
|
};
|
|
|
|
diff --git a/drivers/usb/serial/ti_usb_3410_5052.h b/drivers/usb/serial/ti_usb_3410_5052.h
|
|
index b353e7e..4a2423e 100644
|
|
--- a/drivers/usb/serial/ti_usb_3410_5052.h
|
|
+++ b/drivers/usb/serial/ti_usb_3410_5052.h
|
|
@@ -52,7 +52,9 @@
|
|
|
|
/* Abbott Diabetics vendor and product ids */
|
|
#define ABBOTT_VENDOR_ID 0x1a61
|
|
-#define ABBOTT_PRODUCT_ID 0x3410
|
|
+#define ABBOTT_STEREO_PLUG_ID 0x3410
|
|
+#define ABBOTT_PRODUCT_ID ABBOTT_STEREO_PLUG_ID
|
|
+#define ABBOTT_STRIP_PORT_ID 0x3420
|
|
|
|
/* Commands */
|
|
#define TI_GET_VERSION 0x01
|
|
diff --git a/fs/notify/inotify/inotify_user.c b/fs/notify/inotify/inotify_user.c
|
|
index 6f292dd..f255d37 100644
|
|
--- a/fs/notify/inotify/inotify_user.c
|
|
+++ b/fs/notify/inotify/inotify_user.c
|
|
@@ -577,7 +577,6 @@ static int inotify_update_existing_watch(struct fsnotify_group *group,
|
|
int add = (arg & IN_MASK_ADD);
|
|
int ret;
|
|
|
|
- /* don't allow invalid bits: we don't want flags set */
|
|
mask = inotify_arg_to_mask(arg);
|
|
|
|
fsn_mark = fsnotify_find_inode_mark(group, inode);
|
|
@@ -628,7 +627,6 @@ static int inotify_new_watch(struct fsnotify_group *group,
|
|
struct idr *idr = &group->inotify_data.idr;
|
|
spinlock_t *idr_lock = &group->inotify_data.idr_lock;
|
|
|
|
- /* don't allow invalid bits: we don't want flags set */
|
|
mask = inotify_arg_to_mask(arg);
|
|
|
|
tmp_i_mark = kmem_cache_alloc(inotify_inode_mark_cachep, GFP_KERNEL);
|
|
@@ -757,6 +755,10 @@ SYSCALL_DEFINE3(inotify_add_watch, int, fd, const char __user *, pathname,
|
|
int ret, fput_needed;
|
|
unsigned flags = 0;
|
|
|
|
+ /* don't allow invalid bits: we don't want flags set */
|
|
+ if (unlikely(!(mask & ALL_INOTIFY_BITS)))
|
|
+ return -EINVAL;
|
|
+
|
|
filp = fget_light(fd, &fput_needed);
|
|
if (unlikely(!filp))
|
|
return -EBADF;
|
|
diff --git a/include/linux/rculist_nulls.h b/include/linux/rculist_nulls.h
|
|
index 2ae1371..1c33dd7 100644
|
|
--- a/include/linux/rculist_nulls.h
|
|
+++ b/include/linux/rculist_nulls.h
|
|
@@ -105,9 +105,14 @@ static inline void hlist_nulls_add_head_rcu(struct hlist_nulls_node *n,
|
|
* @head: the head for your list.
|
|
* @member: the name of the hlist_nulls_node within the struct.
|
|
*
|
|
+ * The barrier() is needed to make sure compiler doesn't cache first element [1],
|
|
+ * as this loop can be restarted [2]
|
|
+ * [1] Documentation/atomic_ops.txt around line 114
|
|
+ * [2] Documentation/RCU/rculist_nulls.txt around line 146
|
|
*/
|
|
#define hlist_nulls_for_each_entry_rcu(tpos, pos, head, member) \
|
|
- for (pos = rcu_dereference_raw(hlist_nulls_first_rcu(head)); \
|
|
+ for (({barrier();}), \
|
|
+ pos = rcu_dereference_raw(hlist_nulls_first_rcu(head)); \
|
|
(!is_a_nulls(pos)) && \
|
|
({ tpos = hlist_nulls_entry(pos, typeof(*tpos), member); 1; }); \
|
|
pos = rcu_dereference_raw(hlist_nulls_next_rcu(pos)))
|
|
diff --git a/include/linux/socket.h b/include/linux/socket.h
|
|
index 8f15b1d..9b54ebe 100644
|
|
--- a/include/linux/socket.h
|
|
+++ b/include/linux/socket.h
|
|
@@ -336,6 +336,9 @@ extern int put_cmsg(struct msghdr*, int level, int type, int len, void *data);
|
|
|
|
struct timespec;
|
|
|
|
+/* The __sys_...msg variants allow MSG_CMSG_COMPAT */
|
|
+extern long __sys_recvmsg(int fd, struct msghdr __user *msg, unsigned flags);
|
|
+extern long __sys_sendmsg(int fd, struct msghdr __user *msg, unsigned flags);
|
|
extern int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen,
|
|
unsigned int flags, struct timespec *timeout);
|
|
extern int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg,
|
|
diff --git a/net/compat.c b/net/compat.c
|
|
index ae6d67a..014e1c7 100644
|
|
--- a/net/compat.c
|
|
+++ b/net/compat.c
|
|
@@ -743,19 +743,25 @@ static unsigned char nas[21] = {
|
|
|
|
asmlinkage long compat_sys_sendmsg(int fd, struct compat_msghdr __user *msg, unsigned flags)
|
|
{
|
|
- return sys_sendmsg(fd, (struct msghdr __user *)msg, flags | MSG_CMSG_COMPAT);
|
|
+ if (flags & MSG_CMSG_COMPAT)
|
|
+ return -EINVAL;
|
|
+ return __sys_sendmsg(fd, (struct msghdr __user *)msg, flags | MSG_CMSG_COMPAT);
|
|
}
|
|
|
|
asmlinkage long compat_sys_sendmmsg(int fd, struct compat_mmsghdr __user *mmsg,
|
|
unsigned vlen, unsigned int flags)
|
|
{
|
|
+ if (flags & MSG_CMSG_COMPAT)
|
|
+ return -EINVAL;
|
|
return __sys_sendmmsg(fd, (struct mmsghdr __user *)mmsg, vlen,
|
|
flags | MSG_CMSG_COMPAT);
|
|
}
|
|
|
|
asmlinkage long compat_sys_recvmsg(int fd, struct compat_msghdr __user *msg, unsigned int flags)
|
|
{
|
|
- return sys_recvmsg(fd, (struct msghdr __user *)msg, flags | MSG_CMSG_COMPAT);
|
|
+ if (flags & MSG_CMSG_COMPAT)
|
|
+ return -EINVAL;
|
|
+ return __sys_recvmsg(fd, (struct msghdr __user *)msg, flags | MSG_CMSG_COMPAT);
|
|
}
|
|
|
|
asmlinkage long compat_sys_recv(int fd, void __user *buf, size_t len, unsigned flags)
|
|
@@ -777,6 +783,9 @@ asmlinkage long compat_sys_recvmmsg(int fd, struct compat_mmsghdr __user *mmsg,
|
|
int datagrams;
|
|
struct timespec ktspec;
|
|
|
|
+ if (flags & MSG_CMSG_COMPAT)
|
|
+ return -EINVAL;
|
|
+
|
|
if (COMPAT_USE_64BIT_TIME)
|
|
return __sys_recvmmsg(fd, (struct mmsghdr __user *)mmsg, vlen,
|
|
flags | MSG_CMSG_COMPAT,
|
|
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
|
|
index b57532d..a16509c 100644
|
|
--- a/net/ipv4/ip_gre.c
|
|
+++ b/net/ipv4/ip_gre.c
|
|
@@ -722,6 +722,7 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev
|
|
tiph = &tunnel->parms.iph;
|
|
}
|
|
|
|
+ memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
|
|
if ((dst = tiph->daddr) == 0) {
|
|
/* NBMA tunnel */
|
|
|
|
@@ -865,7 +866,6 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev
|
|
skb_reset_transport_header(skb);
|
|
skb_push(skb, gre_hlen);
|
|
skb_reset_network_header(skb);
|
|
- memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
|
|
IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED |
|
|
IPSKB_REROUTED);
|
|
skb_dst_drop(skb);
|
|
diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c
|
|
index ae1413e..d2f6348 100644
|
|
--- a/net/ipv4/ipip.c
|
|
+++ b/net/ipv4/ipip.c
|
|
@@ -448,6 +448,7 @@ static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
|
|
if (tos & 1)
|
|
tos = old_iph->tos;
|
|
|
|
+ memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
|
|
if (!dst) {
|
|
/* NBMA tunnel */
|
|
if ((rt = skb_rtable(skb)) == NULL) {
|
|
@@ -530,7 +531,6 @@ static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
|
|
skb->transport_header = skb->network_header;
|
|
skb_push(skb, sizeof(struct iphdr));
|
|
skb_reset_network_header(skb);
|
|
- memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
|
|
IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED |
|
|
IPSKB_REROUTED);
|
|
skb_dst_drop(skb);
|
|
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
|
|
index dcb19f5..0b91c30 100644
|
|
--- a/net/ipv4/tcp.c
|
|
+++ b/net/ipv4/tcp.c
|
|
@@ -3055,8 +3055,11 @@ int tcp_md5_hash_skb_data(struct tcp_md5sig_pool *hp,
|
|
|
|
for (i = 0; i < shi->nr_frags; ++i) {
|
|
const struct skb_frag_struct *f = &shi->frags[i];
|
|
- struct page *page = skb_frag_page(f);
|
|
- sg_set_page(&sg, page, skb_frag_size(f), f->page_offset);
|
|
+ unsigned int offset = f->page_offset;
|
|
+ struct page *page = skb_frag_page(f) + (offset >> PAGE_SHIFT);
|
|
+
|
|
+ sg_set_page(&sg, page, skb_frag_size(f),
|
|
+ offset_in_page(offset));
|
|
if (crypto_hash_update(desc, &sg, skb_frag_size(f)))
|
|
return 1;
|
|
}
|
|
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
|
|
index 762c78f..55d96c3 100644
|
|
--- a/net/ipv4/tcp_input.c
|
|
+++ b/net/ipv4/tcp_input.c
|
|
@@ -3038,8 +3038,8 @@ static void tcp_update_cwnd_in_recovery(struct sock *sk, int newly_acked_sacked,
|
|
* tcp_xmit_retransmit_queue().
|
|
*/
|
|
static void tcp_fastretrans_alert(struct sock *sk, int pkts_acked,
|
|
- int prior_sacked, bool is_dupack,
|
|
- int flag)
|
|
+ int prior_sacked, int prior_packets,
|
|
+ bool is_dupack, int flag)
|
|
{
|
|
struct inet_connection_sock *icsk = inet_csk(sk);
|
|
struct tcp_sock *tp = tcp_sk(sk);
|
|
@@ -3105,7 +3105,8 @@ static void tcp_fastretrans_alert(struct sock *sk, int pkts_acked,
|
|
tcp_add_reno_sack(sk);
|
|
} else
|
|
do_lost = tcp_try_undo_partial(sk, pkts_acked);
|
|
- newly_acked_sacked = pkts_acked + tp->sacked_out - prior_sacked;
|
|
+ newly_acked_sacked = prior_packets - tp->packets_out +
|
|
+ tp->sacked_out - prior_sacked;
|
|
break;
|
|
case TCP_CA_Loss:
|
|
if (flag & FLAG_DATA_ACKED)
|
|
@@ -3127,7 +3128,8 @@ static void tcp_fastretrans_alert(struct sock *sk, int pkts_acked,
|
|
if (is_dupack)
|
|
tcp_add_reno_sack(sk);
|
|
}
|
|
- newly_acked_sacked = pkts_acked + tp->sacked_out - prior_sacked;
|
|
+ newly_acked_sacked = prior_packets - tp->packets_out +
|
|
+ tp->sacked_out - prior_sacked;
|
|
|
|
if (icsk->icsk_ca_state <= TCP_CA_Disorder)
|
|
tcp_try_undo_dsack(sk);
|
|
@@ -3740,9 +3742,10 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag)
|
|
bool is_dupack = false;
|
|
u32 prior_in_flight;
|
|
u32 prior_fackets;
|
|
- int prior_packets;
|
|
+ int prior_packets = tp->packets_out;
|
|
int prior_sacked = tp->sacked_out;
|
|
int pkts_acked = 0;
|
|
+ int previous_packets_out = 0;
|
|
int frto_cwnd = 0;
|
|
|
|
/* If the ack is older than previous acks
|
|
@@ -3819,14 +3822,14 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag)
|
|
sk->sk_err_soft = 0;
|
|
icsk->icsk_probes_out = 0;
|
|
tp->rcv_tstamp = tcp_time_stamp;
|
|
- prior_packets = tp->packets_out;
|
|
if (!prior_packets)
|
|
goto no_queue;
|
|
|
|
/* See if we can take anything off of the retransmit queue. */
|
|
+ previous_packets_out = tp->packets_out;
|
|
flag |= tcp_clean_rtx_queue(sk, prior_fackets, prior_snd_una);
|
|
|
|
- pkts_acked = prior_packets - tp->packets_out;
|
|
+ pkts_acked = previous_packets_out - tp->packets_out;
|
|
|
|
if (tp->frto_counter)
|
|
frto_cwnd = tcp_process_frto(sk, flag);
|
|
@@ -3841,7 +3844,7 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag)
|
|
tcp_cong_avoid(sk, ack, prior_in_flight);
|
|
is_dupack = !(flag & (FLAG_SND_UNA_ADVANCED | FLAG_NOT_DUP));
|
|
tcp_fastretrans_alert(sk, pkts_acked, prior_sacked,
|
|
- is_dupack, flag);
|
|
+ prior_packets, is_dupack, flag);
|
|
} else {
|
|
if ((flag & FLAG_DATA_ACKED) && !frto_cwnd)
|
|
tcp_cong_avoid(sk, ack, prior_in_flight);
|
|
@@ -3856,7 +3859,7 @@ no_queue:
|
|
/* If data was DSACKed, see if we can undo a cwnd reduction. */
|
|
if (flag & FLAG_DSACKING_ACK)
|
|
tcp_fastretrans_alert(sk, pkts_acked, prior_sacked,
|
|
- is_dupack, flag);
|
|
+ prior_packets, is_dupack, flag);
|
|
/* If this ack opens up a zero window, clear backoff. It was
|
|
* being used to time the probes, and is probably far higher than
|
|
* it needs to be for normal retransmission.
|
|
@@ -3876,7 +3879,7 @@ old_ack:
|
|
if (TCP_SKB_CB(skb)->sacked) {
|
|
flag |= tcp_sacktag_write_queue(sk, skb, prior_snd_una);
|
|
tcp_fastretrans_alert(sk, pkts_acked, prior_sacked,
|
|
- is_dupack, flag);
|
|
+ prior_packets, is_dupack, flag);
|
|
}
|
|
|
|
SOCK_DEBUG(sk, "Ack %u before %u:%u\n", ack, tp->snd_una, tp->snd_nxt);
|
|
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
|
|
index 9db21e3..12999a3 100644
|
|
--- a/net/ipv4/tcp_output.c
|
|
+++ b/net/ipv4/tcp_output.c
|
|
@@ -835,11 +835,13 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it,
|
|
&md5);
|
|
tcp_header_size = tcp_options_size + sizeof(struct tcphdr);
|
|
|
|
- if (tcp_packets_in_flight(tp) == 0) {
|
|
+ if (tcp_packets_in_flight(tp) == 0)
|
|
tcp_ca_event(sk, CA_EVENT_TX_START);
|
|
- skb->ooo_okay = 1;
|
|
- } else
|
|
- skb->ooo_okay = 0;
|
|
+
|
|
+ /* if no packet is in qdisc/device queue, then allow XPS to select
|
|
+ * another queue.
|
|
+ */
|
|
+ skb->ooo_okay = sk_wmem_alloc_get(sk) == 0;
|
|
|
|
skb_push(skb, tcp_header_size);
|
|
skb_reset_transport_header(skb);
|
|
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
|
|
index 2c496d6..f4fe3c0 100644
|
|
--- a/net/ipv6/addrconf.c
|
|
+++ b/net/ipv6/addrconf.c
|
|
@@ -2432,8 +2432,10 @@ static void init_loopback(struct net_device *dev)
|
|
sp_rt = addrconf_dst_alloc(idev, &sp_ifa->addr, 0);
|
|
|
|
/* Failure cases are ignored */
|
|
- if (!IS_ERR(sp_rt))
|
|
+ if (!IS_ERR(sp_rt)) {
|
|
+ sp_ifa->rt = sp_rt;
|
|
ip6_ins_rt(sp_rt);
|
|
+ }
|
|
}
|
|
read_unlock_bh(&idev->lock);
|
|
}
|
|
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
|
|
index ce661ba..bf290ce 100644
|
|
--- a/net/ipv6/ip6_output.c
|
|
+++ b/net/ipv6/ip6_output.c
|
|
@@ -1236,7 +1236,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
|
|
if (WARN_ON(np->cork.opt))
|
|
return -EINVAL;
|
|
|
|
- np->cork.opt = kmalloc(opt->tot_len, sk->sk_allocation);
|
|
+ np->cork.opt = kzalloc(opt->tot_len, sk->sk_allocation);
|
|
if (unlikely(np->cork.opt == NULL))
|
|
return -ENOBUFS;
|
|
|
|
diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c
|
|
index 9728a75..c6dee80 100644
|
|
--- a/net/l2tp/l2tp_ppp.c
|
|
+++ b/net/l2tp/l2tp_ppp.c
|
|
@@ -350,19 +350,19 @@ static int pppol2tp_sendmsg(struct kiocb *iocb, struct socket *sock, struct msgh
|
|
skb_put(skb, 2);
|
|
|
|
/* Copy user data into skb */
|
|
- error = memcpy_fromiovec(skb->data, m->msg_iov, total_len);
|
|
+ error = memcpy_fromiovec(skb_put(skb, total_len), m->msg_iov,
|
|
+ total_len);
|
|
if (error < 0) {
|
|
kfree_skb(skb);
|
|
goto error_put_sess_tun;
|
|
}
|
|
- skb_put(skb, total_len);
|
|
|
|
l2tp_xmit_skb(session, skb, session->hdr_len);
|
|
|
|
sock_put(ps->tunnel_sock);
|
|
sock_put(sk);
|
|
|
|
- return error;
|
|
+ return total_len;
|
|
|
|
error_put_sess_tun:
|
|
sock_put(ps->tunnel_sock);
|
|
diff --git a/net/netlabel/netlabel_domainhash.c b/net/netlabel/netlabel_domainhash.c
|
|
index d8d4243..6bb1d42 100644
|
|
--- a/net/netlabel/netlabel_domainhash.c
|
|
+++ b/net/netlabel/netlabel_domainhash.c
|
|
@@ -245,6 +245,71 @@ static void netlbl_domhsh_audit_add(struct netlbl_dom_map *entry,
|
|
}
|
|
}
|
|
|
|
+/**
|
|
+ * netlbl_domhsh_validate - Validate a new domain mapping entry
|
|
+ * @entry: the entry to validate
|
|
+ *
|
|
+ * This function validates the new domain mapping entry to ensure that it is
|
|
+ * a valid entry. Returns zero on success, negative values on failure.
|
|
+ *
|
|
+ */
|
|
+static int netlbl_domhsh_validate(const struct netlbl_dom_map *entry)
|
|
+{
|
|
+ struct netlbl_af4list *iter4;
|
|
+ struct netlbl_domaddr4_map *map4;
|
|
+#if IS_ENABLED(CONFIG_IPV6)
|
|
+ struct netlbl_af6list *iter6;
|
|
+ struct netlbl_domaddr6_map *map6;
|
|
+#endif /* IPv6 */
|
|
+
|
|
+ if (entry == NULL)
|
|
+ return -EINVAL;
|
|
+
|
|
+ switch (entry->type) {
|
|
+ case NETLBL_NLTYPE_UNLABELED:
|
|
+ if (entry->type_def.cipsov4 != NULL ||
|
|
+ entry->type_def.addrsel != NULL)
|
|
+ return -EINVAL;
|
|
+ break;
|
|
+ case NETLBL_NLTYPE_CIPSOV4:
|
|
+ if (entry->type_def.cipsov4 == NULL)
|
|
+ return -EINVAL;
|
|
+ break;
|
|
+ case NETLBL_NLTYPE_ADDRSELECT:
|
|
+ netlbl_af4list_foreach(iter4, &entry->type_def.addrsel->list4) {
|
|
+ map4 = netlbl_domhsh_addr4_entry(iter4);
|
|
+ switch (map4->type) {
|
|
+ case NETLBL_NLTYPE_UNLABELED:
|
|
+ if (map4->type_def.cipsov4 != NULL)
|
|
+ return -EINVAL;
|
|
+ break;
|
|
+ case NETLBL_NLTYPE_CIPSOV4:
|
|
+ if (map4->type_def.cipsov4 == NULL)
|
|
+ return -EINVAL;
|
|
+ break;
|
|
+ default:
|
|
+ return -EINVAL;
|
|
+ }
|
|
+ }
|
|
+#if IS_ENABLED(CONFIG_IPV6)
|
|
+ netlbl_af6list_foreach(iter6, &entry->type_def.addrsel->list6) {
|
|
+ map6 = netlbl_domhsh_addr6_entry(iter6);
|
|
+ switch (map6->type) {
|
|
+ case NETLBL_NLTYPE_UNLABELED:
|
|
+ break;
|
|
+ default:
|
|
+ return -EINVAL;
|
|
+ }
|
|
+ }
|
|
+#endif /* IPv6 */
|
|
+ break;
|
|
+ default:
|
|
+ return -EINVAL;
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
/*
|
|
* Domain Hash Table Functions
|
|
*/
|
|
@@ -311,6 +376,10 @@ int netlbl_domhsh_add(struct netlbl_dom_map *entry,
|
|
struct netlbl_af6list *tmp6;
|
|
#endif /* IPv6 */
|
|
|
|
+ ret_val = netlbl_domhsh_validate(entry);
|
|
+ if (ret_val != 0)
|
|
+ return ret_val;
|
|
+
|
|
/* XXX - we can remove this RCU read lock as the spinlock protects the
|
|
* entire function, but before we do we need to fixup the
|
|
* netlbl_af[4,6]list RCU functions to do "the right thing" with
|
|
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
|
|
index cfcd783..8ed5d93 100644
|
|
--- a/net/packet/af_packet.c
|
|
+++ b/net/packet/af_packet.c
|
|
@@ -2848,12 +2848,11 @@ static int packet_getname_spkt(struct socket *sock, struct sockaddr *uaddr,
|
|
return -EOPNOTSUPP;
|
|
|
|
uaddr->sa_family = AF_PACKET;
|
|
+ memset(uaddr->sa_data, 0, sizeof(uaddr->sa_data));
|
|
rcu_read_lock();
|
|
dev = dev_get_by_index_rcu(sock_net(sk), pkt_sk(sk)->ifindex);
|
|
if (dev)
|
|
- strncpy(uaddr->sa_data, dev->name, 14);
|
|
- else
|
|
- memset(uaddr->sa_data, 0, 14);
|
|
+ strlcpy(uaddr->sa_data, dev->name, sizeof(uaddr->sa_data));
|
|
rcu_read_unlock();
|
|
*uaddr_len = sizeof(*uaddr);
|
|
|
|
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
|
|
index 9fd05ed..4bc6e0b 100644
|
|
--- a/net/sctp/socket.c
|
|
+++ b/net/sctp/socket.c
|
|
@@ -3929,6 +3929,12 @@ SCTP_STATIC void sctp_destroy_sock(struct sock *sk)
|
|
|
|
/* Release our hold on the endpoint. */
|
|
sp = sctp_sk(sk);
|
|
+ /* This could happen during socket init, thus we bail out
|
|
+ * early, since the rest of the below is not setup either.
|
|
+ */
|
|
+ if (sp->ep == NULL)
|
|
+ return;
|
|
+
|
|
if (sp->do_auto_asconf) {
|
|
sp->do_auto_asconf = 0;
|
|
list_del(&sp->auto_asconf_list);
|
|
diff --git a/net/socket.c b/net/socket.c
|
|
index dab3176..47ce3ea 100644
|
|
--- a/net/socket.c
|
|
+++ b/net/socket.c
|
|
@@ -1899,9 +1899,9 @@ struct used_address {
|
|
unsigned int name_len;
|
|
};
|
|
|
|
-static int __sys_sendmsg(struct socket *sock, struct msghdr __user *msg,
|
|
- struct msghdr *msg_sys, unsigned flags,
|
|
- struct used_address *used_address)
|
|
+static int ___sys_sendmsg(struct socket *sock, struct msghdr __user *msg,
|
|
+ struct msghdr *msg_sys, unsigned flags,
|
|
+ struct used_address *used_address)
|
|
{
|
|
struct compat_msghdr __user *msg_compat =
|
|
(struct compat_msghdr __user *)msg;
|
|
@@ -2017,22 +2017,30 @@ out:
|
|
* BSD sendmsg interface
|
|
*/
|
|
|
|
-SYSCALL_DEFINE3(sendmsg, int, fd, struct msghdr __user *, msg, unsigned, flags)
|
|
+long __sys_sendmsg(int fd, struct msghdr __user *msg, unsigned flags)
|
|
{
|
|
int fput_needed, err;
|
|
struct msghdr msg_sys;
|
|
- struct socket *sock = sockfd_lookup_light(fd, &err, &fput_needed);
|
|
+ struct socket *sock;
|
|
|
|
+ sock = sockfd_lookup_light(fd, &err, &fput_needed);
|
|
if (!sock)
|
|
goto out;
|
|
|
|
- err = __sys_sendmsg(sock, msg, &msg_sys, flags, NULL);
|
|
+ err = ___sys_sendmsg(sock, msg, &msg_sys, flags, NULL);
|
|
|
|
fput_light(sock->file, fput_needed);
|
|
out:
|
|
return err;
|
|
}
|
|
|
|
+SYSCALL_DEFINE3(sendmsg, int, fd, struct msghdr __user *, msg, unsigned int, flags)
|
|
+{
|
|
+ if (flags & MSG_CMSG_COMPAT)
|
|
+ return -EINVAL;
|
|
+ return __sys_sendmsg(fd, msg, flags);
|
|
+}
|
|
+
|
|
/*
|
|
* Linux sendmmsg interface
|
|
*/
|
|
@@ -2063,15 +2071,16 @@ int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen,
|
|
|
|
while (datagrams < vlen) {
|
|
if (MSG_CMSG_COMPAT & flags) {
|
|
- err = __sys_sendmsg(sock, (struct msghdr __user *)compat_entry,
|
|
- &msg_sys, flags, &used_address);
|
|
+ err = ___sys_sendmsg(sock, (struct msghdr __user *)compat_entry,
|
|
+ &msg_sys, flags, &used_address);
|
|
if (err < 0)
|
|
break;
|
|
err = __put_user(err, &compat_entry->msg_len);
|
|
++compat_entry;
|
|
} else {
|
|
- err = __sys_sendmsg(sock, (struct msghdr __user *)entry,
|
|
- &msg_sys, flags, &used_address);
|
|
+ err = ___sys_sendmsg(sock,
|
|
+ (struct msghdr __user *)entry,
|
|
+ &msg_sys, flags, &used_address);
|
|
if (err < 0)
|
|
break;
|
|
err = put_user(err, &entry->msg_len);
|
|
@@ -2095,11 +2104,13 @@ int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen,
|
|
SYSCALL_DEFINE4(sendmmsg, int, fd, struct mmsghdr __user *, mmsg,
|
|
unsigned int, vlen, unsigned int, flags)
|
|
{
|
|
+ if (flags & MSG_CMSG_COMPAT)
|
|
+ return -EINVAL;
|
|
return __sys_sendmmsg(fd, mmsg, vlen, flags);
|
|
}
|
|
|
|
-static int __sys_recvmsg(struct socket *sock, struct msghdr __user *msg,
|
|
- struct msghdr *msg_sys, unsigned flags, int nosec)
|
|
+static int ___sys_recvmsg(struct socket *sock, struct msghdr __user *msg,
|
|
+ struct msghdr *msg_sys, unsigned flags, int nosec)
|
|
{
|
|
struct compat_msghdr __user *msg_compat =
|
|
(struct compat_msghdr __user *)msg;
|
|
@@ -2192,23 +2203,31 @@ out:
|
|
* BSD recvmsg interface
|
|
*/
|
|
|
|
-SYSCALL_DEFINE3(recvmsg, int, fd, struct msghdr __user *, msg,
|
|
- unsigned int, flags)
|
|
+long __sys_recvmsg(int fd, struct msghdr __user *msg, unsigned flags)
|
|
{
|
|
int fput_needed, err;
|
|
struct msghdr msg_sys;
|
|
- struct socket *sock = sockfd_lookup_light(fd, &err, &fput_needed);
|
|
+ struct socket *sock;
|
|
|
|
+ sock = sockfd_lookup_light(fd, &err, &fput_needed);
|
|
if (!sock)
|
|
goto out;
|
|
|
|
- err = __sys_recvmsg(sock, msg, &msg_sys, flags, 0);
|
|
+ err = ___sys_recvmsg(sock, msg, &msg_sys, flags, 0);
|
|
|
|
fput_light(sock->file, fput_needed);
|
|
out:
|
|
return err;
|
|
}
|
|
|
|
+SYSCALL_DEFINE3(recvmsg, int, fd, struct msghdr __user *, msg,
|
|
+ unsigned int, flags)
|
|
+{
|
|
+ if (flags & MSG_CMSG_COMPAT)
|
|
+ return -EINVAL;
|
|
+ return __sys_recvmsg(fd, msg, flags);
|
|
+}
|
|
+
|
|
/*
|
|
* Linux recvmmsg interface
|
|
*/
|
|
@@ -2246,17 +2265,18 @@ int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen,
|
|
* No need to ask LSM for more than the first datagram.
|
|
*/
|
|
if (MSG_CMSG_COMPAT & flags) {
|
|
- err = __sys_recvmsg(sock, (struct msghdr __user *)compat_entry,
|
|
- &msg_sys, flags & ~MSG_WAITFORONE,
|
|
- datagrams);
|
|
+ err = ___sys_recvmsg(sock, (struct msghdr __user *)compat_entry,
|
|
+ &msg_sys, flags & ~MSG_WAITFORONE,
|
|
+ datagrams);
|
|
if (err < 0)
|
|
break;
|
|
err = __put_user(err, &compat_entry->msg_len);
|
|
++compat_entry;
|
|
} else {
|
|
- err = __sys_recvmsg(sock, (struct msghdr __user *)entry,
|
|
- &msg_sys, flags & ~MSG_WAITFORONE,
|
|
- datagrams);
|
|
+ err = ___sys_recvmsg(sock,
|
|
+ (struct msghdr __user *)entry,
|
|
+ &msg_sys, flags & ~MSG_WAITFORONE,
|
|
+ datagrams);
|
|
if (err < 0)
|
|
break;
|
|
err = put_user(err, &entry->msg_len);
|
|
@@ -2323,6 +2343,9 @@ SYSCALL_DEFINE5(recvmmsg, int, fd, struct mmsghdr __user *, mmsg,
|
|
int datagrams;
|
|
struct timespec timeout_sys;
|
|
|
|
+ if (flags & MSG_CMSG_COMPAT)
|
|
+ return -EINVAL;
|
|
+
|
|
if (!timeout)
|
|
return __sys_recvmmsg(fd, mmsg, vlen, flags, NULL);
|
|
|
|
diff --git a/sound/usb/card.c b/sound/usb/card.c
|
|
index b41730d..658ea11 100644
|
|
--- a/sound/usb/card.c
|
|
+++ b/sound/usb/card.c
|
|
@@ -149,14 +149,32 @@ static int snd_usb_create_stream(struct snd_usb_audio *chip, int ctrlif, int int
|
|
return -EINVAL;
|
|
}
|
|
|
|
+ alts = &iface->altsetting[0];
|
|
+ altsd = get_iface_desc(alts);
|
|
+
|
|
+ /*
|
|
+ * Android with both accessory and audio interfaces enabled gets the
|
|
+ * interface numbers wrong.
|
|
+ */
|
|
+ if ((chip->usb_id == USB_ID(0x18d1, 0x2d04) ||
|
|
+ chip->usb_id == USB_ID(0x18d1, 0x2d05)) &&
|
|
+ interface == 0 &&
|
|
+ altsd->bInterfaceClass == USB_CLASS_VENDOR_SPEC &&
|
|
+ altsd->bInterfaceSubClass == USB_SUBCLASS_VENDOR_SPEC) {
|
|
+ interface = 2;
|
|
+ iface = usb_ifnum_to_if(dev, interface);
|
|
+ if (!iface)
|
|
+ return -EINVAL;
|
|
+ alts = &iface->altsetting[0];
|
|
+ altsd = get_iface_desc(alts);
|
|
+ }
|
|
+
|
|
if (usb_interface_claimed(iface)) {
|
|
snd_printdd(KERN_INFO "%d:%d:%d: skipping, already claimed\n",
|
|
dev->devnum, ctrlif, interface);
|
|
return -EINVAL;
|
|
}
|
|
|
|
- alts = &iface->altsetting[0];
|
|
- altsd = get_iface_desc(alts);
|
|
if ((altsd->bInterfaceClass == USB_CLASS_AUDIO ||
|
|
altsd->bInterfaceClass == USB_CLASS_VENDOR_SPEC) &&
|
|
altsd->bInterfaceSubClass == USB_SUBCLASS_MIDISTREAMING) {
|
|
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
|
|
index e075a67..5ca4652 100644
|
|
--- a/sound/usb/mixer.c
|
|
+++ b/sound/usb/mixer.c
|
|
@@ -821,6 +821,7 @@ static void volume_control_quirks(struct usb_mixer_elem_info *cval,
|
|
|
|
case USB_ID(0x046d, 0x0808):
|
|
case USB_ID(0x046d, 0x0809):
|
|
+ case USB_ID(0x046d, 0x081b): /* HD Webcam c310 */
|
|
case USB_ID(0x046d, 0x081d): /* HD Webcam c510 */
|
|
case USB_ID(0x046d, 0x0825): /* HD Webcam c270 */
|
|
case USB_ID(0x046d, 0x0991):
|