From 2d192d9552881f4cf88e62072047c72ef2b5aa7f Mon Sep 17 00:00:00 2001 From: Michael Wu Date: Sat, 10 Nov 2007 00:15:25 -0500 Subject: [PATCH 01/23] mac80211: Drop out of associated state if link is lost There is no point in staying in IEEE80211_ASSOCIATED if there is no sta_info entry to receive frames with. Signed-off-by: Michael Wu Signed-off-by: John W. Linville --- net/mac80211/ieee80211_sta.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/net/mac80211/ieee80211_sta.c b/net/mac80211/ieee80211_sta.c index 16afd24d4f6b..bee8080f2249 100644 --- a/net/mac80211/ieee80211_sta.c +++ b/net/mac80211/ieee80211_sta.c @@ -808,12 +808,8 @@ static void ieee80211_associated(struct net_device *dev, sta_info_put(sta); } if (disassoc) { - union iwreq_data wrqu; - memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN); - wrqu.ap_addr.sa_family = ARPHRD_ETHER; - wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL); - mod_timer(&ifsta->timer, jiffies + - IEEE80211_MONITORING_INTERVAL + 30 * HZ); + ifsta->state = IEEE80211_DISABLED; + ieee80211_set_associated(dev, ifsta, 0); } else { mod_timer(&ifsta->timer, jiffies + IEEE80211_MONITORING_INTERVAL); From 3333590e94262aebb5d0fb767cc7ed8b2359705c Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 12 Dec 2007 16:31:52 +0100 Subject: [PATCH 02/23] mac80211: fix header ops When using recvfrom() on a SOCK_DGRAM packet socket, I noticed that the MAC address passed back for wireless frames was always completely wrong. The reason for this is that the header parse function assigned to our virtual interfaces is a function parsing an 802.11 rather than 802.3 header. This patch fixes it by keeping the default ethernet header operations assigned. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/ieee80211.c | 1 - 1 file changed, 1 deletion(-) diff --git a/net/mac80211/ieee80211.c b/net/mac80211/ieee80211.c index 505af1f067ab..6378850d8580 100644 --- a/net/mac80211/ieee80211.c +++ b/net/mac80211/ieee80211.c @@ -427,7 +427,6 @@ static const struct header_ops ieee80211_header_ops = { void ieee80211_if_setup(struct net_device *dev) { ether_setup(dev); - dev->header_ops = &ieee80211_header_ops; dev->hard_start_xmit = ieee80211_subif_start_xmit; dev->wireless_handlers = &ieee80211_iw_handler_def; dev->set_multicast_list = ieee80211_set_multicast_list; From 20880e8936e467fe30d79aa838c8d24b7073648f Mon Sep 17 00:00:00 2001 From: Cyrill Gorcunov Date: Thu, 13 Dec 2007 16:17:03 -0800 Subject: [PATCH 03/23] NET: mac80211: fix inappropriate memory freeing Fix inappropriate memory freeing in case of requested rate_control_ops was not found. In this case the list head entity is going to be accidentally wasted. Signed-off-by: Cyrill Gorcunov Acked-by: Michael Wu Signed-off-by: Andrew Morton Signed-off-by: John W. Linville --- net/mac80211/ieee80211_rate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/mac80211/ieee80211_rate.c b/net/mac80211/ieee80211_rate.c index 3260a4a0ecc5..c3f278393741 100644 --- a/net/mac80211/ieee80211_rate.c +++ b/net/mac80211/ieee80211_rate.c @@ -60,11 +60,11 @@ void ieee80211_rate_control_unregister(struct rate_control_ops *ops) list_for_each_entry(alg, &rate_ctrl_algs, list) { if (alg->ops == ops) { list_del(&alg->list); + kfree(alg); break; } } mutex_unlock(&rate_ctrl_mutex); - kfree(alg); } EXPORT_SYMBOL(ieee80211_rate_control_unregister); From b9fc7dc514566e9788c7f064bb08f8b6e2fe6f72 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 17 Dec 2007 22:59:57 -0800 Subject: [PATCH 04/23] [TG3]: Endianness annotations. Fixed misannotations, introduced a new helper - tg3_nvram_read_le(). It gets __le32 * instead of u32 * and puts there the value converted to little-endian. A lot of callers of tg3_nvram_read() were doing that; converted them to tg3_nvram_read_le(). At that point the driver is practically endian-clean; the only remaining place is an actual bug, AFAICS; will be dealt with in the next patch. Signed-off-by: Al Viro Signed-off-by: David S. Miller --- drivers/net/tg3.c | 97 ++++++++++++++++++++++++++--------------------- 1 file changed, 54 insertions(+), 43 deletions(-) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 4942f7d18937..a76bb3dd30f7 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -8189,6 +8189,7 @@ static int tg3_get_eeprom_len(struct net_device *dev) } static int tg3_nvram_read(struct tg3 *tp, u32 offset, u32 *val); +static int tg3_nvram_read_le(struct tg3 *tp, u32 offset, __le32 *val); static int tg3_nvram_read_swab(struct tg3 *tp, u32 offset, u32 *val); static int tg3_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, u8 *data) @@ -8196,7 +8197,8 @@ static int tg3_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, struct tg3 *tp = netdev_priv(dev); int ret; u8 *pd; - u32 i, offset, len, val, b_offset, b_count; + u32 i, offset, len, b_offset, b_count; + __le32 val; if (tp->link_config.phy_is_low_power) return -EAGAIN; @@ -8215,10 +8217,9 @@ static int tg3_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, /* i.e. offset=1 len=2 */ b_count = len; } - ret = tg3_nvram_read(tp, offset-b_offset, &val); + ret = tg3_nvram_read_le(tp, offset-b_offset, &val); if (ret) return ret; - val = cpu_to_le32(val); memcpy(data, ((char*)&val) + b_offset, b_count); len -= b_count; offset += b_count; @@ -8228,12 +8229,11 @@ static int tg3_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, /* read bytes upto the last 4 byte boundary */ pd = &data[eeprom->len]; for (i = 0; i < (len - (len & 3)); i += 4) { - ret = tg3_nvram_read(tp, offset + i, &val); + ret = tg3_nvram_read_le(tp, offset + i, &val); if (ret) { eeprom->len += i; return ret; } - val = cpu_to_le32(val); memcpy(pd + i, &val, 4); } eeprom->len += i; @@ -8243,11 +8243,10 @@ static int tg3_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, pd = &data[eeprom->len]; b_count = len & 3; b_offset = offset + len - b_count; - ret = tg3_nvram_read(tp, b_offset, &val); + ret = tg3_nvram_read_le(tp, b_offset, &val); if (ret) return ret; - val = cpu_to_le32(val); - memcpy(pd, ((char*)&val), b_count); + memcpy(pd, &val, b_count); eeprom->len += b_count; } return 0; @@ -8259,8 +8258,9 @@ static int tg3_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, { struct tg3 *tp = netdev_priv(dev); int ret; - u32 offset, len, b_offset, odd_len, start, end; + u32 offset, len, b_offset, odd_len; u8 *buf; + __le32 start, end; if (tp->link_config.phy_is_low_power) return -EAGAIN; @@ -8273,10 +8273,9 @@ static int tg3_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, if ((b_offset = (offset & 3))) { /* adjustments to start on required 4 byte boundary */ - ret = tg3_nvram_read(tp, offset-b_offset, &start); + ret = tg3_nvram_read_le(tp, offset-b_offset, &start); if (ret) return ret; - start = cpu_to_le32(start); len += b_offset; offset &= ~3; if (len < 4) @@ -8288,10 +8287,9 @@ static int tg3_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, /* adjustments to end on required 4 byte boundary */ odd_len = 1; len = (len + 3) & ~3; - ret = tg3_nvram_read(tp, offset+len-4, &end); + ret = tg3_nvram_read_le(tp, offset+len-4, &end); if (ret) return ret; - end = cpu_to_le32(end); } buf = data; @@ -8734,7 +8732,8 @@ static void tg3_get_ethtool_stats (struct net_device *dev, static int tg3_test_nvram(struct tg3 *tp) { - u32 *buf, csum, magic; + u32 csum, magic; + __le32 *buf; int i, j, k, err = 0, size; if (tg3_nvram_read_swab(tp, 0, &magic) != 0) @@ -8771,21 +8770,19 @@ static int tg3_test_nvram(struct tg3 *tp) err = -EIO; for (i = 0, j = 0; i < size; i += 4, j++) { - u32 val; - - if ((err = tg3_nvram_read(tp, i, &val)) != 0) + if ((err = tg3_nvram_read_le(tp, i, &buf[j])) != 0) break; - buf[j] = cpu_to_le32(val); } if (i < size) goto out; /* Selfboot format */ - if ((cpu_to_be32(buf[0]) & TG3_EEPROM_MAGIC_FW_MSK) == + magic = swab32(le32_to_cpu(buf[0])); + if ((magic & TG3_EEPROM_MAGIC_FW_MSK) == TG3_EEPROM_MAGIC_FW) { u8 *buf8 = (u8 *) buf, csum8 = 0; - if ((cpu_to_be32(buf[0]) & TG3_EEPROM_SB_REVISION_MASK) == + if ((magic & TG3_EEPROM_SB_REVISION_MASK) == TG3_EEPROM_SB_REVISION_2) { /* For rev 2, the csum doesn't include the MBA. */ for (i = 0; i < TG3_EEPROM_SB_F1R2_MBA_OFF; i++) @@ -8806,7 +8803,7 @@ static int tg3_test_nvram(struct tg3 *tp) goto out; } - if ((cpu_to_be32(buf[0]) & TG3_EEPROM_MAGIC_HW_MSK) == + if ((magic & TG3_EEPROM_MAGIC_HW_MSK) == TG3_EEPROM_MAGIC_HW) { u8 data[NVRAM_SELFBOOT_DATA_SIZE]; u8 parity[NVRAM_SELFBOOT_DATA_SIZE]; @@ -8852,12 +8849,12 @@ static int tg3_test_nvram(struct tg3 *tp) /* Bootstrap checksum at offset 0x10 */ csum = calc_crc((unsigned char *) buf, 0x10); - if(csum != cpu_to_le32(buf[0x10/4])) + if(csum != le32_to_cpu(buf[0x10/4])) goto out; /* Manufacturing block starts at offset 0x74, checksum at 0xfc */ csum = calc_crc((unsigned char *) &buf[0x74/4], 0x88); - if (csum != cpu_to_le32(buf[0xfc/4])) + if (csum != le32_to_cpu(buf[0xfc/4])) goto out; err = 0; @@ -10171,6 +10168,15 @@ static int tg3_nvram_read(struct tg3 *tp, u32 offset, u32 *val) return ret; } +static int tg3_nvram_read_le(struct tg3 *tp, u32 offset, __le32 *val) +{ + u32 v; + int res = tg3_nvram_read(tp, offset, &v); + if (!res) + *val = cpu_to_le32(v); + return res; +} + static int tg3_nvram_read_swab(struct tg3 *tp, u32 offset, u32 *val) { int err; @@ -10188,13 +10194,14 @@ static int tg3_nvram_write_block_using_eeprom(struct tg3 *tp, u32 val; for (i = 0; i < len; i += 4) { - u32 addr, data; + u32 addr; + __le32 data; addr = offset + i; memcpy(&data, buf + i, 4); - tw32(GRC_EEPROM_DATA, cpu_to_le32(data)); + tw32(GRC_EEPROM_DATA, le32_to_cpu(data)); val = tr32(GRC_EEPROM_ADDR); tw32(GRC_EEPROM_ADDR, val | EEPROM_ADDR_COMPLETE); @@ -10244,8 +10251,9 @@ static int tg3_nvram_write_block_unbuffered(struct tg3 *tp, u32 offset, u32 len, phy_addr = offset & ~pagemask; for (j = 0; j < pagesize; j += 4) { + /* Almost certainly should be tg3_nvram_read_le */ if ((ret = tg3_nvram_read(tp, phy_addr + j, - (u32 *) (tmp + j)))) + (__le32 *) (tmp + j)))) break; } if (ret) @@ -10289,10 +10297,11 @@ static int tg3_nvram_write_block_unbuffered(struct tg3 *tp, u32 offset, u32 len, break; for (j = 0; j < pagesize; j += 4) { - u32 data; + __be32 data; - data = *((u32 *) (tmp + j)); - tw32(NVRAM_WRDATA, cpu_to_be32(data)); + data = *((__be32 *) (tmp + j)); + /* swab32(le32_to_cpu(data)), actually */ + tw32(NVRAM_WRDATA, be32_to_cpu(data)); tw32(NVRAM_ADDR, phy_addr + j); @@ -10326,10 +10335,11 @@ static int tg3_nvram_write_block_buffered(struct tg3 *tp, u32 offset, u32 len, int i, ret = 0; for (i = 0; i < len; i += 4, offset += 4) { - u32 data, page_off, phy_addr, nvram_cmd; + u32 page_off, phy_addr, nvram_cmd; + __be32 data; memcpy(&data, buf + i, 4); - tw32(NVRAM_WRDATA, cpu_to_be32(data)); + tw32(NVRAM_WRDATA, be32_to_cpu(data)); page_off = offset % tp->nvram_pagesize; @@ -10831,6 +10841,7 @@ static void __devinit tg3_read_partno(struct tg3 *tp) vpd_cap = pci_find_capability(tp->pdev, PCI_CAP_ID_VPD); for (i = 0; i < 256; i += 4) { u32 tmp, j = 0; + __le32 v; u16 tmp16; pci_write_config_word(tp->pdev, vpd_cap + PCI_VPD_ADDR, @@ -10847,8 +10858,8 @@ static void __devinit tg3_read_partno(struct tg3 *tp) pci_read_config_dword(tp->pdev, vpd_cap + PCI_VPD_DATA, &tmp); - tmp = cpu_to_le32(tmp); - memcpy(&vpd_data[i], &tmp, 4); + v = cpu_to_le32(tmp); + memcpy(&vpd_data[i], &v, 4); } } @@ -10941,11 +10952,11 @@ static void __devinit tg3_read_fw_ver(struct tg3 *tp) offset = offset + ver_offset - start; for (i = 0; i < 16; i += 4) { - if (tg3_nvram_read(tp, offset + i, &val)) + __le32 v; + if (tg3_nvram_read_le(tp, offset + i, &v)) return; - val = le32_to_cpu(val); - memcpy(tp->fw_ver + i, &val, 4); + memcpy(tp->fw_ver + i, &v, 4); } if (!(tp->tg3_flags & TG3_FLAG_ENABLE_ASF) || @@ -10983,19 +10994,19 @@ static void __devinit tg3_read_fw_ver(struct tg3 *tp) tp->fw_ver[bcnt++] = ' '; for (i = 0; i < 4; i++) { - if (tg3_nvram_read(tp, offset, &val)) + __le32 v; + if (tg3_nvram_read_le(tp, offset, &v)) return; - val = le32_to_cpu(val); - offset += sizeof(val); + offset += sizeof(v); - if (bcnt > TG3_VER_SIZE - sizeof(val)) { - memcpy(&tp->fw_ver[bcnt], &val, TG3_VER_SIZE - bcnt); + if (bcnt > TG3_VER_SIZE - sizeof(v)) { + memcpy(&tp->fw_ver[bcnt], &v, TG3_VER_SIZE - bcnt); break; } - memcpy(&tp->fw_ver[bcnt], &val, sizeof(val)); - bcnt += sizeof(val); + memcpy(&tp->fw_ver[bcnt], &v, sizeof(v)); + bcnt += sizeof(v); } tp->fw_ver[TG3_VER_SIZE - 1] = 0; From 286e310f94b9459f3fa975333781c969b1041522 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 17 Dec 2007 23:00:31 -0800 Subject: [PATCH 05/23] [TG3]: Endianness bugfix. tg3_nvram_write_block_unbuffered() is reading data from nvram into allocated buffer before overwriting a part of it with user-supplied data. Then it feeds the entire page back to nvram. It should be storing the words it had read as little-endian, not as host-endian. Note that tg3_set_eeprom() does exactly that for padding the same data to full words before it gets passed down to tg3_nvram_write_block() and then to tg3_nvram_write_block_unbuffered(). Moreover, when we get to sending the entire thing back to nvram, we go through it word-by-word, doing essentially writel(swab32(le32_to_cpu(word)), ...) so if we want them to reach the card in host-independent endianness, we'd better really have all that buffer filled with fixed-endian. For user-supplied part we obviously do have that (it's an array of octets memcpy'd in), ditto for padding of user-supplied part to word boundaries (taken care of in tg3_set_eeprom()). The rest of the buffer gets filled by tg3_nvram_write_block_unbuffered() and it would damn better be consistent with that (and with tg3_get_eeprom(), while we are at it - there we also convert the words read from nvram to little-endian before returning the buffer to user). The bug should get triggered on big-endian boxen when set_eeprom is done for less than entire page. Then the words that should've been unaffected at all will actually get byteswapped in place in nvram. Signed-off-by: Al Viro Signed-off-by: David S. Miller --- drivers/net/tg3.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index a76bb3dd30f7..22eb7c8c1a25 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -10251,8 +10251,7 @@ static int tg3_nvram_write_block_unbuffered(struct tg3 *tp, u32 offset, u32 len, phy_addr = offset & ~pagemask; for (j = 0; j < pagesize; j += 4) { - /* Almost certainly should be tg3_nvram_read_le */ - if ((ret = tg3_nvram_read(tp, phy_addr + j, + if ((ret = tg3_nvram_read_le(tp, phy_addr + j, (__le32 *) (tmp + j)))) break; } From e0260feddf8a68301c75cdfff9ec251d5851b006 Mon Sep 17 00:00:00 2001 From: Mark Ryden Date: Wed, 19 Dec 2007 23:38:11 -0800 Subject: [PATCH 06/23] [IPV4] ARP: Remove not used code In arp_process() (net/ipv4/arp.c), there is unused code: definition and assignment of tha (target hw address ). Signed-off-by: Mark Ryden Signed-off-by: David S. Miller --- net/ipv4/arp.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c index b3f366a33a5c..08174a2aa878 100644 --- a/net/ipv4/arp.c +++ b/net/ipv4/arp.c @@ -706,7 +706,7 @@ static int arp_process(struct sk_buff *skb) struct arphdr *arp; unsigned char *arp_ptr; struct rtable *rt; - unsigned char *sha, *tha; + unsigned char *sha; __be32 sip, tip; u16 dev_type = dev->type; int addr_type; @@ -771,7 +771,6 @@ static int arp_process(struct sk_buff *skb) arp_ptr += dev->addr_len; memcpy(&sip, arp_ptr, 4); arp_ptr += 4; - tha = arp_ptr; arp_ptr += dev->addr_len; memcpy(&tip, arp_ptr, 4); /* From f398035f2dec0a6150833b0bc105057953594edb Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Wed, 19 Dec 2007 23:44:29 -0800 Subject: [PATCH 07/23] [IPSEC]: Avoid undefined shift operation when testing algorithm ID The aalgos/ealgos fields are only 32 bits wide. However, af_key tries to test them with the expression 1 << id where id can be as large as 253. This produces different behaviour on different architectures. The following patch explicitly checks whether ID is greater than 31 and fails the check if that's the case. We cannot easily extend the mask to be longer than 32 bits due to exposure to user-space. Besides, this whole interface is obsolete anyway in favour of the xfrm_user interface which doesn't use this bit mask in templates (well not within the kernel anyway). Signed-off-by: Herbert Xu Signed-off-by: David S. Miller --- net/key/af_key.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/net/key/af_key.c b/net/key/af_key.c index 878039b9557d..26d5e63c4cc5 100644 --- a/net/key/af_key.c +++ b/net/key/af_key.c @@ -2784,12 +2784,22 @@ static struct sadb_msg *pfkey_get_base_msg(struct sk_buff *skb, int *errp) static inline int aalg_tmpl_set(struct xfrm_tmpl *t, struct xfrm_algo_desc *d) { - return t->aalgos & (1 << d->desc.sadb_alg_id); + unsigned int id = d->desc.sadb_alg_id; + + if (id >= sizeof(t->aalgos) * 8) + return 0; + + return (t->aalgos >> id) & 1; } static inline int ealg_tmpl_set(struct xfrm_tmpl *t, struct xfrm_algo_desc *d) { - return t->ealgos & (1 << d->desc.sadb_alg_id); + unsigned int id = d->desc.sadb_alg_id; + + if (id >= sizeof(t->ealgos) * 8) + return 0; + + return (t->ealgos >> id) & 1; } static int count_ah_combs(struct xfrm_tmpl *t) From 5951cab136d8b7e84696061dc2e69c402bc94f61 Mon Sep 17 00:00:00 2001 From: Paul Moore Date: Thu, 20 Dec 2007 00:00:45 -0800 Subject: [PATCH 08/23] [XFRM]: Audit function arguments misordered In several places the arguments to the xfrm_audit_start() function are in the wrong order resulting in incorrect user information being reported. This patch corrects this by pacing the arguments in the correct order. Signed-off-by: Paul Moore Signed-off-by: David S. Miller --- net/xfrm/xfrm_policy.c | 4 ++-- net/xfrm/xfrm_state.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index b91b16671c1e..26b846e11bfb 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c @@ -2162,7 +2162,7 @@ xfrm_audit_policy_add(struct xfrm_policy *xp, int result, u32 auid, u32 sid) if (audit_enabled == 0) return; - audit_buf = xfrm_audit_start(sid, auid); + audit_buf = xfrm_audit_start(auid, sid); if (audit_buf == NULL) return; audit_log_format(audit_buf, " op=SPD-add res=%u", result); @@ -2179,7 +2179,7 @@ xfrm_audit_policy_delete(struct xfrm_policy *xp, int result, u32 auid, u32 sid) if (audit_enabled == 0) return; - audit_buf = xfrm_audit_start(sid, auid); + audit_buf = xfrm_audit_start(auid, sid); if (audit_buf == NULL) return; audit_log_format(audit_buf, " op=SPD-delete res=%u", result); diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index 1af522bf12ca..ee1e69753932 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c @@ -2033,7 +2033,7 @@ xfrm_audit_state_add(struct xfrm_state *x, int result, u32 auid, u32 sid) if (audit_enabled == 0) return; - audit_buf = xfrm_audit_start(sid, auid); + audit_buf = xfrm_audit_start(auid, sid); if (audit_buf == NULL) return; audit_log_format(audit_buf, " op=SAD-add res=%u",result); @@ -2053,7 +2053,7 @@ xfrm_audit_state_delete(struct xfrm_state *x, int result, u32 auid, u32 sid) if (audit_enabled == 0) return; - audit_buf = xfrm_audit_start(sid, auid); + audit_buf = xfrm_audit_start(auid, sid); if (audit_buf == NULL) return; audit_log_format(audit_buf, " op=SAD-delete res=%u",result); From 1d0691674764098304ae4c63c715f5883b4d3784 Mon Sep 17 00:00:00 2001 From: Timo Teras Date: Thu, 20 Dec 2007 00:10:33 -0800 Subject: [PATCH 09/23] [IPV4] ip_gre: set mac_header correctly in receive path mac_header update in ipgre_recv() was incorrectly changed to skb_reset_mac_header() when it was introduced. Signed-off-by: Timo Teras Signed-off-by: David S. Miller --- net/ipv4/ip_gre.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index 02b02a8d681c..4b93f32de10d 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -613,7 +613,7 @@ static int ipgre_rcv(struct sk_buff *skb) offset += 4; } - skb_reset_mac_header(skb); + skb->mac_header = skb->network_header; __pskb_pull(skb, offset); skb_reset_network_header(skb); skb_postpull_rcsum(skb, skb_transport_header(skb), offset); From c6e6ca712b5cc06a662f900c0484d49d7334af64 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 20 Dec 2007 00:25:54 -0800 Subject: [PATCH 10/23] [NET]: Correct two mistaken skb_reset_mac_header() conversions. This operation helper abstracts: skb->mac_header = skb->data; but it was done in two more places which were actually: skb->mac_header = skb->network_header; and those are corrected here. Signed-off-by: David S. Miller --- net/ax25/ax25_in.c | 2 +- net/netrom/nr_dev.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/net/ax25/ax25_in.c b/net/ax25/ax25_in.c index 3b7d1720c2ee..d1be080dcb25 100644 --- a/net/ax25/ax25_in.c +++ b/net/ax25/ax25_in.c @@ -124,7 +124,7 @@ int ax25_rx_iframe(ax25_cb *ax25, struct sk_buff *skb) } skb_pull(skb, 1); /* Remove PID */ - skb_reset_mac_header(skb); + skb->mac_header = skb->network_header; skb_reset_network_header(skb); skb->dev = ax25->ax25_dev->dev; skb->pkt_type = PACKET_HOST; diff --git a/net/netrom/nr_dev.c b/net/netrom/nr_dev.c index 8c68da5ef0a1..6caf459665f2 100644 --- a/net/netrom/nr_dev.c +++ b/net/netrom/nr_dev.c @@ -56,7 +56,7 @@ int nr_rx_ip(struct sk_buff *skb, struct net_device *dev) /* Spoof incoming device */ skb->dev = dev; - skb_reset_mac_header(skb); + skb->mac_header = skb->network_header; skb_reset_network_header(skb); skb->pkt_type = PACKET_HOST; From f4ab2f72e9340207ae95e2a7622a74220a61f46a Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Thu, 20 Dec 2007 13:56:32 -0800 Subject: [PATCH 11/23] [NET] include/net/: Spelling fixes Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- include/net/ax25.h | 2 +- include/net/ip6_tunnel.h | 2 +- include/net/irda/discovery.h | 2 +- include/net/sctp/structs.h | 6 +++--- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/include/net/ax25.h b/include/net/ax25.h index 4e3cd93f81fc..32a57e1dee3a 100644 --- a/include/net/ax25.h +++ b/include/net/ax25.h @@ -35,7 +35,7 @@ #define AX25_P_ATALK 0xca /* Appletalk */ #define AX25_P_ATALK_ARP 0xcb /* Appletalk ARP */ #define AX25_P_IP 0xcc /* ARPA Internet Protocol */ -#define AX25_P_ARP 0xcd /* ARPA Adress Resolution */ +#define AX25_P_ARP 0xcd /* ARPA Address Resolution */ #define AX25_P_FLEXNET 0xce /* FlexNet */ #define AX25_P_NETROM 0xcf /* NET/ROM */ #define AX25_P_TEXT 0xF0 /* No layer 3 protocol impl. */ diff --git a/include/net/ip6_tunnel.h b/include/net/ip6_tunnel.h index 29c9da707c7a..c17fa1fdc356 100644 --- a/include/net/ip6_tunnel.h +++ b/include/net/ip6_tunnel.h @@ -23,7 +23,7 @@ struct ip6_tnl { struct net_device *dev; /* virtual device associated with tunnel */ struct net_device_stats stat; /* statistics for tunnel device */ int recursion; /* depth of hard_start_xmit recursion */ - struct ip6_tnl_parm parms; /* tunnel configuration paramters */ + struct ip6_tnl_parm parms; /* tunnel configuration parameters */ struct flowi fl; /* flowi template for xmit */ struct dst_entry *dst_cache; /* cached dst */ u32 dst_cookie; diff --git a/include/net/irda/discovery.h b/include/net/irda/discovery.h index eb0f9de47294..e4efad1f9eff 100644 --- a/include/net/irda/discovery.h +++ b/include/net/irda/discovery.h @@ -80,7 +80,7 @@ typedef struct discovery_t { irda_queue_t q; /* Must be first! */ discinfo_t data; /* Basic discovery information */ - int name_len; /* Lenght of nickname */ + int name_len; /* Length of nickname */ LAP_REASON condition; /* More info about the discovery */ int gen_addr_bit; /* Need to generate a new device diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index 002a00a4e6be..bb965742b64e 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h @@ -301,7 +301,7 @@ struct sctp_sock { /* The default SACK delay timeout for new associations. */ __u32 sackdelay; - /* Flags controling Heartbeat, SACK delay, and Path MTU Discovery. */ + /* Flags controlling Heartbeat, SACK delay, and Path MTU Discovery. */ __u32 param_flags; struct sctp_initmsg initmsg; @@ -955,7 +955,7 @@ struct sctp_transport { /* PMTU : The current known path MTU. */ __u32 pathmtu; - /* Flags controling Heartbeat, SACK delay, and Path MTU Discovery. */ + /* Flags controlling Heartbeat, SACK delay, and Path MTU Discovery. */ __u32 param_flags; /* The number of times INIT has been sent on this transport. */ @@ -1638,7 +1638,7 @@ struct sctp_association { */ __u32 pathmtu; - /* Flags controling Heartbeat, SACK delay, and Path MTU Discovery. */ + /* Flags controlling Heartbeat, SACK delay, and Path MTU Discovery. */ __u32 param_flags; /* SACK delay timeout */ From 5e8e034cc5154abd639aa5c05d13e24e535c6a9c Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Thu, 20 Dec 2007 13:59:39 -0800 Subject: [PATCH 12/23] [DCCP]: Spelling fixes Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- net/dccp/ackvec.h | 2 +- net/dccp/ccids/ccid3.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/net/dccp/ackvec.h b/net/dccp/ackvec.h index 9ef0737043ee..9671ecd17e00 100644 --- a/net/dccp/ackvec.h +++ b/net/dccp/ackvec.h @@ -71,7 +71,7 @@ struct dccp_ackvec { * @dccpavr_ack_ackno - sequence number being acknowledged * @dccpavr_ack_ptr - pointer into dccpav_buf where this record starts * @dccpavr_ack_nonce - dccpav_ack_nonce at the time this record was sent - * @dccpavr_sent_len - lenght of the record in dccpav_buf + * @dccpavr_sent_len - length of the record in dccpav_buf */ struct dccp_ackvec_record { struct list_head dccpavr_node; diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c index 19b33586333d..d133416d3970 100644 --- a/net/dccp/ccids/ccid3.c +++ b/net/dccp/ccids/ccid3.c @@ -239,7 +239,7 @@ static void ccid3_hc_tx_no_feedback_timer(unsigned long data) ccid3_tx_state_name(hctx->ccid3hctx_state), (unsigned)(hctx->ccid3hctx_x >> 6)); /* The value of R is still undefined and so we can not recompute - * the timout value. Keep initial value as per [RFC 4342, 5]. */ + * the timeout value. Keep initial value as per [RFC 4342, 5]. */ t_nfb = TFRC_INITIAL_TIMEOUT; ccid3_update_send_interval(hctx); break; From cc53ded272ecf8d62c9f3b48baadc5165a0b6d7b Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Thu, 20 Dec 2007 14:00:51 -0800 Subject: [PATCH 13/23] [IRDA]: Spelling fixes Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- net/irda/ircomm/ircomm_param.c | 2 +- net/irda/irlan/irlan_eth.c | 2 +- net/irda/irlap_frame.c | 2 +- net/irda/parameters.c | 12 ++++++------ net/irda/wrapper.c | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/net/irda/ircomm/ircomm_param.c b/net/irda/ircomm/ircomm_param.c index e5e4792a0314..598dcbe4a501 100644 --- a/net/irda/ircomm/ircomm_param.c +++ b/net/irda/ircomm/ircomm_param.c @@ -496,7 +496,7 @@ static int ircomm_param_poll(void *instance, irda_param_t *param, int get) IRDA_ASSERT(self != NULL, return -1;); IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;); - /* Poll parameters are always of lenght 0 (just a signal) */ + /* Poll parameters are always of length 0 (just a signal) */ if (!get) { /* Respond with DTE line settings */ ircomm_param_request(self, IRCOMM_DTE, TRUE); diff --git a/net/irda/irlan/irlan_eth.c b/net/irda/irlan/irlan_eth.c index c68220773d28..1ab91f787cc1 100644 --- a/net/irda/irlan/irlan_eth.c +++ b/net/irda/irlan/irlan_eth.c @@ -342,7 +342,7 @@ static void irlan_eth_set_multicast_list(struct net_device *dev) if (dev->flags & IFF_PROMISC) { /* Enable promiscuous mode */ - IRDA_WARNING("Promiscous mode not implemented by IrLAN!\n"); + IRDA_WARNING("Promiscuous mode not implemented by IrLAN!\n"); } else if ((dev->flags & IFF_ALLMULTI) || dev->mc_count > HW_MAX_ADDRS) { /* Disable promiscuous mode, use normal mode. */ diff --git a/net/irda/irlap_frame.c b/net/irda/irlap_frame.c index 4f3764546b2f..7c132d6342af 100644 --- a/net/irda/irlap_frame.c +++ b/net/irda/irlap_frame.c @@ -144,7 +144,7 @@ void irlap_send_snrm_frame(struct irlap_cb *self, struct qos_info *qos) frame->control = SNRM_CMD | PF_BIT; /* - * If we are establishing a connection then insert QoS paramerters + * If we are establishing a connection then insert QoS parameters */ if (qos) { skb_put(tx_skb, 9); /* 25 left */ diff --git a/net/irda/parameters.c b/net/irda/parameters.c index 7183e9ef7996..722bbe044d9c 100644 --- a/net/irda/parameters.c +++ b/net/irda/parameters.c @@ -133,7 +133,7 @@ static int irda_insert_integer(void *self, __u8 *buf, int len, __u8 pi, int err; p.pi = pi; /* In case handler needs to know */ - p.pl = type & PV_MASK; /* The integer type codes the lenght as well */ + p.pl = type & PV_MASK; /* The integer type codes the length as well */ p.pv.i = 0; /* Clear value */ /* Call handler for this parameter */ @@ -142,7 +142,7 @@ static int irda_insert_integer(void *self, __u8 *buf, int len, __u8 pi, return err; /* - * If parameter lenght is still 0, then (1) this is an any length + * If parameter length is still 0, then (1) this is an any length * integer, and (2) the handler function does not care which length * we choose to use, so we pick the one the gives the fewest bytes. */ @@ -206,11 +206,11 @@ static int irda_extract_integer(void *self, __u8 *buf, int len, __u8 pi, { irda_param_t p; int n = 0; - int extract_len; /* Real lenght we extract */ + int extract_len; /* Real length we extract */ int err; p.pi = pi; /* In case handler needs to know */ - p.pl = buf[1]; /* Extract lenght of value */ + p.pl = buf[1]; /* Extract length of value */ p.pv.i = 0; /* Clear value */ extract_len = p.pl; /* Default : extract all */ @@ -297,7 +297,7 @@ static int irda_extract_string(void *self, __u8 *buf, int len, __u8 pi, IRDA_DEBUG(2, "%s()\n", __FUNCTION__); p.pi = pi; /* In case handler needs to know */ - p.pl = buf[1]; /* Extract lenght of value */ + p.pl = buf[1]; /* Extract length of value */ IRDA_DEBUG(2, "%s(), pi=%#x, pl=%d\n", __FUNCTION__, p.pi, p.pl); @@ -339,7 +339,7 @@ static int irda_extract_octseq(void *self, __u8 *buf, int len, __u8 pi, irda_param_t p; p.pi = pi; /* In case handler needs to know */ - p.pl = buf[1]; /* Extract lenght of value */ + p.pl = buf[1]; /* Extract length of value */ /* Check if buffer is long enough for parsing */ if (len < (2+p.pl)) { diff --git a/net/irda/wrapper.c b/net/irda/wrapper.c index e71286768a48..c246983308b8 100644 --- a/net/irda/wrapper.c +++ b/net/irda/wrapper.c @@ -238,7 +238,7 @@ async_bump(struct net_device *dev, skb_reserve(newskb, 1); if(docopy) { - /* Copy data without CRC (lenght already checked) */ + /* Copy data without CRC (length already checked) */ skb_copy_to_linear_data(newskb, rx_buff->data, rx_buff->len - 2); /* Deliver this skb */ From bea851954717ebb0dee557a951e28bb277e1cc1d Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Thu, 20 Dec 2007 14:01:35 -0800 Subject: [PATCH 14/23] [IPV6]: Spelling fixes Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- net/ipv6/ndisc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index 67997a74ddce..777ed733b2d7 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c @@ -612,7 +612,7 @@ void ndisc_send_rs(struct net_device *dev, struct in6_addr *saddr, * optimistic addresses, but we may send the solicitation * if we don't include the sllao. So here we check * if our address is optimistic, and if so, we - * supress the inclusion of the sllao. + * suppress the inclusion of the sllao. */ if (send_sllao) { struct inet6_ifaddr *ifp = ipv6_get_ifaddr(saddr, dev, 1); From 53ccaae1ef749ef87a484a0aa5351c557c0a690e Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Thu, 20 Dec 2007 14:02:06 -0800 Subject: [PATCH 15/23] [NET] net/core/: Spelling fixes Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- net/core/dev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/core/dev.c b/net/core/dev.c index 26a3a3a15be0..be9d3015beaa 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -2819,7 +2819,7 @@ void dev_set_allmulti(struct net_device *dev, int inc) /* * Upload unicast and multicast address lists to device and * configure RX filtering. When the device doesn't support unicast - * filtering it is put in promiscous mode while unicast addresses + * filtering it is put in promiscuous mode while unicast addresses * are present. */ void __dev_set_rx_mode(struct net_device *dev) From 9a94b35184bf095b885ca80099381f8547d5be3a Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Thu, 20 Dec 2007 14:02:40 -0800 Subject: [PATCH 16/23] [PKT_SCHED]: Spelling fixes Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- net/sched/sch_hfsc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c index 55e7e4530f43..a6ad491e434b 100644 --- a/net/sched/sch_hfsc.c +++ b/net/sched/sch_hfsc.c @@ -160,7 +160,7 @@ struct hfsc_class u64 cl_vtoff; /* inter-period cumulative vt offset */ u64 cl_cvtmax; /* max child's vt in the last period */ u64 cl_cvtoff; /* cumulative cvtmax of all periods */ - u64 cl_pcvtoff; /* parent's cvtoff at initalization + u64 cl_pcvtoff; /* parent's cvtoff at initialization time */ struct internal_sc cl_rsc; /* internal real-time service curve */ From e185446ce83f327428624fc4a0392794249311a2 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Thu, 20 Dec 2007 14:03:11 -0800 Subject: [PATCH 17/23] [NETLABEL]: Spelling fixes Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- net/netlabel/netlabel_mgmt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/netlabel/netlabel_mgmt.c b/net/netlabel/netlabel_mgmt.c index 56483377997a..9c41464d58d1 100644 --- a/net/netlabel/netlabel_mgmt.c +++ b/net/netlabel/netlabel_mgmt.c @@ -71,7 +71,7 @@ static const struct nla_policy netlbl_mgmt_genl_policy[NLBL_MGMT_A_MAX + 1] = { }; /* - * NetLabel Misc Managment Functions + * NetLabel Misc Management Functions */ /** From 7aa1b54b74d813e01c46a5344c52f06037a95da0 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Thu, 20 Dec 2007 14:03:52 -0800 Subject: [PATCH 18/23] [SCTP]: Spelling fixes Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- net/sctp/sm_make_chunk.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c index f4876291bb5e..ed7c9e30ebc9 100644 --- a/net/sctp/sm_make_chunk.c +++ b/net/sctp/sm_make_chunk.c @@ -286,7 +286,7 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc, sctp_addto_chunk(retval, sizeof(ecap_param), &ecap_param); - /* Add the supported extensions paramter. Be nice and add this + /* Add the supported extensions parameter. Be nice and add this * fist before addiding the parameters for the extensions themselves */ if (num_ext) { @@ -2859,7 +2859,7 @@ struct sctp_chunk *sctp_process_asconf(struct sctp_association *asoc, chunk_len -= length; /* Skip the address parameter and store a pointer to the first - * asconf paramter. + * asconf parameter. */ length = ntohs(addr_param->v4.param_hdr.length); asconf_param = (sctp_addip_param_t *)((void *)addr_param + length); @@ -2868,7 +2868,7 @@ struct sctp_chunk *sctp_process_asconf(struct sctp_association *asoc, /* create an ASCONF_ACK chunk. * Based on the definitions of parameters, we know that the size of * ASCONF_ACK parameters are less than or equal to the twice of ASCONF - * paramters. + * parameters. */ asconf_ack = sctp_make_asconf_ack(asoc, serial, chunk_len * 2); if (!asconf_ack) @@ -3062,7 +3062,7 @@ int sctp_process_asconf_ack(struct sctp_association *asoc, asconf_len -= length; /* Skip the address parameter in the last asconf sent and store a - * pointer to the first asconf paramter. + * pointer to the first asconf parameter. */ length = ntohs(addr_param->v4.param_hdr.length); asconf_param = (sctp_addip_param_t *)((void *)addr_param + length); From c82381775062cd8d55579959e1fd710f0e607985 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Thu, 20 Dec 2007 14:04:24 -0800 Subject: [PATCH 19/23] [NETFILTER]: Spelling fixes Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- net/netfilter/nf_conntrack_sip.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/netfilter/nf_conntrack_sip.c b/net/netfilter/nf_conntrack_sip.c index 8f8b5a48df38..515abffc4a09 100644 --- a/net/netfilter/nf_conntrack_sip.c +++ b/net/netfilter/nf_conntrack_sip.c @@ -187,7 +187,7 @@ static const struct sip_header_nfo ct_sip_hdrs[] = { } }; -/* get line lenght until first CR or LF seen. */ +/* get line length until first CR or LF seen. */ int ct_sip_lnlen(const char *line, const char *limit) { const char *k = line; @@ -236,7 +236,7 @@ static int digits_len(struct nf_conn *ct, const char *dptr, return len; } -/* get digits lenght, skiping blank spaces. */ +/* get digits length, skipping blank spaces. */ static int skp_digits_len(struct nf_conn *ct, const char *dptr, const char *limit, int *shift) { From e00ccd4a787fe03887f81467babcf8d057f8718d Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Thu, 20 Dec 2007 14:05:03 -0800 Subject: [PATCH 20/23] [NETFILTER] ipv4: Spelling fixes Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- net/ipv4/netfilter/nf_nat_sip.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ipv4/netfilter/nf_nat_sip.c b/net/ipv4/netfilter/nf_nat_sip.c index 3ca98971a1e9..8996ccb757db 100644 --- a/net/ipv4/netfilter/nf_nat_sip.c +++ b/net/ipv4/netfilter/nf_nat_sip.c @@ -165,7 +165,7 @@ static int mangle_content_len(struct sk_buff *skb, dataoff = ip_hdrlen(skb) + sizeof(struct udphdr); - /* Get actual SDP lenght */ + /* Get actual SDP length */ if (ct_sip_get_info(ct, dptr, skb->len - dataoff, &matchoff, &matchlen, POS_SDP_HEADER) > 0) { From c5c0f33d8e5b1219c86757e6afffd6f96823e521 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Thu, 20 Dec 2007 14:05:37 -0800 Subject: [PATCH 21/23] [ATM]: Spelling fixes Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- drivers/atm/firestream.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/atm/firestream.c b/drivers/atm/firestream.c index f8f7139c07c1..c662d686154a 100644 --- a/drivers/atm/firestream.c +++ b/drivers/atm/firestream.c @@ -171,8 +171,8 @@ static char *res_strings[] = { "packet purged", "packet ageing timeout", "channel ageing timeout", - "calculated lenght error", - "programmed lenght limit error", + "calculated length error", + "programmed length limit error", "aal5 crc32 error", "oam transp or transpc crc10 error", "reserved 25", From 1ac70e7ad24a88710cf9b6d7ababaefa2b575df0 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Thu, 20 Dec 2007 14:36:44 -0800 Subject: [PATCH 22/23] [NET]: Fix function put_cmsg() which may cause usr application memory overflow When used function put_cmsg() to copy kernel information to user application memory, if the memory length given by user application is not enough, by the bad length calculate of msg.msg_controllen, put_cmsg() function may cause the msg.msg_controllen to be a large value, such as 0xFFFFFFF0, so the following put_cmsg() can also write data to usr application memory even usr has no valid memory to store this. This may cause usr application memory overflow. int put_cmsg(struct msghdr * msg, int level, int type, int len, void *data) { struct cmsghdr __user *cm = (__force struct cmsghdr __user *)msg->msg_control; struct cmsghdr cmhdr; int cmlen = CMSG_LEN(len); ~~~~~~~~~~~~~~~~~~~~~ int err; if (MSG_CMSG_COMPAT & msg->msg_flags) return put_cmsg_compat(msg, level, type, len, data); if (cm==NULL || msg->msg_controllen < sizeof(*cm)) { msg->msg_flags |= MSG_CTRUNC; return 0; /* XXX: return error? check spec. */ } if (msg->msg_controllen < cmlen) { ~~~~~~~~~~~~~~~~~~~~~~~~ msg->msg_flags |= MSG_CTRUNC; cmlen = msg->msg_controllen; } cmhdr.cmsg_level = level; cmhdr.cmsg_type = type; cmhdr.cmsg_len = cmlen; err = -EFAULT; if (copy_to_user(cm, &cmhdr, sizeof cmhdr)) goto out; if (copy_to_user(CMSG_DATA(cm), data, cmlen - sizeof(struct cmsghdr))) goto out; cmlen = CMSG_SPACE(len); ~~~~~~~~~~~~~~~~~~~~~~~~~~~ If MSG_CTRUNC flags is set, msg->msg_controllen is less than CMSG_SPACE(len), "msg->msg_controllen -= cmlen" will cause unsinged int type msg->msg_controllen to be a large value. ~~~~~~~~~~~~~~~~~~~~~~~~~~~ msg->msg_control += cmlen; msg->msg_controllen -= cmlen; ~~~~~~~~~~~~~~~~~~~~~ err = 0; out: return err; } The same promble exists in put_cmsg_compat(). This patch can fix this problem. Signed-off-by: Wei Yongjun Signed-off-by: David S. Miller --- net/compat.c | 2 ++ net/core/scm.c | 2 ++ 2 files changed, 4 insertions(+) diff --git a/net/compat.c b/net/compat.c index d74d82155d78..377e560ab5c9 100644 --- a/net/compat.c +++ b/net/compat.c @@ -254,6 +254,8 @@ int put_cmsg_compat(struct msghdr *kmsg, int level, int type, int len, void *dat if (copy_to_user(CMSG_COMPAT_DATA(cm), data, cmlen - sizeof(struct compat_cmsghdr))) return -EFAULT; cmlen = CMSG_COMPAT_SPACE(len); + if (kmsg->msg_controllen < cmlen) + cmlen = kmsg->msg_controllen; kmsg->msg_control += cmlen; kmsg->msg_controllen -= cmlen; return 0; diff --git a/net/core/scm.c b/net/core/scm.c index 100ba6d9d478..10f5c65f6a47 100644 --- a/net/core/scm.c +++ b/net/core/scm.c @@ -196,6 +196,8 @@ int put_cmsg(struct msghdr * msg, int level, int type, int len, void *data) if (copy_to_user(CMSG_DATA(cm), data, cmlen - sizeof(struct cmsghdr))) goto out; cmlen = CMSG_SPACE(len); + if (msg->msg_controllen < cmlen) + cmlen = msg->msg_controllen; msg->msg_control += cmlen; msg->msg_controllen -= cmlen; err = 0; From d883a0367149506e8b7a3f31891d1ea30b9377f3 Mon Sep 17 00:00:00 2001 From: "Denis V. Lunev" Date: Fri, 21 Dec 2007 02:01:53 -0800 Subject: [PATCH 23/23] [IPV4]: OOPS with NETLINK_FIB_LOOKUP netlink socket [ Regression added by changeset: cd40b7d3983c708aabe3d3008ec64ffce56d33b0 [NET]: make netlink user -> kernel interface synchronious -DaveM ] nl_fib_input re-reuses incoming skb to send the reply. This means that this packet will be freed twice, namely in: - netlink_unicast_kernel - on receive path Use clone to send as a cure, the caller is responsible for kfree_skb on error. Thanks to Alexey Dobryan, who originally found the problem. Signed-off-by: Denis V. Lunev Signed-off-by: David S. Miller --- net/ipv4/fib_frontend.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index 732d8f088b13..97abf934d185 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c @@ -804,10 +804,13 @@ static void nl_fib_input(struct sk_buff *skb) nlh = nlmsg_hdr(skb); if (skb->len < NLMSG_SPACE(0) || skb->len < nlh->nlmsg_len || - nlh->nlmsg_len < NLMSG_LENGTH(sizeof(*frn))) { - kfree_skb(skb); + nlh->nlmsg_len < NLMSG_LENGTH(sizeof(*frn))) return; - } + + skb = skb_clone(skb, GFP_KERNEL); + if (skb == NULL) + return; + nlh = nlmsg_hdr(skb); frn = (struct fib_result_nl *) NLMSG_DATA(nlh); tb = fib_get_table(frn->tb_id_in);