Skip to content

Commit

Permalink
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/…
Browse files Browse the repository at this point in the history
…davem/net-2.6

* 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6:
  [NET]: Fix race condition about network device name allocation.
  [IPV4]: icmp: fix crash with sysctl_icmp_errors_use_inbound_ifaddr
  [NETFILTER]: nf_conntrack_ipv4: fix incorrect #ifdef config name
  [NETFILTER]: nf_conntrack: fix use-after-free in helper destroy callback invocation
  [IPSEC] pfkey: Load specific algorithm in pfkey_add rather than all
  [TCP] FRTO: Prevent state inconsistency in corner cases
  [TCP] FRTO: Add missing ECN CWR sending to one of the responses
  [NET]: Fix net/core/skbuff.c gcc-3.2.3 compilation error
  [RFKILL]: Fix check for correct rfkill allocation
  [IPV6]: Add ip6_tunnel.h to headers_install
  • Loading branch information
Linus Torvalds committed May 21, 2007
2 parents d07b3c2 + 9093bbb commit 6044ab3
Show file tree
Hide file tree
Showing 11 changed files with 103 additions and 83 deletions.
1 change: 1 addition & 0 deletions include/linux/Kbuild
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,7 @@ unifdef-y += ipc.h
unifdef-y += ipmi.h
unifdef-y += ipv6.h
unifdef-y += ipv6_route.h
unifdef-y += ip6_tunnel.h
unifdef-y += isdn.h
unifdef-y += isdnif.h
unifdef-y += isdn_divertif.h
Expand Down
10 changes: 6 additions & 4 deletions net/core/dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -3314,7 +3314,6 @@ void netdev_run_todo(void)
continue;
}

netdev_unregister_sysfs(dev);
dev->reg_state = NETREG_UNREGISTERED;

netdev_wait_allrefs(dev);
Expand All @@ -3325,11 +3324,11 @@ void netdev_run_todo(void)
BUG_TRAP(!dev->ip6_ptr);
BUG_TRAP(!dev->dn_ptr);

/* It must be the very last action,
* after this 'dev' may point to freed up memory.
*/
if (dev->destructor)
dev->destructor(dev);

/* Free network device */
kobject_put(&dev->dev.kobj);
}

out:
Expand Down Expand Up @@ -3480,6 +3479,9 @@ void unregister_netdevice(struct net_device *dev)
/* Notifier chain MUST detach us from master device. */
BUG_TRAP(!dev->master);

/* Remove entries from sysfs */
netdev_unregister_sysfs(dev);

/* Finish processing unregister after unlock */
net_set_todo(dev);

Expand Down
8 changes: 7 additions & 1 deletion net/core/net-sysfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -456,9 +456,15 @@ static struct class net_class = {
#endif
};

/* Delete sysfs entries but hold kobject reference until after all
* netdev references are gone.
*/
void netdev_unregister_sysfs(struct net_device * net)
{
device_del(&(net->dev));
struct device *dev = &(net->dev);

kobject_get(&dev->kobj);
device_del(dev);
}

/* Create sysfs entries for network device. */
Expand Down
5 changes: 2 additions & 3 deletions net/core/skbuff.c
Original file line number Diff line number Diff line change
Expand Up @@ -644,11 +644,10 @@ int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail,

/* Copy only real data... and, alas, header. This should be
* optimized for the cases when header is void. */
memcpy(data + nhead, skb->head,
#ifdef NET_SKBUFF_DATA_USES_OFFSET
skb->tail);
memcpy(data + nhead, skb->head, skb->tail);
#else
skb->tail - skb->head);
memcpy(data + nhead, skb->head, skb->tail - skb->head);
#endif
memcpy(data + size, skb_end_pointer(skb),
sizeof(struct skb_shared_info));
Expand Down
5 changes: 4 additions & 1 deletion net/ipv4/icmp.c
Original file line number Diff line number Diff line change
Expand Up @@ -514,7 +514,10 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info)

saddr = iph->daddr;
if (!(rt->rt_flags & RTCF_LOCAL)) {
if (sysctl_icmp_errors_use_inbound_ifaddr)
/* This is broken, skb_in->dev points to the outgoing device
* after the packet passes through ip_output().
*/
if (skb_in->dev && sysctl_icmp_errors_use_inbound_ifaddr)
saddr = inet_select_addr(skb_in->dev, 0, RT_SCOPE_LINK);
else
saddr = 0;
Expand Down
2 changes: 0 additions & 2 deletions net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
Original file line number Diff line number Diff line change
Expand Up @@ -154,12 +154,10 @@ static unsigned int ipv4_conntrack_defrag(unsigned int hooknum,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
#if !defined(CONFIG_IP_NF_NAT) && !defined(CONFIG_IP_NF_NAT_MODULE)
/* Previously seen (loopback)? Ignore. Do this before
fragment check. */
if ((*pskb)->nfct)
return NF_ACCEPT;
#endif

/* Gather fragments. */
if (ip_hdr(*pskb)->frag_off & htons(IP_MF | IP_OFFSET)) {
Expand Down
3 changes: 3 additions & 0 deletions net/ipv4/tcp_input.c
Original file line number Diff line number Diff line change
Expand Up @@ -1501,6 +1501,8 @@ void tcp_enter_loss(struct sock *sk, int how)
tcp_set_ca_state(sk, TCP_CA_Loss);
tp->high_seq = tp->snd_nxt;
TCP_ECN_queue_cwr(tp);
/* Abort FRTO algorithm if one is in progress */
tp->frto_counter = 0;

clear_all_retrans_hints(tp);
}
Expand Down Expand Up @@ -2608,6 +2610,7 @@ static void tcp_conservative_spur_to_response(struct tcp_sock *tp)
{
tp->snd_cwnd = min(tp->snd_cwnd, tp->snd_ssthresh);
tp->snd_cwnd_cnt = 0;
TCP_ECN_queue_cwr(tp);
tcp_moderate_cwnd(tp);
}

Expand Down
2 changes: 0 additions & 2 deletions net/key/af_key.c
Original file line number Diff line number Diff line change
Expand Up @@ -1448,8 +1448,6 @@ static int pfkey_add(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr,
int err;
struct km_event c;

xfrm_probe_algs();

x = pfkey_msg2xfrm_state(hdr, ext_hdrs);
if (IS_ERR(x))
return PTR_ERR(x);
Expand Down
8 changes: 4 additions & 4 deletions net/netfilter/nf_conntrack_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,6 @@ static void
destroy_conntrack(struct nf_conntrack *nfct)
{
struct nf_conn *ct = (struct nf_conn *)nfct;
struct nf_conn_help *help = nfct_help(ct);
struct nf_conntrack_l4proto *l4proto;
typeof(nf_conntrack_destroyed) destroyed;

Expand All @@ -309,9 +308,6 @@ destroy_conntrack(struct nf_conntrack *nfct)
nf_conntrack_event(IPCT_DESTROY, ct);
set_bit(IPS_DYING_BIT, &ct->status);

if (help && help->helper && help->helper->destroy)
help->helper->destroy(ct);

/* To make sure we don't get any weird locking issues here:
* destroy_conntrack() MUST NOT be called with a write lock
* to nf_conntrack_lock!!! -HW */
Expand Down Expand Up @@ -353,6 +349,10 @@ destroy_conntrack(struct nf_conntrack *nfct)
static void death_by_timeout(unsigned long ul_conntrack)
{
struct nf_conn *ct = (void *)ul_conntrack;
struct nf_conn_help *help = nfct_help(ct);

if (help && help->helper && help->helper->destroy)
help->helper->destroy(ct);

write_lock_bh(&nf_conntrack_lock);
/* Inside lock so preempt is disabled on module removal path.
Expand Down
2 changes: 1 addition & 1 deletion net/rfkill/rfkill.c
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,7 @@ struct rfkill *rfkill_allocate(struct device *parent, enum rfkill_type type)
struct device *dev;

rfkill = kzalloc(sizeof(struct rfkill), GFP_KERNEL);
if (rfkill)
if (!rfkill)
return NULL;

mutex_init(&rfkill->mutex);
Expand Down
140 changes: 75 additions & 65 deletions net/xfrm/xfrm_algo.c
Original file line number Diff line number Diff line change
Expand Up @@ -347,67 +347,44 @@ static inline int calg_entries(void)
return ARRAY_SIZE(calg_list);
}

/* Todo: generic iterators */
struct xfrm_algo_desc *xfrm_aalg_get_byid(int alg_id)
{
int i;

for (i = 0; i < aalg_entries(); i++) {
if (aalg_list[i].desc.sadb_alg_id == alg_id) {
if (aalg_list[i].available)
return &aalg_list[i];
else
break;
}
}
return NULL;
}
EXPORT_SYMBOL_GPL(xfrm_aalg_get_byid);

struct xfrm_algo_desc *xfrm_ealg_get_byid(int alg_id)
{
int i;
struct xfrm_algo_list {
struct xfrm_algo_desc *algs;
int entries;
u32 type;
u32 mask;
};

for (i = 0; i < ealg_entries(); i++) {
if (ealg_list[i].desc.sadb_alg_id == alg_id) {
if (ealg_list[i].available)
return &ealg_list[i];
else
break;
}
}
return NULL;
}
EXPORT_SYMBOL_GPL(xfrm_ealg_get_byid);
static const struct xfrm_algo_list xfrm_aalg_list = {
.algs = aalg_list,
.entries = ARRAY_SIZE(aalg_list),
.type = CRYPTO_ALG_TYPE_HASH,
.mask = CRYPTO_ALG_TYPE_HASH_MASK | CRYPTO_ALG_ASYNC,
};

struct xfrm_algo_desc *xfrm_calg_get_byid(int alg_id)
{
int i;
static const struct xfrm_algo_list xfrm_ealg_list = {
.algs = ealg_list,
.entries = ARRAY_SIZE(ealg_list),
.type = CRYPTO_ALG_TYPE_BLKCIPHER,
.mask = CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_ASYNC,
};

for (i = 0; i < calg_entries(); i++) {
if (calg_list[i].desc.sadb_alg_id == alg_id) {
if (calg_list[i].available)
return &calg_list[i];
else
break;
}
}
return NULL;
}
EXPORT_SYMBOL_GPL(xfrm_calg_get_byid);
static const struct xfrm_algo_list xfrm_calg_list = {
.algs = calg_list,
.entries = ARRAY_SIZE(calg_list),
.type = CRYPTO_ALG_TYPE_COMPRESS,
.mask = CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_ASYNC,
};

static struct xfrm_algo_desc *xfrm_get_byname(struct xfrm_algo_desc *list,
int entries, u32 type, u32 mask,
char *name, int probe)
static struct xfrm_algo_desc *xfrm_find_algo(
const struct xfrm_algo_list *algo_list,
int match(const struct xfrm_algo_desc *entry, const void *data),
const void *data, int probe)
{
struct xfrm_algo_desc *list = algo_list->algs;
int i, status;

if (!name)
return NULL;

for (i = 0; i < entries; i++) {
if (strcmp(name, list[i].name) &&
(!list[i].compat || strcmp(name, list[i].compat)))
for (i = 0; i < algo_list->entries; i++) {
if (!match(list + i, data))
continue;

if (list[i].available)
Expand All @@ -416,8 +393,8 @@ static struct xfrm_algo_desc *xfrm_get_byname(struct xfrm_algo_desc *list,
if (!probe)
break;

status = crypto_has_alg(list[i].name, type,
mask | CRYPTO_ALG_ASYNC);
status = crypto_has_alg(list[i].name, algo_list->type,
algo_list->mask);
if (!status)
break;

Expand All @@ -427,27 +404,60 @@ static struct xfrm_algo_desc *xfrm_get_byname(struct xfrm_algo_desc *list,
return NULL;
}

static int xfrm_alg_id_match(const struct xfrm_algo_desc *entry,
const void *data)
{
return entry->desc.sadb_alg_id == (int)data;
}

struct xfrm_algo_desc *xfrm_aalg_get_byid(int alg_id)
{
return xfrm_find_algo(&xfrm_aalg_list, xfrm_alg_id_match,
(void *)alg_id, 1);
}
EXPORT_SYMBOL_GPL(xfrm_aalg_get_byid);

struct xfrm_algo_desc *xfrm_ealg_get_byid(int alg_id)
{
return xfrm_find_algo(&xfrm_ealg_list, xfrm_alg_id_match,
(void *)alg_id, 1);
}
EXPORT_SYMBOL_GPL(xfrm_ealg_get_byid);

struct xfrm_algo_desc *xfrm_calg_get_byid(int alg_id)
{
return xfrm_find_algo(&xfrm_calg_list, xfrm_alg_id_match,
(void *)alg_id, 1);
}
EXPORT_SYMBOL_GPL(xfrm_calg_get_byid);

static int xfrm_alg_name_match(const struct xfrm_algo_desc *entry,
const void *data)
{
const char *name = data;

return name && (!strcmp(name, entry->name) ||
(entry->compat && !strcmp(name, entry->compat)));
}

struct xfrm_algo_desc *xfrm_aalg_get_byname(char *name, int probe)
{
return xfrm_get_byname(aalg_list, aalg_entries(),
CRYPTO_ALG_TYPE_HASH, CRYPTO_ALG_TYPE_HASH_MASK,
name, probe);
return xfrm_find_algo(&xfrm_aalg_list, xfrm_alg_name_match, name,
probe);
}
EXPORT_SYMBOL_GPL(xfrm_aalg_get_byname);

struct xfrm_algo_desc *xfrm_ealg_get_byname(char *name, int probe)
{
return xfrm_get_byname(ealg_list, ealg_entries(),
CRYPTO_ALG_TYPE_BLKCIPHER, CRYPTO_ALG_TYPE_MASK,
name, probe);
return xfrm_find_algo(&xfrm_ealg_list, xfrm_alg_name_match, name,
probe);
}
EXPORT_SYMBOL_GPL(xfrm_ealg_get_byname);

struct xfrm_algo_desc *xfrm_calg_get_byname(char *name, int probe)
{
return xfrm_get_byname(calg_list, calg_entries(),
CRYPTO_ALG_TYPE_COMPRESS, CRYPTO_ALG_TYPE_MASK,
name, probe);
return xfrm_find_algo(&xfrm_calg_list, xfrm_alg_name_match, name,
probe);
}
EXPORT_SYMBOL_GPL(xfrm_calg_get_byname);

Expand Down

0 comments on commit 6044ab3

Please sign in to comment.