From patchwork Wed Jun 24 16:28:51 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoph Hellwig X-Patchwork-Id: 11623733 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id B887092A for ; Wed, 24 Jun 2020 16:30:39 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id A021420857 for ; Wed, 24 Jun 2020 16:30:39 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=infradead.org header.i=@infradead.org header.b="ZJv/2q54" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2404725AbgFXQ30 (ORCPT ); Wed, 24 Jun 2020 12:29:26 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41074 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2404911AbgFXQ3V (ORCPT ); Wed, 24 Jun 2020 12:29:21 -0400 Received: from casper.infradead.org (unknown [IPv6:2001:8b0:10b:1236::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BA32DC0613ED; Wed, 24 Jun 2020 09:29:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To: Content-Type:Content-ID:Content-Description; bh=Dr/cOIncKjeeFU+aDyXMiz0vyGhNWfe5V14YtpSjdI0=; b=ZJv/2q54bEef4yvTAHOtWXCm3x J1MBhZQQwtLkIhIkIWo4Ry7P+COIFBkBZzz7ueR56jv16WawR7NkE4cz6fkJICCM+a9k9enMK7fcE 7rxc08vnMJH11liHYfwI76mPJgW++se+LbdEru/eObiOnMM3GnWp2SA/MkzNixKF0XeohhqM/fSUf pIPUkK3K/jyG8xnzz7rcprIeIpFeZxW2PXQioPAi9OmJcW3jILilwDhQ9PYrUiPFxKiJNVG8hb6YZ Ue6NhMyEtNxj4IVhvP/hHSEDavqhcPa429xUrTxOmBuyJE3Lg2Pm005kEmSDWCjdbkqYfgQF9RsuQ tDldon9g==; Received: from [2001:4bb8:180:a3:5c7c:8955:539d:955b] (helo=localhost) by casper.infradead.org with esmtpsa (Exim 4.92.3 #3 (Red Hat Linux)) id 1jo8Gl-0006nk-RK; Wed, 24 Jun 2020 16:29:04 +0000 From: Christoph Hellwig To: Al Viro , Linus Torvalds Cc: Luis Chamberlain , Kees Cook , Iurii Zaikin , linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org Subject: [PATCH 01/11] uptr: add a new "universal pointer" type Date: Wed, 24 Jun 2020 18:28:51 +0200 Message-Id: <20200624162901.1814136-2-hch@lst.de> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200624162901.1814136-1-hch@lst.de> References: <20200624162901.1814136-1-hch@lst.de> MIME-Version: 1.0 X-SRS-Rewrite: SMTP reverse-path rewritten from by casper.infradead.org. See http://www.infradead.org/rpr.html Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Add a uptr_t type that can hold a pointer to either a user or kernel memory region, and simply helpers to copy to and from it. For architectures like x86 that have non-overlapping user and kernel address space it just is a union and uses a TASK_SIZE check to select the proper copy routine. For architectures with overlapping address spaces a flag to indicate the address space is used instead. Signed-off-by: Christoph Hellwig --- include/linux/uptr.h | 72 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 include/linux/uptr.h diff --git a/include/linux/uptr.h b/include/linux/uptr.h new file mode 100644 index 00000000000000..1373511f9897b4 --- /dev/null +++ b/include/linux/uptr.h @@ -0,0 +1,72 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2020 Christoph Hellwig. + * + * Support for "universal" pointers that can point to either kernel or userspace + * memory. + */ +#ifndef _LINUX_UPTR_H +#define _LINUX_UPTR_H + +#ifdef CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE +typedef union { + void *kernel; + void __user *user; +} uptr_t; + +static inline uptr_t USER_UPTR(void __user *p) +{ + return (uptr_t) { .user = p }; +} + +static inline uptr_t KERNEL_UPTR(void *p) +{ + return (uptr_t) { .kernel = p }; +} + +static inline bool uptr_is_kernel(uptr_t uptr) +{ + return (unsigned long)uptr.kernel >= TASK_SIZE; +} +#else /* CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE */ +typedef struct { + union { + void *kernel; + void __user *user; + }; + bool is_kernel : 1; +} uptr_t; + +static inline uptr_t USER_UPTR(void __user *p) +{ + return (uptr_t) { .user = p }; +} + +static inline uptr_t KERNEL_UPTR(void *p) +{ + return (uptr_t) { .kernel = p, .is_kernel = true }; +} + +static inline bool uptr_is_kernel(uptr_t uptr) +{ + return uptr.is_kernel; +} +#endif /* CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE */ + +static inline int copy_from_uptr(void *dst, uptr_t src, size_t size) +{ + if (!uptr_is_kernel(src)) + return copy_from_user(dst, src.user, size); + memcpy(dst, src.kernel, size); + return 0; +} + +static inline int copy_to_uptr(uptr_t dst, const void *src, size_t size) +{ + if (!uptr_is_kernel(dst)) + return copy_to_user(dst.user, src, size); + memcpy(dst.kernel, src, size); + return 0; +} + +#endif /* _LINUX_UPTR_H */ From patchwork Wed Jun 24 16:28:52 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoph Hellwig X-Patchwork-Id: 11623735 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 43D6F60D for ; Wed, 24 Jun 2020 16:30:48 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 2C64D20857 for ; Wed, 24 Jun 2020 16:30:48 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=infradead.org header.i=@infradead.org header.b="RutPLeiK" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2405162AbgFXQap (ORCPT ); Wed, 24 Jun 2020 12:30:45 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41082 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2404692AbgFXQ3Z (ORCPT ); Wed, 24 Jun 2020 12:29:25 -0400 Received: from casper.infradead.org (unknown [IPv6:2001:8b0:10b:1236::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CA41EC0613ED; Wed, 24 Jun 2020 09:29:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To: Content-Type:Content-ID:Content-Description; bh=CNk/aSiWmmbV6EV6DanHCszvKlV+254CO/X+KDTk2bo=; b=RutPLeiKe6pB5IbiaUm72jhFLG MlClnq7utWReRPV633zRff0I6qSvq7hy2NV+KiIFdwOX7vs9hc22h8j78nNavOr9ReVGnpHq8NIeG 6uMnXtaN/XLoo0dV/lYr7h+nScNlmiG6oqCu5H6fYe/kxh1FlJ3PR6wJaJsa+Jtp65dRtnvN8FlvF QD73Vg1VIUcEdqDcTtjhbtZ+bhxo7EOpuxfOAL1ZY6qRXg484Rt9tYHGmUdleVvrFxPlykR/EkR7x SRHsZDWGW6hKoBmooVTYu4tqYvvVTlGxy9rxPV0Ef97df46BEGuKKiswVMB3Lvaza2B2OeSqpiNo5 bhM/du8A==; Received: from [2001:4bb8:180:a3:5c7c:8955:539d:955b] (helo=localhost) by casper.infradead.org with esmtpsa (Exim 4.92.3 #3 (Red Hat Linux)) id 1jo8Gn-0006nz-0a; Wed, 24 Jun 2020 16:29:05 +0000 From: Christoph Hellwig To: Al Viro , Linus Torvalds Cc: Luis Chamberlain , Kees Cook , Iurii Zaikin , linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org Subject: [PATCH 02/11] fs: factor out a set_fmode_can_read_write helper Date: Wed, 24 Jun 2020 18:28:52 +0200 Message-Id: <20200624162901.1814136-3-hch@lst.de> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200624162901.1814136-1-hch@lst.de> References: <20200624162901.1814136-1-hch@lst.de> MIME-Version: 1.0 X-SRS-Rewrite: SMTP reverse-path rewritten from by casper.infradead.org. See http://www.infradead.org/rpr.html Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Add a helper to set the FMODE_CAN_READ and FMODE_CAN_WRITE logic instead of duplicating it in two places. Signed-off-by: Christoph Hellwig --- fs/file_table.c | 7 +------ fs/internal.h | 10 ++++++++++ fs/open.c | 8 +------- 3 files changed, 12 insertions(+), 13 deletions(-) diff --git a/fs/file_table.c b/fs/file_table.c index 656647f9575a7c..646b83f07a9589 100644 --- a/fs/file_table.c +++ b/fs/file_table.c @@ -199,16 +199,11 @@ static struct file *alloc_file(const struct path *path, int flags, file->f_mapping = path->dentry->d_inode->i_mapping; file->f_wb_err = filemap_sample_wb_err(file->f_mapping); file->f_sb_err = file_sample_sb_err(file); - if ((file->f_mode & FMODE_READ) && - likely(fop->read || fop->read_iter)) - file->f_mode |= FMODE_CAN_READ; - if ((file->f_mode & FMODE_WRITE) && - likely(fop->write || fop->write_iter)) - file->f_mode |= FMODE_CAN_WRITE; file->f_mode |= FMODE_OPENED; file->f_op = fop; if ((file->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ) i_readcount_inc(path->dentry->d_inode); + set_fmode_can_read_write(file); return file; } diff --git a/fs/internal.h b/fs/internal.h index 9b863a7bd70892..242f2845b3428b 100644 --- a/fs/internal.h +++ b/fs/internal.h @@ -185,3 +185,13 @@ int sb_init_dio_done_wq(struct super_block *sb); */ int do_statx(int dfd, const char __user *filename, unsigned flags, unsigned int mask, struct statx __user *buffer); + +static inline void set_fmode_can_read_write(struct file *f) +{ + if ((f->f_mode & FMODE_READ) && + (f->f_op->read || f->f_op->read_iter)) + f->f_mode |= FMODE_CAN_READ; + if ((f->f_mode & FMODE_WRITE) && + (f->f_op->write || f->f_op->write_iter)) + f->f_mode |= FMODE_CAN_WRITE; +} diff --git a/fs/open.c b/fs/open.c index 6cd48a61cda3b9..01f2de93c91710 100644 --- a/fs/open.c +++ b/fs/open.c @@ -832,13 +832,7 @@ static int do_dentry_open(struct file *f, f->f_mode |= FMODE_OPENED; if ((f->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ) i_readcount_inc(inode); - if ((f->f_mode & FMODE_READ) && - likely(f->f_op->read || f->f_op->read_iter)) - f->f_mode |= FMODE_CAN_READ; - if ((f->f_mode & FMODE_WRITE) && - likely(f->f_op->write || f->f_op->write_iter)) - f->f_mode |= FMODE_CAN_WRITE; - + set_fmode_can_read_write(f); f->f_write_hint = WRITE_LIFE_NOT_SET; f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC); From patchwork Wed Jun 24 16:28:53 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoph Hellwig X-Patchwork-Id: 11623719 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 6488C913 for ; Wed, 24 Jun 2020 16:29:48 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 4C1772082F for ; Wed, 24 Jun 2020 16:29:48 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=infradead.org header.i=@infradead.org header.b="BYmF1uoU" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2405059AbgFXQ3n (ORCPT ); Wed, 24 Jun 2020 12:29:43 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41092 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2404764AbgFXQ31 (ORCPT ); Wed, 24 Jun 2020 12:29:27 -0400 Received: from casper.infradead.org (unknown [IPv6:2001:8b0:10b:1236::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1DAAFC061573; Wed, 24 Jun 2020 09:29:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To: Content-Type:Content-ID:Content-Description; bh=VHv8vV/zSvtU7OOAqr9Qu8tuddmtuvpgD3IE+DOaLXs=; b=BYmF1uoU37E5NXUZV/N5uUhN8L kLfdntSaS1J2sHkhwgkQe1bigYHTeSylJDZtb0graYXEYbmzBB/X1PKcIzLUdTGqiwdoGPIJYlHnQ OnLOhoqF3MsIvho4MQa1Fl/Kw4SPil8+tSFfLpz4IhRWZfeHevlBOXTM95MFt+XE8p1RDB0mAWdZ2 5o+O1PQpPEIo21Ku67TdxawC5gZLVT41G+f9UwWgaOQOZjxSYimoFsNCWostJL/bXWCi7HatkdbdP gswGXJi/BNohjkC15q0HPX5FGlteXfDKsg1poy8KnwRs4m1RAN2LNGqmULVAytMvxnq/yP9d3k3A1 6SwKDAIg==; Received: from [2001:4bb8:180:a3:5c7c:8955:539d:955b] (helo=localhost) by casper.infradead.org with esmtpsa (Exim 4.92.3 #3 (Red Hat Linux)) id 1jo8Go-0006oQ-EA; Wed, 24 Jun 2020 16:29:06 +0000 From: Christoph Hellwig To: Al Viro , Linus Torvalds Cc: Luis Chamberlain , Kees Cook , Iurii Zaikin , linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org Subject: [PATCH 03/11] fs: add new read_uptr and write_uptr file operations Date: Wed, 24 Jun 2020 18:28:53 +0200 Message-Id: <20200624162901.1814136-4-hch@lst.de> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200624162901.1814136-1-hch@lst.de> References: <20200624162901.1814136-1-hch@lst.de> MIME-Version: 1.0 X-SRS-Rewrite: SMTP reverse-path rewritten from by casper.infradead.org. See http://www.infradead.org/rpr.html Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Add two new file operations that are identical to ->read and ->write except that they can also safely take kernel pointers using the uptr_t type. Signed-off-by: Christoph Hellwig Signed-off-by: Matthew Wilcox (Oracle) Signed-off-by: Matthew Wilcox (Oracle) --- fs/internal.h | 4 ++-- fs/read_write.c | 18 ++++++++++++++---- include/linux/fs.h | 3 +++ 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/fs/internal.h b/fs/internal.h index 242f2845b3428b..b6777a47b05163 100644 --- a/fs/internal.h +++ b/fs/internal.h @@ -189,9 +189,9 @@ int do_statx(int dfd, const char __user *filename, unsigned flags, static inline void set_fmode_can_read_write(struct file *f) { if ((f->f_mode & FMODE_READ) && - (f->f_op->read || f->f_op->read_iter)) + (f->f_op->read || f->f_op->read_uptr || f->f_op->read_iter)) f->f_mode |= FMODE_CAN_READ; if ((f->f_mode & FMODE_WRITE) && - (f->f_op->write || f->f_op->write_iter)) + (f->f_op->write || f->f_op->write_uptr || f->f_op->write_iter)) f->f_mode |= FMODE_CAN_WRITE; } diff --git a/fs/read_write.c b/fs/read_write.c index e7f36b15683049..24ffbf3cbda243 100644 --- a/fs/read_write.c +++ b/fs/read_write.c @@ -430,7 +430,9 @@ ssize_t __kernel_read(struct file *file, void *buf, size_t count, loff_t *pos) if (count > MAX_RW_COUNT) count = MAX_RW_COUNT; - if (file->f_op->read) { + if (file->f_op->read_uptr) { + ret = file->f_op->read_uptr(file, KERNEL_UPTR(buf), count, pos); + } else if (file->f_op->read) { mm_segment_t old_fs = get_fs(); set_fs(KERNEL_DS); @@ -485,7 +487,9 @@ ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos) if (count > MAX_RW_COUNT) count = MAX_RW_COUNT; - if (file->f_op->read) + if (file->f_op->read_uptr) + ret = file->f_op->read_uptr(file, USER_UPTR(buf), count, pos); + else if (file->f_op->read) ret = file->f_op->read(file, buf, count, pos); else if (file->f_op->read_iter) ret = new_sync_read(file, buf, count, pos); @@ -530,7 +534,10 @@ ssize_t __kernel_write(struct file *file, const void *buf, size_t count, if (count > MAX_RW_COUNT) count = MAX_RW_COUNT; - if (file->f_op->write) { + if (file->f_op->write_uptr) { + ret = file->f_op->write_uptr(file, KERNEL_UPTR((void *)buf), + count, pos); + } else if (file->f_op->write) { mm_segment_t old_fs = get_fs(); set_fs(KERNEL_DS); @@ -592,7 +599,10 @@ ssize_t vfs_write(struct file *file, const char __user *buf, size_t count, loff_ if (count > MAX_RW_COUNT) count = MAX_RW_COUNT; file_start_write(file); - if (file->f_op->write) + if (file->f_op->write_uptr) + ret = file->f_op->write_uptr(file, + USER_UPTR((char __user *)buf), count, pos); + else if (file->f_op->write) ret = file->f_op->write(file, buf, count, pos); else if (file->f_op->write_iter) ret = new_sync_write(file, buf, count, pos); diff --git a/include/linux/fs.h b/include/linux/fs.h index fac6aead402a98..d8fc3015f5a197 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -39,6 +39,7 @@ #include #include #include +#include #include #include @@ -1830,6 +1831,8 @@ struct file_operations { ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *); ssize_t (*read_iter) (struct kiocb *, struct iov_iter *); ssize_t (*write_iter) (struct kiocb *, struct iov_iter *); + ssize_t (*read_uptr) (struct file *, uptr_t, size_t, loff_t *); + ssize_t (*write_uptr) (struct file *, uptr_t, size_t, loff_t *); int (*iopoll)(struct kiocb *kiocb, bool spin); int (*iterate) (struct file *, struct dir_context *); int (*iterate_shared) (struct file *, struct dir_context *); From patchwork Wed Jun 24 16:28:54 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoph Hellwig X-Patchwork-Id: 11623727 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 9E2F092A for ; Wed, 24 Jun 2020 16:30:14 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 85CC420836 for ; Wed, 24 Jun 2020 16:30:14 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=infradead.org header.i=@infradead.org header.b="DcTcPMHn" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2405025AbgFXQ3i (ORCPT ); Wed, 24 Jun 2020 12:29:38 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41100 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2404833AbgFXQ31 (ORCPT ); Wed, 24 Jun 2020 12:29:27 -0400 Received: from casper.infradead.org (unknown [IPv6:2001:8b0:10b:1236::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C4A12C061798; Wed, 24 Jun 2020 09:29:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To: Content-Type:Content-ID:Content-Description; bh=2HvZhOUeF9FDVyXb54Pz1N0sRkDLIwNnoR/STkbBseI=; b=DcTcPMHn3/rJewMozHZFNKVYdM Y1kb+6nBjEQdRJu32NwJA7MDexPZ1wLpJWq8BoSNtXEEvIRm3GFf1mN+oy19oDUMUITMHjO+0vZGa m9ApZHQq5C/AU4VMTc89L18igA+ZrWZXIlj8TDNGG1ouHSZddAZeZMrl+mc+A/uENcUnyjq8TVYm3 0qiZiVg1ujK0pfVcDSEbxT2n2Ropj4fUdtilZsuzMsLvjKgn5SwQ0J9FThJBFXE96/uBfFCaCuICu OlFbejHbwAB2QrMRcbhGUhvuIVwYbfaFksLl7bipA0i3X5LncABo28fKgYMq/2UuzU0OGbxpIoKe2 GD1UtjAA==; Received: from [2001:4bb8:180:a3:5c7c:8955:539d:955b] (helo=localhost) by casper.infradead.org with esmtpsa (Exim 4.92.3 #3 (Red Hat Linux)) id 1jo8Gq-0006oi-Mj; Wed, 24 Jun 2020 16:29:08 +0000 From: Christoph Hellwig To: Al Viro , Linus Torvalds Cc: Luis Chamberlain , Kees Cook , Iurii Zaikin , linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org Subject: [PATCH 04/11] sysctl: switch to ->{read,write}_uptr Date: Wed, 24 Jun 2020 18:28:54 +0200 Message-Id: <20200624162901.1814136-5-hch@lst.de> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200624162901.1814136-1-hch@lst.de> References: <20200624162901.1814136-1-hch@lst.de> MIME-Version: 1.0 X-SRS-Rewrite: SMTP reverse-path rewritten from by casper.infradead.org. See http://www.infradead.org/rpr.html Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org This allows the sysctl handler to safely take kernel space pointers, as required for the new code to set sysctl parameters at boot time. Signed-off-by: Christoph Hellwig --- fs/proc/proc_sysctl.c | 39 ++++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c index 42c5128c7d1c76..dd5eb693bd00df 100644 --- a/fs/proc/proc_sysctl.c +++ b/fs/proc/proc_sysctl.c @@ -540,7 +540,7 @@ static struct dentry *proc_sys_lookup(struct inode *dir, struct dentry *dentry, return err; } -static ssize_t proc_sys_call_handler(struct file *filp, void __user *ubuf, +static ssize_t proc_sys_call_handler(struct file *filp, uptr_t buf, size_t count, loff_t *ppos, int write) { struct inode *inode = file_inode(filp); @@ -566,20 +566,21 @@ static ssize_t proc_sys_call_handler(struct file *filp, void __user *ubuf, goto out; /* don't even try if the size is too large */ - if (count > KMALLOC_MAX_SIZE) + if (count >= KMALLOC_MAX_SIZE) return -ENOMEM; + error = -ENOMEM; + + /* allow for NULL termination on writes */ + kbuf = kzalloc(count + (write ? 1 : 0), GFP_KERNEL); + if (!kbuf) + goto out; + if (write) { - kbuf = memdup_user_nul(ubuf, count); - if (IS_ERR(kbuf)) { - error = PTR_ERR(kbuf); - goto out; - } - } else { - error = -ENOMEM; - kbuf = kzalloc(count, GFP_KERNEL); - if (!kbuf) - goto out; + error = -EFAULT; + if (copy_from_uptr(kbuf, buf, count)) + goto out_free_buf; + ((char *)kbuf)[count] = '\0'; } error = BPF_CGROUP_RUN_PROG_SYSCTL(head, table, write, &kbuf, &count, @@ -594,7 +595,7 @@ static ssize_t proc_sys_call_handler(struct file *filp, void __user *ubuf, if (!write) { error = -EFAULT; - if (copy_to_user(ubuf, kbuf, count)) + if (copy_to_uptr(buf, kbuf, count)) goto out_free_buf; } @@ -607,16 +608,16 @@ static ssize_t proc_sys_call_handler(struct file *filp, void __user *ubuf, return error; } -static ssize_t proc_sys_read(struct file *filp, char __user *buf, +static ssize_t proc_sys_read(struct file *filp, uptr_t buf, size_t count, loff_t *ppos) { - return proc_sys_call_handler(filp, (void __user *)buf, count, ppos, 0); + return proc_sys_call_handler(filp, buf, count, ppos, 0); } -static ssize_t proc_sys_write(struct file *filp, const char __user *buf, +static ssize_t proc_sys_write(struct file *filp, uptr_t buf, size_t count, loff_t *ppos) { - return proc_sys_call_handler(filp, (void __user *)buf, count, ppos, 1); + return proc_sys_call_handler(filp, buf, count, ppos, 1); } static int proc_sys_open(struct inode *inode, struct file *filp) @@ -853,8 +854,8 @@ static int proc_sys_getattr(const struct path *path, struct kstat *stat, static const struct file_operations proc_sys_file_operations = { .open = proc_sys_open, .poll = proc_sys_poll, - .read = proc_sys_read, - .write = proc_sys_write, + .read_uptr = proc_sys_read, + .write_uptr = proc_sys_write, .llseek = default_llseek, }; From patchwork Wed Jun 24 16:28:55 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoph Hellwig X-Patchwork-Id: 11623721 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 4F43C60D for ; Wed, 24 Jun 2020 16:30:07 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 354D920857 for ; Wed, 24 Jun 2020 16:30:07 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=infradead.org header.i=@infradead.org header.b="lkvN4/Zo" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2405057AbgFXQ3m (ORCPT ); Wed, 24 Jun 2020 12:29:42 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41094 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2404782AbgFXQ31 (ORCPT ); Wed, 24 Jun 2020 12:29:27 -0400 Received: from casper.infradead.org (unknown [IPv6:2001:8b0:10b:1236::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id AF591C061795; Wed, 24 Jun 2020 09:29:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To: Content-Type:Content-ID:Content-Description; bh=AYFB+Z0RU8R831U4cx7G5n0/06yd4vKHvkQQiVELYcc=; b=lkvN4/ZoodNqqMV2cXxhBSLzWu CfYlslhKWkfLn2dHg/ETf3XsFO7e4jkbaUvl0EAmC4oiNAxmBzo0DiPGbMnxEJJQMKkanElt/VcVp iSt46GH9LEODydo+p5UPJdPPpiN7Uhce8jOdOej3/oOS39QjLn+ptNV5G6UxbCAwTQxM0MP0Ottm3 KsJ137m9E51U6FAMfaxSJ/V6dpVEUxNY6p6C9otT8x6bD7QHRQ1FCjcBhiNkfmcuBEnAFNANLCMdh uQeEMzLY11Bf2Rp2p+pUqrt24S7O79O3c7ziyHouFOkjIkSWewyzn3e6J4/+aQdG+5ZEjWlgC6wV1 xZQpk0SA==; Received: from [2001:4bb8:180:a3:5c7c:8955:539d:955b] (helo=localhost) by casper.infradead.org with esmtpsa (Exim 4.92.3 #3 (Red Hat Linux)) id 1jo8Gr-0006oy-R1; Wed, 24 Jun 2020 16:29:10 +0000 From: Christoph Hellwig To: Al Viro , Linus Torvalds Cc: Luis Chamberlain , Kees Cook , Iurii Zaikin , linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org Subject: [PATCH 05/11] fs: refactor new_sync_read Date: Wed, 24 Jun 2020 18:28:55 +0200 Message-Id: <20200624162901.1814136-6-hch@lst.de> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200624162901.1814136-1-hch@lst.de> References: <20200624162901.1814136-1-hch@lst.de> MIME-Version: 1.0 X-SRS-Rewrite: SMTP reverse-path rewritten from by casper.infradead.org. See http://www.infradead.org/rpr.html Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Pass the read_iter method as a parameter and mark the function non-static. This allows reusing it for additional callsites e.g. in procfs. Signed-off-by: Christoph Hellwig --- fs/read_write.c | 8 +++++--- include/linux/fs.h | 2 ++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/fs/read_write.c b/fs/read_write.c index 24ffbf3cbda243..b92c222ca886ca 100644 --- a/fs/read_write.c +++ b/fs/read_write.c @@ -401,7 +401,8 @@ int rw_verify_area(int read_write, struct file *file, const loff_t *ppos, size_t read_write == READ ? MAY_READ : MAY_WRITE); } -static ssize_t new_sync_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos) +ssize_t iter_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos, + ssize_t (*cb)(struct kiocb *iocb, struct iov_iter *iter)) { struct iovec iov = { .iov_base = buf, .iov_len = len }; struct kiocb kiocb; @@ -412,7 +413,7 @@ static ssize_t new_sync_read(struct file *filp, char __user *buf, size_t len, lo kiocb.ki_pos = (ppos ? *ppos : 0); iov_iter_init(&iter, READ, &iov, 1, len); - ret = call_read_iter(filp, &kiocb, &iter); + ret = cb(&kiocb, &iter); BUG_ON(ret == -EIOCBQUEUED); if (ppos) *ppos = kiocb.ki_pos; @@ -492,7 +493,8 @@ ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos) else if (file->f_op->read) ret = file->f_op->read(file, buf, count, pos); else if (file->f_op->read_iter) - ret = new_sync_read(file, buf, count, pos); + ret = iter_read(file, buf, count, pos, + file->f_op->read_iter); else ret = -EINVAL; if (ret > 0) { diff --git a/include/linux/fs.h b/include/linux/fs.h index d8fc3015f5a197..d0fea0281ef29b 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1919,6 +1919,8 @@ ssize_t rw_copy_check_uvector(int type, const struct iovec __user * uvector, unsigned long nr_segs, unsigned long fast_segs, struct iovec *fast_pointer, struct iovec **ret_pointer); +ssize_t iter_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos, + ssize_t (*cb)(struct kiocb *iocb, struct iov_iter *iter)); extern ssize_t vfs_read(struct file *, char __user *, size_t, loff_t *); extern ssize_t vfs_write(struct file *, const char __user *, size_t, loff_t *); From patchwork Wed Jun 24 16:28:56 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoph Hellwig X-Patchwork-Id: 11623717 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id BD13E913 for ; Wed, 24 Jun 2020 16:29:43 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id A41032082F for ; Wed, 24 Jun 2020 16:29:43 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=infradead.org header.i=@infradead.org header.b="ZcRz/r/Z" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2405045AbgFXQ3m (ORCPT ); Wed, 24 Jun 2020 12:29:42 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41096 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2404972AbgFXQ31 (ORCPT ); Wed, 24 Jun 2020 12:29:27 -0400 Received: from casper.infradead.org (unknown [IPv6:2001:8b0:10b:1236::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B8504C061796; Wed, 24 Jun 2020 09:29:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To: Content-Type:Content-ID:Content-Description; bh=jlXrr1b8urlbr9PamhblsvEHUflz9FDOmmp8LAbhvP8=; b=ZcRz/r/ZjrVgAJ909ZujqBY8oh Ce9L+w4v2XlH2P8BGq6gN98rHNiwqs4PP6YTZigXOf3/pbVUfBUsBCrxlgtKaDesBAla3vsbr8Q/B vjXnaMjyj1tpkksab9vWuNgdjh1UEYQt6crU4FpIecPSqIhT0c1Ji1YvHr0T6sbmRseNRuvWkR9Mp 2vmDmtuf5CvQ5vwuq9JcgVCcXh7XBNM3pskikeFGDzwM8r9JwwKX4qewPasTiGwhdp8IEiI4QRqzu aG3cwv1bo5tyMmz16koMIZyrqKifzlTRJ8+MfNg8tAoiFFmkSE38qulZqHiaBJ+dsMAPE1UFmWV5W 5urflNKw==; Received: from [2001:4bb8:180:a3:5c7c:8955:539d:955b] (helo=localhost) by casper.infradead.org with esmtpsa (Exim 4.92.3 #3 (Red Hat Linux)) id 1jo8Gs-0006p8-VG; Wed, 24 Jun 2020 16:29:11 +0000 From: Christoph Hellwig To: Al Viro , Linus Torvalds Cc: Luis Chamberlain , Kees Cook , Iurii Zaikin , linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org Subject: [PATCH 06/11] proc: add a read_iter method to proc proc_ops Date: Wed, 24 Jun 2020 18:28:56 +0200 Message-Id: <20200624162901.1814136-7-hch@lst.de> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200624162901.1814136-1-hch@lst.de> References: <20200624162901.1814136-1-hch@lst.de> MIME-Version: 1.0 X-SRS-Rewrite: SMTP reverse-path rewritten from by casper.infradead.org. See http://www.infradead.org/rpr.html Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org This will allow proc files to implement iter read semantics. Signed-off-by: Christoph Hellwig --- fs/proc/inode.c | 28 ++++++++++++++++++++++++++++ include/linux/proc_fs.h | 1 + 2 files changed, 29 insertions(+) diff --git a/fs/proc/inode.c b/fs/proc/inode.c index 28d6105e908e4c..fa86619cebc2be 100644 --- a/fs/proc/inode.c +++ b/fs/proc/inode.c @@ -297,6 +297,29 @@ static loff_t proc_reg_llseek(struct file *file, loff_t offset, int whence) return rv; } +static ssize_t pde_read_iter(struct proc_dir_entry *pde, struct kiocb *iocb, + struct iov_iter *iter) +{ + if (!pde->proc_ops->proc_read_iter) + return -EINVAL; + return pde->proc_ops->proc_read_iter(iocb, iter); +} + +static ssize_t proc_reg_read_iter(struct kiocb *iocb, struct iov_iter *iter) +{ + struct proc_dir_entry *pde = PDE(file_inode(iocb->ki_filp)); + ssize_t ret; + + if (pde_is_permanent(pde)) + return pde_read_iter(pde, iocb, iter); + + if (!use_pde(pde)) + return -EIO; + ret = pde_read_iter(pde, iocb, iter); + unuse_pde(pde); + return ret; +} + static ssize_t pde_read(struct proc_dir_entry *pde, struct file *file, char __user *buf, size_t count, loff_t *ppos) { typeof_member(struct proc_ops, proc_read) read; @@ -312,6 +335,9 @@ static ssize_t proc_reg_read(struct file *file, char __user *buf, size_t count, struct proc_dir_entry *pde = PDE(file_inode(file)); ssize_t rv = -EIO; + if (pde->proc_ops->proc_read_iter) + return iter_read(file, buf, count, ppos, proc_reg_read_iter); + if (pde_is_permanent(pde)) { return pde_read(pde, file, buf, count, ppos); } else if (use_pde(pde)) { @@ -569,6 +595,7 @@ static int proc_reg_release(struct inode *inode, struct file *file) static const struct file_operations proc_reg_file_ops = { .llseek = proc_reg_llseek, .read = proc_reg_read, + .read_iter = proc_reg_read_iter, .write = proc_reg_write, .poll = proc_reg_poll, .unlocked_ioctl = proc_reg_unlocked_ioctl, @@ -585,6 +612,7 @@ static const struct file_operations proc_reg_file_ops = { static const struct file_operations proc_reg_file_ops_no_compat = { .llseek = proc_reg_llseek, .read = proc_reg_read, + .read_iter = proc_reg_read_iter, .write = proc_reg_write, .poll = proc_reg_poll, .unlocked_ioctl = proc_reg_unlocked_ioctl, diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h index d1eed1b4365172..97b3f5f06db9d8 100644 --- a/include/linux/proc_fs.h +++ b/include/linux/proc_fs.h @@ -30,6 +30,7 @@ struct proc_ops { unsigned int proc_flags; int (*proc_open)(struct inode *, struct file *); ssize_t (*proc_read)(struct file *, char __user *, size_t, loff_t *); + ssize_t (*proc_read_iter)(struct kiocb *, struct iov_iter *); ssize_t (*proc_write)(struct file *, const char __user *, size_t, loff_t *); loff_t (*proc_lseek)(struct file *, loff_t, int); int (*proc_release)(struct inode *, struct file *); From patchwork Wed Jun 24 16:28:57 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoph Hellwig X-Patchwork-Id: 11623723 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 29B3160D for ; Wed, 24 Jun 2020 16:30:12 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 1162920836 for ; Wed, 24 Jun 2020 16:30:12 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=infradead.org header.i=@infradead.org header.b="jhPk2eCJ" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2405038AbgFXQ3l (ORCPT ); Wed, 24 Jun 2020 12:29:41 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41098 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2404947AbgFXQ31 (ORCPT ); Wed, 24 Jun 2020 12:29:27 -0400 Received: from casper.infradead.org (unknown [IPv6:2001:8b0:10b:1236::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BF0E3C061797; Wed, 24 Jun 2020 09:29:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To: Content-Type:Content-ID:Content-Description; bh=sTsOMUcnMDqLSD97+IRNpD3MR/vvaG/xJH7og4zU1hM=; b=jhPk2eCJY85SXEQzK08WlwL2m/ aP3CcE72jpwW5SK6+L+lEwL1pClFHQQBfGACi7P/o8qe4FyYM+yY/V0FmXXymANsvG/u/IOys76q5 fFAM0KLtlklNxzRSXaVGSTEhQPkmDFuO0WyXkUIwt3mXEUJmKXOASzCaAi+S63Vglrfy7Sp1dfFZP 73G5hlDYksWREi+n8mNVJm0tUw06ucT/xQKVhnI2mzkWpEPVUJTTfKhKIQUumaFoaMI6OxIjpG+te cFZ/OJsZ2W5DMxn37t/l1uQV0FcjzI3Rv4hjMBij3eU/r4blswSKgxbkEbI9voidvLYJe9s8ejeHi gG1bjokg==; Received: from [2001:4bb8:180:a3:5c7c:8955:539d:955b] (helo=localhost) by casper.infradead.org with esmtpsa (Exim 4.92.3 #3 (Red Hat Linux)) id 1jo8Gu-0006pH-4O; Wed, 24 Jun 2020 16:29:12 +0000 From: Christoph Hellwig To: Al Viro , Linus Torvalds Cc: Luis Chamberlain , Kees Cook , Iurii Zaikin , linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org Subject: [PATCH 07/11] seq_file: add seq_read_iter Date: Wed, 24 Jun 2020 18:28:57 +0200 Message-Id: <20200624162901.1814136-8-hch@lst.de> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200624162901.1814136-1-hch@lst.de> References: <20200624162901.1814136-1-hch@lst.de> MIME-Version: 1.0 X-SRS-Rewrite: SMTP reverse-path rewritten from by casper.infradead.org. See http://www.infradead.org/rpr.html Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org iov_iter based variant for reading a seq_file. seq_read is reimplemented on top of the iter variant. Signed-off-by: Christoph Hellwig --- fs/seq_file.c | 34 +++++++++++++++++++++------------- include/linux/seq_file.h | 1 + 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/fs/seq_file.c b/fs/seq_file.c index 4e6239f33c066a..159a3e12cadd30 100644 --- a/fs/seq_file.c +++ b/fs/seq_file.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -146,7 +147,17 @@ static int traverse(struct seq_file *m, loff_t offset) */ ssize_t seq_read(struct file *file, char __user *buf, size_t size, loff_t *ppos) { - struct seq_file *m = file->private_data; + return iter_read(file, buf, size, ppos, seq_read_iter); +} +EXPORT_SYMBOL(seq_read); + +/* + * Ready-made ->f_op->read_iter() + */ +ssize_t seq_read_iter(struct kiocb *iocb, struct iov_iter *iter) +{ + struct seq_file *m = iocb->ki_filp->private_data; + size_t size = iov_iter_count(iter); size_t copied = 0; size_t n; void *p; @@ -158,14 +169,14 @@ ssize_t seq_read(struct file *file, char __user *buf, size_t size, loff_t *ppos) * if request is to read from zero offset, reset iterator to first * record as it might have been already advanced by previous requests */ - if (*ppos == 0) { + if (iocb->ki_pos == 0) { m->index = 0; m->count = 0; } - /* Don't assume *ppos is where we left it */ - if (unlikely(*ppos != m->read_pos)) { - while ((err = traverse(m, *ppos)) == -EAGAIN) + /* Don't assume ki_pos is where we left it */ + if (unlikely(iocb->ki_pos != m->read_pos)) { + while ((err = traverse(m, iocb->ki_pos)) == -EAGAIN) ; if (err) { /* With prejudice... */ @@ -174,7 +185,7 @@ ssize_t seq_read(struct file *file, char __user *buf, size_t size, loff_t *ppos) m->count = 0; goto Done; } else { - m->read_pos = *ppos; + m->read_pos = iocb->ki_pos; } } @@ -187,13 +198,11 @@ ssize_t seq_read(struct file *file, char __user *buf, size_t size, loff_t *ppos) /* if not empty - flush it first */ if (m->count) { n = min(m->count, size); - err = copy_to_user(buf, m->buf + m->from, n); - if (err) + if (copy_to_iter(m->buf + m->from, n, iter) != n) goto Efault; m->count -= n; m->from += n; size -= n; - buf += n; copied += n; if (!size) goto Done; @@ -254,8 +263,7 @@ ssize_t seq_read(struct file *file, char __user *buf, size_t size, loff_t *ppos) } m->op->stop(m, p); n = min(m->count, size); - err = copy_to_user(buf, m->buf, n); - if (err) + if (copy_to_iter(m->buf, n, iter) != n) goto Efault; copied += n; m->count -= n; @@ -264,7 +272,7 @@ ssize_t seq_read(struct file *file, char __user *buf, size_t size, loff_t *ppos) if (!copied) copied = err; else { - *ppos += copied; + iocb->ki_pos += copied; m->read_pos += copied; } mutex_unlock(&m->lock); @@ -276,7 +284,7 @@ ssize_t seq_read(struct file *file, char __user *buf, size_t size, loff_t *ppos) err = -EFAULT; goto Done; } -EXPORT_SYMBOL(seq_read); +EXPORT_SYMBOL(seq_read_iter); /** * seq_lseek - ->llseek() method for sequential files. diff --git a/include/linux/seq_file.h b/include/linux/seq_file.h index 813614d4b71fbc..b83b3ae3c877f3 100644 --- a/include/linux/seq_file.h +++ b/include/linux/seq_file.h @@ -107,6 +107,7 @@ void seq_pad(struct seq_file *m, char c); char *mangle_path(char *s, const char *p, const char *esc); int seq_open(struct file *, const struct seq_operations *); ssize_t seq_read(struct file *, char __user *, size_t, loff_t *); +ssize_t seq_read_iter(struct kiocb *iocb, struct iov_iter *iter); loff_t seq_lseek(struct file *, loff_t, int); int seq_release(struct inode *, struct file *); int seq_write(struct seq_file *seq, const void *data, size_t len); From patchwork Wed Jun 24 16:28:59 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoph Hellwig X-Patchwork-Id: 11623725 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C3BB060D for ; Wed, 24 Jun 2020 16:30:13 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 8CC2720857 for ; Wed, 24 Jun 2020 16:30:13 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=infradead.org header.i=@infradead.org header.b="CwdtVXSB" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2404965AbgFXQ3k (ORCPT ); Wed, 24 Jun 2020 12:29:40 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41118 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2404975AbgFXQ3d (ORCPT ); Wed, 24 Jun 2020 12:29:33 -0400 Received: from casper.infradead.org (unknown [IPv6:2001:8b0:10b:1236::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E4ED3C061573; Wed, 24 Jun 2020 09:29:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To: Content-Type:Content-ID:Content-Description; bh=3gaKDuc6LM8tozUjP0qjr/LZp6Odny34/yeCokgXXnk=; b=CwdtVXSBf337eJTu4tCZ1Ktufe KqSAR2R39eQ2wGU7GwMaHnLXnK3slwirV3EcMs/VqP8cIGFUYb52AEV8/nmbUPyZ/VZeIhIylIHFm iGBMzjOr21q1wyX+DIbqH/dUWNEu92ZVfq0L0+usxHja+yloYvHj21REmuc8+yC9dgHh04AMJaoMi A/DN3qLth7WAAhsuD6igtO3VxR5acYAjxCF0Lxy/MmP/2RWcLDh0dZVIQ+8BTfEhPqCQgXcxWkUnI 6FsCIzwYL1bQIWEfC3/kY/6EdSSz2ThQ18uRXKdova4wlIPv8gu/jSDBgWcI4IjA69OdVAhHyiy7l nHQ5Lf+w==; Received: from [2001:4bb8:180:a3:5c7c:8955:539d:955b] (helo=localhost) by casper.infradead.org with esmtpsa (Exim 4.92.3 #3 (Red Hat Linux)) id 1jo8Gx-0006pZ-1E; Wed, 24 Jun 2020 16:29:15 +0000 From: Christoph Hellwig To: Al Viro , Linus Torvalds Cc: Luis Chamberlain , Kees Cook , Iurii Zaikin , linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org Subject: [PATCH 09/11] proc: switch over direct seq_read method calls to seq_read_iter Date: Wed, 24 Jun 2020 18:28:59 +0200 Message-Id: <20200624162901.1814136-10-hch@lst.de> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200624162901.1814136-1-hch@lst.de> References: <20200624162901.1814136-1-hch@lst.de> MIME-Version: 1.0 X-SRS-Rewrite: SMTP reverse-path rewritten from by casper.infradead.org. See http://www.infradead.org/rpr.html Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Switch over all instances used directly as methods using these sed expressions: sed -i -e 's/\.proc_read\(\s*=\s*\)seq_read/\.proc_read_iter\1seq_read_iter/g' Signed-off-by: Christoph Hellwig --- arch/alpha/kernel/srm_env.c | 2 +- arch/arm/mm/alignment.c | 2 +- arch/powerpc/kernel/rtas-proc.c | 10 +++++----- arch/powerpc/mm/numa.c | 2 +- arch/powerpc/platforms/pseries/lpar.c | 4 ++-- arch/powerpc/platforms/pseries/lparcfg.c | 2 +- arch/sh/mm/alignment.c | 2 +- arch/sparc/kernel/led.c | 2 +- arch/um/kernel/exitcode.c | 2 +- arch/um/kernel/process.c | 2 +- arch/x86/kernel/cpu/mtrr/if.c | 2 +- arch/x86/platform/uv/tlb_uv.c | 2 +- drivers/acpi/battery.c | 2 +- drivers/acpi/proc.c | 2 +- drivers/hwmon/dell-smm-hwmon.c | 2 +- drivers/ide/ide-proc.c | 2 +- drivers/input/input.c | 4 ++-- drivers/macintosh/via-pmu.c | 2 +- drivers/md/md.c | 2 +- drivers/misc/sgi-gru/gruprocfs.c | 6 +++--- drivers/net/wireless/intel/ipw2x00/libipw_module.c | 2 +- .../net/wireless/intersil/hostap/hostap_download.c | 2 +- drivers/parisc/led.c | 2 +- drivers/platform/x86/thinkpad_acpi.c | 2 +- drivers/platform/x86/toshiba_acpi.c | 8 ++++---- drivers/pnp/pnpbios/proc.c | 2 +- drivers/s390/block/dasd_proc.c | 2 +- drivers/s390/cio/blacklist.c | 2 +- drivers/scsi/scsi_devinfo.c | 2 +- drivers/scsi/scsi_proc.c | 4 ++-- drivers/scsi/sg.c | 4 ++-- .../staging/rtl8192u/ieee80211/ieee80211_module.c | 2 +- drivers/usb/gadget/function/rndis.c | 2 +- drivers/video/fbdev/via/viafbdev.c | 14 +++++++------- fs/cifs/cifs_debug.c | 14 +++++++------- fs/cifs/dfs_cache.c | 2 +- fs/fscache/object-list.c | 2 +- fs/jbd2/journal.c | 2 +- fs/jfs/jfs_debug.c | 2 +- fs/nfsd/nfsctl.c | 2 +- fs/nfsd/stats.c | 2 +- fs/proc/cpuinfo.c | 2 +- fs/proc/generic.c | 4 ++-- fs/proc/proc_net.c | 4 ++-- fs/proc/stat.c | 2 +- include/linux/seq_file.h | 2 +- ipc/util.c | 2 +- kernel/irq/proc.c | 6 +++--- kernel/kallsyms.c | 2 +- kernel/latencytop.c | 2 +- kernel/locking/lockdep_proc.c | 2 +- kernel/module.c | 2 +- kernel/profile.c | 2 +- kernel/sched/psi.c | 6 +++--- lib/dynamic_debug.c | 2 +- mm/slab_common.c | 2 +- mm/swapfile.c | 2 +- net/atm/mpoa_proc.c | 2 +- net/core/pktgen.c | 6 +++--- net/ipv4/netfilter/ipt_CLUSTERIP.c | 2 +- net/ipv4/route.c | 4 ++-- net/netfilter/xt_recent.c | 2 +- net/sunrpc/cache.c | 2 +- net/sunrpc/stats.c | 2 +- sound/core/info.c | 2 +- 65 files changed, 99 insertions(+), 99 deletions(-) diff --git a/arch/alpha/kernel/srm_env.c b/arch/alpha/kernel/srm_env.c index 528d2be5818298..8ad9c100ef7612 100644 --- a/arch/alpha/kernel/srm_env.c +++ b/arch/alpha/kernel/srm_env.c @@ -121,7 +121,7 @@ static ssize_t srm_env_proc_write(struct file *file, const char __user *buffer, static const struct proc_ops srm_env_proc_ops = { .proc_open = srm_env_proc_open, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_lseek = seq_lseek, .proc_release = single_release, .proc_write = srm_env_proc_write, diff --git a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c index 81a627e6e1c599..412cab88402acd 100644 --- a/arch/arm/mm/alignment.c +++ b/arch/arm/mm/alignment.c @@ -164,7 +164,7 @@ static ssize_t alignment_proc_write(struct file *file, const char __user *buffer static const struct proc_ops alignment_proc_ops = { .proc_open = alignment_proc_open, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_lseek = seq_lseek, .proc_release = single_release, .proc_write = alignment_proc_write, diff --git a/arch/powerpc/kernel/rtas-proc.c b/arch/powerpc/kernel/rtas-proc.c index 2d33f342a29307..3aace56aacc1df 100644 --- a/arch/powerpc/kernel/rtas-proc.c +++ b/arch/powerpc/kernel/rtas-proc.c @@ -161,7 +161,7 @@ static int poweron_open(struct inode *inode, struct file *file) static const struct proc_ops ppc_rtas_poweron_proc_ops = { .proc_open = poweron_open, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_lseek = seq_lseek, .proc_write = ppc_rtas_poweron_write, .proc_release = single_release, @@ -174,7 +174,7 @@ static int progress_open(struct inode *inode, struct file *file) static const struct proc_ops ppc_rtas_progress_proc_ops = { .proc_open = progress_open, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_lseek = seq_lseek, .proc_write = ppc_rtas_progress_write, .proc_release = single_release, @@ -187,7 +187,7 @@ static int clock_open(struct inode *inode, struct file *file) static const struct proc_ops ppc_rtas_clock_proc_ops = { .proc_open = clock_open, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_lseek = seq_lseek, .proc_write = ppc_rtas_clock_write, .proc_release = single_release, @@ -200,7 +200,7 @@ static int tone_freq_open(struct inode *inode, struct file *file) static const struct proc_ops ppc_rtas_tone_freq_proc_ops = { .proc_open = tone_freq_open, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_lseek = seq_lseek, .proc_write = ppc_rtas_tone_freq_write, .proc_release = single_release, @@ -213,7 +213,7 @@ static int tone_volume_open(struct inode *inode, struct file *file) static const struct proc_ops ppc_rtas_tone_volume_proc_ops = { .proc_open = tone_volume_open, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_lseek = seq_lseek, .proc_write = ppc_rtas_tone_volume_write, .proc_release = single_release, diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c index 9fcf2d19583004..2f3aef6c0b513b 100644 --- a/arch/powerpc/mm/numa.c +++ b/arch/powerpc/mm/numa.c @@ -1672,7 +1672,7 @@ static ssize_t topology_write(struct file *file, const char __user *buf, } static const struct proc_ops topology_proc_ops = { - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_write = topology_write, .proc_open = topology_open, .proc_release = single_release, diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c index fd26f3d21d7b4b..2b13a67d60e206 100644 --- a/arch/powerpc/platforms/pseries/lpar.c +++ b/arch/powerpc/platforms/pseries/lpar.c @@ -584,7 +584,7 @@ static int vcpudispatch_stats_open(struct inode *inode, struct file *file) static const struct proc_ops vcpudispatch_stats_proc_ops = { .proc_open = vcpudispatch_stats_open, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_write = vcpudispatch_stats_write, .proc_lseek = seq_lseek, .proc_release = single_release, @@ -628,7 +628,7 @@ static int vcpudispatch_stats_freq_open(struct inode *inode, struct file *file) static const struct proc_ops vcpudispatch_stats_freq_proc_ops = { .proc_open = vcpudispatch_stats_freq_open, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_write = vcpudispatch_stats_freq_write, .proc_lseek = seq_lseek, .proc_release = single_release, diff --git a/arch/powerpc/platforms/pseries/lparcfg.c b/arch/powerpc/platforms/pseries/lparcfg.c index b8d28ab881789d..35eb0e4b8fd31a 100644 --- a/arch/powerpc/platforms/pseries/lparcfg.c +++ b/arch/powerpc/platforms/pseries/lparcfg.c @@ -699,7 +699,7 @@ static int lparcfg_open(struct inode *inode, struct file *file) } static const struct proc_ops lparcfg_proc_ops = { - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_write = lparcfg_write, .proc_open = lparcfg_open, .proc_release = single_release, diff --git a/arch/sh/mm/alignment.c b/arch/sh/mm/alignment.c index fb517b82a87b10..66115241ad93a4 100644 --- a/arch/sh/mm/alignment.c +++ b/arch/sh/mm/alignment.c @@ -154,7 +154,7 @@ static ssize_t alignment_proc_write(struct file *file, static const struct proc_ops alignment_proc_ops = { .proc_open = alignment_proc_open, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_lseek = seq_lseek, .proc_release = single_release, .proc_write = alignment_proc_write, diff --git a/arch/sparc/kernel/led.c b/arch/sparc/kernel/led.c index bd48575172c323..a0b893d216c443 100644 --- a/arch/sparc/kernel/led.c +++ b/arch/sparc/kernel/led.c @@ -106,7 +106,7 @@ static ssize_t led_proc_write(struct file *file, const char __user *buffer, static const struct proc_ops led_proc_ops = { .proc_open = led_proc_open, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_lseek = seq_lseek, .proc_release = single_release, .proc_write = led_proc_write, diff --git a/arch/um/kernel/exitcode.c b/arch/um/kernel/exitcode.c index 43edc2aa57e4fb..95184d271a47cf 100644 --- a/arch/um/kernel/exitcode.c +++ b/arch/um/kernel/exitcode.c @@ -57,7 +57,7 @@ static ssize_t exitcode_proc_write(struct file *file, static const struct proc_ops exitcode_proc_ops = { .proc_open = exitcode_proc_open, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_lseek = seq_lseek, .proc_release = single_release, .proc_write = exitcode_proc_write, diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c index e3a2cf92a3738b..f3e4bd48f6d5b6 100644 --- a/arch/um/kernel/process.c +++ b/arch/um/kernel/process.c @@ -312,7 +312,7 @@ static ssize_t sysemu_proc_write(struct file *file, const char __user *buf, static const struct proc_ops sysemu_proc_ops = { .proc_open = sysemu_proc_open, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_lseek = seq_lseek, .proc_release = single_release, .proc_write = sysemu_proc_write, diff --git a/arch/x86/kernel/cpu/mtrr/if.c b/arch/x86/kernel/cpu/mtrr/if.c index a5c506f6da7fa1..f5743b5ecaf232 100644 --- a/arch/x86/kernel/cpu/mtrr/if.c +++ b/arch/x86/kernel/cpu/mtrr/if.c @@ -398,7 +398,7 @@ static int mtrr_open(struct inode *inode, struct file *file) static const struct proc_ops mtrr_proc_ops = { .proc_open = mtrr_open, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_lseek = seq_lseek, .proc_write = mtrr_write, .proc_ioctl = mtrr_ioctl, diff --git a/arch/x86/platform/uv/tlb_uv.c b/arch/x86/platform/uv/tlb_uv.c index 0ac96ca304c7b5..cd6ee86283e6e1 100644 --- a/arch/x86/platform/uv/tlb_uv.c +++ b/arch/x86/platform/uv/tlb_uv.c @@ -1670,7 +1670,7 @@ static int tunables_open(struct inode *inode, struct file *file) static const struct proc_ops uv_ptc_proc_ops = { .proc_open = ptc_proc_open, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_write = ptc_proc_write, .proc_lseek = seq_lseek, .proc_release = seq_release, diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index 366c389175d844..c8e5972ad6c952 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c @@ -1204,7 +1204,7 @@ static int acpi_battery_alarm_proc_open(struct inode *inode, struct file *file) static const struct proc_ops acpi_battery_alarm_proc_ops = { .proc_open = acpi_battery_alarm_proc_open, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_write = acpi_battery_write_alarm, .proc_lseek = seq_lseek, .proc_release = single_release, diff --git a/drivers/acpi/proc.c b/drivers/acpi/proc.c index 7892980b3ce4d3..774da498c77265 100644 --- a/drivers/acpi/proc.c +++ b/drivers/acpi/proc.c @@ -136,7 +136,7 @@ acpi_system_wakeup_device_open_fs(struct inode *inode, struct file *file) static const struct proc_ops acpi_system_wakeup_device_proc_ops = { .proc_open = acpi_system_wakeup_device_open_fs, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_write = acpi_system_write_wakeup_device, .proc_lseek = seq_lseek, .proc_release = single_release, diff --git a/drivers/hwmon/dell-smm-hwmon.c b/drivers/hwmon/dell-smm-hwmon.c index 16be012a95ed84..29ac388429620f 100644 --- a/drivers/hwmon/dell-smm-hwmon.c +++ b/drivers/hwmon/dell-smm-hwmon.c @@ -597,7 +597,7 @@ static int i8k_open_fs(struct inode *inode, struct file *file) static const struct proc_ops i8k_proc_ops = { .proc_open = i8k_open_fs, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_lseek = seq_lseek, .proc_release = single_release, .proc_ioctl = i8k_ioctl, diff --git a/drivers/ide/ide-proc.c b/drivers/ide/ide-proc.c index 8ea282a3a19f0d..a0b56737152fb5 100644 --- a/drivers/ide/ide-proc.c +++ b/drivers/ide/ide-proc.c @@ -383,7 +383,7 @@ static ssize_t ide_settings_proc_write(struct file *file, const char __user *buf static const struct proc_ops ide_settings_proc_ops = { .proc_open = ide_settings_proc_open, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_lseek = seq_lseek, .proc_release = single_release, .proc_write = ide_settings_proc_write, diff --git a/drivers/input/input.c b/drivers/input/input.c index 3cfd2c18eebd9d..c8180d7f92d576 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -1220,7 +1220,7 @@ static int input_proc_devices_open(struct inode *inode, struct file *file) static const struct proc_ops input_devices_proc_ops = { .proc_open = input_proc_devices_open, .proc_poll = input_proc_devices_poll, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_lseek = seq_lseek, .proc_release = seq_release, }; @@ -1282,7 +1282,7 @@ static int input_proc_handlers_open(struct inode *inode, struct file *file) static const struct proc_ops input_handlers_proc_ops = { .proc_open = input_proc_handlers_open, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_lseek = seq_lseek, .proc_release = seq_release, }; diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c index 73e6ae88fafd4e..9415eddb419402 100644 --- a/drivers/macintosh/via-pmu.c +++ b/drivers/macintosh/via-pmu.c @@ -973,7 +973,7 @@ static ssize_t pmu_options_proc_write(struct file *file, static const struct proc_ops pmu_options_proc_ops = { .proc_open = pmu_options_proc_open, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_lseek = seq_lseek, .proc_release = single_release, .proc_write = pmu_options_proc_write, diff --git a/drivers/md/md.c b/drivers/md/md.c index f567f536b529bd..0bae6c1523cec6 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -8301,7 +8301,7 @@ static __poll_t mdstat_poll(struct file *filp, poll_table *wait) static const struct proc_ops mdstat_proc_ops = { .proc_open = md_seq_open, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_lseek = seq_lseek, .proc_release = seq_release, .proc_poll = mdstat_poll, diff --git a/drivers/misc/sgi-gru/gruprocfs.c b/drivers/misc/sgi-gru/gruprocfs.c index 97b8b38ab47dfd..fc9498ec797762 100644 --- a/drivers/misc/sgi-gru/gruprocfs.c +++ b/drivers/misc/sgi-gru/gruprocfs.c @@ -257,7 +257,7 @@ static int options_open(struct inode *inode, struct file *file) /* *INDENT-OFF* */ static const struct proc_ops statistics_proc_ops = { .proc_open = statistics_open, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_write = statistics_write, .proc_lseek = seq_lseek, .proc_release = single_release, @@ -265,7 +265,7 @@ static const struct proc_ops statistics_proc_ops = { static const struct proc_ops mcs_statistics_proc_ops = { .proc_open = mcs_statistics_open, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_write = mcs_statistics_write, .proc_lseek = seq_lseek, .proc_release = single_release, @@ -273,7 +273,7 @@ static const struct proc_ops mcs_statistics_proc_ops = { static const struct proc_ops options_proc_ops = { .proc_open = options_open, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_write = options_write, .proc_lseek = seq_lseek, .proc_release = single_release, diff --git a/drivers/net/wireless/intel/ipw2x00/libipw_module.c b/drivers/net/wireless/intel/ipw2x00/libipw_module.c index 43bab92a4148f2..1929db6921d7e0 100644 --- a/drivers/net/wireless/intel/ipw2x00/libipw_module.c +++ b/drivers/net/wireless/intel/ipw2x00/libipw_module.c @@ -242,7 +242,7 @@ static ssize_t debug_level_proc_write(struct file *file, static const struct proc_ops debug_level_proc_ops = { .proc_open = debug_level_proc_open, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_lseek = seq_lseek, .proc_release = single_release, .proc_write = debug_level_proc_write, diff --git a/drivers/net/wireless/intersil/hostap/hostap_download.c b/drivers/net/wireless/intersil/hostap/hostap_download.c index 7c6a5a6d1d45d8..8980fd57b2eda4 100644 --- a/drivers/net/wireless/intersil/hostap/hostap_download.c +++ b/drivers/net/wireless/intersil/hostap/hostap_download.c @@ -234,7 +234,7 @@ static int prism2_download_aux_dump_proc_open(struct inode *inode, struct file * static const struct proc_ops prism2_download_aux_dump_proc_ops = { .proc_open = prism2_download_aux_dump_proc_open, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_lseek = seq_lseek, .proc_release = seq_release_private, }; diff --git a/drivers/parisc/led.c b/drivers/parisc/led.c index 36c6613f7a36b7..d75df3977926b3 100644 --- a/drivers/parisc/led.c +++ b/drivers/parisc/led.c @@ -232,7 +232,7 @@ static ssize_t led_proc_write(struct file *file, const char __user *buf, static const struct proc_ops led_proc_ops = { .proc_open = led_proc_open, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_lseek = seq_lseek, .proc_release = single_release, .proc_write = led_proc_write, diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index ff7f0a4f247563..f571d6254e7c34 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -901,7 +901,7 @@ static ssize_t dispatch_proc_write(struct file *file, static const struct proc_ops dispatch_proc_ops = { .proc_open = dispatch_proc_open, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_lseek = seq_lseek, .proc_release = single_release, .proc_write = dispatch_proc_write, diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c index 1ddab5a6dead6d..770477bb407d49 100644 --- a/drivers/platform/x86/toshiba_acpi.c +++ b/drivers/platform/x86/toshiba_acpi.c @@ -1428,7 +1428,7 @@ static ssize_t lcd_proc_write(struct file *file, const char __user *buf, static const struct proc_ops lcd_proc_ops = { .proc_open = lcd_proc_open, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_lseek = seq_lseek, .proc_release = single_release, .proc_write = lcd_proc_write, @@ -1534,7 +1534,7 @@ static ssize_t video_proc_write(struct file *file, const char __user *buf, static const struct proc_ops video_proc_ops = { .proc_open = video_proc_open, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_lseek = seq_lseek, .proc_release = single_release, .proc_write = video_proc_write, @@ -1611,7 +1611,7 @@ static ssize_t fan_proc_write(struct file *file, const char __user *buf, static const struct proc_ops fan_proc_ops = { .proc_open = fan_proc_open, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_lseek = seq_lseek, .proc_release = single_release, .proc_write = fan_proc_write, @@ -1655,7 +1655,7 @@ static ssize_t keys_proc_write(struct file *file, const char __user *buf, static const struct proc_ops keys_proc_ops = { .proc_open = keys_proc_open, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_lseek = seq_lseek, .proc_release = single_release, .proc_write = keys_proc_write, diff --git a/drivers/pnp/pnpbios/proc.c b/drivers/pnp/pnpbios/proc.c index a806830e3a407f..10d0181c4430ab 100644 --- a/drivers/pnp/pnpbios/proc.c +++ b/drivers/pnp/pnpbios/proc.c @@ -212,7 +212,7 @@ static ssize_t pnpbios_proc_write(struct file *file, const char __user *buf, static const struct proc_ops pnpbios_proc_ops = { .proc_open = pnpbios_proc_open, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_lseek = seq_lseek, .proc_release = single_release, .proc_write = pnpbios_proc_write, diff --git a/drivers/s390/block/dasd_proc.c b/drivers/s390/block/dasd_proc.c index 62a859ea67f893..278f0dccc85ff1 100644 --- a/drivers/s390/block/dasd_proc.c +++ b/drivers/s390/block/dasd_proc.c @@ -322,7 +322,7 @@ static ssize_t dasd_stats_proc_write(struct file *file, static const struct proc_ops dasd_stats_proc_ops = { .proc_open = dasd_stats_proc_open, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_lseek = seq_lseek, .proc_release = single_release, .proc_write = dasd_stats_proc_write, diff --git a/drivers/s390/cio/blacklist.c b/drivers/s390/cio/blacklist.c index 4dd2eb63485699..05f58c453b060c 100644 --- a/drivers/s390/cio/blacklist.c +++ b/drivers/s390/cio/blacklist.c @@ -401,7 +401,7 @@ cio_ignore_proc_open(struct inode *inode, struct file *file) static const struct proc_ops cio_ignore_proc_ops = { .proc_open = cio_ignore_proc_open, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_lseek = seq_lseek, .proc_release = seq_release_private, .proc_write = cio_ignore_write, diff --git a/drivers/scsi/scsi_devinfo.c b/drivers/scsi/scsi_devinfo.c index eed31021e7885c..87fb440ddfc5d8 100644 --- a/drivers/scsi/scsi_devinfo.c +++ b/drivers/scsi/scsi_devinfo.c @@ -738,7 +738,7 @@ static ssize_t proc_scsi_devinfo_write(struct file *file, static const struct proc_ops scsi_devinfo_proc_ops = { .proc_open = proc_scsi_devinfo_open, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_write = proc_scsi_devinfo_write, .proc_lseek = seq_lseek, .proc_release = seq_release, diff --git a/drivers/scsi/scsi_proc.c b/drivers/scsi/scsi_proc.c index d6982d3557396b..81601a9e79c4db 100644 --- a/drivers/scsi/scsi_proc.c +++ b/drivers/scsi/scsi_proc.c @@ -86,7 +86,7 @@ static int proc_scsi_host_open(struct inode *inode, struct file *file) static const struct proc_ops proc_scsi_ops = { .proc_open = proc_scsi_host_open, .proc_release = single_release, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_lseek = seq_lseek, .proc_write = proc_scsi_host_write }; @@ -438,7 +438,7 @@ static int proc_scsi_open(struct inode *inode, struct file *file) static const struct proc_ops scsi_scsi_proc_ops = { .proc_open = proc_scsi_open, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_write = proc_scsi_write, .proc_lseek = seq_lseek, .proc_release = seq_release, diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index 20472aaaf630a4..c5d482190066bc 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c @@ -2328,7 +2328,7 @@ static ssize_t sg_proc_write_adio(struct file *filp, const char __user *buffer, size_t count, loff_t *off); static const struct proc_ops adio_proc_ops = { .proc_open = sg_proc_single_open_adio, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_lseek = seq_lseek, .proc_write = sg_proc_write_adio, .proc_release = single_release, @@ -2339,7 +2339,7 @@ static ssize_t sg_proc_write_dressz(struct file *filp, const char __user *buffer, size_t count, loff_t *off); static const struct proc_ops dressz_proc_ops = { .proc_open = sg_proc_single_open_dressz, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_lseek = seq_lseek, .proc_write = sg_proc_write_dressz, .proc_release = single_release, diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_module.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_module.c index a5a1b14f5a40c5..e198779db6fc2e 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_module.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_module.c @@ -265,7 +265,7 @@ static int open_debug_level(struct inode *inode, struct file *file) static const struct proc_ops debug_level_proc_ops = { .proc_open = open_debug_level, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_lseek = seq_lseek, .proc_write = write_debug_level, .proc_release = single_release, diff --git a/drivers/usb/gadget/function/rndis.c b/drivers/usb/gadget/function/rndis.c index 64de9f1b874c55..562781b95101d3 100644 --- a/drivers/usb/gadget/function/rndis.c +++ b/drivers/usb/gadget/function/rndis.c @@ -1166,7 +1166,7 @@ static int rndis_proc_open(struct inode *inode, struct file *file) static const struct proc_ops rndis_proc_ops = { .proc_open = rndis_proc_open, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_lseek = seq_lseek, .proc_release = single_release, .proc_write = rndis_proc_write, diff --git a/drivers/video/fbdev/via/viafbdev.c b/drivers/video/fbdev/via/viafbdev.c index 22deb340a0484f..6cf91191de7f15 100644 --- a/drivers/video/fbdev/via/viafbdev.c +++ b/drivers/video/fbdev/via/viafbdev.c @@ -1175,7 +1175,7 @@ static ssize_t viafb_dvp0_proc_write(struct file *file, static const struct proc_ops viafb_dvp0_proc_ops = { .proc_open = viafb_dvp0_proc_open, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_lseek = seq_lseek, .proc_release = single_release, .proc_write = viafb_dvp0_proc_write, @@ -1239,7 +1239,7 @@ static ssize_t viafb_dvp1_proc_write(struct file *file, static const struct proc_ops viafb_dvp1_proc_ops = { .proc_open = viafb_dvp1_proc_open, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_lseek = seq_lseek, .proc_release = single_release, .proc_write = viafb_dvp1_proc_write, @@ -1273,7 +1273,7 @@ static ssize_t viafb_dfph_proc_write(struct file *file, static const struct proc_ops viafb_dfph_proc_ops = { .proc_open = viafb_dfph_proc_open, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_lseek = seq_lseek, .proc_release = single_release, .proc_write = viafb_dfph_proc_write, @@ -1307,7 +1307,7 @@ static ssize_t viafb_dfpl_proc_write(struct file *file, static const struct proc_ops viafb_dfpl_proc_ops = { .proc_open = viafb_dfpl_proc_open, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_lseek = seq_lseek, .proc_release = single_release, .proc_write = viafb_dfpl_proc_write, @@ -1442,7 +1442,7 @@ static ssize_t viafb_vt1636_proc_write(struct file *file, static const struct proc_ops viafb_vt1636_proc_ops = { .proc_open = viafb_vt1636_proc_open, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_lseek = seq_lseek, .proc_release = single_release, .proc_write = viafb_vt1636_proc_write, @@ -1519,7 +1519,7 @@ static ssize_t viafb_iga1_odev_proc_write(struct file *file, static const struct proc_ops viafb_iga1_odev_proc_ops = { .proc_open = viafb_iga1_odev_proc_open, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_lseek = seq_lseek, .proc_release = single_release, .proc_write = viafb_iga1_odev_proc_write, @@ -1558,7 +1558,7 @@ static ssize_t viafb_iga2_odev_proc_write(struct file *file, static const struct proc_ops viafb_iga2_odev_proc_ops = { .proc_open = viafb_iga2_odev_proc_open, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_lseek = seq_lseek, .proc_release = single_release, .proc_write = viafb_iga2_odev_proc_write, diff --git a/fs/cifs/cifs_debug.c b/fs/cifs/cifs_debug.c index fc98b97b396a44..65eb425cc3adf0 100644 --- a/fs/cifs/cifs_debug.c +++ b/fs/cifs/cifs_debug.c @@ -615,7 +615,7 @@ static int cifs_stats_proc_open(struct inode *inode, struct file *file) static const struct proc_ops cifs_stats_proc_ops = { .proc_open = cifs_stats_proc_open, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_lseek = seq_lseek, .proc_release = single_release, .proc_write = cifs_stats_proc_write, @@ -644,7 +644,7 @@ static int name##_open(struct inode *inode, struct file *file) \ \ static const struct proc_ops cifs_##name##_proc_fops = { \ .proc_open = name##_open, \ - .proc_read = seq_read, \ + .proc_read_iter = seq_read_iter, \ .proc_lseek = seq_lseek, \ .proc_release = single_release, \ .proc_write = name##_write, \ @@ -778,7 +778,7 @@ static ssize_t cifsFYI_proc_write(struct file *file, const char __user *buffer, static const struct proc_ops cifsFYI_proc_ops = { .proc_open = cifsFYI_proc_open, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_lseek = seq_lseek, .proc_release = single_release, .proc_write = cifsFYI_proc_write, @@ -809,7 +809,7 @@ static ssize_t cifs_linux_ext_proc_write(struct file *file, static const struct proc_ops cifs_linux_ext_proc_ops = { .proc_open = cifs_linux_ext_proc_open, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_lseek = seq_lseek, .proc_release = single_release, .proc_write = cifs_linux_ext_proc_write, @@ -840,7 +840,7 @@ static ssize_t cifs_lookup_cache_proc_write(struct file *file, static const struct proc_ops cifs_lookup_cache_proc_ops = { .proc_open = cifs_lookup_cache_proc_open, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_lseek = seq_lseek, .proc_release = single_release, .proc_write = cifs_lookup_cache_proc_write, @@ -871,7 +871,7 @@ static ssize_t traceSMB_proc_write(struct file *file, const char __user *buffer, static const struct proc_ops traceSMB_proc_ops = { .proc_open = traceSMB_proc_open, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_lseek = seq_lseek, .proc_release = single_release, .proc_write = traceSMB_proc_write, @@ -982,7 +982,7 @@ static ssize_t cifs_security_flags_proc_write(struct file *file, static const struct proc_ops cifs_security_flags_proc_ops = { .proc_open = cifs_security_flags_proc_open, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_lseek = seq_lseek, .proc_release = single_release, .proc_write = cifs_security_flags_proc_write, diff --git a/fs/cifs/dfs_cache.c b/fs/cifs/dfs_cache.c index df81c718d2faec..a4fe155fc92a7a 100644 --- a/fs/cifs/dfs_cache.c +++ b/fs/cifs/dfs_cache.c @@ -214,7 +214,7 @@ static int dfscache_proc_open(struct inode *inode, struct file *file) const struct proc_ops dfscache_proc_ops = { .proc_open = dfscache_proc_open, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_lseek = seq_lseek, .proc_release = single_release, .proc_write = dfscache_proc_write, diff --git a/fs/fscache/object-list.c b/fs/fscache/object-list.c index e106a1a1600d82..fab5a4197f50c3 100644 --- a/fs/fscache/object-list.c +++ b/fs/fscache/object-list.c @@ -408,7 +408,7 @@ static int fscache_objlist_release(struct inode *inode, struct file *file) const struct proc_ops fscache_objlist_proc_ops = { .proc_open = fscache_objlist_open, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_lseek = seq_lseek, .proc_release = fscache_objlist_release, }; diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c index e4944436e733d0..db661b953c4378 100644 --- a/fs/jbd2/journal.c +++ b/fs/jbd2/journal.c @@ -1080,7 +1080,7 @@ static int jbd2_seq_info_release(struct inode *inode, struct file *file) static const struct proc_ops jbd2_info_proc_ops = { .proc_open = jbd2_seq_info_open, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_lseek = seq_lseek, .proc_release = jbd2_seq_info_release, }; diff --git a/fs/jfs/jfs_debug.c b/fs/jfs/jfs_debug.c index 44b62b3c322e9a..235df6bac1d71a 100644 --- a/fs/jfs/jfs_debug.c +++ b/fs/jfs/jfs_debug.c @@ -45,7 +45,7 @@ static ssize_t jfs_loglevel_proc_write(struct file *file, static const struct proc_ops jfs_loglevel_proc_ops = { .proc_open = jfs_loglevel_proc_open, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_lseek = seq_lseek, .proc_release = single_release, .proc_write = jfs_loglevel_proc_write, diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c index 1b36a8ba82d204..a73899dfc09b9d 100644 --- a/fs/nfsd/nfsctl.c +++ b/fs/nfsd/nfsctl.c @@ -159,7 +159,7 @@ static int exports_proc_open(struct inode *inode, struct file *file) static const struct proc_ops exports_proc_ops = { .proc_open = exports_proc_open, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_lseek = seq_lseek, .proc_release = seq_release, }; diff --git a/fs/nfsd/stats.c b/fs/nfsd/stats.c index b1bc582b0493e4..1076f87715ad88 100644 --- a/fs/nfsd/stats.c +++ b/fs/nfsd/stats.c @@ -86,7 +86,7 @@ static int nfsd_proc_open(struct inode *inode, struct file *file) static const struct proc_ops nfsd_proc_ops = { .proc_open = nfsd_proc_open, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_lseek = seq_lseek, .proc_release = single_release, }; diff --git a/fs/proc/cpuinfo.c b/fs/proc/cpuinfo.c index d0989a443c77df..419760fd77bdd8 100644 --- a/fs/proc/cpuinfo.c +++ b/fs/proc/cpuinfo.c @@ -19,7 +19,7 @@ static int cpuinfo_open(struct inode *inode, struct file *file) static const struct proc_ops cpuinfo_proc_ops = { .proc_flags = PROC_ENTRY_PERMANENT, .proc_open = cpuinfo_open, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_lseek = seq_lseek, .proc_release = seq_release, }; diff --git a/fs/proc/generic.c b/fs/proc/generic.c index 2f9fa179194d72..4323b28db5643a 100644 --- a/fs/proc/generic.c +++ b/fs/proc/generic.c @@ -590,7 +590,7 @@ static int proc_seq_release(struct inode *inode, struct file *file) static const struct proc_ops proc_seq_ops = { /* not permanent -- can call into arbitrary seq_operations */ .proc_open = proc_seq_open, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_lseek = seq_lseek, .proc_release = proc_seq_release, }; @@ -621,7 +621,7 @@ static int proc_single_open(struct inode *inode, struct file *file) static const struct proc_ops proc_single_ops = { /* not permanent -- can call into arbitrary ->single_show */ .proc_open = proc_single_open, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_lseek = seq_lseek, .proc_release = single_release, }; diff --git a/fs/proc/proc_net.c b/fs/proc/proc_net.c index dba63b2429f05f..8274f4fc4d4338 100644 --- a/fs/proc/proc_net.c +++ b/fs/proc/proc_net.c @@ -92,7 +92,7 @@ static int seq_release_net(struct inode *ino, struct file *f) static const struct proc_ops proc_net_seq_ops = { .proc_open = seq_open_net, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_write = proc_simple_write, .proc_lseek = seq_lseek, .proc_release = seq_release_net, @@ -204,7 +204,7 @@ static int single_release_net(struct inode *ino, struct file *f) static const struct proc_ops proc_net_single_ops = { .proc_open = single_open_net, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_write = proc_simple_write, .proc_lseek = seq_lseek, .proc_release = single_release_net, diff --git a/fs/proc/stat.c b/fs/proc/stat.c index 46b3293015fe61..4695b6de315129 100644 --- a/fs/proc/stat.c +++ b/fs/proc/stat.c @@ -226,7 +226,7 @@ static int stat_open(struct inode *inode, struct file *file) static const struct proc_ops stat_proc_ops = { .proc_flags = PROC_ENTRY_PERMANENT, .proc_open = stat_open, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_lseek = seq_lseek, .proc_release = single_release, }; diff --git a/include/linux/seq_file.h b/include/linux/seq_file.h index 0c9e9c8607e788..04f342179f5572 100644 --- a/include/linux/seq_file.h +++ b/include/linux/seq_file.h @@ -187,7 +187,7 @@ static int __name ## _open(struct inode *inode, struct file *file) \ \ static const struct proc_ops __name ## _proc_ops = { \ .proc_open = __name ## _open, \ - .proc_read = seq_read, \ + .proc_read_iter = seq_read_iter, \ .proc_lseek = seq_lseek, \ .proc_release = single_release, \ } diff --git a/ipc/util.c b/ipc/util.c index cfa0045e748d55..189c835108afc8 100644 --- a/ipc/util.c +++ b/ipc/util.c @@ -887,7 +887,7 @@ static int sysvipc_proc_release(struct inode *inode, struct file *file) static const struct proc_ops sysvipc_proc_ops = { .proc_flags = PROC_ENTRY_PERMANENT, .proc_open = sysvipc_proc_open, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_lseek = seq_lseek, .proc_release = sysvipc_proc_release, }; diff --git a/kernel/irq/proc.c b/kernel/irq/proc.c index 32c071d7bc0338..6c541898f614c4 100644 --- a/kernel/irq/proc.c +++ b/kernel/irq/proc.c @@ -200,7 +200,7 @@ static int irq_affinity_list_proc_open(struct inode *inode, struct file *file) static const struct proc_ops irq_affinity_proc_ops = { .proc_open = irq_affinity_proc_open, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_lseek = seq_lseek, .proc_release = single_release, .proc_write = irq_affinity_proc_write, @@ -208,7 +208,7 @@ static const struct proc_ops irq_affinity_proc_ops = { static const struct proc_ops irq_affinity_list_proc_ops = { .proc_open = irq_affinity_list_proc_open, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_lseek = seq_lseek, .proc_release = single_release, .proc_write = irq_affinity_list_proc_write, @@ -270,7 +270,7 @@ static int default_affinity_open(struct inode *inode, struct file *file) static const struct proc_ops default_affinity_proc_ops = { .proc_open = default_affinity_open, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_lseek = seq_lseek, .proc_release = single_release, .proc_write = default_affinity_write, diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c index 16c8c605f4b0fa..90facda3b723ab 100644 --- a/kernel/kallsyms.c +++ b/kernel/kallsyms.c @@ -699,7 +699,7 @@ const char *kdb_walk_kallsyms(loff_t *pos) static const struct proc_ops kallsyms_proc_ops = { .proc_open = kallsyms_open, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_lseek = seq_lseek, .proc_release = seq_release_private, }; diff --git a/kernel/latencytop.c b/kernel/latencytop.c index 166d7bf49666b0..543c7f552c45ce 100644 --- a/kernel/latencytop.c +++ b/kernel/latencytop.c @@ -257,7 +257,7 @@ static int lstats_open(struct inode *inode, struct file *filp) static const struct proc_ops lstats_proc_ops = { .proc_open = lstats_open, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_write = lstats_write, .proc_lseek = seq_lseek, .proc_release = single_release, diff --git a/kernel/locking/lockdep_proc.c b/kernel/locking/lockdep_proc.c index 5525cd3ba0c83c..60c725f53c26d7 100644 --- a/kernel/locking/lockdep_proc.c +++ b/kernel/locking/lockdep_proc.c @@ -669,7 +669,7 @@ static int lock_stat_release(struct inode *inode, struct file *file) static const struct proc_ops lock_stat_proc_ops = { .proc_open = lock_stat_open, .proc_write = lock_stat_write, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_lseek = seq_lseek, .proc_release = lock_stat_release, }; diff --git a/kernel/module.c b/kernel/module.c index e8a198588f26ee..019e7b21dbbf3c 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -4386,7 +4386,7 @@ static int modules_open(struct inode *inode, struct file *file) static const struct proc_ops modules_proc_ops = { .proc_flags = PROC_ENTRY_PERMANENT, .proc_open = modules_open, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_lseek = seq_lseek, .proc_release = seq_release, }; diff --git a/kernel/profile.c b/kernel/profile.c index 6f69a4195d5630..101090397235ae 100644 --- a/kernel/profile.c +++ b/kernel/profile.c @@ -444,7 +444,7 @@ static ssize_t prof_cpu_mask_proc_write(struct file *file, static const struct proc_ops prof_cpu_mask_proc_ops = { .proc_open = prof_cpu_mask_proc_open, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_lseek = seq_lseek, .proc_release = single_release, .proc_write = prof_cpu_mask_proc_write, diff --git a/kernel/sched/psi.c b/kernel/sched/psi.c index 8f45cdb6463b88..6795170140a031 100644 --- a/kernel/sched/psi.c +++ b/kernel/sched/psi.c @@ -1305,7 +1305,7 @@ static int psi_fop_release(struct inode *inode, struct file *file) static const struct proc_ops psi_io_proc_ops = { .proc_open = psi_io_open, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_lseek = seq_lseek, .proc_write = psi_io_write, .proc_poll = psi_fop_poll, @@ -1314,7 +1314,7 @@ static const struct proc_ops psi_io_proc_ops = { static const struct proc_ops psi_memory_proc_ops = { .proc_open = psi_memory_open, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_lseek = seq_lseek, .proc_write = psi_memory_write, .proc_poll = psi_fop_poll, @@ -1323,7 +1323,7 @@ static const struct proc_ops psi_memory_proc_ops = { static const struct proc_ops psi_cpu_proc_ops = { .proc_open = psi_cpu_open, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_lseek = seq_lseek, .proc_write = psi_cpu_write, .proc_poll = psi_fop_poll, diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c index 76750e73dcaf9d..2317d29e16def9 100644 --- a/lib/dynamic_debug.c +++ b/lib/dynamic_debug.c @@ -878,7 +878,7 @@ static const struct file_operations ddebug_proc_fops = { static const struct proc_ops proc_fops = { .proc_open = ddebug_proc_open, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_lseek = seq_lseek, .proc_release = seq_release_private, .proc_write = ddebug_proc_write diff --git a/mm/slab_common.c b/mm/slab_common.c index 9e72ba2241750c..8497bdf79a770f 100644 --- a/mm/slab_common.c +++ b/mm/slab_common.c @@ -1584,7 +1584,7 @@ static int slabinfo_open(struct inode *inode, struct file *file) static const struct proc_ops slabinfo_proc_ops = { .proc_flags = PROC_ENTRY_PERMANENT, .proc_open = slabinfo_open, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_write = slabinfo_write, .proc_lseek = seq_lseek, .proc_release = seq_release, diff --git a/mm/swapfile.c b/mm/swapfile.c index 987276c557d1f1..2e50f52a14c7c2 100644 --- a/mm/swapfile.c +++ b/mm/swapfile.c @@ -2835,7 +2835,7 @@ static int swaps_open(struct inode *inode, struct file *file) static const struct proc_ops swaps_proc_ops = { .proc_flags = PROC_ENTRY_PERMANENT, .proc_open = swaps_open, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_lseek = seq_lseek, .proc_release = seq_release, .proc_poll = swaps_poll, diff --git a/net/atm/mpoa_proc.c b/net/atm/mpoa_proc.c index 829db9eba0cb95..fe8f822c7750a6 100644 --- a/net/atm/mpoa_proc.c +++ b/net/atm/mpoa_proc.c @@ -55,7 +55,7 @@ static int parse_qos(const char *buff); static const struct proc_ops mpc_proc_ops = { .proc_open = proc_mpc_open, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_lseek = seq_lseek, .proc_write = proc_mpc_write, .proc_release = seq_release, diff --git a/net/core/pktgen.c b/net/core/pktgen.c index b53b6d38c4dff8..200b976202d0d1 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c @@ -537,7 +537,7 @@ static int pgctrl_open(struct inode *inode, struct file *file) static const struct proc_ops pktgen_proc_ops = { .proc_open = pgctrl_open, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_lseek = seq_lseek, .proc_write = pgctrl_write, .proc_release = single_release, @@ -1709,7 +1709,7 @@ static int pktgen_if_open(struct inode *inode, struct file *file) static const struct proc_ops pktgen_if_proc_ops = { .proc_open = pktgen_if_open, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_lseek = seq_lseek, .proc_write = pktgen_if_write, .proc_release = single_release, @@ -1846,7 +1846,7 @@ static int pktgen_thread_open(struct inode *inode, struct file *file) static const struct proc_ops pktgen_thread_proc_ops = { .proc_open = pktgen_thread_open, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_lseek = seq_lseek, .proc_write = pktgen_thread_write, .proc_release = single_release, diff --git a/net/ipv4/netfilter/ipt_CLUSTERIP.c b/net/ipv4/netfilter/ipt_CLUSTERIP.c index f8755a4ae9d4bd..67472389c9c395 100644 --- a/net/ipv4/netfilter/ipt_CLUSTERIP.c +++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c @@ -806,7 +806,7 @@ static ssize_t clusterip_proc_write(struct file *file, const char __user *input, static const struct proc_ops clusterip_proc_ops = { .proc_open = clusterip_proc_open, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_write = clusterip_proc_write, .proc_lseek = seq_lseek, .proc_release = clusterip_proc_release, diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 1d7076b78e630b..4d5f26478f1001 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -239,7 +239,7 @@ static int rt_cache_seq_open(struct inode *inode, struct file *file) static const struct proc_ops rt_cache_proc_ops = { .proc_open = rt_cache_seq_open, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_lseek = seq_lseek, .proc_release = seq_release, }; @@ -330,7 +330,7 @@ static int rt_cpu_seq_open(struct inode *inode, struct file *file) static const struct proc_ops rt_cpu_proc_ops = { .proc_open = rt_cpu_seq_open, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_lseek = seq_lseek, .proc_release = seq_release, }; diff --git a/net/netfilter/xt_recent.c b/net/netfilter/xt_recent.c index 19bef176145eb9..f9cc00f7486058 100644 --- a/net/netfilter/xt_recent.c +++ b/net/netfilter/xt_recent.c @@ -618,7 +618,7 @@ recent_mt_proc_write(struct file *file, const char __user *input, static const struct proc_ops recent_mt_proc_ops = { .proc_open = recent_seq_open, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_write = recent_mt_proc_write, .proc_release = seq_release_private, .proc_lseek = seq_lseek, diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c index e5c01697c3f1d6..3671c464e0d30f 100644 --- a/net/sunrpc/cache.c +++ b/net/sunrpc/cache.c @@ -1623,7 +1623,7 @@ static int content_release_procfs(struct inode *inode, struct file *filp) static const struct proc_ops content_proc_ops = { .proc_open = content_open_procfs, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_lseek = seq_lseek, .proc_release = content_release_procfs, }; diff --git a/net/sunrpc/stats.c b/net/sunrpc/stats.c index c964b48eaabae4..95b56f0e5a01e8 100644 --- a/net/sunrpc/stats.c +++ b/net/sunrpc/stats.c @@ -71,7 +71,7 @@ static int rpc_proc_open(struct inode *inode, struct file *file) static const struct proc_ops rpc_proc_ops = { .proc_open = rpc_proc_open, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, .proc_lseek = seq_lseek, .proc_release = single_release, }; diff --git a/sound/core/info.c b/sound/core/info.c index 8c6bc5241df50c..6e2a35a37b5e6b 100644 --- a/sound/core/info.c +++ b/sound/core/info.c @@ -426,7 +426,7 @@ static const struct proc_ops snd_info_text_entry_ops = .proc_release = snd_info_text_entry_release, .proc_write = snd_info_text_entry_write, .proc_lseek = seq_lseek, - .proc_read = seq_read, + .proc_read_iter = seq_read_iter, }; static struct snd_info_entry *create_subdir(struct module *mod, From patchwork Wed Jun 24 16:29:00 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoph Hellwig X-Patchwork-Id: 11623731 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 54344138C for ; Wed, 24 Jun 2020 16:30:37 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 3AA522082F for ; Wed, 24 Jun 2020 16:30:37 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=infradead.org header.i=@infradead.org header.b="OLCJ24nc" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2404883AbgFXQaR (ORCPT ); Wed, 24 Jun 2020 12:30:17 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41126 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2405011AbgFXQ3e (ORCPT ); Wed, 24 Jun 2020 12:29:34 -0400 Received: from casper.infradead.org (unknown [IPv6:2001:8b0:10b:1236::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DBED2C061795; Wed, 24 Jun 2020 09:29:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To: Content-Type:Content-ID:Content-Description; bh=oEIeGipGiq5zsPlrQwSey3OskkAUJ0grTVV3VZoK4No=; b=OLCJ24nc1l859RJjra1fthfHGt yY7smJc+rzD0a17nd/xH1ZwVbZI0Gdn8nCYP9sZ/pFUiaLqCpdVh2iwQQnEELV9XrCC+mNfL9yqIU /I9LIREnuOQRg0XbAdE61h1JoIf5++5nTCviE37+dbgI8y+5ZvUYibfLp14vOxOLWAb3LFmDLRUkf l/G+Bio6YHI4n8enbltsl1Nwg3lGSKcyuYr7zOzlTDovPkq25Fs4zhZHUILxLTDJfYeTZoQfNZAJH PpinyiOLTsSz1HdR0Av6kxsR9xjbx6B8vSb7kFpp6XPwiNaDUO/gYyNogHYGg3w34Ye1hgYpI3mia gzDeWYjA==; Received: from [2001:4bb8:180:a3:5c7c:8955:539d:955b] (helo=localhost) by casper.infradead.org with esmtpsa (Exim 4.92.3 #3 (Red Hat Linux)) id 1jo8Gy-0006pi-D9; Wed, 24 Jun 2020 16:29:16 +0000 From: Christoph Hellwig To: Al Viro , Linus Torvalds Cc: Luis Chamberlain , Kees Cook , Iurii Zaikin , linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org Subject: [PATCH 10/11] fs: don't allow kernel reads and writes using ->read and ->write Date: Wed, 24 Jun 2020 18:29:00 +0200 Message-Id: <20200624162901.1814136-11-hch@lst.de> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200624162901.1814136-1-hch@lst.de> References: <20200624162901.1814136-1-hch@lst.de> MIME-Version: 1.0 X-SRS-Rewrite: SMTP reverse-path rewritten from by casper.infradead.org. See http://www.infradead.org/rpr.html Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Don't allow calling ->read or ->write with set_fs as a preparation for killing off set_fs. While I've not triggered any of these cases in my setups as all the usual suspect (file systems, pipes, sockets, block devices, system character devices) use the iter ops this is almost going to be guaranteed to eventuall break something, so print a detailed error message helping to debug such cases. The fix will be to switch the affected driver to use ->read_uptr / ->write_uptr or ->read_iter / ->write_iter. Signed-off-by: Christoph Hellwig --- fs/read_write.c | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/fs/read_write.c b/fs/read_write.c index b92c222ca886ca..1b813d9bcf08b7 100644 --- a/fs/read_write.c +++ b/fs/read_write.c @@ -420,6 +420,18 @@ ssize_t iter_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos, return ret; } +static void warn_unsupported(struct file *file, const char *op) +{ + char pathname[128], *path; + + path = file_path(file, pathname, sizeof(pathname)); + if (IS_ERR(path)) + path = "(unknown)"; + pr_warn_ratelimited( + "kernel space %s not supported for file %s (pid: %d comm: %.20s)\n", + op, path, current->pid, current->comm); +} + ssize_t __kernel_read(struct file *file, void *buf, size_t count, loff_t *pos) { ssize_t ret; @@ -433,12 +445,6 @@ ssize_t __kernel_read(struct file *file, void *buf, size_t count, loff_t *pos) count = MAX_RW_COUNT; if (file->f_op->read_uptr) { ret = file->f_op->read_uptr(file, KERNEL_UPTR(buf), count, pos); - } else if (file->f_op->read) { - mm_segment_t old_fs = get_fs(); - - set_fs(KERNEL_DS); - ret = file->f_op->read(file, (void __user *)buf, count, pos); - set_fs(old_fs); } else if (file->f_op->read_iter) { struct kvec iov = { .iov_base = buf, .iov_len = count }; struct kiocb kiocb; @@ -450,6 +456,8 @@ ssize_t __kernel_read(struct file *file, void *buf, size_t count, loff_t *pos) ret = file->f_op->read_iter(&kiocb, &iter); *pos = kiocb.ki_pos; } else { + if (file->f_op->read) + warn_unsupported(file, "read"); ret = -EINVAL; } if (ret > 0) { @@ -539,13 +547,6 @@ ssize_t __kernel_write(struct file *file, const void *buf, size_t count, if (file->f_op->write_uptr) { ret = file->f_op->write_uptr(file, KERNEL_UPTR((void *)buf), count, pos); - } else if (file->f_op->write) { - mm_segment_t old_fs = get_fs(); - - set_fs(KERNEL_DS); - ret = file->f_op->write(file, (__force const char __user *)buf, - count, pos); - set_fs(old_fs); } else if (file->f_op->write_iter) { struct kvec iov = { .iov_base = (void *)buf, .iov_len = count }; struct kiocb kiocb; @@ -558,6 +559,8 @@ ssize_t __kernel_write(struct file *file, const void *buf, size_t count, if (ret > 0) *pos = kiocb.ki_pos; } else { + if (file->f_op->write) + warn_unsupported(file, "write"); ret = -EINVAL; } if (ret > 0) { From patchwork Wed Jun 24 16:29:01 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoph Hellwig X-Patchwork-Id: 11623729 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id D41E892A for ; Wed, 24 Jun 2020 16:30:36 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id B828C2082F for ; Wed, 24 Jun 2020 16:30:36 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=infradead.org header.i=@infradead.org header.b="UcgHI197" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2405123AbgFXQaR (ORCPT ); Wed, 24 Jun 2020 12:30:17 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41132 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2405017AbgFXQ3g (ORCPT ); Wed, 24 Jun 2020 12:29:36 -0400 Received: from casper.infradead.org (unknown [IPv6:2001:8b0:10b:1236::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 27251C061796; Wed, 24 Jun 2020 09:29:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To: Content-Type:Content-ID:Content-Description; bh=EBfONOMY9ii8aUk0u+XmJ5cXTI9HYeiCStmwDHUGa3I=; b=UcgHI197Wnq3bDYvHG8N72al3l iB/UodguMmn5YNn4A6Y1KFSvg6LBUUIUN3OHs7RgH0iU+uMjjFItSmbOxFxRpRz7OrrBfiY2BUOSi XAhuJyLy5iXdSbZ2c2n3GhNNicPUx5/g7WHGMbGEAzGon7vLS6WFLeAX6rTvolsWzMxoC5a/D1TlT bsAtq31gKvAu2/6x8jTmDLSwuCrXhEhZg4GdBWCKA4o3xeXejS2nttJco4QmtA1COXThLaZUY3tZt /CW5xD8DQfI7wypmzZiMd9+gsgT0ovvxz8D/jQGN1J5BFu1tCb9nSmIVgs/aztTMyuT3tViYjA4uP goO4sFlA==; Received: from [2001:4bb8:180:a3:5c7c:8955:539d:955b] (helo=localhost) by casper.infradead.org with esmtpsa (Exim 4.92.3 #3 (Red Hat Linux)) id 1jo8Gz-0006pr-PS; Wed, 24 Jun 2020 16:29:18 +0000 From: Christoph Hellwig To: Al Viro , Linus Torvalds Cc: Luis Chamberlain , Kees Cook , Iurii Zaikin , linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org Subject: [PATCH 11/11] fs: don't allow splice read/write without explicit ops Date: Wed, 24 Jun 2020 18:29:01 +0200 Message-Id: <20200624162901.1814136-12-hch@lst.de> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200624162901.1814136-1-hch@lst.de> References: <20200624162901.1814136-1-hch@lst.de> MIME-Version: 1.0 X-SRS-Rewrite: SMTP reverse-path rewritten from by casper.infradead.org. See http://www.infradead.org/rpr.html Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Now that __kernel_write or __kernel_write don't just work on all file operations instances there is not much of a point of providing default splice methods. Renamed the existing default ones to simple_ and wire them up for the few instancas actually implementing ->read_uptr and ->write_uptr. Signed-off-by: Christoph Hellwig --- fs/proc/proc_sysctl.c | 2 ++ fs/splice.c | 40 ++++++++++++++++++++++++++++------------ include/linux/fs.h | 5 ++++- 3 files changed, 34 insertions(+), 13 deletions(-) diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c index dd5eb693bd00df..5adbc1c8f899cd 100644 --- a/fs/proc/proc_sysctl.c +++ b/fs/proc/proc_sysctl.c @@ -856,6 +856,8 @@ static const struct file_operations proc_sys_file_operations = { .poll = proc_sys_poll, .read_uptr = proc_sys_read, .write_uptr = proc_sys_write, + .splice_read = simple_splice_read, + .splice_write = simple_splice_write, .llseek = default_llseek, }; diff --git a/fs/splice.c b/fs/splice.c index d1efc53875bd93..d5bba2cd695b5d 100644 --- a/fs/splice.c +++ b/fs/splice.c @@ -342,9 +342,8 @@ const struct pipe_buf_operations nosteal_pipe_buf_ops = { }; EXPORT_SYMBOL(nosteal_pipe_buf_ops); -static ssize_t default_file_splice_read(struct file *in, loff_t *ppos, - struct pipe_inode_info *pipe, size_t len, - unsigned int flags) +ssize_t simple_splice_read(struct file *in, loff_t *ppos, + struct pipe_inode_info *pipe, size_t len, unsigned int flags) { struct iov_iter to; struct page **pages; @@ -779,9 +778,8 @@ static int write_pipe_buf(struct pipe_inode_info *pipe, struct pipe_buffer *buf, return ret; } -static ssize_t default_file_splice_write(struct pipe_inode_info *pipe, - struct file *out, loff_t *ppos, - size_t len, unsigned int flags) +ssize_t simple_splice_write(struct pipe_inode_info *pipe, struct file *out, + loff_t *ppos, size_t len, unsigned int flags) { ssize_t ret; @@ -813,15 +811,30 @@ ssize_t generic_splice_sendpage(struct pipe_inode_info *pipe, struct file *out, EXPORT_SYMBOL(generic_splice_sendpage); +static void warn_unsupported(struct file *file, const char *op) +{ + char pathname[128], *path; + + path = file_path(file, pathname, sizeof(pathname)); + if (IS_ERR(path)) + path = "(unknown)"; + pr_debug_ratelimited( + "splice %s not supported for file %s (pid: %d comm: %.20s)\n", + op, path, current->pid, current->comm); +} + /* * Attempt to initiate a splice from pipe to file. */ static long do_splice_from(struct pipe_inode_info *pipe, struct file *out, loff_t *ppos, size_t len, unsigned int flags) { - if (out->f_op->splice_write) - return out->f_op->splice_write(pipe, out, ppos, len, flags); - return default_file_splice_write(pipe, out, ppos, len, flags); + if (!out->f_op->splice_write) { + warn_unsupported(out, "write"); + return -EINVAL; + } + + return out->f_op->splice_write(pipe, out, ppos, len, flags); } /* @@ -843,9 +856,12 @@ static long do_splice_to(struct file *in, loff_t *ppos, if (unlikely(len > MAX_RW_COUNT)) len = MAX_RW_COUNT; - if (in->f_op->splice_read) - return in->f_op->splice_read(in, ppos, pipe, len, flags); - return default_file_splice_read(in, ppos, pipe, len, flags); + if (!in->f_op->splice_read) { + warn_unsupported(in, "read"); + return -EINVAL; + } + + return in->f_op->splice_read(in, ppos, pipe, len, flags); } /** diff --git a/include/linux/fs.h b/include/linux/fs.h index d0fea0281ef29b..64a6506cba0446 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -3175,7 +3175,10 @@ extern ssize_t generic_splice_sendpage(struct pipe_inode_info *pipe, struct file *out, loff_t *, size_t len, unsigned int flags); extern long do_splice_direct(struct file *in, loff_t *ppos, struct file *out, loff_t *opos, size_t len, unsigned int flags); - +ssize_t simple_splice_read(struct file *in, loff_t *ppos, + struct pipe_inode_info *pipe, size_t len, unsigned int flags); +ssize_t simple_splice_write(struct pipe_inode_info *pipe, struct file *out, + loff_t *ppos, size_t len, unsigned int flags); extern void file_ra_state_init(struct file_ra_state *ra, struct address_space *mapping);