X-Git-Url: http://pilppa.org/gitweb/?a=blobdiff_plain;f=net%2Fkey%2Faf_key.c;h=1c853927810add38d862838c702de91bb687e4f0;hb=0eddf038adc8dff78efe86b71284e3f52b7cef27;hp=878039b9557dddae70eddd32a342fed056261581;hpb=75e7766680b4b196073bdc941b8a6570b9f777af;p=linux-2.6-omap-h63xx.git diff --git a/net/key/af_key.c b/net/key/af_key.c index 878039b9557..1c853927810 100644 --- a/net/key/af_key.c +++ b/net/key/af_key.c @@ -1466,7 +1466,7 @@ static int pfkey_add(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, err = xfrm_state_update(x); xfrm_audit_state_add(x, err ? 0 : 1, - audit_get_loginuid(current->audit_context), 0); + audit_get_loginuid(current), 0); if (err < 0) { x->km.state = XFRM_STATE_DEAD; @@ -1520,7 +1520,7 @@ static int pfkey_delete(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h km_state_notify(x, &c); out: xfrm_audit_state_delete(x, err ? 0 : 1, - audit_get_loginuid(current->audit_context), 0); + audit_get_loginuid(current), 0); xfrm_state_put(x); return err; @@ -1695,7 +1695,7 @@ static int pfkey_flush(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hd if (proto == 0) return -EINVAL; - audit_info.loginuid = audit_get_loginuid(current->audit_context); + audit_info.loginuid = audit_get_loginuid(current); audit_info.secid = 0; err = xfrm_state_flush(proto, &audit_info); if (err) @@ -2273,7 +2273,7 @@ static int pfkey_spdadd(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h hdr->sadb_msg_type != SADB_X_SPDUPDATE); xfrm_audit_policy_add(xp, err ? 0 : 1, - audit_get_loginuid(current->audit_context), 0); + audit_get_loginuid(current), 0); if (err) goto out; @@ -2291,8 +2291,8 @@ static int pfkey_spdadd(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h return 0; out: - security_xfrm_policy_free(xp); - kfree(xp); + xp->dead = 1; + xfrm_policy_destroy(xp); return err; } @@ -2357,7 +2357,7 @@ static int pfkey_spddelete(struct sock *sk, struct sk_buff *skb, struct sadb_msg return -ENOENT; xfrm_audit_policy_delete(xp, err ? 0 : 1, - audit_get_loginuid(current->audit_context), 0); + audit_get_loginuid(current), 0); if (err) goto out; @@ -2618,7 +2618,7 @@ static int pfkey_spdget(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h if (delete) { xfrm_audit_policy_delete(xp, err ? 0 : 1, - audit_get_loginuid(current->audit_context), 0); + audit_get_loginuid(current), 0); if (err) goto out; @@ -2695,7 +2695,7 @@ static int pfkey_spdflush(struct sock *sk, struct sk_buff *skb, struct sadb_msg struct xfrm_audit audit_info; int err; - audit_info.loginuid = audit_get_loginuid(current->audit_context); + audit_info.loginuid = audit_get_loginuid(current); audit_info.secid = 0; err = xfrm_policy_flush(XFRM_POLICY_TYPE_MAIN, &audit_info); if (err) @@ -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) @@ -3226,8 +3236,7 @@ static struct xfrm_policy *pfkey_compile_policy(struct sock *sk, int opt, return xp; out: - security_xfrm_policy_free(xp); - kfree(xp); + xfrm_policy_destroy(xp); return NULL; } @@ -3583,27 +3592,29 @@ static int pfkey_send_migrate(struct xfrm_selector *sel, u8 dir, u8 type, /* old ipsecrequest */ int mode = pfkey_mode_from_xfrm(mp->mode); if (mode < 0) - return -EINVAL; + goto err; if (set_ipsecrequest(skb, mp->proto, mode, (mp->reqid ? IPSEC_LEVEL_UNIQUE : IPSEC_LEVEL_REQUIRE), mp->reqid, mp->old_family, - &mp->old_saddr, &mp->old_daddr) < 0) { - return -EINVAL; - } + &mp->old_saddr, &mp->old_daddr) < 0) + goto err; /* new ipsecrequest */ if (set_ipsecrequest(skb, mp->proto, mode, (mp->reqid ? IPSEC_LEVEL_UNIQUE : IPSEC_LEVEL_REQUIRE), mp->reqid, mp->new_family, - &mp->new_saddr, &mp->new_daddr) < 0) { - return -EINVAL; - } + &mp->new_saddr, &mp->new_daddr) < 0) + goto err; } /* broadcast migrate message to sockets */ pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_ALL, NULL); return 0; + +err: + kfree_skb(skb); + return -EINVAL; } #else static int pfkey_send_migrate(struct xfrm_selector *sel, u8 dir, u8 type, @@ -3724,21 +3735,15 @@ static struct net_proto_family pfkey_family_ops = { }; #ifdef CONFIG_PROC_FS -static int pfkey_read_proc(char *buffer, char **start, off_t offset, - int length, int *eof, void *data) +static int pfkey_seq_show(struct seq_file *f, void *v) { - off_t pos = 0; - off_t begin = 0; - int len = 0; struct sock *s; - struct hlist_node *node; - - len += sprintf(buffer,"sk RefCnt Rmem Wmem User Inode\n"); - - read_lock(&pfkey_table_lock); - sk_for_each(s, node, &pfkey_table) { - len += sprintf(buffer+len,"%p %-6d %-6u %-6u %-6u %-6lu", + s = (struct sock *)v; + if (v == SEQ_START_TOKEN) + seq_printf(f ,"sk RefCnt Rmem Wmem User Inode\n"); + else + seq_printf(f ,"%p %-6d %-6u %-6u %-6u %-6lu\n", s, atomic_read(&s->sk_refcnt), atomic_read(&s->sk_rmem_alloc), @@ -3746,31 +3751,82 @@ static int pfkey_read_proc(char *buffer, char **start, off_t offset, sock_i_uid(s), sock_i_ino(s) ); + return 0; +} - buffer[len++] = '\n'; +static void *pfkey_seq_start(struct seq_file *f, loff_t *ppos) +{ + struct sock *s; + struct hlist_node *node; + loff_t pos = *ppos; - pos = begin + len; - if (pos < offset) { - len = 0; - begin = pos; - } - if(pos > offset + length) - goto done; - } - *eof = 1; + read_lock(&pfkey_table_lock); + if (pos == 0) + return SEQ_START_TOKEN; + + sk_for_each(s, node, &pfkey_table) + if (pos-- == 1) + return s; + + return NULL; +} -done: +static void *pfkey_seq_next(struct seq_file *f, void *v, loff_t *ppos) +{ + ++*ppos; + return (v == SEQ_START_TOKEN) ? + sk_head(&pfkey_table) : + sk_next((struct sock *)v); +} + +static void pfkey_seq_stop(struct seq_file *f, void *v) +{ read_unlock(&pfkey_table_lock); +} + +static struct seq_operations pfkey_seq_ops = { + .start = pfkey_seq_start, + .next = pfkey_seq_next, + .stop = pfkey_seq_stop, + .show = pfkey_seq_show, +}; + +static int pfkey_seq_open(struct inode *inode, struct file *file) +{ + return seq_open(file, &pfkey_seq_ops); +} - *start = buffer + (offset - begin); - len -= (offset - begin); +static struct file_operations pfkey_proc_ops = { + .open = pfkey_seq_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + +static int pfkey_init_proc(void) +{ + struct proc_dir_entry *e; - if (len > length) - len = length; - if (len < 0) - len = 0; + e = create_proc_entry("pfkey", 0, init_net.proc_net); + if (e == NULL) + return -ENOMEM; - return len; + e->proc_fops = &pfkey_proc_ops; + return 0; +} + +static void pfkey_exit_proc(void) +{ + remove_proc_entry("net/pfkey", NULL); +} +#else +static inline int pfkey_init_proc(void) +{ + return 0; +} + +static inline void pfkey_exit_proc(void) +{ } #endif @@ -3788,7 +3844,7 @@ static struct xfrm_mgr pfkeyv2_mgr = static void __exit ipsec_pfkey_exit(void) { xfrm_unregister_km(&pfkeyv2_mgr); - remove_proc_entry("pfkey", init_net.proc_net); + pfkey_exit_proc(); sock_unregister(PF_KEY); proto_unregister(&key_proto); } @@ -3803,21 +3859,17 @@ static int __init ipsec_pfkey_init(void) err = sock_register(&pfkey_family_ops); if (err != 0) goto out_unregister_key_proto; -#ifdef CONFIG_PROC_FS - err = -ENOMEM; - if (create_proc_read_entry("pfkey", 0, init_net.proc_net, pfkey_read_proc, NULL) == NULL) + err = pfkey_init_proc(); + if (err != 0) goto out_sock_unregister; -#endif err = xfrm_register_km(&pfkeyv2_mgr); if (err != 0) goto out_remove_proc_entry; out: return err; out_remove_proc_entry: -#ifdef CONFIG_PROC_FS - remove_proc_entry("net/pfkey", NULL); + pfkey_exit_proc(); out_sock_unregister: -#endif sock_unregister(PF_KEY); out_unregister_key_proto: proto_unregister(&key_proto);