Commit 85a33188 authored by Linus Torvalds's avatar Linus Torvalds

Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6: (27 commits)
  net: clear heap allocation for ETHTOOL_GRXCLSRLALL
  isdn: strcpy() => strlcpy()
  Revert "mac80211: use netif_receive_skb in ieee80211_tx_status callpath"
  mac80211: delete AddBA response timer
  ath9k_hw: fix regression in ANI listen time calculation
  caif: fix two caif_connect() bugs
  bonding: fix WARN_ON when writing to bond_master sysfs file
  skge: add quirk to limit DMA
  MAINTAINERS: update Intel LAN Ethernet info
  e1000e.txt: Add e1000e documentation
  e1000.txt: Update e1000 documentation
  ixgbevf.txt: Update ixgbevf documentation
  cls_u32: signedness bug
  Bluetooth: Disallow to change L2CAP_OPTIONS values when connected
  sctp: Fix out-of-bounds reading in sctp_asoc_get_hmac()
  sctp: prevent reading out-of-bounds memory
  ipv4: correct IGMP behavior on v3 query during v2-compatibility mode
  netdev: Depend on INET before selecting INET_LRO
  Revert "ipv4: Make INET_LRO a bool instead of tristate."
  net: Fix the condition passed to sk_wait_event()
  ...
parents 63847e66 ae6df5f9
This diff is collapsed.
This diff is collapsed.
Linux* Base Driver for Intel(R) Network Connection
==================================================
November 24, 2009
Intel Gigabit Linux driver.
Copyright(c) 1999 - 2010 Intel Corporation.
Contents
========
- In This Release
- Identifying Your Adapter
- Known Issues/Troubleshooting
- Support
In This Release
===============
This file describes the ixgbevf Linux* Base Driver for Intel Network
Connection.
......@@ -33,7 +30,7 @@ Identifying Your Adapter
For more information on how to identify your adapter, go to the Adapter &
Driver ID Guide at:
http://support.intel.com/support/network/sb/CS-008441.htm
http://support.intel.com/support/go/network/adapter/idguide.htm
Known Issues/Troubleshooting
============================
......@@ -57,34 +54,3 @@ or the Intel Wired Networking project hosted by Sourceforge at:
If an issue is identified with the released source code on the supported
kernel with a supported adapter, email the specific information related
to the issue to e1000-devel@lists.sf.net
License
=======
Intel 10 Gigabit Linux driver.
Copyright(c) 1999 - 2009 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
version 2, as published by the Free Software Foundation.
This program is distributed in the hope it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
The full GNU General Public License is included in this distribution in
the file called "COPYING".
Trademarks
==========
Intel, Itanium, and Pentium are trademarks or registered trademarks of
Intel Corporation or its subsidiaries in the United States and other
countries.
* Other names and brands may be claimed as the property of others.
......@@ -3073,16 +3073,27 @@ L: netdev@vger.kernel.org
S: Maintained
F: drivers/net/ixp2000/
INTEL ETHERNET DRIVERS (e100/e1000/e1000e/igb/igbvf/ixgb/ixgbe)
INTEL ETHERNET DRIVERS (e100/e1000/e1000e/igb/igbvf/ixgb/ixgbe/ixgbevf)
M: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
M: Jesse Brandeburg <jesse.brandeburg@intel.com>
M: Bruce Allan <bruce.w.allan@intel.com>
M: Alex Duyck <alexander.h.duyck@intel.com>
M: Carolyn Wyborny <carolyn.wyborny@intel.com>
M: Don Skidmore <donald.c.skidmore@intel.com>
M: Greg Rose <gregory.v.rose@intel.com>
M: PJ Waskiewicz <peter.p.waskiewicz.jr@intel.com>
M: Alex Duyck <alexander.h.duyck@intel.com>
M: John Ronciak <john.ronciak@intel.com>
L: e1000-devel@lists.sourceforge.net
W: http://e1000.sourceforge.net/
S: Supported
F: Documentation/networking/e100.txt
F: Documentation/networking/e1000.txt
F: Documentation/networking/e1000e.txt
F: Documentation/networking/igb.txt
F: Documentation/networking/igbvf.txt
F: Documentation/networking/ixgb.txt
F: Documentation/networking/ixgbe.txt
F: Documentation/networking/ixgbevf.txt
F: drivers/net/e100.c
F: drivers/net/e1000/
F: drivers/net/e1000e/
......@@ -3090,6 +3101,7 @@ F: drivers/net/igb/
F: drivers/net/igbvf/
F: drivers/net/ixgb/
F: drivers/net/ixgbe/
F: drivers/net/ixgbevf/
INTEL PRO/WIRELESS 2100 NETWORK CONNECTION SUPPORT
L: linux-wireless@vger.kernel.org
......
......@@ -112,11 +112,19 @@ irqreturn_t interrupt_handler(int dummy, void *card_inst)
}
else if(callid>=0x0000 && callid<=0x7FFF)
{
int len;
pr_debug("%s: Got Incoming Call\n",
sc_adapter[card]->devicename);
strcpy(setup.phone,&(rcvmsg.msg_data.byte_array[4]));
strcpy(setup.eazmsn,
sc_adapter[card]->channel[rcvmsg.phy_link_no-1].dn);
len = strlcpy(setup.phone, &(rcvmsg.msg_data.byte_array[4]),
sizeof(setup.phone));
if (len >= sizeof(setup.phone))
continue;
len = strlcpy(setup.eazmsn,
sc_adapter[card]->channel[rcvmsg.phy_link_no - 1].dn,
sizeof(setup.eazmsn));
if (len >= sizeof(setup.eazmsn))
continue;
setup.si1 = 7;
setup.si2 = 0;
setup.plan = 0;
......@@ -176,7 +184,9 @@ irqreturn_t interrupt_handler(int dummy, void *card_inst)
* Handle a GetMyNumber Rsp
*/
if (IS_CE_MESSAGE(rcvmsg,Call,0,GetMyNumber)){
strcpy(sc_adapter[card]->channel[rcvmsg.phy_link_no-1].dn,rcvmsg.msg_data.byte_array);
strlcpy(sc_adapter[card]->channel[rcvmsg.phy_link_no - 1].dn,
rcvmsg.msg_data.byte_array,
sizeof(rcvmsg.msg_data.byte_array));
continue;
}
......
......@@ -2428,7 +2428,7 @@ config UGETH_TX_ON_DEMAND
config MV643XX_ETH
tristate "Marvell Discovery (643XX) and Orion ethernet support"
depends on MV64X60 || PPC32 || PLAT_ORION
depends on (MV64X60 || PPC32 || PLAT_ORION) && INET
select INET_LRO
select PHYLIB
help
......@@ -2803,7 +2803,7 @@ config NIU
config PASEMI_MAC
tristate "PA Semi 1/10Gbit MAC"
depends on PPC_PASEMI && PCI
depends on PPC_PASEMI && PCI && INET
select PHYLIB
select INET_LRO
help
......
......@@ -5164,6 +5164,15 @@ int bond_create(struct net *net, const char *name)
res = dev_alloc_name(bond_dev, "bond%d");
if (res < 0)
goto out;
} else {
/*
* If we're given a name to register
* we need to ensure that its not already
* registered
*/
res = -EEXIST;
if (__dev_get_by_name(net, name) != NULL)
goto out;
}
res = register_netdevice(bond_dev);
......
......@@ -43,6 +43,7 @@
#include <linux/seq_file.h>
#include <linux/mii.h>
#include <linux/slab.h>
#include <linux/dmi.h>
#include <asm/irq.h>
#include "skge.h"
......@@ -3868,6 +3869,8 @@ static void __devinit skge_show_addr(struct net_device *dev)
netif_info(skge, probe, skge->netdev, "addr %pM\n", dev->dev_addr);
}
static int only_32bit_dma;
static int __devinit skge_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
......@@ -3889,7 +3892,7 @@ static int __devinit skge_probe(struct pci_dev *pdev,
pci_set_master(pdev);
if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
if (!only_32bit_dma && !pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
using_dac = 1;
err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
} else if (!(err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)))) {
......@@ -4147,8 +4150,21 @@ static struct pci_driver skge_driver = {
.shutdown = skge_shutdown,
};
static struct dmi_system_id skge_32bit_dma_boards[] = {
{
.ident = "Gigabyte nForce boards",
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "Gigabyte Technology Co"),
DMI_MATCH(DMI_BOARD_NAME, "nForce"),
},
},
{}
};
static int __init skge_init_module(void)
{
if (dmi_check_system(skge_32bit_dma_boards))
only_32bit_dma = 1;
skge_debug_init();
return pci_register_driver(&skge_driver);
}
......
......@@ -543,7 +543,7 @@ static u8 ath9k_hw_chan_2_clockrate_mhz(struct ath_hw *ah)
if (conf_is_ht40(conf))
return clockrate * 2;
return clockrate * 2;
return clockrate;
}
static int32_t ath9k_hw_ani_get_listen_time(struct ath_hw *ah)
......
......@@ -161,12 +161,30 @@ static inline struct sk_buff *bt_skb_send_alloc(struct sock *sk, unsigned long l
{
struct sk_buff *skb;
release_sock(sk);
if ((skb = sock_alloc_send_skb(sk, len + BT_SKB_RESERVE, nb, err))) {
skb_reserve(skb, BT_SKB_RESERVE);
bt_cb(skb)->incoming = 0;
}
lock_sock(sk);
if (!skb && *err)
return NULL;
*err = sock_error(sk);
if (*err)
goto out;
if (sk->sk_shutdown) {
*err = -ECONNRESET;
goto out;
}
return skb;
out:
kfree_skb(skb);
return NULL;
}
int bt_err(__u16 code);
......
......@@ -1441,33 +1441,23 @@ static inline void l2cap_do_send(struct sock *sk, struct sk_buff *skb)
static void l2cap_streaming_send(struct sock *sk)
{
struct sk_buff *skb, *tx_skb;
struct sk_buff *skb;
struct l2cap_pinfo *pi = l2cap_pi(sk);
u16 control, fcs;
while ((skb = sk->sk_send_head)) {
tx_skb = skb_clone(skb, GFP_ATOMIC);
control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
while ((skb = skb_dequeue(TX_QUEUE(sk)))) {
control = get_unaligned_le16(skb->data + L2CAP_HDR_SIZE);
control |= pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT;
put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
put_unaligned_le16(control, skb->data + L2CAP_HDR_SIZE);
if (pi->fcs == L2CAP_FCS_CRC16) {
fcs = crc16(0, (u8 *)tx_skb->data, tx_skb->len - 2);
put_unaligned_le16(fcs, tx_skb->data + tx_skb->len - 2);
fcs = crc16(0, (u8 *)skb->data, skb->len - 2);
put_unaligned_le16(fcs, skb->data + skb->len - 2);
}
l2cap_do_send(sk, tx_skb);
l2cap_do_send(sk, skb);
pi->next_tx_seq = (pi->next_tx_seq + 1) % 64;
if (skb_queue_is_last(TX_QUEUE(sk), skb))
sk->sk_send_head = NULL;
else
sk->sk_send_head = skb_queue_next(TX_QUEUE(sk), skb);
skb = skb_dequeue(TX_QUEUE(sk));
kfree_skb(skb);
}
}
......@@ -1960,6 +1950,11 @@ static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __us
switch (optname) {
case L2CAP_OPTIONS:
if (sk->sk_state == BT_CONNECTED) {
err = -EINVAL;
break;
}
opts.imtu = l2cap_pi(sk)->imtu;
opts.omtu = l2cap_pi(sk)->omtu;
opts.flush_to = l2cap_pi(sk)->flush_to;
......@@ -2771,10 +2766,10 @@ static int l2cap_parse_conf_rsp(struct sock *sk, void *rsp, int len, void *data,
case L2CAP_CONF_MTU:
if (val < L2CAP_DEFAULT_MIN_MTU) {
*result = L2CAP_CONF_UNACCEPT;
pi->omtu = L2CAP_DEFAULT_MIN_MTU;
pi->imtu = L2CAP_DEFAULT_MIN_MTU;
} else
pi->omtu = val;
l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu);
pi->imtu = val;
l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu);
break;
case L2CAP_CONF_FLUSH_TO:
......@@ -3071,6 +3066,17 @@ static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hd
return 0;
}
static inline void set_default_fcs(struct l2cap_pinfo *pi)
{
/* FCS is enabled only in ERTM or streaming mode, if one or both
* sides request it.
*/
if (pi->mode != L2CAP_MODE_ERTM && pi->mode != L2CAP_MODE_STREAMING)
pi->fcs = L2CAP_FCS_NONE;
else if (!(pi->conf_state & L2CAP_CONF_NO_FCS_RECV))
pi->fcs = L2CAP_FCS_CRC16;
}
static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data)
{
struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
......@@ -3088,14 +3094,8 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr
if (!sk)
return -ENOENT;
if (sk->sk_state != BT_CONFIG) {
struct l2cap_cmd_rej rej;
rej.reason = cpu_to_le16(0x0002);
l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ,
sizeof(rej), &rej);
if (sk->sk_state == BT_DISCONN)
goto unlock;
}
/* Reject if config buffer is too small. */
len = cmd_len - sizeof(*req);
......@@ -3135,9 +3135,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr
goto unlock;
if (l2cap_pi(sk)->conf_state & L2CAP_CONF_INPUT_DONE) {
if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_NO_FCS_RECV) ||
l2cap_pi(sk)->fcs != L2CAP_FCS_NONE)
l2cap_pi(sk)->fcs = L2CAP_FCS_CRC16;
set_default_fcs(l2cap_pi(sk));
sk->sk_state = BT_CONNECTED;
......@@ -3225,9 +3223,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr
l2cap_pi(sk)->conf_state |= L2CAP_CONF_INPUT_DONE;
if (l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE) {
if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_NO_FCS_RECV) ||
l2cap_pi(sk)->fcs != L2CAP_FCS_NONE)
l2cap_pi(sk)->fcs = L2CAP_FCS_CRC16;
set_default_fcs(l2cap_pi(sk));
sk->sk_state = BT_CONNECTED;
l2cap_pi(sk)->next_tx_seq = 0;
......
......@@ -82,11 +82,14 @@ static void rfcomm_sk_data_ready(struct rfcomm_dlc *d, struct sk_buff *skb)
static void rfcomm_sk_state_change(struct rfcomm_dlc *d, int err)
{
struct sock *sk = d->owner, *parent;
unsigned long flags;
if (!sk)
return;
BT_DBG("dlc %p state %ld err %d", d, d->state, err);
local_irq_save(flags);
bh_lock_sock(sk);
if (err)
......@@ -108,6 +111,7 @@ static void rfcomm_sk_state_change(struct rfcomm_dlc *d, int err)
}
bh_unlock_sock(sk);
local_irq_restore(flags);
if (parent && sock_flag(sk, SOCK_ZAPPED)) {
/* We have to drop DLC lock here, otherwise
......
......@@ -827,6 +827,7 @@ static int caif_connect(struct socket *sock, struct sockaddr *uaddr,
long timeo;
int err;
int ifindex, headroom, tailroom;
unsigned int mtu;
struct net_device *dev;
lock_sock(sk);
......@@ -896,15 +897,23 @@ static int caif_connect(struct socket *sock, struct sockaddr *uaddr,
cf_sk->sk.sk_state = CAIF_DISCONNECTED;
goto out;
}
dev = dev_get_by_index(sock_net(sk), ifindex);
err = -ENODEV;
rcu_read_lock();
dev = dev_get_by_index_rcu(sock_net(sk), ifindex);
if (!dev) {
rcu_read_unlock();
goto out;
}
cf_sk->headroom = LL_RESERVED_SPACE_EXTRA(dev, headroom);
mtu = dev->mtu;
rcu_read_unlock();
cf_sk->tailroom = tailroom;
cf_sk->maxframe = dev->mtu - (headroom + tailroom);
dev_put(dev);
cf_sk->maxframe = mtu - (headroom + tailroom);
if (cf_sk->maxframe < 1) {
pr_warning("CAIF: %s(): CAIF Interface MTU too small (%d)\n",
__func__, dev->mtu);
err = -ENODEV;
pr_warning("CAIF: %s(): CAIF Interface MTU too small (%u)\n",
__func__, mtu);
goto out;
}
......
......@@ -348,7 +348,7 @@ static noinline_for_stack int ethtool_get_rxnfc(struct net_device *dev,
if (info.cmd == ETHTOOL_GRXCLSRLALL) {
if (info.rule_cnt > 0) {
if (info.rule_cnt <= KMALLOC_MAX_SIZE / sizeof(u32))
rule_buf = kmalloc(info.rule_cnt * sizeof(u32),
rule_buf = kzalloc(info.rule_cnt * sizeof(u32),
GFP_USER);
if (!rule_buf)
return -ENOMEM;
......
......@@ -141,10 +141,10 @@ int sk_stream_wait_memory(struct sock *sk, long *timeo_p)
set_bit(SOCK_NOSPACE, &sk->sk_socket->flags);
sk->sk_write_pending++;
sk_wait_event(sk, &current_timeo, !sk->sk_err &&
!(sk->sk_shutdown & SEND_SHUTDOWN) &&
sk_stream_memory_free(sk) &&
vm_wait);
sk_wait_event(sk, &current_timeo, sk->sk_err ||
(sk->sk_shutdown & SEND_SHUTDOWN) ||
(sk_stream_memory_free(sk) &&
!vm_wait));
sk->sk_write_pending--;
if (vm_wait) {
......
......@@ -413,7 +413,7 @@ config INET_XFRM_MODE_BEET
If unsure, say Y.
config INET_LRO
bool "Large Receive Offload (ipv4/tcp)"
tristate "Large Receive Offload (ipv4/tcp)"
default y
---help---
Support for Large Receive Offload (ipv4/tcp).
......
......@@ -834,7 +834,7 @@ static void igmp_heard_query(struct in_device *in_dev, struct sk_buff *skb,
int mark = 0;
if (len == 8 || IGMP_V2_SEEN(in_dev)) {
if (len == 8) {
if (ih->code == 0) {
/* Alas, old v1 router presents here. */
......@@ -856,6 +856,18 @@ static void igmp_heard_query(struct in_device *in_dev, struct sk_buff *skb,
igmpv3_clear_delrec(in_dev);
} else if (len < 12) {
return; /* ignore bogus packet; freed by caller */
} else if (IGMP_V1_SEEN(in_dev)) {
/* This is a v3 query with v1 queriers present */
max_delay = IGMP_Query_Response_Interval;
group = 0;
} else if (IGMP_V2_SEEN(in_dev)) {
/* this is a v3 query with v2 queriers present;
* Interpretation of the max_delay code is problematic here.
* A real v2 host would use ih_code directly, while v3 has a
* different encoding. We use the v3 encoding as more likely
* to be intended in a v3 query.
*/
max_delay = IGMPV3_MRC(ih3->code)*(HZ/IGMP_TIMER_SCALE);
} else { /* v3 */
if (!pskb_may_pull(skb, sizeof(struct igmpv3_query)))
return;
......
......@@ -1556,14 +1556,13 @@ void rt6_redirect(struct in6_addr *dest, struct in6_addr *src,
* i.e. Path MTU discovery
*/
void rt6_pmtu_discovery(struct in6_addr *daddr, struct in6_addr *saddr,
struct net_device *dev, u32 pmtu)
static void rt6_do_pmtu_disc(struct in6_addr *daddr, struct in6_addr *saddr,
struct net *net, u32 pmtu, int ifindex)
{
struct rt6_info *rt, *nrt;
struct net *net = dev_net(dev);
int allfrag = 0;
rt = rt6_lookup(net, daddr, saddr, dev->ifindex, 0);
rt = rt6_lookup(net, daddr, saddr, ifindex, 0);
if (rt == NULL)
return;
......@@ -1631,6 +1630,27 @@ void rt6_pmtu_discovery(struct in6_addr *daddr, struct in6_addr *saddr,
dst_release(&rt->dst);
}
void rt6_pmtu_discovery(struct in6_addr *daddr, struct in6_addr *saddr,
struct net_device *dev, u32 pmtu)
{
struct net *net = dev_net(dev);
/*
* RFC 1981 states that a node "MUST reduce the size of the packets it
* is sending along the path" that caused the Packet Too Big message.
* Since it's not possible in the general case to determine which
* interface was used to send the original packet, we update the MTU
* on the interface that will be used to send future packets. We also
* update the MTU on the interface that received the Packet Too Big in
* case the original packet was forced out that interface with
* SO_BINDTODEVICE or similar. This is the next best thing to the
* correct behaviour, which would be to update the MTU on all
* interfaces.
*/
rt6_do_pmtu_disc(daddr, saddr, net, pmtu, 0);
rt6_do_pmtu_disc(daddr, saddr, net, pmtu, dev->ifindex);
}
/*
* Misc support functions
*/
......
......@@ -175,6 +175,8 @@ int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
set_bit(HT_AGG_STATE_STOPPING, &tid_tx->state);
del_timer_sync(&tid_tx->addba_resp_timer);
/*
* After this packets are no longer handed right through
* to the driver but are put onto tid_tx->pending instead,
......
......@@ -377,7 +377,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
skb2 = skb_clone(skb, GFP_ATOMIC);
if (skb2) {
skb2->dev = prev_dev;
netif_receive_skb(skb2);
netif_rx(skb2);
}
}
......@@ -386,7 +386,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
}
if (prev_dev) {
skb->dev = prev_dev;
netif_receive_skb(skb);
netif_rx(skb);
skb = NULL;
}
rcu_read_unlock();
......
......@@ -137,7 +137,7 @@ static int u32_classify(struct sk_buff *skb, struct tcf_proto *tp, struct tcf_re
int toff = off + key->off + (off2 & key->offmask);
__be32 *data, _data;
if (skb_headroom(skb) + toff < 0)
if (skb_headroom(skb) + toff > INT_MAX)
goto out;
data = skb_header_pointer(skb, toff, 4, &_data);
......
......@@ -543,16 +543,20 @@ struct sctp_hmac *sctp_auth_asoc_get_hmac(const struct sctp_association *asoc)
id = ntohs(hmacs->hmac_ids[i]);
/* Check the id is in the supported range */
if (id > SCTP_AUTH_HMAC_ID_MAX)
if (id > SCTP_AUTH_HMAC_ID_MAX) {
id = 0;
continue;
}
/* See is we support the id. Supported IDs have name and
* length fields set, so that we can allocated and use
* them. We can safely just check for name, for without the
* name, we can't allocate the TFM.
*/
if (!sctp_hmac_list[id].hmac_name)
if (!sctp_hmac_list[id].hmac_name) {
id = 0;
continue;
}
break;
}
......
......@@ -916,6 +916,11 @@ SCTP_STATIC int sctp_setsockopt_bindx(struct sock* sk,
/* Walk through the addrs buffer and count the number of addresses. */
addr_buf = kaddrs;
while (walk_size < addrs_size) {
if (walk_size + sizeof(sa_family_t) > addrs_size) {
kfree(kaddrs);
return -EINVAL;
}
sa_addr = (struct sockaddr *)addr_buf;
af = sctp_get_af_specific(sa_addr->sa_family);
......@@ -1002,9 +1007,13 @@ static int __sctp_connect(struct sock* sk,
/* Walk through the addrs buffer and count the number of addresses. */
addr_buf = kaddrs;
while (walk_size < addrs_size) {
if (walk_size + sizeof(sa_family_t) > addrs_size) {
err = -EINVAL;
goto out_free;
}
sa_addr = (union sctp_addr *)addr_buf;
af = sctp_get_af_specific(sa_addr->sa.sa_family);
port = ntohs(sa_addr->v4.sin_port);
/* If the address family is not supported or if this address
* causes the address buffer to overflow return EINVAL.
......@@ -1014,6 +1023,8 @@ static int __sctp_connect(struct sock* sk,
goto out_free;
}
port = ntohs(sa_addr->v4.sin_port);
/* Save current address so we can work with it */
memcpy(&to, sa_addr, af->sockaddr_len);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment