linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Andrea Arcangeli <andrea@suse.de>
To: Alexander Viro <viro@math.psu.edu>
Cc: Linus Torvalds <torvalds@transmeta.com>,
	Kernel Mailing List <linux-kernel@vger.kernel.org>
Subject: Re: Linux 2.4.10-pre11
Date: Thu, 20 Sep 2001 04:34:04 +0200	[thread overview]
Message-ID: <20010920043404.K720@athlon.random> (raw)
In-Reply-To: <20010919202539.E720@athlon.random> <Pine.GSO.4.21.0109191515200.901-100000@weyl.math.psu.edu>
In-Reply-To: <Pine.GSO.4.21.0109191515200.901-100000@weyl.math.psu.edu>; from viro@math.psu.edu on Wed, Sep 19, 2001 at 03:21:09PM -0400

On Wed, Sep 19, 2001 at 03:21:09PM -0400, Alexander Viro wrote:
> int fd = open("/dev/ram0", O_RDWR);
> ioctl(fd, BLKFLSBUF);
> ioctl(fd, BLKFLSBUF);

here it is the fix below.

actually it also notably fixes a subtle security problem with the
ramdisk. The fact is that we are asked to read/write from the same
pagecache page that also was the destination of the I/O (ramdisk is
zerocopy), so we actually need a new bitflag to know if this a page
secure, this way we know if we need to bother hiding its contents or
not, if it's a secure page we don't need to do anything. It is a zero
cost bitflag for the nonramdisk case so it shouldn't be a problem and I
cannot imagine a better fix.

Now the only bit left in the ramdisk is a race condition in rmmod, I can
now see why you were converting rd_inode to rd_bdev :).

--- 2.4.10pre11aa1/include/linux/mm.h.~1~	Thu Sep 20 01:20:38 2001
+++ 2.4.10pre11aa1/include/linux/mm.h	Thu Sep 20 03:57:25 2001
@@ -282,6 +282,7 @@
 #define PG_checked		12	/* kill me in 2.5.<early>. */
 #define PG_arch_1		13
 #define PG_reserved		14
+#define PG_secure		15
 
 /* Make it prettier to test the above... */
 #define Page_Uptodate(page)	test_bit(PG_uptodate, &(page)->flags)
@@ -295,6 +296,9 @@
 #define TryLockPage(page)	test_and_set_bit(PG_locked, &(page)->flags)
 #define PageChecked(page)	test_bit(PG_checked, &(page)->flags)
 #define SetPageChecked(page)	set_bit(PG_checked, &(page)->flags)
+
+#define PageSecure(page)	test_bit(PG_secure, &(page)->flags)
+#define SetPageSecure(page)	set_bit(PG_secure, &(page)->flags)
 
 extern void __set_page_dirty(struct page *);
 
--- 2.4.10pre11aa1/mm/filemap.c.~1~	Tue Sep 18 15:39:51 2001
+++ 2.4.10pre11aa1/mm/filemap.c	Thu Sep 20 03:59:00 2001
@@ -621,7 +621,7 @@
 	if (PageLocked(page))
 		BUG();
 
-	flags = page->flags & ~(1 << PG_uptodate | 1 << PG_error | 1 << PG_dirty | 1 << PG_referenced | 1 << PG_arch_1 | 1 << PG_checked);
+	flags = page->flags & ~(1 << PG_uptodate | 1 << PG_error | 1 << PG_dirty | 1 << PG_referenced | 1 << PG_arch_1 | 1 << PG_checked | 1 << PG_secure);
 	page->flags = flags | (1 << PG_locked);
 	page_cache_get(page);
 	page->index = offset;
--- 2.4.10pre11aa1/mm/shmem.c.~1~	Tue Sep 18 02:43:04 2001
+++ 2.4.10pre11aa1/mm/shmem.c	Thu Sep 20 03:59:09 2001
@@ -353,7 +353,7 @@
 		swap_free(*entry);
 		*entry = (swp_entry_t) {0};
 		delete_from_swap_cache_nolock(page);
-		flags = page->flags & ~(1 << PG_uptodate | 1 << PG_error | 1 << PG_referenced | 1 << PG_arch_1);
+		flags = page->flags & ~(1 << PG_uptodate | 1 << PG_error | 1 << PG_referenced | 1 << PG_arch_1 | 1 << PG_secure);
 		page->flags = flags | (1 << PG_dirty);
 		add_to_page_cache_locked(page, mapping, idx);
 		info->swapped--;
--- 2.4.10pre11aa1/mm/swap_state.c.~1~	Tue Sep 18 02:43:04 2001
+++ 2.4.10pre11aa1/mm/swap_state.c	Thu Sep 20 03:59:20 2001
@@ -70,7 +70,7 @@
 		BUG();
 
 	/* clear PG_dirty so a subsequent set_page_dirty takes effect */
-	flags = page->flags & ~(1 << PG_error | 1 << PG_dirty | 1 << PG_arch_1 | 1 << PG_referenced);
+	flags = page->flags & ~(1 << PG_error | 1 << PG_dirty | 1 << PG_arch_1 | 1 << PG_referenced | 1 << PG_secure);
 	page->flags = flags | (1 << PG_uptodate);
 	add_to_page_cache_locked(page, &swapper_space, entry.val);
 }
--- 2.4.10pre11/drivers/block/rd.c	Tue Sep 18 02:42:23 2001
+++ 2.4.10pre11aa1/drivers/block/rd.c	Thu Sep 20 04:22:44 2001
@@ -188,11 +188,23 @@
 
 static int rd_blkdev_pagecache_IO(int rw, struct buffer_head * sbh, int minor)
 {
-	struct address_space * mapping = rd_inode[minor]->i_mapping;
+	struct address_space * mapping;
 	unsigned long index;
-	int offset, size, err = 0;
+	int offset, size, err;
 
-	if (sbh->b_page->mapping == mapping) {
+	err = -EIO;
+	/*
+	 * If we did BLKFLSBUF just before doing read/write,
+	 * we could see a rd_inode before the opener had a chance
+	 * to return from rd_open(), that's ok, as soon as we
+	 * see the inode we can use its i_mapping, and the inode
+	 * cannot go away from under us.
+	 */
+	if (!rd_inode[minor])
+		goto out;
+	err = 0;
+	mapping = rd_inode[minor]->i_mapping;
+	if (sbh->b_page->mapping == mapping && PageSecure(sbh->b_page)) {
 		if (rw != READ)
 			SetPageDirty(sbh->b_page);
 		goto out;
@@ -217,7 +229,7 @@
 
 		hash = page_hash(mapping, index);
 		page = __find_get_page(mapping, index, hash);
-		if (!page && rw != READ) {
+		if (!page) {
 			page = grab_cache_page(mapping, index);
 			err = -ENOMEM;
 			if (!page)
@@ -227,18 +239,40 @@
 		}
 
 		index++;
-		if (!page) {
-			offset = 0;
-			continue;
-		}
 
 		if (rw == READ) {
 			src = kmap(page);
+
+			if (!PageSecure(page)) {
+				clear_page(src);
+				SetPageSecure(page);
+			}
+
 			src += offset;
 			dst = bh_kmap(sbh);
 		} else {
 			dst = kmap(page);
 			dst += offset;
+
+			if (!PageSecure(page)) {
+				unsigned long addr, start, end;
+
+				/* clear around */
+				addr = (unsigned long) dst;
+				if (addr & ~PAGE_CACHE_MASK) {
+					start = addr & PAGE_CACHE_MASK;
+					end = addr;
+					memset((char *) start, 0, end - start);
+				}
+				addr = (unsigned long) dst + count;
+				if (addr & ~PAGE_CACHE_MASK) {
+					start = addr;
+					end = (addr + PAGE_CACHE_SIZE - 1) & PAGE_CACHE_MASK;
+					memset((char *) start, 0, end - start);
+				}
+				SetPageSecure(page);
+			}
+
 			src = bh_kmap(sbh);
 		}
 		offset = 0;
@@ -321,6 +355,13 @@
 				struct block_device * bdev = inode->i_bdev;
 
 				down(&bdev->bd_sem);
+				/*
+				 * We're the only users here, protected by the
+				 * bd_sem, but first check if we didn't just
+				 * flushed the ramdisk.
+				 */
+				if (!rd_inode[minor])
+					goto unlock;
 				if (bdev->bd_openers > 2) {
 					up(&bdev->bd_sem);
 					return -EBUSY;
@@ -328,8 +369,16 @@
 				bdev->bd_openers--;
 				bdev->bd_cache_openers--;
 				iput(rd_inode[minor]);
+				/*
+				 * Make sure the cache is flushed from here
+				 * and not from close(2), somebody
+				 * could reopen the device before we have a
+				 * chance to close it ourself.
+				 */
+				truncate_inode_pages(rd_inode[minor]->i_mapping, 0);
 				rd_inode[minor] = NULL;
 				rd_blocksizes[minor] = rd_blocksize;
+			unlock:
 				up(&bdev->bd_sem);
 			}
 			break;



Andrea

  parent reply	other threads:[~2001-09-20  2:33 UTC|newest]

Thread overview: 110+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2001-09-18  0:08 Linux 2.4.10-pre11 Linus Torvalds
2001-09-17 23:17 ` Marcelo Tosatti
2001-09-18  1:08   ` Marcelo Tosatti
2001-09-18  3:37     ` Andrea Arcangeli
2001-09-18  2:25       ` Marcelo Tosatti
2001-09-18  3:58         ` Andrea Arcangeli
2001-09-18  2:53           ` Marcelo Tosatti
2001-09-18  4:54             ` Andrea Arcangeli
2001-09-18  3:33               ` Marcelo Tosatti
2001-09-18  5:06                 ` Andrea Arcangeli
2001-09-18  3:55                   ` Marcelo Tosatti
2001-09-18  5:32                     ` Andrea Arcangeli
2001-09-18  4:14                       ` Marcelo Tosatti
2001-09-18  5:59                         ` Andrea Arcangeli
2001-09-18  5:00                       ` Marcelo Tosatti
     [not found] ` <20010917211834.A31693@redhat.com>
     [not found]   ` <20010918035055.J698@athlon.random>
2001-09-18  2:02     ` Andrea Arcangeli
     [not found]     ` <20010917221653.B31693@redhat.com>
2001-09-18  2:27       ` Linus Torvalds
2001-09-18  3:14         ` Alan Cox
2001-09-18  3:26         ` Andrea Arcangeli
     [not found]       ` <20010918052201.N698@athlon.random>
2001-09-18  4:01         ` Benjamin LaHaise
2001-09-18  4:39           ` Andrea Arcangeli
2001-09-18  5:04             ` Alan Cox
2001-09-18  5:09               ` Andrea Arcangeli
2001-09-18  5:22             ` Benjamin LaHaise
2001-09-18  5:48               ` Andrea Arcangeli
2001-09-18  5:48 ` Andrew Morton
2001-09-18  6:11   ` Andrea Arcangeli
2001-09-18  5:02     ` Marcelo Tosatti
2001-09-18  6:40       ` Andrea Arcangeli
2001-09-18 16:06         ` Marcelo Tosatti
2001-09-18 19:18           ` Marcelo Tosatti
2001-09-18 21:05             ` Andrea Arcangeli
2001-09-19 13:57               ` Rik van Riel
2001-09-18 10:58   ` Martin Dalecki
2001-09-18  9:31 ` Alexander Viro
2001-09-18  9:39   ` Andrea Arcangeli
2001-09-18  9:44     ` Alexander Viro
2001-09-18  9:57       ` Andrea Arcangeli
2001-09-18 10:02         ` Alexander Viro
2001-09-18 10:17           ` Andrea Arcangeli
2001-09-18 10:28             ` Alexander Viro
2001-09-18 10:35               ` Andrea Arcangeli
2001-09-18 10:52                 ` Alexander Viro
2001-09-18 11:05             ` Helge Hafting
2001-09-18 12:40               ` Andrea Arcangeli
2001-09-18 17:02             ` Linus Torvalds
2001-09-18 16:45   ` Linus Torvalds
2001-09-18 18:19     ` Alexander Viro
2001-09-18 18:27       ` Linus Torvalds
2001-09-18 19:14         ` Andreas Dilger
2001-09-18 19:41           ` Alexander Viro
2001-09-18 20:33           ` Richard Gooch
2001-09-18 20:53             ` Alexander Viro
2001-09-18 21:06             ` Richard Gooch
2001-09-18 21:27               ` Alexander Viro
2001-09-18 19:29         ` Benjamin LaHaise
2001-09-18 20:17         ` Stephan von Krawczynski
2001-09-18 20:33           ` Alan Cox
2001-09-19 13:42           ` Rik van Riel
2001-09-19 14:27             ` Alexander Viro
2001-09-19  2:59         ` Michael Peddemors
2001-09-19 16:11         ` Alexander Viro
2001-09-19 18:25           ` Andrea Arcangeli
2001-09-19 19:21             ` Alexander Viro
2001-09-19 20:55               ` Andrea Arcangeli
2001-09-19 21:17                 ` Alexander Viro
2001-09-19 23:01                   ` Andrea Arcangeli
2001-09-19 23:03                   ` Andrea Arcangeli
2001-09-19 23:30                     ` Alexander Viro
2001-09-19 23:40                       ` Andrea Arcangeli
2001-09-20 13:56                         ` Alexander Viro
2001-09-20 14:38                           ` Chris Mason
2001-09-20 14:50                             ` Alexander Viro
2001-09-20 15:44                               ` Chris Mason
2001-09-20 16:43                                 ` Alexander Viro
2001-09-20 20:54                                   ` [PATCH] fs/block_dev.c cleanup Alexander Viro
2001-09-19 22:15                 ` Linux 2.4.10-pre11 Richard Gooch
2001-09-20  2:34               ` Andrea Arcangeli [this message]
2001-09-20 10:52                 ` Alexander Viro
2001-09-20 18:18                   ` Andrea Arcangeli
2001-09-20 18:33                     ` Alexander Viro
2001-09-20 18:59                       ` Andrea Arcangeli
2001-09-20 20:41                         ` Alexander Viro
2001-09-20 21:18                           ` Andrea Arcangeli
2001-09-20 21:40                             ` Alexander Viro
2001-09-20 22:13                               ` Andrea Arcangeli
2001-09-20 22:20                                 ` Alexander Viro
2001-09-20 22:31                                   ` Andrea Arcangeli
2001-09-20 22:44                                     ` Alexander Viro
2001-09-20 23:03                                       ` Andrea Arcangeli
2001-09-20 23:11                                         ` Alexander Viro
2001-09-21  1:50                                           ` Alexander Viro
2001-09-21  2:42                                             ` Andrea Arcangeli
2001-09-21  3:47                                         ` Andrea Arcangeli
2001-09-21  4:00                                           ` Alexander Viro
2001-09-21  4:06                                             ` Andrea Arcangeli
2001-09-21  4:06                                           ` Andrea Arcangeli
2001-09-21  4:46                                             ` Andrea Arcangeli
2001-09-21  7:09                                               ` Andrea Arcangeli
2001-09-19 20:41             ` Richard Gooch
2001-09-19 13:38       ` Rik van Riel
2001-09-19 16:35       ` Andrea Arcangeli
2001-09-18  3:18 Ed Tomlinson
2001-09-18  2:31 ` Magnus Naeslund(f)
2001-09-18  2:49   ` David B. Stevens
2001-09-18  3:38   ` Ed Tomlinson
2001-09-18  3:15 ` Alan Cox
2001-09-18  4:41   ` H. Peter Anvin
2001-09-18  6:14 Alexei Podtelezhnikov
2001-09-18 13:51 ` Rik van Riel

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20010920043404.K720@athlon.random \
    --to=andrea@suse.de \
    --cc=linux-kernel@vger.kernel.org \
    --cc=torvalds@transmeta.com \
    --cc=viro@math.psu.edu \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).