0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023 #include <linux/compat.h>
0024 #include <linux/export.h>
0025 #include <linux/file.h>
0026
0027 #include "hidp.h"
0028
0029 static struct bt_sock_list hidp_sk_list = {
0030 .lock = __RW_LOCK_UNLOCKED(hidp_sk_list.lock)
0031 };
0032
0033 static int hidp_sock_release(struct socket *sock)
0034 {
0035 struct sock *sk = sock->sk;
0036
0037 BT_DBG("sock %p sk %p", sock, sk);
0038
0039 if (!sk)
0040 return 0;
0041
0042 bt_sock_unlink(&hidp_sk_list, sk);
0043
0044 sock_orphan(sk);
0045 sock_put(sk);
0046
0047 return 0;
0048 }
0049
0050 static int do_hidp_sock_ioctl(struct socket *sock, unsigned int cmd, void __user *argp)
0051 {
0052 struct hidp_connadd_req ca;
0053 struct hidp_conndel_req cd;
0054 struct hidp_connlist_req cl;
0055 struct hidp_conninfo ci;
0056 struct socket *csock;
0057 struct socket *isock;
0058 int err;
0059
0060 BT_DBG("cmd %x arg %p", cmd, argp);
0061
0062 switch (cmd) {
0063 case HIDPCONNADD:
0064 if (!capable(CAP_NET_ADMIN))
0065 return -EPERM;
0066
0067 if (copy_from_user(&ca, argp, sizeof(ca)))
0068 return -EFAULT;
0069
0070 csock = sockfd_lookup(ca.ctrl_sock, &err);
0071 if (!csock)
0072 return err;
0073
0074 isock = sockfd_lookup(ca.intr_sock, &err);
0075 if (!isock) {
0076 sockfd_put(csock);
0077 return err;
0078 }
0079 ca.name[sizeof(ca.name)-1] = 0;
0080
0081 err = hidp_connection_add(&ca, csock, isock);
0082 if (!err && copy_to_user(argp, &ca, sizeof(ca)))
0083 err = -EFAULT;
0084
0085 sockfd_put(csock);
0086 sockfd_put(isock);
0087
0088 return err;
0089
0090 case HIDPCONNDEL:
0091 if (!capable(CAP_NET_ADMIN))
0092 return -EPERM;
0093
0094 if (copy_from_user(&cd, argp, sizeof(cd)))
0095 return -EFAULT;
0096
0097 return hidp_connection_del(&cd);
0098
0099 case HIDPGETCONNLIST:
0100 if (copy_from_user(&cl, argp, sizeof(cl)))
0101 return -EFAULT;
0102
0103 if (cl.cnum <= 0)
0104 return -EINVAL;
0105
0106 err = hidp_get_connlist(&cl);
0107 if (!err && copy_to_user(argp, &cl, sizeof(cl)))
0108 return -EFAULT;
0109
0110 return err;
0111
0112 case HIDPGETCONNINFO:
0113 if (copy_from_user(&ci, argp, sizeof(ci)))
0114 return -EFAULT;
0115
0116 err = hidp_get_conninfo(&ci);
0117 if (!err && copy_to_user(argp, &ci, sizeof(ci)))
0118 return -EFAULT;
0119
0120 return err;
0121 }
0122
0123 return -EINVAL;
0124 }
0125
0126 static int hidp_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
0127 {
0128 return do_hidp_sock_ioctl(sock, cmd, (void __user *)arg);
0129 }
0130
0131 #ifdef CONFIG_COMPAT
0132 struct compat_hidp_connadd_req {
0133 int ctrl_sock;
0134 int intr_sock;
0135 __u16 parser;
0136 __u16 rd_size;
0137 compat_uptr_t rd_data;
0138 __u8 country;
0139 __u8 subclass;
0140 __u16 vendor;
0141 __u16 product;
0142 __u16 version;
0143 __u32 flags;
0144 __u32 idle_to;
0145 char name[128];
0146 };
0147
0148 static int hidp_sock_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
0149 {
0150 void __user *argp = compat_ptr(arg);
0151 int err;
0152
0153 if (cmd == HIDPGETCONNLIST) {
0154 struct hidp_connlist_req cl;
0155 u32 __user *p = argp;
0156 u32 uci;
0157
0158 if (get_user(cl.cnum, p) || get_user(uci, p + 1))
0159 return -EFAULT;
0160
0161 cl.ci = compat_ptr(uci);
0162
0163 if (cl.cnum <= 0)
0164 return -EINVAL;
0165
0166 err = hidp_get_connlist(&cl);
0167
0168 if (!err && put_user(cl.cnum, p))
0169 err = -EFAULT;
0170
0171 return err;
0172 } else if (cmd == HIDPCONNADD) {
0173 struct compat_hidp_connadd_req ca32;
0174 struct hidp_connadd_req ca;
0175 struct socket *csock;
0176 struct socket *isock;
0177
0178 if (!capable(CAP_NET_ADMIN))
0179 return -EPERM;
0180
0181 if (copy_from_user(&ca32, (void __user *) arg, sizeof(ca32)))
0182 return -EFAULT;
0183
0184 ca.ctrl_sock = ca32.ctrl_sock;
0185 ca.intr_sock = ca32.intr_sock;
0186 ca.parser = ca32.parser;
0187 ca.rd_size = ca32.rd_size;
0188 ca.rd_data = compat_ptr(ca32.rd_data);
0189 ca.country = ca32.country;
0190 ca.subclass = ca32.subclass;
0191 ca.vendor = ca32.vendor;
0192 ca.product = ca32.product;
0193 ca.version = ca32.version;
0194 ca.flags = ca32.flags;
0195 ca.idle_to = ca32.idle_to;
0196 ca32.name[sizeof(ca32.name) - 1] = '\0';
0197 memcpy(ca.name, ca32.name, 128);
0198
0199 csock = sockfd_lookup(ca.ctrl_sock, &err);
0200 if (!csock)
0201 return err;
0202
0203 isock = sockfd_lookup(ca.intr_sock, &err);
0204 if (!isock) {
0205 sockfd_put(csock);
0206 return err;
0207 }
0208
0209 err = hidp_connection_add(&ca, csock, isock);
0210 if (!err && copy_to_user(argp, &ca32, sizeof(ca32)))
0211 err = -EFAULT;
0212
0213 sockfd_put(csock);
0214 sockfd_put(isock);
0215
0216 return err;
0217 }
0218
0219 return hidp_sock_ioctl(sock, cmd, arg);
0220 }
0221 #endif
0222
0223 static const struct proto_ops hidp_sock_ops = {
0224 .family = PF_BLUETOOTH,
0225 .owner = THIS_MODULE,
0226 .release = hidp_sock_release,
0227 .ioctl = hidp_sock_ioctl,
0228 #ifdef CONFIG_COMPAT
0229 .compat_ioctl = hidp_sock_compat_ioctl,
0230 #endif
0231 .bind = sock_no_bind,
0232 .getname = sock_no_getname,
0233 .sendmsg = sock_no_sendmsg,
0234 .recvmsg = sock_no_recvmsg,
0235 .listen = sock_no_listen,
0236 .shutdown = sock_no_shutdown,
0237 .connect = sock_no_connect,
0238 .socketpair = sock_no_socketpair,
0239 .accept = sock_no_accept,
0240 .mmap = sock_no_mmap
0241 };
0242
0243 static struct proto hidp_proto = {
0244 .name = "HIDP",
0245 .owner = THIS_MODULE,
0246 .obj_size = sizeof(struct bt_sock)
0247 };
0248
0249 static int hidp_sock_create(struct net *net, struct socket *sock, int protocol,
0250 int kern)
0251 {
0252 struct sock *sk;
0253
0254 BT_DBG("sock %p", sock);
0255
0256 if (sock->type != SOCK_RAW)
0257 return -ESOCKTNOSUPPORT;
0258
0259 sk = sk_alloc(net, PF_BLUETOOTH, GFP_ATOMIC, &hidp_proto, kern);
0260 if (!sk)
0261 return -ENOMEM;
0262
0263 sock_init_data(sock, sk);
0264
0265 sock->ops = &hidp_sock_ops;
0266
0267 sock->state = SS_UNCONNECTED;
0268
0269 sock_reset_flag(sk, SOCK_ZAPPED);
0270
0271 sk->sk_protocol = protocol;
0272 sk->sk_state = BT_OPEN;
0273
0274 bt_sock_link(&hidp_sk_list, sk);
0275
0276 return 0;
0277 }
0278
0279 static const struct net_proto_family hidp_sock_family_ops = {
0280 .family = PF_BLUETOOTH,
0281 .owner = THIS_MODULE,
0282 .create = hidp_sock_create
0283 };
0284
0285 int __init hidp_init_sockets(void)
0286 {
0287 int err;
0288
0289 err = proto_register(&hidp_proto, 0);
0290 if (err < 0)
0291 return err;
0292
0293 err = bt_sock_register(BTPROTO_HIDP, &hidp_sock_family_ops);
0294 if (err < 0) {
0295 BT_ERR("Can't register HIDP socket");
0296 goto error;
0297 }
0298
0299 err = bt_procfs_init(&init_net, "hidp", &hidp_sk_list, NULL);
0300 if (err < 0) {
0301 BT_ERR("Failed to create HIDP proc file");
0302 bt_sock_unregister(BTPROTO_HIDP);
0303 goto error;
0304 }
0305
0306 BT_INFO("HIDP socket layer initialized");
0307
0308 return 0;
0309
0310 error:
0311 proto_unregister(&hidp_proto);
0312 return err;
0313 }
0314
0315 void __exit hidp_cleanup_sockets(void)
0316 {
0317 bt_procfs_cleanup(&init_net, "hidp");
0318 bt_sock_unregister(BTPROTO_HIDP);
0319 proto_unregister(&hidp_proto);
0320 }