0001
0002 #include <linux/types.h>
0003 #include <linux/spinlock.h>
0004 #include <linux/sock_diag.h>
0005 #include <linux/unix_diag.h>
0006 #include <linux/skbuff.h>
0007 #include <linux/module.h>
0008 #include <linux/uidgid.h>
0009 #include <net/netlink.h>
0010 #include <net/af_unix.h>
0011 #include <net/tcp_states.h>
0012 #include <net/sock.h>
0013
0014 static int sk_diag_dump_name(struct sock *sk, struct sk_buff *nlskb)
0015 {
0016
0017 struct unix_address *addr = smp_load_acquire(&unix_sk(sk)->addr);
0018
0019 if (!addr)
0020 return 0;
0021
0022 return nla_put(nlskb, UNIX_DIAG_NAME,
0023 addr->len - offsetof(struct sockaddr_un, sun_path),
0024 addr->name->sun_path);
0025 }
0026
0027 static int sk_diag_dump_vfs(struct sock *sk, struct sk_buff *nlskb)
0028 {
0029 struct dentry *dentry = unix_sk(sk)->path.dentry;
0030
0031 if (dentry) {
0032 struct unix_diag_vfs uv = {
0033 .udiag_vfs_ino = d_backing_inode(dentry)->i_ino,
0034 .udiag_vfs_dev = dentry->d_sb->s_dev,
0035 };
0036
0037 return nla_put(nlskb, UNIX_DIAG_VFS, sizeof(uv), &uv);
0038 }
0039
0040 return 0;
0041 }
0042
0043 static int sk_diag_dump_peer(struct sock *sk, struct sk_buff *nlskb)
0044 {
0045 struct sock *peer;
0046 int ino;
0047
0048 peer = unix_peer_get(sk);
0049 if (peer) {
0050 unix_state_lock(peer);
0051 ino = sock_i_ino(peer);
0052 unix_state_unlock(peer);
0053 sock_put(peer);
0054
0055 return nla_put_u32(nlskb, UNIX_DIAG_PEER, ino);
0056 }
0057
0058 return 0;
0059 }
0060
0061 static int sk_diag_dump_icons(struct sock *sk, struct sk_buff *nlskb)
0062 {
0063 struct sk_buff *skb;
0064 struct nlattr *attr;
0065 u32 *buf;
0066 int i;
0067
0068 if (sk->sk_state == TCP_LISTEN) {
0069 spin_lock(&sk->sk_receive_queue.lock);
0070
0071 attr = nla_reserve(nlskb, UNIX_DIAG_ICONS,
0072 sk->sk_receive_queue.qlen * sizeof(u32));
0073 if (!attr)
0074 goto errout;
0075
0076 buf = nla_data(attr);
0077 i = 0;
0078 skb_queue_walk(&sk->sk_receive_queue, skb) {
0079 struct sock *req, *peer;
0080
0081 req = skb->sk;
0082
0083
0084
0085
0086
0087 unix_state_lock_nested(req);
0088 peer = unix_sk(req)->peer;
0089 buf[i++] = (peer ? sock_i_ino(peer) : 0);
0090 unix_state_unlock(req);
0091 }
0092 spin_unlock(&sk->sk_receive_queue.lock);
0093 }
0094
0095 return 0;
0096
0097 errout:
0098 spin_unlock(&sk->sk_receive_queue.lock);
0099 return -EMSGSIZE;
0100 }
0101
0102 static int sk_diag_show_rqlen(struct sock *sk, struct sk_buff *nlskb)
0103 {
0104 struct unix_diag_rqlen rql;
0105
0106 if (sk->sk_state == TCP_LISTEN) {
0107 rql.udiag_rqueue = sk->sk_receive_queue.qlen;
0108 rql.udiag_wqueue = sk->sk_max_ack_backlog;
0109 } else {
0110 rql.udiag_rqueue = (u32) unix_inq_len(sk);
0111 rql.udiag_wqueue = (u32) unix_outq_len(sk);
0112 }
0113
0114 return nla_put(nlskb, UNIX_DIAG_RQLEN, sizeof(rql), &rql);
0115 }
0116
0117 static int sk_diag_dump_uid(struct sock *sk, struct sk_buff *nlskb)
0118 {
0119 uid_t uid = from_kuid_munged(sk_user_ns(nlskb->sk), sock_i_uid(sk));
0120 return nla_put(nlskb, UNIX_DIAG_UID, sizeof(uid_t), &uid);
0121 }
0122
0123 static int sk_diag_fill(struct sock *sk, struct sk_buff *skb, struct unix_diag_req *req,
0124 u32 portid, u32 seq, u32 flags, int sk_ino)
0125 {
0126 struct nlmsghdr *nlh;
0127 struct unix_diag_msg *rep;
0128
0129 nlh = nlmsg_put(skb, portid, seq, SOCK_DIAG_BY_FAMILY, sizeof(*rep),
0130 flags);
0131 if (!nlh)
0132 return -EMSGSIZE;
0133
0134 rep = nlmsg_data(nlh);
0135 rep->udiag_family = AF_UNIX;
0136 rep->udiag_type = sk->sk_type;
0137 rep->udiag_state = sk->sk_state;
0138 rep->pad = 0;
0139 rep->udiag_ino = sk_ino;
0140 sock_diag_save_cookie(sk, rep->udiag_cookie);
0141
0142 if ((req->udiag_show & UDIAG_SHOW_NAME) &&
0143 sk_diag_dump_name(sk, skb))
0144 goto out_nlmsg_trim;
0145
0146 if ((req->udiag_show & UDIAG_SHOW_VFS) &&
0147 sk_diag_dump_vfs(sk, skb))
0148 goto out_nlmsg_trim;
0149
0150 if ((req->udiag_show & UDIAG_SHOW_PEER) &&
0151 sk_diag_dump_peer(sk, skb))
0152 goto out_nlmsg_trim;
0153
0154 if ((req->udiag_show & UDIAG_SHOW_ICONS) &&
0155 sk_diag_dump_icons(sk, skb))
0156 goto out_nlmsg_trim;
0157
0158 if ((req->udiag_show & UDIAG_SHOW_RQLEN) &&
0159 sk_diag_show_rqlen(sk, skb))
0160 goto out_nlmsg_trim;
0161
0162 if ((req->udiag_show & UDIAG_SHOW_MEMINFO) &&
0163 sock_diag_put_meminfo(sk, skb, UNIX_DIAG_MEMINFO))
0164 goto out_nlmsg_trim;
0165
0166 if (nla_put_u8(skb, UNIX_DIAG_SHUTDOWN, sk->sk_shutdown))
0167 goto out_nlmsg_trim;
0168
0169 if ((req->udiag_show & UDIAG_SHOW_UID) &&
0170 sk_diag_dump_uid(sk, skb))
0171 goto out_nlmsg_trim;
0172
0173 nlmsg_end(skb, nlh);
0174 return 0;
0175
0176 out_nlmsg_trim:
0177 nlmsg_cancel(skb, nlh);
0178 return -EMSGSIZE;
0179 }
0180
0181 static int sk_diag_dump(struct sock *sk, struct sk_buff *skb, struct unix_diag_req *req,
0182 u32 portid, u32 seq, u32 flags)
0183 {
0184 int sk_ino;
0185
0186 unix_state_lock(sk);
0187 sk_ino = sock_i_ino(sk);
0188 unix_state_unlock(sk);
0189
0190 if (!sk_ino)
0191 return 0;
0192
0193 return sk_diag_fill(sk, skb, req, portid, seq, flags, sk_ino);
0194 }
0195
0196 static int unix_diag_dump(struct sk_buff *skb, struct netlink_callback *cb)
0197 {
0198 struct net *net = sock_net(skb->sk);
0199 int num, s_num, slot, s_slot;
0200 struct unix_diag_req *req;
0201
0202 req = nlmsg_data(cb->nlh);
0203
0204 s_slot = cb->args[0];
0205 num = s_num = cb->args[1];
0206
0207 for (slot = s_slot; slot < UNIX_HASH_SIZE; s_num = 0, slot++) {
0208 struct sock *sk;
0209
0210 num = 0;
0211 spin_lock(&net->unx.table.locks[slot]);
0212 sk_for_each(sk, &net->unx.table.buckets[slot]) {
0213 if (num < s_num)
0214 goto next;
0215 if (!(req->udiag_states & (1 << sk->sk_state)))
0216 goto next;
0217 if (sk_diag_dump(sk, skb, req,
0218 NETLINK_CB(cb->skb).portid,
0219 cb->nlh->nlmsg_seq,
0220 NLM_F_MULTI) < 0) {
0221 spin_unlock(&net->unx.table.locks[slot]);
0222 goto done;
0223 }
0224 next:
0225 num++;
0226 }
0227 spin_unlock(&net->unx.table.locks[slot]);
0228 }
0229 done:
0230 cb->args[0] = slot;
0231 cb->args[1] = num;
0232
0233 return skb->len;
0234 }
0235
0236 static struct sock *unix_lookup_by_ino(struct net *net, unsigned int ino)
0237 {
0238 struct sock *sk;
0239 int i;
0240
0241 for (i = 0; i < UNIX_HASH_SIZE; i++) {
0242 spin_lock(&net->unx.table.locks[i]);
0243 sk_for_each(sk, &net->unx.table.buckets[i]) {
0244 if (ino == sock_i_ino(sk)) {
0245 sock_hold(sk);
0246 spin_unlock(&net->unx.table.locks[i]);
0247 return sk;
0248 }
0249 }
0250 spin_unlock(&net->unx.table.locks[i]);
0251 }
0252 return NULL;
0253 }
0254
0255 static int unix_diag_get_exact(struct sk_buff *in_skb,
0256 const struct nlmsghdr *nlh,
0257 struct unix_diag_req *req)
0258 {
0259 struct net *net = sock_net(in_skb->sk);
0260 unsigned int extra_len;
0261 struct sk_buff *rep;
0262 struct sock *sk;
0263 int err;
0264
0265 err = -EINVAL;
0266 if (req->udiag_ino == 0)
0267 goto out_nosk;
0268
0269 sk = unix_lookup_by_ino(net, req->udiag_ino);
0270 err = -ENOENT;
0271 if (sk == NULL)
0272 goto out_nosk;
0273
0274 err = sock_diag_check_cookie(sk, req->udiag_cookie);
0275 if (err)
0276 goto out;
0277
0278 extra_len = 256;
0279 again:
0280 err = -ENOMEM;
0281 rep = nlmsg_new(sizeof(struct unix_diag_msg) + extra_len, GFP_KERNEL);
0282 if (!rep)
0283 goto out;
0284
0285 err = sk_diag_fill(sk, rep, req, NETLINK_CB(in_skb).portid,
0286 nlh->nlmsg_seq, 0, req->udiag_ino);
0287 if (err < 0) {
0288 nlmsg_free(rep);
0289 extra_len += 256;
0290 if (extra_len >= PAGE_SIZE)
0291 goto out;
0292
0293 goto again;
0294 }
0295 err = nlmsg_unicast(net->diag_nlsk, rep, NETLINK_CB(in_skb).portid);
0296
0297 out:
0298 if (sk)
0299 sock_put(sk);
0300 out_nosk:
0301 return err;
0302 }
0303
0304 static int unix_diag_handler_dump(struct sk_buff *skb, struct nlmsghdr *h)
0305 {
0306 int hdrlen = sizeof(struct unix_diag_req);
0307
0308 if (nlmsg_len(h) < hdrlen)
0309 return -EINVAL;
0310
0311 if (h->nlmsg_flags & NLM_F_DUMP) {
0312 struct netlink_dump_control c = {
0313 .dump = unix_diag_dump,
0314 };
0315 return netlink_dump_start(sock_net(skb->sk)->diag_nlsk, skb, h, &c);
0316 } else
0317 return unix_diag_get_exact(skb, h, nlmsg_data(h));
0318 }
0319
0320 static const struct sock_diag_handler unix_diag_handler = {
0321 .family = AF_UNIX,
0322 .dump = unix_diag_handler_dump,
0323 };
0324
0325 static int __init unix_diag_init(void)
0326 {
0327 return sock_diag_register(&unix_diag_handler);
0328 }
0329
0330 static void __exit unix_diag_exit(void)
0331 {
0332 sock_diag_unregister(&unix_diag_handler);
0333 }
0334
0335 module_init(unix_diag_init);
0336 module_exit(unix_diag_exit);
0337 MODULE_LICENSE("GPL");
0338 MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_NETLINK, NETLINK_SOCK_DIAG, 1 );