From: Dan Smith <da...@us.ibm.com>

This moves the meat out of the bind(), getsockname(), and getpeername() syscalls
into helper functions that performs security_socket_bind() and then the
sock->ops->call().  This allows a unification of this behavior between the
syscalls and the pending socket restart logic.

Cc: net...@vger.kernel.org
Signed-off-by: Dan Smith <da...@us.ibm.com>
Acked-by: Serge E. Hallyn <se...@us.ibm.com>
Tested-by: Serge E. Hallyn <se...@us.ibm.com>
---
 include/net/sock.h |   48 ++++++++++++++++++++++++++++++++++++++++++++++++
 net/socket.c       |   29 ++++++-----------------------
 2 files changed, 54 insertions(+), 23 deletions(-)

diff --git a/include/net/sock.h b/include/net/sock.h
index b4603cd..3cf7de4 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -1645,6 +1645,54 @@ extern void sock_enable_timestamp(struct sock *sk, int 
flag);
 extern int sock_get_timestamp(struct sock *, struct timeval __user *);
 extern int sock_get_timestampns(struct sock *, struct timespec __user *);
 
+/* bind() helper shared between any callers needing to perform a bind on
+ * behalf of userspace (syscall and restart) with the security hooks.
+ */
+static inline int sock_bind(struct socket *sock,
+                           struct sockaddr *addr,
+                           int addr_len)
+{
+       int err;
+
+       err = security_socket_bind(sock, addr, addr_len);
+       if (err)
+               return err;
+       else
+               return sock->ops->bind(sock, addr, addr_len);
+}
+
+/* getname() helper shared between any callers needing to perform a getname on
+ * behalf of userspace (syscall and restart) with the security hooks.
+ */
+static inline int sock_getname(struct socket *sock,
+                              struct sockaddr *addr,
+                              int *addr_len)
+{
+       int err;
+
+       err = security_socket_getsockname(sock);
+       if (err)
+               return err;
+       else
+               return sock->ops->getname(sock, addr, addr_len, 0);
+}
+
+/* getpeer() helper shared between any callers needing to perform a getpeer on
+ * behalf of userspace (syscall and restart) with the security hooks.
+ */
+static inline int sock_getpeer(struct socket *sock,
+                              struct sockaddr *addr,
+                              int *addr_len)
+{
+       int err;
+
+       err = security_socket_getpeername(sock);
+       if (err)
+               return err;
+       else
+               return sock->ops->getname(sock, addr, addr_len, 1);
+}
+
 /* 
  *     Enable debug/info messages 
  */
diff --git a/net/socket.c b/net/socket.c
index 5e8d0af..b9f421b 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -1422,15 +1422,10 @@ SYSCALL_DEFINE3(bind, int, fd, struct sockaddr __user 
*, umyaddr, int, addrlen)
        sock = sockfd_lookup_light(fd, &err, &fput_needed);
        if (sock) {
                err = move_addr_to_kernel(umyaddr, addrlen, (struct sockaddr 
*)&address);
-               if (err >= 0) {
-                       err = security_socket_bind(sock,
-                                                  (struct sockaddr *)&address,
-                                                  addrlen);
-                       if (!err)
-                               err = sock->ops->bind(sock,
-                                                     (struct sockaddr *)
-                                                     &address, addrlen);
-               }
+               if (err >= 0)
+                       err = sock_bind(sock,
+                                       (struct sockaddr *)&address,
+                                       addrlen);
                fput_light(sock->file, fput_needed);
        }
        return err;
@@ -1609,11 +1604,7 @@ SYSCALL_DEFINE3(getsockname, int, fd, struct sockaddr 
__user *, usockaddr,
        if (!sock)
                goto out;
 
-       err = security_socket_getsockname(sock);
-       if (err)
-               goto out_put;
-
-       err = sock->ops->getname(sock, (struct sockaddr *)&address, &len, 0);
+       err = sock_getname(sock, (struct sockaddr *)&address, &len);
        if (err)
                goto out_put;
        err = move_addr_to_user((struct sockaddr *)&address, len, usockaddr, 
usockaddr_len);
@@ -1638,15 +1629,7 @@ SYSCALL_DEFINE3(getpeername, int, fd, struct sockaddr 
__user *, usockaddr,
 
        sock = sockfd_lookup_light(fd, &err, &fput_needed);
        if (sock != NULL) {
-               err = security_socket_getpeername(sock);
-               if (err) {
-                       fput_light(sock->file, fput_needed);
-                       return err;
-               }
-
-               err =
-                   sock->ops->getname(sock, (struct sockaddr *)&address, &len,
-                                      1);
+               err = sock_getpeer(sock, (struct sockaddr *)&address, &len);
                if (!err)
                        err = move_addr_to_user((struct sockaddr *)&address, 
len, usockaddr,
                                                usockaddr_len);
-- 
1.6.3.3

_______________________________________________
Containers mailing list
contain...@lists.linux-foundation.org
https://lists.linux-foundation.org/mailman/listinfo/containers

_______________________________________________
Devel mailing list
Devel@openvz.org
https://openvz.org/mailman/listinfo/devel

Reply via email to