diff options
Diffstat (limited to 'net/socket.c')
-rw-r--r-- | net/socket.c | 77 |
1 files changed, 60 insertions, 17 deletions
diff --git a/net/socket.c b/net/socket.c index ac2219f90d5d..332c43007d10 100644 --- a/net/socket.c +++ b/net/socket.c @@ -98,6 +98,7 @@ #include <net/sock.h> #include <linux/netfilter.h> +#include <trace/socket.h> #include <linux/if_tun.h> #include <linux/ipv6_route.h> @@ -164,6 +165,21 @@ static const struct net_proto_family __rcu *net_families[NPROTO] __read_mostly; static DEFINE_PER_CPU(int, sockets_in_use); +DEFINE_TRACE(socket_create); +DEFINE_TRACE(socket_bind); +DEFINE_TRACE(socket_connect); +DEFINE_TRACE(socket_listen); +DEFINE_TRACE(socket_accept); +DEFINE_TRACE(socket_getsockname); +DEFINE_TRACE(socket_getpeername); +DEFINE_TRACE(socket_socketpair); +DEFINE_TRACE(socket_sendmsg); +DEFINE_TRACE(socket_recvmsg); +DEFINE_TRACE(socket_setsockopt); +DEFINE_TRACE(socket_getsockopt); +DEFINE_TRACE(socket_shutdown); +DEFINE_TRACE(socket_call); + /* * Support routines. * Move socket addresses back and forth across the kernel/user @@ -564,7 +580,9 @@ static inline int __sock_sendmsg(struct kiocb *iocb, struct socket *sock, if (err) return err; - return sock->ops->sendmsg(iocb, sock, msg, size); + err = sock->ops->sendmsg(iocb, sock, msg, size); + trace_socket_sendmsg(sock, msg, size, err); + return err; } int sock_sendmsg(struct socket *sock, struct msghdr *msg, size_t size) @@ -682,6 +700,7 @@ static inline int __sock_recvmsg_nosec(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t size, int flags) { struct sock_iocb *si = kiocb_to_siocb(iocb); + int err; sock_update_classid(sock->sk); @@ -691,7 +710,9 @@ static inline int __sock_recvmsg_nosec(struct kiocb *iocb, struct socket *sock, si->size = size; si->flags = flags; - return sock->ops->recvmsg(iocb, sock, msg, size, flags); + err = sock->ops->recvmsg(iocb, sock, msg, size, flags); + trace_socket_recvmsg(sock, msg, size, flags, err); + return err; } static inline int __sock_recvmsg(struct kiocb *iocb, struct socket *sock, @@ -1299,8 +1320,10 @@ SYSCALL_DEFINE3(socket, int, family, int, type, int, protocol) BUILD_BUG_ON(SOCK_NONBLOCK & SOCK_TYPE_MASK); flags = type & ~SOCK_TYPE_MASK; - if (flags & ~(SOCK_CLOEXEC | SOCK_NONBLOCK)) - return -EINVAL; + if (flags & ~(SOCK_CLOEXEC | SOCK_NONBLOCK)) { + retval = -EINVAL; + goto out; + } type &= SOCK_TYPE_MASK; if (SOCK_NONBLOCK != O_NONBLOCK && (flags & SOCK_NONBLOCK)) @@ -1314,12 +1337,12 @@ SYSCALL_DEFINE3(socket, int, family, int, type, int, protocol) if (retval < 0) goto out_release; -out: - /* It may be already another descriptor 8) Not kernel problem. */ - return retval; - + goto out; out_release: sock_release(sock); +out: + trace_socket_create(family, type, protocol, sock, retval); + /* It may be already another descriptor 8) Not kernel problem. */ return retval; } @@ -1336,8 +1359,10 @@ SYSCALL_DEFINE4(socketpair, int, family, int, type, int, protocol, int flags; flags = type & ~SOCK_TYPE_MASK; - if (flags & ~(SOCK_CLOEXEC | SOCK_NONBLOCK)) - return -EINVAL; + if (flags & ~(SOCK_CLOEXEC | SOCK_NONBLOCK)) { + err = -EINVAL; + goto out; + } type &= SOCK_TYPE_MASK; if (SOCK_NONBLOCK != O_NONBLOCK && (flags & SOCK_NONBLOCK)) @@ -1386,17 +1411,18 @@ SYSCALL_DEFINE4(socketpair, int, family, int, type, int, protocol, if (!err) err = put_user(fd2, &usockvec[1]); if (!err) - return 0; + goto out; sys_close(fd2); sys_close(fd1); - return err; + goto out; out_release_both: sock_release(sock2); out_release_1: sock_release(sock1); out: + trace_socket_socketpair(family, type, protocol, usockvec, err); return err; } @@ -1428,6 +1454,7 @@ SYSCALL_DEFINE3(bind, int, fd, struct sockaddr __user *, umyaddr, int, addrlen) } fput_light(sock->file, fput_needed); } + trace_socket_bind(fd, umyaddr, addrlen, err); return err; } @@ -1455,6 +1482,7 @@ SYSCALL_DEFINE2(listen, int, fd, int, backlog) fput_light(sock->file, fput_needed); } + trace_socket_listen(fd, backlog, err); return err; } @@ -1478,8 +1506,10 @@ SYSCALL_DEFINE4(accept4, int, fd, struct sockaddr __user *, upeer_sockaddr, int err, len, newfd, fput_needed; struct sockaddr_storage address; - if (flags & ~(SOCK_CLOEXEC | SOCK_NONBLOCK)) - return -EINVAL; + if (flags & ~(SOCK_CLOEXEC | SOCK_NONBLOCK)) { + err = -EINVAL; + goto out; + } if (SOCK_NONBLOCK != O_NONBLOCK && (flags & SOCK_NONBLOCK)) flags = (flags & ~SOCK_NONBLOCK) | O_NONBLOCK; @@ -1537,6 +1567,7 @@ SYSCALL_DEFINE4(accept4, int, fd, struct sockaddr __user *, upeer_sockaddr, out_put: fput_light(sock->file, fput_needed); out: + trace_socket_accept(fd, upeer_sockaddr, upeer_addrlen, flags, err); return err; out_fd: fput(newfile); @@ -1586,6 +1617,7 @@ SYSCALL_DEFINE3(connect, int, fd, struct sockaddr __user *, uservaddr, out_put: fput_light(sock->file, fput_needed); out: + trace_socket_connect(fd, uservaddr, addrlen, err); return err; } @@ -1617,6 +1649,7 @@ SYSCALL_DEFINE3(getsockname, int, fd, struct sockaddr __user *, usockaddr, out_put: fput_light(sock->file, fput_needed); out: + trace_socket_getsockname(fd, usockaddr, usockaddr_len, err); return err; } @@ -1637,7 +1670,7 @@ SYSCALL_DEFINE3(getpeername, int, fd, struct sockaddr __user *, usockaddr, err = security_socket_getpeername(sock); if (err) { fput_light(sock->file, fput_needed); - return err; + goto out; } err = @@ -1648,6 +1681,8 @@ SYSCALL_DEFINE3(getpeername, int, fd, struct sockaddr __user *, usockaddr, usockaddr_len); fput_light(sock->file, fput_needed); } +out: + trace_socket_getpeername(fd, usockaddr, usockaddr_len, err); return err; } @@ -1778,8 +1813,10 @@ SYSCALL_DEFINE5(setsockopt, int, fd, int, level, int, optname, int err, fput_needed; struct socket *sock; - if (optlen < 0) - return -EINVAL; + if (optlen < 0) { + err = -EINVAL; + goto out; + } sock = sockfd_lookup_light(fd, &err, &fput_needed); if (sock != NULL) { @@ -1798,6 +1835,8 @@ SYSCALL_DEFINE5(setsockopt, int, fd, int, level, int, optname, out_put: fput_light(sock->file, fput_needed); } +out: + trace_socket_setsockopt(fd, level, optname, optval, optlen, err); return err; } @@ -1829,6 +1868,7 @@ SYSCALL_DEFINE5(getsockopt, int, fd, int, level, int, optname, out_put: fput_light(sock->file, fput_needed); } + trace_socket_getsockopt(fd, level, optname, optval, optlen, err); return err; } @@ -1848,6 +1888,7 @@ SYSCALL_DEFINE2(shutdown, int, fd, int, how) err = sock->ops->shutdown(sock, how); fput_light(sock->file, fput_needed); } + trace_socket_shutdown(fd, how, err); return err; } @@ -2249,6 +2290,8 @@ SYSCALL_DEFINE2(socketcall, int, call, unsigned long __user *, args) a0 = a[0]; a1 = a[1]; + trace_socket_call(call, a0); + switch (call) { case SYS_SOCKET: err = sys_socket(a0, a1, a[2]); |