Commit 4245375d authored by Thomas Graf's avatar Thomas Graf Committed by David S. Miller

unix_diag: Do not use RTA_PUT() macros

Also, no need to trim on nlmsg_put() failure, nothing has been added
yet.  We also want to use nlmsg_end(), nlmsg_new() and nlmsg_free().
Signed-off-by: default avatarThomas Graf <tgraf@suug.ch>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent c074da28
...@@ -8,40 +8,31 @@ ...@@ -8,40 +8,31 @@
#include <net/af_unix.h> #include <net/af_unix.h>
#include <net/tcp_states.h> #include <net/tcp_states.h>
#define UNIX_DIAG_PUT(skb, attrtype, attrlen) \
RTA_DATA(__RTA_PUT(skb, attrtype, attrlen))
static int sk_diag_dump_name(struct sock *sk, struct sk_buff *nlskb) static int sk_diag_dump_name(struct sock *sk, struct sk_buff *nlskb)
{ {
struct unix_address *addr = unix_sk(sk)->addr; struct unix_address *addr = unix_sk(sk)->addr;
char *s;
if (addr) {
s = UNIX_DIAG_PUT(nlskb, UNIX_DIAG_NAME, addr->len - sizeof(short));
memcpy(s, addr->name->sun_path, addr->len - sizeof(short));
}
return 0; if (!addr)
return 0;
rtattr_failure: return nla_put(nlskb, UNIX_DIAG_NAME, addr->len - sizeof(short),
return -EMSGSIZE; addr->name->sun_path);
} }
static int sk_diag_dump_vfs(struct sock *sk, struct sk_buff *nlskb) static int sk_diag_dump_vfs(struct sock *sk, struct sk_buff *nlskb)
{ {
struct dentry *dentry = unix_sk(sk)->path.dentry; struct dentry *dentry = unix_sk(sk)->path.dentry;
struct unix_diag_vfs *uv;
if (dentry) { if (dentry) {
uv = UNIX_DIAG_PUT(nlskb, UNIX_DIAG_VFS, sizeof(*uv)); struct unix_diag_vfs uv = {
uv->udiag_vfs_ino = dentry->d_inode->i_ino; .udiag_vfs_ino = dentry->d_inode->i_ino,
uv->udiag_vfs_dev = dentry->d_sb->s_dev; .udiag_vfs_dev = dentry->d_sb->s_dev,
};
return nla_put(nlskb, UNIX_DIAG_VFS, sizeof(uv), &uv);
} }
return 0; return 0;
rtattr_failure:
return -EMSGSIZE;
} }
static int sk_diag_dump_peer(struct sock *sk, struct sk_buff *nlskb) static int sk_diag_dump_peer(struct sock *sk, struct sk_buff *nlskb)
...@@ -56,24 +47,28 @@ static int sk_diag_dump_peer(struct sock *sk, struct sk_buff *nlskb) ...@@ -56,24 +47,28 @@ static int sk_diag_dump_peer(struct sock *sk, struct sk_buff *nlskb)
unix_state_unlock(peer); unix_state_unlock(peer);
sock_put(peer); sock_put(peer);
RTA_PUT_U32(nlskb, UNIX_DIAG_PEER, ino); return nla_put_u32(nlskb, UNIX_DIAG_PEER, ino);
} }
return 0; return 0;
rtattr_failure:
return -EMSGSIZE;
} }
static int sk_diag_dump_icons(struct sock *sk, struct sk_buff *nlskb) static int sk_diag_dump_icons(struct sock *sk, struct sk_buff *nlskb)
{ {
struct sk_buff *skb; struct sk_buff *skb;
struct nlattr *attr;
u32 *buf; u32 *buf;
int i; int i;
if (sk->sk_state == TCP_LISTEN) { if (sk->sk_state == TCP_LISTEN) {
spin_lock(&sk->sk_receive_queue.lock); spin_lock(&sk->sk_receive_queue.lock);
buf = UNIX_DIAG_PUT(nlskb, UNIX_DIAG_ICONS,
sk->sk_receive_queue.qlen * sizeof(u32)); attr = nla_reserve(nlskb, UNIX_DIAG_ICONS,
sk->sk_receive_queue.qlen * sizeof(u32));
if (!attr)
goto errout;
buf = nla_data(attr);
i = 0; i = 0;
skb_queue_walk(&sk->sk_receive_queue, skb) { skb_queue_walk(&sk->sk_receive_queue, skb) {
struct sock *req, *peer; struct sock *req, *peer;
...@@ -94,45 +89,38 @@ static int sk_diag_dump_icons(struct sock *sk, struct sk_buff *nlskb) ...@@ -94,45 +89,38 @@ static int sk_diag_dump_icons(struct sock *sk, struct sk_buff *nlskb)
return 0; return 0;
rtattr_failure: errout:
spin_unlock(&sk->sk_receive_queue.lock); spin_unlock(&sk->sk_receive_queue.lock);
return -EMSGSIZE; return -EMSGSIZE;
} }
static int sk_diag_show_rqlen(struct sock *sk, struct sk_buff *nlskb) static int sk_diag_show_rqlen(struct sock *sk, struct sk_buff *nlskb)
{ {
struct unix_diag_rqlen *rql; struct unix_diag_rqlen rql;
rql = UNIX_DIAG_PUT(nlskb, UNIX_DIAG_RQLEN, sizeof(*rql));
if (sk->sk_state == TCP_LISTEN) { if (sk->sk_state == TCP_LISTEN) {
rql->udiag_rqueue = sk->sk_receive_queue.qlen; rql.udiag_rqueue = sk->sk_receive_queue.qlen;
rql->udiag_wqueue = sk->sk_max_ack_backlog; rql.udiag_wqueue = sk->sk_max_ack_backlog;
} else { } else {
rql->udiag_rqueue = (__u32)unix_inq_len(sk); rql.udiag_rqueue = (u32) unix_inq_len(sk);
rql->udiag_wqueue = (__u32)unix_outq_len(sk); rql.udiag_wqueue = (u32) unix_outq_len(sk);
} }
return 0; return nla_put(nlskb, UNIX_DIAG_RQLEN, sizeof(rql), &rql);
rtattr_failure:
return -EMSGSIZE;
} }
static int sk_diag_fill(struct sock *sk, struct sk_buff *skb, struct unix_diag_req *req, static int sk_diag_fill(struct sock *sk, struct sk_buff *skb, struct unix_diag_req *req,
u32 pid, u32 seq, u32 flags, int sk_ino) u32 pid, u32 seq, u32 flags, int sk_ino)
{ {
unsigned char *b = skb_tail_pointer(skb);
struct nlmsghdr *nlh; struct nlmsghdr *nlh;
struct unix_diag_msg *rep; struct unix_diag_msg *rep;
nlh = nlmsg_put(skb, pid, seq, SOCK_DIAG_BY_FAMILY, sizeof(*rep), 0); nlh = nlmsg_put(skb, pid, seq, SOCK_DIAG_BY_FAMILY, sizeof(*rep),
flags);
if (!nlh) if (!nlh)
goto out_nlmsg_trim; return -EMSGSIZE;
nlh->nlmsg_flags = flags;
rep = nlmsg_data(nlh); rep = nlmsg_data(nlh);
rep->udiag_family = AF_UNIX; rep->udiag_family = AF_UNIX;
rep->udiag_type = sk->sk_type; rep->udiag_type = sk->sk_type;
rep->udiag_state = sk->sk_state; rep->udiag_state = sk->sk_state;
...@@ -163,11 +151,10 @@ static int sk_diag_fill(struct sock *sk, struct sk_buff *skb, struct unix_diag_r ...@@ -163,11 +151,10 @@ static int sk_diag_fill(struct sock *sk, struct sk_buff *skb, struct unix_diag_r
sock_diag_put_meminfo(sk, skb, UNIX_DIAG_MEMINFO)) sock_diag_put_meminfo(sk, skb, UNIX_DIAG_MEMINFO))
goto out_nlmsg_trim; goto out_nlmsg_trim;
nlh->nlmsg_len = skb_tail_pointer(skb) - b; return nlmsg_end(skb, nlh);
return skb->len;
out_nlmsg_trim: out_nlmsg_trim:
nlmsg_trim(skb, b); nlmsg_cancel(skb, nlh);
return -EMSGSIZE; return -EMSGSIZE;
} }
...@@ -272,15 +259,14 @@ static int unix_diag_get_exact(struct sk_buff *in_skb, ...@@ -272,15 +259,14 @@ static int unix_diag_get_exact(struct sk_buff *in_skb,
extra_len = 256; extra_len = 256;
again: again:
err = -ENOMEM; err = -ENOMEM;
rep = alloc_skb(NLMSG_SPACE((sizeof(struct unix_diag_msg) + extra_len)), rep = nlmsg_new(sizeof(struct unix_diag_msg) + extra_len, GFP_KERNEL);
GFP_KERNEL);
if (!rep) if (!rep)
goto out; goto out;
err = sk_diag_fill(sk, rep, req, NETLINK_CB(in_skb).pid, err = sk_diag_fill(sk, rep, req, NETLINK_CB(in_skb).pid,
nlh->nlmsg_seq, 0, req->udiag_ino); nlh->nlmsg_seq, 0, req->udiag_ino);
if (err < 0) { if (err < 0) {
kfree_skb(rep); nlmsg_free(rep);
extra_len += 256; extra_len += 256;
if (extra_len >= PAGE_SIZE) if (extra_len >= PAGE_SIZE)
goto out; goto out;
......
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