Commit 8bbb2b41 authored by David S. Miller's avatar David S. Miller

Merge bk://kernel.bkbits.net/acme/net_family-2.5

into nuts.ninka.net:/home/davem/src/BK/net-2.5
parents d7920faf 8b97999a
......@@ -494,16 +494,21 @@ static int pppoe_create(struct socket *sock)
struct sock *sk;
struct pppox_opt *po;
sk = pppox_sk_alloc(sock, PX_PROTO_OE, GFP_KERNEL, 1, NULL);
sk = sk_alloc(PF_PPPOX, GFP_KERNEL, 1, NULL);
if (!sk)
goto out;
sock_init_data(sock, sk);
sk_set_owner(sk, THIS_MODULE);
sock->state = SS_UNCONNECTED;
sock->ops = &pppoe_ops;
sk->backlog_rcv = pppoe_rcv_core;
sk->state = PPPOX_NONE;
sk->type = SOCK_STREAM;
sk->family = PF_PPPOX;
sk->protocol = PX_PROTO_OE;
sk->destruct = pppoe_sk_free;
po = pppox_sk(sk) = kmalloc(sizeof(*po), GFP_KERNEL);
if (!po)
......@@ -1062,10 +1067,12 @@ static struct file_operations pppoe_seq_fops = {
};
#endif /* CONFIG_PROC_FS */
/* ->release and ->ioctl are set at pppox_create */
/* ->ioctl are set at pppox_create */
struct proto_ops pppoe_ops = {
.family = AF_PPPOX,
.owner = THIS_MODULE,
.release = pppoe_release,
.bind = sock_no_bind,
.connect = pppoe_connect,
.socketpair = sock_no_socketpair,
......@@ -1084,8 +1091,6 @@ struct proto_ops pppoe_ops = {
struct pppox_proto pppoe_proto = {
.create = pppoe_create,
.ioctl = pppoe_ioctl,
.release = pppoe_release,
.sk_free = pppoe_sk_free,
.owner = THIS_MODULE,
};
......
......@@ -64,45 +64,9 @@ void pppox_unbind_sock(struct sock *sk)
}
}
static int pppox_release(struct socket *sock)
{
struct sock *sk = sock->sk;
int rc = pppox_protos[sk->protocol]->release(sock);
module_put(pppox_protos[sk->protocol]->owner);
return rc;
}
static void pppox_sk_free(struct sock *sk)
{
pppox_protos[sk->protocol]->sk_free(sk);
module_put(pppox_protos[sk->protocol]->owner);
}
struct sock *pppox_sk_alloc(struct socket *sock, int protocol, int priority,
int zero_it, kmem_cache_t *slab)
{
struct sock *sk = NULL;
if (!try_module_get(pppox_protos[protocol]->owner))
goto out;
sk = sk_alloc(PF_PPPOX, priority, zero_it, slab);
if (sk) {
sock_init_data(sock, sk);
sk->family = PF_PPPOX;
sk->protocol = protocol;
sk->destruct = pppox_sk_free;
} else
module_put(pppox_protos[protocol]->owner);
out:
return sk;
}
EXPORT_SYMBOL(register_pppox_proto);
EXPORT_SYMBOL(unregister_pppox_proto);
EXPORT_SYMBOL(pppox_unbind_sock);
EXPORT_SYMBOL(pppox_sk_alloc);
static int pppox_ioctl(struct socket* sock, unsigned int cmd,
unsigned long arg)
......@@ -156,12 +120,10 @@ static int pppox_create(struct socket *sock, int protocol)
rc = pppox_protos[protocol]->create(sock);
if (!rc) {
/* We get to set the ioctl handler. */
/* And the release handler, for module refcounting */
/* For everything else, pppox is just a shell. */
sock->ops->ioctl = pppox_ioctl;
sock->ops->release = pppox_release;
} else
module_put(pppox_protos[protocol]->owner);
}
module_put(pppox_protos[protocol]->owner);
out:
return rc;
}
......
......@@ -140,8 +140,6 @@ struct pppox_proto {
int (*create)(struct socket *sock);
int (*ioctl)(struct socket *sock, unsigned int cmd,
unsigned long arg);
int (*release)(struct socket *sock);
void (*sk_free)(struct sock *sk);
struct module *owner;
};
......@@ -150,9 +148,6 @@ extern void unregister_pppox_proto(int proto_num);
extern void pppox_unbind_sock(struct sock *sk);/* delete ppp-channel binding */
extern int pppox_channel_ioctl(struct ppp_channel *pc, unsigned int cmd,
unsigned long arg);
extern struct sock *pppox_sk_alloc(struct socket *sock, int protocol,
int priority, int zero_it,
kmem_cache_t *slab);
/* PPPoX socket states */
enum {
......
......@@ -89,9 +89,11 @@ struct page;
struct kiocb;
struct sockaddr;
struct msghdr;
struct module;
struct proto_ops {
int family;
struct module *owner;
int (*release) (struct socket *sock);
int (*bind) (struct socket *sock,
struct sockaddr *umyaddr,
......@@ -127,8 +129,6 @@ struct proto_ops {
int offset, size_t size, int flags);
};
struct module;
struct net_proto_family {
int family;
int (*create)(struct socket *sock, int protocol);
......@@ -140,9 +140,6 @@ struct net_proto_family {
struct module *owner;
};
extern int net_family_get(int family);
extern void net_family_put(int family);
struct iovec;
extern int sock_wake_async(struct socket *sk, int how, int band);
......@@ -227,7 +224,7 @@ SOCKCALL_WRAP(name, mmap, (struct file *file, struct socket *sock, struct vm_are
\
static struct proto_ops name##_ops = { \
.family = fam, \
\
.owner = THIS_MODULE, \
.release = __lock_##name##_release, \
.bind = __lock_##name##_bind, \
.connect = __lock_##name##_connect, \
......
......@@ -43,7 +43,7 @@
#include <linux/config.h>
#include <linux/timer.h>
#include <linux/cache.h>
#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h> /* struct sk_buff */
#include <linux/security.h>
......@@ -197,6 +197,7 @@ struct sock {
void *user_data;
/* Callbacks */
struct module *owner;
void (*state_change)(struct sock *sk);
void (*data_ready)(struct sock *sk,int bytes);
void (*write_space)(struct sock *sk);
......@@ -270,6 +271,23 @@ struct proto {
} stats[NR_CPUS];
};
static __inline__ void sk_set_owner(struct sock *sk, struct module *owner)
{
/*
* One should use sk_set_owner just once, after struct sock creation,
* be it shortly after sk_alloc or after a function that returns a new
* struct sock (and that down the call chain called sk_alloc), e.g. the
* IPv4 and IPv6 modules share tcp_create_openreq_child, so if
* tcp_create_openreq_child called sk_set_owner IPv6 would have to
* change the ownership of this struct sock, with one not needed
* transient sk_set_owner call.
*/
if (unlikely(sk->owner != NULL))
BUG();
sk->owner = owner;
__module_get(owner);
}
/* Called with local bh disabled */
static __inline__ void sock_prot_inc_use(struct proto *prot)
{
......
......@@ -1778,6 +1778,7 @@ static struct net_proto_family atalk_family_ops = {
static struct proto_ops SOCKOPS_WRAPPED(atalk_dgram_ops) = {
.family = PF_APPLETALK,
.owner = THIS_MODULE,
.release = atalk_release,
.bind = atalk_bind,
.connect = atalk_connect,
......
......@@ -845,6 +845,7 @@ int ax25_create(struct socket *sock, int protocol)
}
sock_init_data(sock, sk);
sk_set_owner(sk, THIS_MODULE);
sk->destruct = ax25_free_sock;
sock->ops = &ax25_proto_ops;
......@@ -880,6 +881,7 @@ struct sock *ax25_make_new(struct sock *osk, struct ax25_dev *ax25_dev)
}
sock_init_data(NULL, sk);
sk_set_owner(sk, THIS_MODULE);
sk->destruct = ax25_free_sock;
sk->type = osk->type;
......@@ -1913,7 +1915,7 @@ static struct net_proto_family ax25_family_ops = {
static struct proto_ops ax25_proto_ops = {
.family = PF_AX25,
.owner = THIS_MODULE,
.release = ax25_release,
.bind = ax25_bind,
.connect = ax25_connect,
......
......@@ -148,6 +148,7 @@ static int bnep_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long
static struct proto_ops bnep_sock_ops = {
.family = PF_BLUETOOTH,
.owner = THIS_MODULE,
.release = bnep_sock_release,
.ioctl = bnep_sock_ioctl,
.bind = sock_no_bind,
......
......@@ -553,6 +553,7 @@ int hci_sock_getsockopt(struct socket *sock, int level, int optname, char *optva
struct proto_ops hci_sock_ops = {
.family = PF_BLUETOOTH,
.owner = THIS_MODULE,
.release = hci_sock_release,
.bind = hci_sock_bind,
.getname = hci_sock_getname,
......
......@@ -2084,6 +2084,7 @@ static void __exit l2cap_proc_cleanup(void)
static struct proto_ops l2cap_sock_ops = {
.family = PF_BLUETOOTH,
.owner = THIS_MODULE,
.release = l2cap_sock_release,
.bind = l2cap_sock_bind,
.connect = l2cap_sock_connect,
......@@ -2104,6 +2105,7 @@ static struct proto_ops l2cap_sock_ops = {
static struct net_proto_family l2cap_sock_family_ops = {
.family = PF_BLUETOOTH,
.create = l2cap_sock_create,
.owner = THIS_MODULE,
};
static struct hci_proto l2cap_hci_proto = {
......
......@@ -856,6 +856,7 @@ static void __exit rfcomm_sock_proc_cleanup(void)
static struct proto_ops rfcomm_sock_ops = {
.family = PF_BLUETOOTH,
.owner = THIS_MODULE,
.release = rfcomm_sock_release,
.bind = rfcomm_sock_bind,
.connect = rfcomm_sock_connect,
......
......@@ -969,6 +969,7 @@ static void __exit sco_proc_cleanup(void)
static struct proto_ops sco_sock_ops = {
.family = PF_BLUETOOTH,
.owner = THIS_MODULE,
.release = sco_sock_release,
.bind = sco_sock_bind,
.connect = sco_sock_connect,
......@@ -989,6 +990,7 @@ static struct proto_ops sco_sock_ops = {
static struct net_proto_family sco_sock_family_ops = {
.family = PF_BLUETOOTH,
.create = sco_sock_create,
.owner = THIS_MODULE,
};
static struct hci_proto sco_hci_proto = {
......
......@@ -591,8 +591,6 @@ struct sock *sk_alloc(int family, int priority, int zero_it, kmem_cache_t *slab)
{
struct sock *sk = NULL;
if (!net_family_get(family))
goto out;
if (!slab)
slab = sk_cachep;
sk = kmem_cache_alloc(slab, priority);
......@@ -604,16 +602,14 @@ struct sock *sk_alloc(int family, int priority, int zero_it, kmem_cache_t *slab)
sock_lock_init(sk);
}
sk->slab = slab;
} else
net_family_put(family);
out:
}
return sk;
}
void sk_free(struct sock *sk)
{
struct sk_filter *filter;
const int family = sk->family;
struct module *owner = sk->owner;
if (sk->destruct)
sk->destruct(sk);
......@@ -628,7 +624,7 @@ void sk_free(struct sock *sk)
printk(KERN_DEBUG "sk_free: optmem leakage (%d bytes) detected.\n", atomic_read(&sk->omem_alloc));
kmem_cache_free(sk->slab, sk);
net_family_put(family);
module_put(owner);
}
void __init sk_init(void)
......@@ -1112,6 +1108,7 @@ void sock_init_data(struct socket *sock, struct sock *sk)
sk->rcvlowat = 1;
sk->rcvtimeo = MAX_SCHEDULE_TIMEOUT;
sk->sndtimeo = MAX_SCHEDULE_TIMEOUT;
sk->owner = NULL;
atomic_set(&sk->refcnt, 1);
}
......@@ -485,6 +485,7 @@ struct sock *dn_alloc_sock(struct socket *sock, int gfp)
if (sock)
sock->ops = &dn_proto_ops;
sock_init_data(sock, sk);
sk_set_owner(sk, THIS_MODULE);
sk->backlog_rcv = dn_nsp_backlog_rcv;
sk->destruct = dn_destruct;
......@@ -2235,7 +2236,7 @@ static struct net_proto_family dn_family_ops = {
static struct proto_ops dn_proto_ops = {
.family = AF_DECnet,
.owner = THIS_MODULE,
.release = dn_release,
.bind = dn_bind,
.connect = dn_connect,
......
......@@ -694,7 +694,7 @@ static struct net_proto_family econet_family_ops = {
static struct proto_ops SOCKOPS_WRAPPED(econet_ops) = {
.family = PF_ECONET,
.owner = THIS_MODULE,
.release = econet_release,
.bind = econet_bind,
.connect = sock_no_connect,
......
......@@ -390,6 +390,7 @@ static int inet_create(struct socket *sock, int protocol)
inet->id = 0;
sock_init_data(sock, sk);
sk_set_owner(sk, THIS_MODULE);
sk->destruct = inet_sock_destruct;
sk->zapped = 0;
......@@ -882,7 +883,7 @@ int inet_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
struct proto_ops inet_stream_ops = {
.family = PF_INET,
.owner = THIS_MODULE,
.release = inet_release,
.bind = inet_bind,
.connect = inet_stream_connect,
......@@ -903,7 +904,7 @@ struct proto_ops inet_stream_ops = {
struct proto_ops inet_dgram_ops = {
.family = PF_INET,
.owner = THIS_MODULE,
.release = inet_release,
.bind = inet_bind,
.connect = inet_dgram_connect,
......
......@@ -101,9 +101,10 @@ static inline struct sock *get_cookie_sock(struct sock *sk, struct sk_buff *skb,
struct sock *child;
child = tp->af_specific->syn_recv_sock(sk, skb, req, dst);
if (child)
if (child) {
sk_set_owner(child, sk->owner);
tcp_acceptq_queue(sk, req, child);
else
} else
tcp_openreq_free(req);
return child;
......
......@@ -967,6 +967,7 @@ struct sock *tcp_check_req(struct sock *sk,struct sk_buff *skb,
if (child == NULL)
goto listen_overflow;
sk_set_owner(child, sk->owner);
tcp_synq_unlink(tp, req, prev);
tcp_synq_removed(sk, req);
......
......@@ -193,6 +193,7 @@ static int inet6_create(struct socket *sock, int protocol)
sock->ops = answer->ops;
sock_init_data(sock, sk);
sk_set_owner(sk, THIS_MODULE);
sk->prot = answer->prot;
sk->no_check = answer->no_check;
......@@ -498,7 +499,7 @@ int inet6_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
struct proto_ops inet6_stream_ops = {
.family = PF_INET6,
.owner = THIS_MODULE,
.release = inet6_release,
.bind = inet6_bind,
.connect = inet_stream_connect, /* ok */
......@@ -519,7 +520,7 @@ struct proto_ops inet6_stream_ops = {
struct proto_ops inet6_dgram_ops = {
.family = PF_INET6,
.owner = THIS_MODULE,
.release = inet6_release,
.bind = inet6_bind,
.connect = inet_dgram_connect, /* ok */
......
......@@ -1309,7 +1309,6 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
#ifdef INET_REFCNT_DEBUG
atomic_inc(&inet6_sock_nr);
#endif
MOD_INC_USE_COUNT;
/* It is tricky place. Until this moment IPv4 tcp
worked with IPv6 af_tcp.af_specific.
......@@ -1359,7 +1358,6 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
#ifdef INET_REFCNT_DEBUG
atomic_inc(&inet6_sock_nr);
#endif
MOD_INC_USE_COUNT;
ip6_dst_store(newsk, dst, NULL);
sk->route_caps = dst->dev->features&~(NETIF_F_IP_CSUM|NETIF_F_TSO);
......
......@@ -2221,6 +2221,7 @@ static struct net_proto_family ipx_family_ops = {
static struct proto_ops SOCKOPS_WRAPPED(ipx_dgram_ops) = {
.family = PF_IPX,
.owner = THIS_MODULE,
.release = ipx_release,
.bind = ipx_bind,
.connect = ipx_connect,
......
......@@ -2408,7 +2408,7 @@ static struct net_proto_family irda_family_ops = {
static struct proto_ops SOCKOPS_WRAPPED(irda_stream_ops) = {
.family = PF_IRDA,
.owner = THIS_MODULE,
.release = irda_release,
.bind = irda_bind,
.connect = irda_connect,
......@@ -2429,7 +2429,7 @@ static struct proto_ops SOCKOPS_WRAPPED(irda_stream_ops) = {
static struct proto_ops SOCKOPS_WRAPPED(irda_seqpacket_ops) = {
.family = PF_IRDA,
.owner = THIS_MODULE,
.release = irda_release,
.bind = irda_bind,
.connect = irda_connect,
......@@ -2450,7 +2450,7 @@ static struct proto_ops SOCKOPS_WRAPPED(irda_seqpacket_ops) = {
static struct proto_ops SOCKOPS_WRAPPED(irda_dgram_ops) = {
.family = PF_IRDA,
.owner = THIS_MODULE,
.release = irda_release,
.bind = irda_bind,
.connect = irda_connect,
......@@ -2472,7 +2472,7 @@ static struct proto_ops SOCKOPS_WRAPPED(irda_dgram_ops) = {
#ifdef CONFIG_IRDA_ULTRA
static struct proto_ops SOCKOPS_WRAPPED(irda_ultra_ops) = {
.family = PF_IRDA,
.owner = THIS_MODULE,
.release = irda_release,
.bind = irda_bind,
.connect = sock_no_connect,
......
......@@ -152,9 +152,10 @@ static int pfkey_create(struct socket *sock, int protocol)
sk = sk_alloc(PF_KEY, GFP_KERNEL, 1, NULL);
if (sk == NULL)
goto out;
sock->ops = &pfkey_ops;
sock_init_data(sock, sk);
sk_set_owner(sk, THIS_MODULE);
err = -ENOMEM;
pfk = pfkey_sk(sk) = kmalloc(sizeof(*pfk), GFP_KERNEL);
......@@ -2761,7 +2762,7 @@ static int pfkey_recvmsg(struct kiocb *kiocb,
static struct proto_ops pfkey_ops = {
.family = PF_KEY,
.owner = THIS_MODULE,
/* Operations that make no sense on pfkey sockets. */
.bind = sock_no_bind,
.connect = sock_no_connect,
......
......@@ -1023,6 +1023,7 @@ static struct net_proto_family llc_ui_family_ops = {
static struct proto_ops llc_ui_ops = {
.family = PF_LLC,
.owner = THIS_MODULE,
.release = llc_ui_release,
.bind = llc_ui_bind,
.connect = llc_ui_connect,
......
......@@ -235,6 +235,7 @@ static int netlink_create(struct socket *sock, int protocol)
return -ENOMEM;
sock_init_data(sock,sk);
sk_set_owner(sk, THIS_MODULE);
nlk = nlk_sk(sk) = kmalloc(sizeof(*nlk), GFP_KERNEL);
if (!nlk) {
......@@ -1030,7 +1031,7 @@ int netlink_unregister_notifier(struct notifier_block *nb)
struct proto_ops netlink_ops = {
.family = PF_NETLINK,
.owner = THIS_MODULE,
.release = netlink_release,
.bind = netlink_bind,
.connect = netlink_connect,
......
......@@ -1227,7 +1227,7 @@ static struct net_proto_family nr_family_ops = {
static struct proto_ops nr_proto_ops = {
.family = PF_NETROM,
.owner = THIS_MODULE,
.release = nr_release,
.bind = nr_bind,
.connect = nr_connect,
......
......@@ -950,6 +950,7 @@ static int packet_create(struct socket *sock, int protocol)
sock->ops = &packet_ops_spkt;
#endif
sock_init_data(sock,sk);
sk_set_owner(sk, THIS_MODULE);
po = pkt_sk(sk) = kmalloc(sizeof(*po), GFP_KERNEL);
if (!po)
......@@ -1705,7 +1706,7 @@ static int packet_mmap(struct file *file, struct socket *sock, struct vm_area_st
#ifdef CONFIG_SOCK_PACKET
struct proto_ops packet_ops_spkt = {
.family = PF_PACKET,
.owner = THIS_MODULE,
.release = packet_release,
.bind = packet_bind_spkt,
.connect = sock_no_connect,
......@@ -1727,7 +1728,7 @@ struct proto_ops packet_ops_spkt = {
struct proto_ops packet_ops = {
.family = PF_PACKET,
.owner = THIS_MODULE,
.release = packet_release,
.bind = packet_bind,
.connect = sock_no_connect,
......
......@@ -1424,7 +1424,7 @@ static struct net_proto_family rose_family_ops = {
static struct proto_ops rose_proto_ops = {
.family = PF_ROSE,
.owner = THIS_MODULE,
.release = rose_release,
.bind = rose_bind,
.connect = rose_connect,
......
......@@ -508,6 +508,7 @@ struct sock *sctp_v6_create_accept_sk(struct sock *sk,
goto out;
sock_init_data(NULL, newsk);
sk_set_owner(newsk, THIS_MODULE);
newsk->type = SOCK_STREAM;
......@@ -749,6 +750,7 @@ static int sctp_inet6_supported_addrs(const struct sctp_opt *opt,
static struct proto_ops inet6_seqpacket_ops = {
.family = PF_INET6,
.owner = THIS_MODULE,
.release = inet6_release,
.bind = inet6_bind,
.connect = inet_dgram_connect,
......
......@@ -499,6 +499,7 @@ struct sock *sctp_v4_create_accept_sk(struct sock *sk,
goto out;
sock_init_data(NULL, newsk);
sk_set_owner(newsk, THIS_MODULE);
newsk->type = SOCK_STREAM;
......@@ -748,6 +749,7 @@ struct notifier_block sctp_inetaddr_notifier = {
/* Socket operations. */
struct proto_ops inet_seqpacket_ops = {
.family = PF_INET,
.owner = THIS_MODULE,
.release = inet_release, /* Needs to be wrapped... */
.bind = inet_bind,
.connect = inet_dgram_connect,
......
......@@ -141,36 +141,6 @@ static struct file_operations socket_file_ops = {
static struct net_proto_family *net_families[NPROTO];
static __inline__ void net_family_bug(int family)
{
printk(KERN_ERR "%d is not yet sock_registered!\n", family);
BUG();
}
int net_family_get(int family)
{
struct net_proto_family *prot = net_families[family];
int rc = 1;
barrier();
if (likely(prot != NULL))
rc = try_module_get(prot->owner);
else
net_family_bug(family);
return rc;
}
void net_family_put(int family)
{
struct net_proto_family *prot = net_families[family];
barrier();
if (likely(prot != NULL))
module_put(prot->owner);
else
net_family_bug(family);
}
#if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT)
static atomic_t net_family_lockct = ATOMIC_INIT(0);
static spinlock_t net_family_lock = SPIN_LOCK_UNLOCKED;
......@@ -535,11 +505,11 @@ struct file_operations bad_sock_fops = {
void sock_release(struct socket *sock)
{
if (sock->ops) {
const int family = sock->ops->family;
struct module *owner = sock->ops->owner;
sock->ops->release(sock);
sock->ops = NULL;
net_family_put(family);
module_put(owner);
}
if (sock->fasync_list)
......@@ -1091,19 +1061,37 @@ int sock_create(int family, int type, int protocol, struct socket **res)
sock->type = type;
/*
* We will call the ->create function, that possibly is in a loadable
* module, so we have to bump that loadable module refcnt first.
*/
i = -EAFNOSUPPORT;
if (!net_family_get(family))
goto out_release;
if ((i = net_families[family]->create(sock, protocol)) < 0)
if (!try_module_get(net_families[family]->owner))
goto out_release;
if ((i = net_families[family]->create(sock, protocol)) < 0)
goto out_module_put;
/*
* Now to bump the refcnt of the [loadable] module that owns this
* socket at sock_release time we decrement its refcnt.
*/
if (!try_module_get(sock->ops->owner)) {
sock->ops = NULL;
goto out_module_put;
}
/*
* Now that we're done with the ->create function, the [loadable]
* module can have its refcnt decremented
*/
module_put(net_families[family]->owner);
*res = sock;
security_socket_post_create(sock, family, type, protocol);
out:
net_family_read_unlock();
return i;
out_module_put:
module_put(net_families[family]->owner);
out_release:
sock_release(sock);
goto out;
......@@ -1288,28 +1276,30 @@ asmlinkage long sys_accept(int fd, struct sockaddr *upeer_sockaddr, int *upeer_a
if (err)
goto out_release;
err = -EAFNOSUPPORT;
if (!net_family_get(sock->ops->family))
goto out_release;
/*
* We don't need try_module_get here, as the listening socket (sock)
* has the protocol module (sock->ops->owner) held.
*/
__module_get(sock->ops->owner);
err = sock->ops->accept(sock, newsock, sock->file->f_flags);
if (err < 0)
goto out_family_put;
goto out_module_put;
if (upeer_sockaddr) {
if(newsock->ops->getname(newsock, (struct sockaddr *)address, &len, 2)<0) {
err = -ECONNABORTED;
goto out_family_put;
goto out_module_put;
}
err = move_addr_to_user(address, len, upeer_sockaddr, upeer_addrlen);
if (err < 0)
goto out_family_put;
goto out_module_put;
}
/* File flags are not inherited via accept() unlike another OSes. */
if ((err = sock_map_fd(newsock)) < 0)
goto out_family_put;
goto out_module_put;
security_socket_post_accept(sock, newsock);
......@@ -1317,8 +1307,8 @@ asmlinkage long sys_accept(int fd, struct sockaddr *upeer_sockaddr, int *upeer_a
sockfd_put(sock);
out:
return err;
out_family_put:
net_family_put(sock->ops->family);
out_module_put:
module_put(sock->ops->owner);
out_release:
sock_release(newsock);
goto out_put;
......
......@@ -494,6 +494,7 @@ static struct sock * unix_create1(struct socket *sock)
atomic_inc(&unix_nr_socks);
sock_init_data(sock,sk);
sk_set_owner(sk, THIS_MODULE);
sk->write_space = unix_write_space;
......@@ -1884,7 +1885,7 @@ static int unix_read_proc(char *buffer, char **start, off_t offset,
struct proto_ops unix_stream_ops = {
.family = PF_UNIX,
.owner = THIS_MODULE,
.release = unix_release,
.bind = unix_bind,
.connect = unix_stream_connect,
......@@ -1905,7 +1906,7 @@ struct proto_ops unix_stream_ops = {
struct proto_ops unix_dgram_ops = {
.family = PF_UNIX,
.owner = THIS_MODULE,
.release = unix_release,
.bind = unix_bind,
.connect = unix_dgram_connect,
......
......@@ -2551,7 +2551,7 @@ static int wanpipe_connect(struct socket *sock, struct sockaddr *uaddr, int addr
struct proto_ops wanpipe_ops = {
.family = PF_WANPIPE,
.owner = THIS_MODULE,
.release = wanpipe_release,
.bind = wanpipe_bind,
.connect = wanpipe_connect,
......
......@@ -1323,7 +1323,7 @@ struct net_proto_family x25_family_ops = {
static struct proto_ops SOCKOPS_WRAPPED(x25_proto_ops) = {
.family = AF_X25,
.owner = THIS_MODULE,
.release = x25_release,
.bind = x25_bind,
.connect = x25_connect,
......
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