| From d9539752d23283db4692384a634034f451261e29 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> |
| |
| diff --git a/include/net/sock.h b/include/net/sock.h |
| index c53cc42b5ab9..2be67f1ee8b1 100644 |
| --- a/include/net/sock.h |
| +++ b/include/net/sock.h |
| @@ -890,6 +890,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) |
| @@ -897,6 +899,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 5e3041a2c37d..2937b816107d 100644 |
| --- a/net/compat.c |
| +++ b/net/compat.c |
| @@ -309,6 +309,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 6c4acf1f0220..bde394979041 100644 |
| --- a/net/core/sock.c |
| +++ b/net/core/sock.c |
| @@ -2840,6 +2840,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 |
| |