mirror of
https://github.com/Fishwaldo/build.git
synced 2025-03-27 17:21:34 +00:00
654 lines
21 KiB
Diff
654 lines
21 KiB
Diff
diff --git a/Makefile b/Makefile
|
|
index 8f45901dd370..b2192326e7f9 100644
|
|
--- a/Makefile
|
|
+++ b/Makefile
|
|
@@ -1,6 +1,6 @@
|
|
VERSION = 3
|
|
PATCHLEVEL = 4
|
|
-SUBLEVEL = 87
|
|
+SUBLEVEL = 88
|
|
EXTRAVERSION =
|
|
NAME = Saber-toothed Squirrel
|
|
|
|
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
|
|
index 76c7ccfb1ebe..37a8daf105eb 100644
|
|
--- a/arch/sparc/Kconfig
|
|
+++ b/arch/sparc/Kconfig
|
|
@@ -24,7 +24,7 @@ config SPARC
|
|
select HAVE_IRQ_WORK
|
|
select HAVE_DMA_ATTRS
|
|
select HAVE_DMA_API_DEBUG
|
|
- select HAVE_ARCH_JUMP_LABEL
|
|
+ select HAVE_ARCH_JUMP_LABEL if SPARC64
|
|
select HAVE_GENERIC_HARDIRQS
|
|
select GENERIC_IRQ_SHOW
|
|
select USE_GENERIC_SMP_HELPERS if SMP
|
|
diff --git a/arch/sparc/include/asm/uaccess_64.h b/arch/sparc/include/asm/uaccess_64.h
|
|
index a1091afb8831..8bc9afdea2d4 100644
|
|
--- a/arch/sparc/include/asm/uaccess_64.h
|
|
+++ b/arch/sparc/include/asm/uaccess_64.h
|
|
@@ -266,8 +266,8 @@ extern long __strnlen_user(const char __user *, long len);
|
|
|
|
#define strlen_user __strlen_user
|
|
#define strnlen_user __strnlen_user
|
|
-#define __copy_to_user_inatomic ___copy_to_user
|
|
-#define __copy_from_user_inatomic ___copy_from_user
|
|
+#define __copy_to_user_inatomic __copy_to_user
|
|
+#define __copy_from_user_inatomic __copy_from_user
|
|
|
|
#endif /* __ASSEMBLY__ */
|
|
|
|
diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c
|
|
index fdaf21811670..8c5c9a5675b4 100644
|
|
--- a/arch/sparc/kernel/pci.c
|
|
+++ b/arch/sparc/kernel/pci.c
|
|
@@ -486,8 +486,8 @@ static void __devinit apb_fake_ranges(struct pci_dev *dev,
|
|
apb_calc_first_last(map, &first, &last);
|
|
res = bus->resource[1];
|
|
res->flags = IORESOURCE_MEM;
|
|
- region.start = (first << 21);
|
|
- region.end = (last << 21) + ((1 << 21) - 1);
|
|
+ region.start = (first << 29);
|
|
+ region.end = (last << 29) + ((1 << 29) - 1);
|
|
pcibios_bus_to_resource(dev, res, ®ion);
|
|
}
|
|
|
|
diff --git a/arch/sparc/kernel/syscalls.S b/arch/sparc/kernel/syscalls.S
|
|
index 817187d42777..557212cfa0f2 100644
|
|
--- a/arch/sparc/kernel/syscalls.S
|
|
+++ b/arch/sparc/kernel/syscalls.S
|
|
@@ -184,7 +184,8 @@ linux_sparc_syscall32:
|
|
mov %i0, %l5 ! IEU1
|
|
5: call %l7 ! CTI Group brk forced
|
|
srl %i5, 0, %o5 ! IEU1
|
|
- ba,a,pt %xcc, 3f
|
|
+ ba,pt %xcc, 3f
|
|
+ sra %o0, 0, %o0
|
|
|
|
/* Linux native system calls enter here... */
|
|
.align 32
|
|
@@ -212,7 +213,6 @@ linux_sparc_syscall:
|
|
3: stx %o0, [%sp + PTREGS_OFF + PT_V9_I0]
|
|
ret_sys_call:
|
|
ldx [%sp + PTREGS_OFF + PT_V9_TSTATE], %g3
|
|
- sra %o0, 0, %o0
|
|
mov %ulo(TSTATE_XCARRY | TSTATE_ICARRY), %g2
|
|
sllx %g2, 32, %g2
|
|
|
|
diff --git a/drivers/char/ipmi/ipmi_bt_sm.c b/drivers/char/ipmi/ipmi_bt_sm.c
|
|
index a22a7a502740..8156cafad11a 100644
|
|
--- a/drivers/char/ipmi/ipmi_bt_sm.c
|
|
+++ b/drivers/char/ipmi/ipmi_bt_sm.c
|
|
@@ -352,7 +352,7 @@ static inline void write_all_bytes(struct si_sm_data *bt)
|
|
|
|
static inline int read_all_bytes(struct si_sm_data *bt)
|
|
{
|
|
- unsigned char i;
|
|
+ unsigned int i;
|
|
|
|
/*
|
|
* length is "framing info", minimum = 4: NetFn, Seq, Cmd, cCode.
|
|
diff --git a/drivers/isdn/isdnloop/isdnloop.c b/drivers/isdn/isdnloop/isdnloop.c
|
|
index 02125e6a9109..5a4da94aefb0 100644
|
|
--- a/drivers/isdn/isdnloop/isdnloop.c
|
|
+++ b/drivers/isdn/isdnloop/isdnloop.c
|
|
@@ -518,9 +518,9 @@ static isdnloop_stat isdnloop_cmd_table[] =
|
|
static void
|
|
isdnloop_fake_err(isdnloop_card *card)
|
|
{
|
|
- char buf[60];
|
|
+ char buf[64];
|
|
|
|
- sprintf(buf, "E%s", card->omsg);
|
|
+ snprintf(buf, sizeof(buf), "E%s", card->omsg);
|
|
isdnloop_fake(card, buf, -1);
|
|
isdnloop_fake(card, "NAK", -1);
|
|
}
|
|
@@ -903,6 +903,8 @@ isdnloop_parse_cmd(isdnloop_card *card)
|
|
case 7:
|
|
/* 0x;EAZ */
|
|
p += 3;
|
|
+ if (strlen(p) >= sizeof(card->eazlist[0]))
|
|
+ break;
|
|
strcpy(card->eazlist[ch - 1], p);
|
|
break;
|
|
case 8:
|
|
@@ -1070,6 +1072,12 @@ isdnloop_start(isdnloop_card *card, isdnloop_sdef *sdefp)
|
|
return -EBUSY;
|
|
if (copy_from_user((char *) &sdef, (char *) sdefp, sizeof(sdef)))
|
|
return -EFAULT;
|
|
+
|
|
+ for (i = 0; i < 3; i++) {
|
|
+ if (!memchr(sdef.num[i], 0, sizeof(sdef.num[i])))
|
|
+ return -EINVAL;
|
|
+ }
|
|
+
|
|
spin_lock_irqsave(&card->isdnloop_lock, flags);
|
|
switch (sdef.ptype) {
|
|
case ISDN_PTYPE_EURO:
|
|
@@ -1127,7 +1135,7 @@ isdnloop_command(isdn_ctrl *c, isdnloop_card *card)
|
|
{
|
|
ulong a;
|
|
int i;
|
|
- char cbuf[60];
|
|
+ char cbuf[80];
|
|
isdn_ctrl cmd;
|
|
isdnloop_cdef cdef;
|
|
|
|
@@ -1192,7 +1200,6 @@ isdnloop_command(isdn_ctrl *c, isdnloop_card *card)
|
|
break;
|
|
if ((c->arg & 255) < ISDNLOOP_BCH) {
|
|
char *p;
|
|
- char dial[50];
|
|
char dcode[4];
|
|
|
|
a = c->arg;
|
|
@@ -1204,10 +1211,10 @@ isdnloop_command(isdn_ctrl *c, isdnloop_card *card)
|
|
} else
|
|
/* Normal Dial */
|
|
strcpy(dcode, "CAL");
|
|
- strcpy(dial, p);
|
|
- sprintf(cbuf, "%02d;D%s_R%s,%02d,%02d,%s\n", (int) (a + 1),
|
|
- dcode, dial, c->parm.setup.si1,
|
|
- c->parm.setup.si2, c->parm.setup.eazmsn);
|
|
+ snprintf(cbuf, sizeof(cbuf),
|
|
+ "%02d;D%s_R%s,%02d,%02d,%s\n", (int) (a + 1),
|
|
+ dcode, p, c->parm.setup.si1,
|
|
+ c->parm.setup.si2, c->parm.setup.eazmsn);
|
|
i = isdnloop_writecmd(cbuf, strlen(cbuf), 0, card);
|
|
}
|
|
break;
|
|
diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c
|
|
index a3e5cdd1cf56..cd4966bcb2d2 100644
|
|
--- a/drivers/net/xen-netback/netback.c
|
|
+++ b/drivers/net/xen-netback/netback.c
|
|
@@ -338,8 +338,8 @@ static bool start_new_rx_buffer(int offset, unsigned long size, int head)
|
|
* into multiple copies tend to give large frags their
|
|
* own buffers as before.
|
|
*/
|
|
- if ((offset + size > MAX_BUFFER_OFFSET) &&
|
|
- (size <= MAX_BUFFER_OFFSET) && offset && !head)
|
|
+ BUG_ON(size > MAX_BUFFER_OFFSET);
|
|
+ if ((offset + size > MAX_BUFFER_OFFSET) && offset && !head)
|
|
return true;
|
|
|
|
return false;
|
|
diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
|
|
index 50a3cb5b589a..3fd908c5c0cc 100644
|
|
--- a/drivers/vhost/net.c
|
|
+++ b/drivers/vhost/net.c
|
|
@@ -324,9 +324,13 @@ static int get_rx_bufs(struct vhost_virtqueue *vq,
|
|
r = -ENOBUFS;
|
|
goto err;
|
|
}
|
|
- d = vhost_get_vq_desc(vq->dev, vq, vq->iov + seg,
|
|
+ r = vhost_get_vq_desc(vq->dev, vq, vq->iov + seg,
|
|
ARRAY_SIZE(vq->iov) - seg, &out,
|
|
&in, log, log_num);
|
|
+ if (unlikely(r < 0))
|
|
+ goto err;
|
|
+
|
|
+ d = r;
|
|
if (d == vq->num) {
|
|
r = 0;
|
|
goto err;
|
|
@@ -351,6 +355,12 @@ static int get_rx_bufs(struct vhost_virtqueue *vq,
|
|
*iovcount = seg;
|
|
if (unlikely(log))
|
|
*log_num = nlogs;
|
|
+
|
|
+ /* Detect overrun */
|
|
+ if (unlikely(datalen > 0)) {
|
|
+ r = UIO_MAXIOV + 1;
|
|
+ goto err;
|
|
+ }
|
|
return headcount;
|
|
err:
|
|
vhost_discard_vq_desc(vq, headcount);
|
|
@@ -405,6 +415,14 @@ static void handle_rx(struct vhost_net *net)
|
|
/* On error, stop handling until the next kick. */
|
|
if (unlikely(headcount < 0))
|
|
break;
|
|
+ /* On overrun, truncate and discard */
|
|
+ if (unlikely(headcount > UIO_MAXIOV)) {
|
|
+ msg.msg_iovlen = 1;
|
|
+ err = sock->ops->recvmsg(NULL, sock, &msg,
|
|
+ 1, MSG_DONTWAIT | MSG_TRUNC);
|
|
+ pr_debug("Discarded rx packet: len %zd\n", sock_len);
|
|
+ continue;
|
|
+ }
|
|
/* OK, now we need to know about added descriptors. */
|
|
if (!headcount) {
|
|
if (unlikely(vhost_enable_notify(&net->dev, vq))) {
|
|
diff --git a/fs/jffs2/compr_rtime.c b/fs/jffs2/compr_rtime.c
|
|
index 16a5047903a6..406d9cc84ba8 100644
|
|
--- a/fs/jffs2/compr_rtime.c
|
|
+++ b/fs/jffs2/compr_rtime.c
|
|
@@ -33,7 +33,7 @@ static int jffs2_rtime_compress(unsigned char *data_in,
|
|
unsigned char *cpage_out,
|
|
uint32_t *sourcelen, uint32_t *dstlen)
|
|
{
|
|
- short positions[256];
|
|
+ unsigned short positions[256];
|
|
int outpos = 0;
|
|
int pos=0;
|
|
|
|
@@ -74,7 +74,7 @@ static int jffs2_rtime_decompress(unsigned char *data_in,
|
|
unsigned char *cpage_out,
|
|
uint32_t srclen, uint32_t destlen)
|
|
{
|
|
- short positions[256];
|
|
+ unsigned short positions[256];
|
|
int outpos = 0;
|
|
int pos=0;
|
|
|
|
diff --git a/fs/jffs2/nodelist.h b/fs/jffs2/nodelist.h
|
|
index e4619b00f7c5..fa35ff79ab35 100644
|
|
--- a/fs/jffs2/nodelist.h
|
|
+++ b/fs/jffs2/nodelist.h
|
|
@@ -231,7 +231,7 @@ struct jffs2_tmp_dnode_info
|
|
uint32_t version;
|
|
uint32_t data_crc;
|
|
uint32_t partial_crc;
|
|
- uint16_t csize;
|
|
+ uint32_t csize;
|
|
uint16_t overlapped;
|
|
};
|
|
|
|
diff --git a/fs/jffs2/nodemgmt.c b/fs/jffs2/nodemgmt.c
|
|
index ffa8f12c7a54..87044bcc4137 100644
|
|
--- a/fs/jffs2/nodemgmt.c
|
|
+++ b/fs/jffs2/nodemgmt.c
|
|
@@ -139,6 +139,7 @@ int jffs2_reserve_space(struct jffs2_sb_info *c, uint32_t minsize,
|
|
spin_unlock(&c->erase_completion_lock);
|
|
|
|
schedule();
|
|
+ remove_wait_queue(&c->erase_wait, &wait);
|
|
} else
|
|
spin_unlock(&c->erase_completion_lock);
|
|
} else if (ret)
|
|
@@ -169,20 +170,25 @@ int jffs2_reserve_space(struct jffs2_sb_info *c, uint32_t minsize,
|
|
int jffs2_reserve_space_gc(struct jffs2_sb_info *c, uint32_t minsize,
|
|
uint32_t *len, uint32_t sumsize)
|
|
{
|
|
- int ret = -EAGAIN;
|
|
+ int ret;
|
|
minsize = PAD(minsize);
|
|
|
|
jffs2_dbg(1, "%s(): Requested 0x%x bytes\n", __func__, minsize);
|
|
|
|
- spin_lock(&c->erase_completion_lock);
|
|
- while(ret == -EAGAIN) {
|
|
+ while (true) {
|
|
+ spin_lock(&c->erase_completion_lock);
|
|
ret = jffs2_do_reserve_space(c, minsize, len, sumsize);
|
|
if (ret) {
|
|
jffs2_dbg(1, "%s(): looping, ret is %d\n",
|
|
__func__, ret);
|
|
}
|
|
+ spin_unlock(&c->erase_completion_lock);
|
|
+
|
|
+ if (ret == -EAGAIN)
|
|
+ cond_resched();
|
|
+ else
|
|
+ break;
|
|
}
|
|
- spin_unlock(&c->erase_completion_lock);
|
|
if (!ret)
|
|
ret = jffs2_prealloc_raw_node_refs(c, c->nextblock, 1);
|
|
|
|
diff --git a/kernel/exit.c b/kernel/exit.c
|
|
index bfbd85669694..3eb4dcfc658a 100644
|
|
--- a/kernel/exit.c
|
|
+++ b/kernel/exit.c
|
|
@@ -761,9 +761,6 @@ static void reparent_leader(struct task_struct *father, struct task_struct *p,
|
|
struct list_head *dead)
|
|
{
|
|
list_move_tail(&p->sibling, &p->real_parent->children);
|
|
-
|
|
- if (p->exit_state == EXIT_DEAD)
|
|
- return;
|
|
/*
|
|
* If this is a threaded reparent there is no need to
|
|
* notify anyone anything has happened.
|
|
@@ -771,9 +768,19 @@ static void reparent_leader(struct task_struct *father, struct task_struct *p,
|
|
if (same_thread_group(p->real_parent, father))
|
|
return;
|
|
|
|
- /* We don't want people slaying init. */
|
|
+ /*
|
|
+ * We don't want people slaying init.
|
|
+ *
|
|
+ * Note: we do this even if it is EXIT_DEAD, wait_task_zombie()
|
|
+ * can change ->exit_state to EXIT_ZOMBIE. If this is the final
|
|
+ * state, do_notify_parent() was already called and ->exit_signal
|
|
+ * doesn't matter.
|
|
+ */
|
|
p->exit_signal = SIGCHLD;
|
|
|
|
+ if (p->exit_state == EXIT_DEAD)
|
|
+ return;
|
|
+
|
|
/* If it has exited notify the new parent about this child's death. */
|
|
if (!p->ptrace &&
|
|
p->exit_state == EXIT_ZOMBIE && thread_group_empty(p)) {
|
|
diff --git a/lib/nlattr.c b/lib/nlattr.c
|
|
index 4226dfeb5178..01c67507dc43 100644
|
|
--- a/lib/nlattr.c
|
|
+++ b/lib/nlattr.c
|
|
@@ -299,9 +299,15 @@ int nla_memcmp(const struct nlattr *nla, const void *data,
|
|
*/
|
|
int nla_strcmp(const struct nlattr *nla, const char *str)
|
|
{
|
|
- int len = strlen(str) + 1;
|
|
- int d = nla_len(nla) - len;
|
|
+ int len = strlen(str);
|
|
+ char *buf = nla_data(nla);
|
|
+ int attrlen = nla_len(nla);
|
|
+ int d;
|
|
|
|
+ if (attrlen > 0 && buf[attrlen - 1] == '\0')
|
|
+ attrlen--;
|
|
+
|
|
+ d = attrlen - len;
|
|
if (d == 0)
|
|
d = memcmp(nla_data(nla), str, len);
|
|
|
|
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c
|
|
index c2029f732126..cf88c2f3b9e3 100644
|
|
--- a/net/8021q/vlan_dev.c
|
|
+++ b/net/8021q/vlan_dev.c
|
|
@@ -533,6 +533,9 @@ static int vlan_passthru_hard_header(struct sk_buff *skb, struct net_device *dev
|
|
struct vlan_dev_priv *vlan = vlan_dev_priv(dev);
|
|
struct net_device *real_dev = vlan->real_dev;
|
|
|
|
+ if (saddr == NULL)
|
|
+ saddr = dev->dev_addr;
|
|
+
|
|
return dev_hard_header(skb, real_dev, type, daddr, saddr, len);
|
|
}
|
|
|
|
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
|
|
index 1e6347cf77f2..21b2de18c3b7 100644
|
|
--- a/net/bluetooth/hci_event.c
|
|
+++ b/net/bluetooth/hci_event.c
|
|
@@ -3383,7 +3383,13 @@ static inline void hci_le_ltk_request_evt(struct hci_dev *hdev,
|
|
|
|
hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp);
|
|
|
|
- if (ltk->type & HCI_SMP_STK) {
|
|
+ /* Ref. Bluetooth Core SPEC pages 1975 and 2004. STK is a
|
|
+ * temporary key used to encrypt a connection following
|
|
+ * pairing. It is used during the Encrypted Session Setup to
|
|
+ * distribute the keys. Later, security can be re-established
|
|
+ * using a distributed LTK.
|
|
+ */
|
|
+ if (ltk->type == HCI_SMP_STK_SLAVE) {
|
|
list_del(<k->list);
|
|
kfree(ltk);
|
|
}
|
|
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c
|
|
index cef202a94112..0b870d75a542 100644
|
|
--- a/net/bridge/br_multicast.c
|
|
+++ b/net/bridge/br_multicast.c
|
|
@@ -1138,6 +1138,12 @@ static int br_ip6_multicast_query(struct net_bridge *br,
|
|
|
|
br_multicast_query_received(br, port, !ipv6_addr_any(&ip6h->saddr));
|
|
|
|
+ /* RFC2710+RFC3810 (MLDv1+MLDv2) require link-local source addresses */
|
|
+ if (!(ipv6_addr_type(&ip6h->saddr) & IPV6_ADDR_LINKLOCAL)) {
|
|
+ err = -EINVAL;
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
if (skb->len == sizeof(*mld)) {
|
|
if (!pskb_may_pull(skb, sizeof(*mld))) {
|
|
err = -EINVAL;
|
|
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
|
|
index abfa0074d59f..f976c3858df0 100644
|
|
--- a/net/ipv6/addrconf.c
|
|
+++ b/net/ipv6/addrconf.c
|
|
@@ -897,8 +897,11 @@ retry:
|
|
* Lifetime is greater than REGEN_ADVANCE time units. In particular,
|
|
* an implementation must not create a temporary address with a zero
|
|
* Preferred Lifetime.
|
|
+ * Use age calculation as in addrconf_verify to avoid unnecessary
|
|
+ * temporary addresses being generated.
|
|
*/
|
|
- if (tmp_prefered_lft <= regen_advance) {
|
|
+ age = (now - tmp_tstamp + ADDRCONF_TIMER_FUZZ_MINUS) / HZ;
|
|
+ if (tmp_prefered_lft <= regen_advance + age) {
|
|
in6_ifa_put(ifp);
|
|
in6_dev_put(idev);
|
|
ret = -1;
|
|
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
|
|
index dbf20f620936..50b124fe9a3a 100644
|
|
--- a/net/ipv6/icmp.c
|
|
+++ b/net/ipv6/icmp.c
|
|
@@ -501,7 +501,7 @@ void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info)
|
|
np->tclass, NULL, &fl6, (struct rt6_info*)dst,
|
|
MSG_DONTWAIT, np->dontfrag);
|
|
if (err) {
|
|
- ICMP6_INC_STATS_BH(net, idev, ICMP6_MIB_OUTERRORS);
|
|
+ ICMP6_INC_STATS(net, idev, ICMP6_MIB_OUTERRORS);
|
|
ip6_flush_pending_frames(sk);
|
|
} else {
|
|
err = icmpv6_push_pending_frames(sk, &fl6, &tmp_hdr,
|
|
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
|
|
index 8cd6854c2cae..5a2d819d8262 100644
|
|
--- a/net/ipv6/ip6_output.c
|
|
+++ b/net/ipv6/ip6_output.c
|
|
@@ -1194,21 +1194,19 @@ static void ip6_append_data_mtu(unsigned int *mtu,
|
|
unsigned int fragheaderlen,
|
|
struct sk_buff *skb,
|
|
struct rt6_info *rt,
|
|
- bool pmtuprobe)
|
|
+ unsigned int orig_mtu)
|
|
{
|
|
if (!(rt->dst.flags & DST_XFRM_TUNNEL)) {
|
|
if (skb == NULL) {
|
|
/* first fragment, reserve header_len */
|
|
- *mtu = *mtu - rt->dst.header_len;
|
|
+ *mtu = orig_mtu - rt->dst.header_len;
|
|
|
|
} else {
|
|
/*
|
|
* this fragment is not first, the headers
|
|
* space is regarded as data space.
|
|
*/
|
|
- *mtu = min(*mtu, pmtuprobe ?
|
|
- rt->dst.dev->mtu :
|
|
- dst_mtu(rt->dst.path));
|
|
+ *mtu = orig_mtu;
|
|
}
|
|
*maxfraglen = ((*mtu - fragheaderlen) & ~7)
|
|
+ fragheaderlen - sizeof(struct frag_hdr);
|
|
@@ -1225,7 +1223,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
|
|
struct ipv6_pinfo *np = inet6_sk(sk);
|
|
struct inet_cork *cork;
|
|
struct sk_buff *skb, *skb_prev = NULL;
|
|
- unsigned int maxfraglen, fragheaderlen, mtu;
|
|
+ unsigned int maxfraglen, fragheaderlen, mtu, orig_mtu;
|
|
int exthdrlen;
|
|
int dst_exthdrlen;
|
|
int hh_len;
|
|
@@ -1310,6 +1308,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
|
|
dst_exthdrlen = 0;
|
|
mtu = cork->fragsize;
|
|
}
|
|
+ orig_mtu = mtu;
|
|
|
|
hh_len = LL_RESERVED_SPACE(rt->dst.dev);
|
|
|
|
@@ -1392,8 +1391,7 @@ alloc_new_skb:
|
|
if (skb == NULL || skb_prev == NULL)
|
|
ip6_append_data_mtu(&mtu, &maxfraglen,
|
|
fragheaderlen, skb, rt,
|
|
- np->pmtudisc ==
|
|
- IPV6_PMTUDISC_PROBE);
|
|
+ orig_mtu);
|
|
|
|
skb_prev = skb;
|
|
|
|
@@ -1663,8 +1661,8 @@ int ip6_push_pending_frames(struct sock *sk)
|
|
if (proto == IPPROTO_ICMPV6) {
|
|
struct inet6_dev *idev = ip6_dst_idev(skb_dst(skb));
|
|
|
|
- ICMP6MSGOUT_INC_STATS_BH(net, idev, icmp6_hdr(skb)->icmp6_type);
|
|
- ICMP6_INC_STATS_BH(net, idev, ICMP6_MIB_OUTMSGS);
|
|
+ ICMP6MSGOUT_INC_STATS(net, idev, icmp6_hdr(skb)->icmp6_type);
|
|
+ ICMP6_INC_STATS(net, idev, ICMP6_MIB_OUTMSGS);
|
|
}
|
|
|
|
err = ip6_local_out(skb);
|
|
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
|
|
index 9728df5c569e..e027bf21c6f4 100644
|
|
--- a/net/ipv6/mcast.c
|
|
+++ b/net/ipv6/mcast.c
|
|
@@ -1430,11 +1430,12 @@ static void mld_sendpack(struct sk_buff *skb)
|
|
dst_output);
|
|
out:
|
|
if (!err) {
|
|
- ICMP6MSGOUT_INC_STATS_BH(net, idev, ICMPV6_MLD2_REPORT);
|
|
- ICMP6_INC_STATS_BH(net, idev, ICMP6_MIB_OUTMSGS);
|
|
- IP6_UPD_PO_STATS_BH(net, idev, IPSTATS_MIB_OUTMCAST, payload_len);
|
|
- } else
|
|
- IP6_INC_STATS_BH(net, idev, IPSTATS_MIB_OUTDISCARDS);
|
|
+ ICMP6MSGOUT_INC_STATS(net, idev, ICMPV6_MLD2_REPORT);
|
|
+ ICMP6_INC_STATS(net, idev, ICMP6_MIB_OUTMSGS);
|
|
+ IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_OUTMCAST, payload_len);
|
|
+ } else {
|
|
+ IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTDISCARDS);
|
|
+ }
|
|
|
|
rcu_read_unlock();
|
|
return;
|
|
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
|
|
index 335b16fccb9d..b685f99ffb18 100644
|
|
--- a/net/ipv6/route.c
|
|
+++ b/net/ipv6/route.c
|
|
@@ -1302,7 +1302,7 @@ int ip6_route_add(struct fib6_config *cfg)
|
|
if (!table)
|
|
goto out;
|
|
|
|
- rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops, NULL, DST_NOCOUNT);
|
|
+ rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops, NULL, (cfg->fc_flags & RTF_ADDRCONF) ? 0 : DST_NOCOUNT);
|
|
|
|
if (!rt) {
|
|
err = -ENOMEM;
|
|
diff --git a/net/rds/iw.c b/net/rds/iw.c
|
|
index 7826d46baa70..589935661d66 100644
|
|
--- a/net/rds/iw.c
|
|
+++ b/net/rds/iw.c
|
|
@@ -239,7 +239,8 @@ static int rds_iw_laddr_check(__be32 addr)
|
|
ret = rdma_bind_addr(cm_id, (struct sockaddr *)&sin);
|
|
/* due to this, we will claim to support IB devices unless we
|
|
check node_type. */
|
|
- if (ret || cm_id->device->node_type != RDMA_NODE_RNIC)
|
|
+ if (ret || !cm_id->device ||
|
|
+ cm_id->device->node_type != RDMA_NODE_RNIC)
|
|
ret = -EADDRNOTAVAIL;
|
|
|
|
rdsdebug("addr %pI4 ret %d node type %d\n",
|
|
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
|
|
index a85eeeb55dd0..adb028746270 100644
|
|
--- a/net/sctp/sm_make_chunk.c
|
|
+++ b/net/sctp/sm_make_chunk.c
|
|
@@ -1366,8 +1366,8 @@ static void sctp_chunk_destroy(struct sctp_chunk *chunk)
|
|
BUG_ON(!list_empty(&chunk->list));
|
|
list_del_init(&chunk->transmitted_list);
|
|
|
|
- /* Free the chunk skb data and the SCTP_chunk stub itself. */
|
|
- dev_kfree_skb(chunk->skb);
|
|
+ consume_skb(chunk->skb);
|
|
+ consume_skb(chunk->auth_chunk);
|
|
|
|
SCTP_DBG_OBJCNT_DEC(chunk);
|
|
kmem_cache_free(sctp_chunk_cachep, chunk);
|
|
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
|
|
index f131caf06a19..5ac33b600538 100644
|
|
--- a/net/sctp/sm_statefuns.c
|
|
+++ b/net/sctp/sm_statefuns.c
|
|
@@ -749,7 +749,6 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(const struct sctp_endpoint *ep,
|
|
|
|
/* Make sure that we and the peer are AUTH capable */
|
|
if (!sctp_auth_enable || !new_asoc->peer.auth_capable) {
|
|
- kfree_skb(chunk->auth_chunk);
|
|
sctp_association_free(new_asoc);
|
|
return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
|
|
}
|
|
@@ -764,10 +763,6 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(const struct sctp_endpoint *ep,
|
|
auth.transport = chunk->transport;
|
|
|
|
ret = sctp_sf_authenticate(ep, new_asoc, type, &auth);
|
|
-
|
|
- /* We can now safely free the auth_chunk clone */
|
|
- kfree_skb(chunk->auth_chunk);
|
|
-
|
|
if (ret != SCTP_IERROR_NO_ERROR) {
|
|
sctp_association_free(new_asoc);
|
|
return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
|
|
diff --git a/net/socket.c b/net/socket.c
|
|
index 4006452e8475..cc3fc4d4263e 100644
|
|
--- a/net/socket.c
|
|
+++ b/net/socket.c
|
|
@@ -1907,6 +1907,10 @@ static int copy_msghdr_from_user(struct msghdr *kmsg,
|
|
{
|
|
if (copy_from_user(kmsg, umsg, sizeof(struct msghdr)))
|
|
return -EFAULT;
|
|
+
|
|
+ if (kmsg->msg_namelen < 0)
|
|
+ return -EINVAL;
|
|
+
|
|
if (kmsg->msg_namelen > sizeof(struct sockaddr_storage))
|
|
kmsg->msg_namelen = sizeof(struct sockaddr_storage);
|
|
return 0;
|
|
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
|
|
index c0a81a50bd4e..09a84c9f2f59 100644
|
|
--- a/net/unix/af_unix.c
|
|
+++ b/net/unix/af_unix.c
|
|
@@ -1787,8 +1787,11 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock,
|
|
goto out;
|
|
|
|
err = mutex_lock_interruptible(&u->readlock);
|
|
- if (err) {
|
|
- err = sock_intr_errno(sock_rcvtimeo(sk, noblock));
|
|
+ if (unlikely(err)) {
|
|
+ /* recvmsg() in non blocking mode is supposed to return -EAGAIN
|
|
+ * sk_rcvtimeo is not honored by mutex_lock_interruptible()
|
|
+ */
|
|
+ err = noblock ? -EAGAIN : -ERESTARTSYS;
|
|
goto out;
|
|
}
|
|
|
|
@@ -1910,6 +1913,7 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
|
|
struct unix_sock *u = unix_sk(sk);
|
|
struct sockaddr_un *sunaddr = msg->msg_name;
|
|
int copied = 0;
|
|
+ int noblock = flags & MSG_DONTWAIT;
|
|
int check_creds = 0;
|
|
int target;
|
|
int err = 0;
|
|
@@ -1925,7 +1929,7 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
|
|
goto out;
|
|
|
|
target = sock_rcvlowat(sk, flags&MSG_WAITALL, size);
|
|
- timeo = sock_rcvtimeo(sk, flags&MSG_DONTWAIT);
|
|
+ timeo = sock_rcvtimeo(sk, noblock);
|
|
|
|
/* Lock the socket to prevent queue disordering
|
|
* while sleeps in memcpy_tomsg
|
|
@@ -1937,8 +1941,11 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
|
|
}
|
|
|
|
err = mutex_lock_interruptible(&u->readlock);
|
|
- if (err) {
|
|
- err = sock_intr_errno(timeo);
|
|
+ if (unlikely(err)) {
|
|
+ /* recvmsg() in non blocking mode is supposed to return -EAGAIN
|
|
+ * sk_rcvtimeo is not honored by mutex_lock_interruptible()
|
|
+ */
|
|
+ err = noblock ? -EAGAIN : -ERESTARTSYS;
|
|
goto out;
|
|
}
|
|
|