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
next prev 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 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-18 19:29 ` Benjamin LaHaise
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:41 ` Richard Gooch
2001-09-19 20:55 ` Andrea Arcangeli
2001-09-19 21:17 ` Alexander Viro
2001-09-19 22:15 ` Richard Gooch
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-20 2:34 ` Andrea Arcangeli [this message]
2001-09-20 10:52 ` Linux 2.4.10-pre11 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 13:38 ` Rik van Riel
2001-09-19 16:35 ` Andrea Arcangeli
-- strict thread matches above, loose matches on Subject: below --
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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.