[PATCH v18 68/80] Add common socket helpers to unify the security hooks
From: Oren Laadan <hidden>
Date: 2009-09-24 00:29:30
Also in:
linux-api, linux-mm, lkml
Subsystem:
networking [general], networking [sockets], the rest · Maintainers:
"David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Kuniyuki Iwashima, Willem de Bruijn, Linus Torvalds
From: Dan Smith <redacted> 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. Acked-by: Serge Hallyn <redacted> Signed-off-by: Dan Smith <redacted> Cc: netdev@vger.kernel.org --- 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 950409d..12530bf 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h@@ -1578,6 +1578,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 6d47165..63c4498 100644
--- a/net/socket.c
+++ b/net/socket.c@@ -1414,15 +1414,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;
@@ -1610,11 +1605,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);
@@ -1639,15 +1630,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.0.4
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>