| From a28e840a6dd4ff5d65e8395fc5642ca661090535 Mon Sep 17 00:00:00 2001 |
| From: Kees Cook <keescook@chromium.org> |
| Date: Tue, 9 Jun 2020 16:11:29 -0700 |
| Subject: [PATCH] net/compat: Add missing sock updates for SCM_RIGHTS |
| |
| commit d9539752d23283db4692384a634034f451261e29 upstream. |
| |
| Add missed sock updates to compat path via a new helper, which will be |
| used more in coming patches. (The net/core/scm.c code is left as-is here |
| to assist with -stable backports for the compat path.) |
| |
| Cc: Christoph Hellwig <hch@lst.de> |
| Cc: Sargun Dhillon <sargun@sargun.me> |
| Cc: Jakub Kicinski <kuba@kernel.org> |
| Cc: stable@vger.kernel.org |
| Fixes: 48a87cc26c13 ("net: netprio: fd passed in SCM_RIGHTS datagram not set correctly") |
| Fixes: d84295067fc7 ("net: net_cls: fd passed in SCM_RIGHTS datagram not set correctly") |
| Acked-by: Christian Brauner <christian.brauner@ubuntu.com> |
| Signed-off-by: Kees Cook <keescook@chromium.org> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/include/net/sock.h b/include/net/sock.h |
| index d17d6086a39d..86ec9c407746 100644 |
| --- a/include/net/sock.h |
| +++ b/include/net/sock.h |
| @@ -849,6 +849,8 @@ static inline int sk_memalloc_socks(void) |
| { |
| return static_branch_unlikely(&memalloc_socks_key); |
| } |
| + |
| +void __receive_sock(struct file *file); |
| #else |
| |
| static inline int sk_memalloc_socks(void) |
| @@ -856,6 +858,8 @@ static inline int sk_memalloc_socks(void) |
| return 0; |
| } |
| |
| +static inline void __receive_sock(struct file *file) |
| +{ } |
| #endif |
| |
| static inline gfp_t sk_gfp_mask(const struct sock *sk, gfp_t gfp_mask) |
| diff --git a/net/compat.c b/net/compat.c |
| index 3f9ce609397f..24906536870f 100644 |
| --- a/net/compat.c |
| +++ b/net/compat.c |
| @@ -290,6 +290,7 @@ void scm_detach_fds_compat(struct msghdr *kmsg, struct scm_cookie *scm) |
| break; |
| } |
| /* Bump the usage count and install the file. */ |
| + __receive_sock(fp[i]); |
| fd_install(new_fd, get_file(fp[i])); |
| } |
| |
| diff --git a/net/core/sock.c b/net/core/sock.c |
| index 65c529c1d55f..fb83335a5abb 100644 |
| --- a/net/core/sock.c |
| +++ b/net/core/sock.c |
| @@ -2729,6 +2729,27 @@ int sock_no_mmap(struct file *file, struct socket *sock, struct vm_area_struct * |
| } |
| EXPORT_SYMBOL(sock_no_mmap); |
| |
| +/* |
| + * When a file is received (via SCM_RIGHTS, etc), we must bump the |
| + * various sock-based usage counts. |
| + */ |
| +void __receive_sock(struct file *file) |
| +{ |
| + struct socket *sock; |
| + int error; |
| + |
| + /* |
| + * The resulting value of "error" is ignored here since we only |
| + * need to take action when the file is a socket and testing |
| + * "sock" for NULL is sufficient. |
| + */ |
| + sock = sock_from_file(file, &error); |
| + if (sock) { |
| + sock_update_netprioidx(&sock->sk->sk_cgrp_data); |
| + sock_update_classid(&sock->sk->sk_cgrp_data); |
| + } |
| +} |
| + |
| ssize_t sock_no_sendpage(struct socket *sock, struct page *page, int offset, size_t size, int flags) |
| { |
| ssize_t res; |
| -- |
| 2.27.0 |
| |