X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=net%2Fbluetooth%2Fbnep%2Fsock.c;h=5563db1bf526e94d4a48c5af511315c4d3646786;hb=97bf2856c6014879bd04983a3e9dfcdac1e7fe85;hp=0978a58b77037e53eedb1be33aeca954e3f05ce9;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/net/bluetooth/bnep/sock.c b/net/bluetooth/bnep/sock.c index 0978a58b7..5563db1bf 100644 --- a/net/bluetooth/bnep/sock.c +++ b/net/bluetooth/bnep/sock.c @@ -28,13 +28,12 @@ * $Id: sock.c,v 1.4 2002/08/04 21:23:58 maxk Exp $ */ -#include #include #include +#include #include #include -#include #include #include #include @@ -44,6 +43,7 @@ #include #include #include +#include #include #include @@ -77,6 +77,7 @@ static int bnep_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long struct bnep_conndel_req cd; struct bnep_conninfo ci; struct socket *nsock; + void __user *argp = (void __user *)arg; int err; BT_DBG("cmd %x arg %lx", cmd, arg); @@ -86,7 +87,7 @@ static int bnep_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long if (!capable(CAP_NET_ADMIN)) return -EACCES; - if (copy_from_user(&ca, (void *) arg, sizeof(ca))) + if (copy_from_user(&ca, argp, sizeof(ca))) return -EFAULT; nsock = sockfd_lookup(ca.sock, &err); @@ -100,7 +101,7 @@ static int bnep_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long err = bnep_add_connection(&ca, nsock); if (!err) { - if (copy_to_user((void *) arg, &ca, sizeof(ca))) + if (copy_to_user(argp, &ca, sizeof(ca))) err = -EFAULT; } else fput(nsock->file); @@ -111,30 +112,30 @@ static int bnep_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long if (!capable(CAP_NET_ADMIN)) return -EACCES; - if (copy_from_user(&cd, (void *) arg, sizeof(cd))) + if (copy_from_user(&cd, argp, sizeof(cd))) return -EFAULT; return bnep_del_connection(&cd); case BNEPGETCONNLIST: - if (copy_from_user(&cl, (void *) arg, sizeof(cl))) + if (copy_from_user(&cl, argp, sizeof(cl))) return -EFAULT; if (cl.cnum <= 0) return -EINVAL; err = bnep_get_connlist(&cl); - if (!err && copy_to_user((void *) arg, &cl, sizeof(cl))) + if (!err && copy_to_user(argp, &cl, sizeof(cl))) return -EFAULT; return err; case BNEPGETCONNINFO: - if (copy_from_user(&ci, (void *) arg, sizeof(ci))) + if (copy_from_user(&ci, argp, sizeof(ci))) return -EFAULT; err = bnep_get_conninfo(&ci); - if (!err && copy_to_user((void *) arg, &ci, sizeof(ci))) + if (!err && copy_to_user(argp, &ci, sizeof(ci))) return -EFAULT; return err; @@ -146,24 +147,62 @@ static int bnep_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long return 0; } -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, - .getname = sock_no_getname, - .sendmsg = sock_no_sendmsg, - .recvmsg = sock_no_recvmsg, - .poll = sock_no_poll, - .listen = sock_no_listen, - .shutdown = sock_no_shutdown, - .setsockopt = sock_no_setsockopt, - .getsockopt = sock_no_getsockopt, - .connect = sock_no_connect, - .socketpair = sock_no_socketpair, - .accept = sock_no_accept, - .mmap = sock_no_mmap +#ifdef CONFIG_COMPAT +static int bnep_sock_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) +{ + if (cmd == BNEPGETCONNLIST) { + struct bnep_connlist_req cl; + uint32_t uci; + int err; + + if (get_user(cl.cnum, (uint32_t __user *) arg) || + get_user(uci, (u32 __user *) (arg + 4))) + return -EFAULT; + + cl.ci = compat_ptr(uci); + + if (cl.cnum <= 0) + return -EINVAL; + + err = bnep_get_connlist(&cl); + + if (!err && put_user(cl.cnum, (uint32_t __user *) arg)) + err = -EFAULT; + + return err; + } + + return bnep_sock_ioctl(sock, cmd, arg); +} +#endif + +static const struct proto_ops bnep_sock_ops = { + .family = PF_BLUETOOTH, + .owner = THIS_MODULE, + .release = bnep_sock_release, + .ioctl = bnep_sock_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = bnep_sock_compat_ioctl, +#endif + .bind = sock_no_bind, + .getname = sock_no_getname, + .sendmsg = sock_no_sendmsg, + .recvmsg = sock_no_recvmsg, + .poll = sock_no_poll, + .listen = sock_no_listen, + .shutdown = sock_no_shutdown, + .setsockopt = sock_no_setsockopt, + .getsockopt = sock_no_getsockopt, + .connect = sock_no_connect, + .socketpair = sock_no_socketpair, + .accept = sock_no_accept, + .mmap = sock_no_mmap +}; + +static struct proto bnep_proto = { + .name = "BNEP", + .owner = THIS_MODULE, + .obj_size = sizeof(struct bt_sock) }; static int bnep_sock_create(struct socket *sock, int protocol) @@ -175,17 +214,21 @@ static int bnep_sock_create(struct socket *sock, int protocol) if (sock->type != SOCK_RAW) return -ESOCKTNOSUPPORT; - if (!(sk = bt_sock_alloc(sock, PF_BLUETOOTH, 0, GFP_KERNEL))) + sk = sk_alloc(PF_BLUETOOTH, GFP_ATOMIC, &bnep_proto, 1); + if (!sk) return -ENOMEM; - sk_set_owner(sk, THIS_MODULE); + sock_init_data(sock, sk); sock->ops = &bnep_sock_ops; - sock->state = SS_UNCONNECTED; + sock->state = SS_UNCONNECTED; + + sock_reset_flag(sk, SOCK_ZAPPED); - sk->sk_destruct = NULL; sk->sk_protocol = protocol; + sk->sk_state = BT_OPEN; + return 0; } @@ -197,13 +240,30 @@ static struct net_proto_family bnep_sock_family_ops = { int __init bnep_sock_init(void) { - bt_sock_register(BTPROTO_BNEP, &bnep_sock_family_ops); + int err; + + err = proto_register(&bnep_proto, 0); + if (err < 0) + return err; + + err = bt_sock_register(BTPROTO_BNEP, &bnep_sock_family_ops); + if (err < 0) + goto error; + return 0; + +error: + BT_ERR("Can't register BNEP socket"); + proto_unregister(&bnep_proto); + return err; } int __exit bnep_sock_cleanup(void) { - if (bt_sock_unregister(BTPROTO_BNEP)) + if (bt_sock_unregister(BTPROTO_BNEP) < 0) BT_ERR("Can't unregister BNEP socket"); + + proto_unregister(&bnep_proto); + return 0; }