linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* DoS with tmpfs #3
@ 2001-08-03 16:34 Ivan Kalvatchev
  2001-08-04  6:07 ` Rik van Riel
  0 siblings, 1 reply; 12+ messages in thread
From: Ivan Kalvatchev @ 2001-08-03 16:34 UTC (permalink / raw)
  To: linux-kernel

Dear Rik van Riel
I don't like stuped jokes.
If you think that there is no problem, mount tmpfs
somewhere on your system and give me shell on it. As
/dev/shm should be tmpfs (Configure.help) and any
process can write (why shared memory should be root
only?) i think that there is a problem.  
Have you ever tried to reproduse the bug.
That are these shits for removing files. Do you know
what is freepages.high or freepages.low?
Oh maybe you have used to work in microsoft and this
is not a bug but a feature :-{
I'm not a kernel hacker. I want to help. I don't want
to mess in your business.
PS
I was able to reproduse the problem after limiting
tmpfs size to 160MB (nr_blocks=40k),not with KDE2 but
with gimp and big picture.

--- Rik van Riel <riel@conectiva.com.br> wrote:
> On Thu, 2 Aug 2001, Ivan Kalvatchev wrote:
> 
> > Yes, i fill all memory and swap.
> > No, limiting filesistem size will make the problem
> > harder to reproduce.
> 
> "Doctor, it hurts when I eat 5 kilos of icecream..."
> 
> When all memory and swap are exhausted, the system
> really cannot do much.  The only thing it could do
> (and should do, with 2.4) is kill some applications.
> 
> Randomly removing files in tmpfs is out of the
> question, as far as I'm concerned, so there really
> isn't much we can do to save the machine's
> performance.
> 
> regards,
> 
> Rik
> --
> Executive summary of a recent Microsoft press
> release:
>    "we are concerned about the GNU General Public
> License (GPL)"
> 
> 
> 		http://www.surriel.com/
> http://www.conectiva.com/
> http://distro.conectiva.com/
> 
//-----------------------------------------------------
Yes, i fill all memory and swap. 
No, limiting filesistem size will make the problem
harder to reproduce. If i make tmpfs to use 160MB and
test it it will be ok(160 ram + 128 swap). But if i
run KDE2 and make test agein it will lock (i'm gona
test it after 1 hour) becouse KDE2 eats all my ram
(160MB).
As i wrote you could decreasing tmpfs free space with
freepages.high(*4kb). 
Wish You Best

--- Rik van Riel <riel@conectiva.com.br> wrote:
> On Wed, 1 Aug 2001, Ivan Kalvatchev wrote:
> 
> > mount tmpfs /mnt/tmp -o tmpfs
> > dd if=/dev/zero if=/mnt/tmp/test
> 
> So you let tmpfs fill up all memory and swap...
> 
> mount -t tmpfs -o nr_blocks=<SIZE> none /mnt/tmp
> 
> Where <SIZE> is the maximum size of tmpfs, in pages.
> 
> regards,
> 
> Rik
> --
> Executive summary of a recent Microsoft press
> release:
>    "we are concerned about the GNU General Public
> License (GPL)"
> 
> 
> 		http://www.surriel.com/
> http://www.conectiva.com/
> http://distro.conectiva.com/
> 
//----------------------original
bugreport-------------------------------
1.  It is possible for every user that have write
access to tmpfs mounted filesystem to lock the system.
2.  Why tmpfs have status of stable? 
This filesystem have limit checking and the output of
df shows that all free ram+swap is usable for this
filesystem. The problem comes then some process tries
to get all free space. 
The problem raise when free memory drops under
freepages.low, then kswapd starts swapping
aggressively. Then the system gets trashed (and maybe
free memory gets under freepages.low. look at SysRq
Meminfo at the bottom). 
I didn't dig in the source but i think that
immediately after one page is swapped out (discarded)
it is filled with data and at some point no more pages
are freed or just freed pages are reallocated. At this
point all non kernel processed are stopped and
computer is working on swap.
In this state i can switch virtual consoles, the hard
is working, and i can type on the screen. The programs
lock when i try to do something with them (maybe when
they allocate memory or when they need swapped
pages?). 
This could be "virtual memory" bug ( no free memory),
but it could be surrounded just by decreasing tmpfs
free space to (freemem - freepages.high).
The same horrible think happens to ramfs, but this
could be expected. Ramfs don't have size check so that
hack cannot be used for it.  In this case ramfs must
be marked as dangerous. 
I had very interesting conversation with some person
in the chat, that could not reproduce the bug, and he
told me to decrease memory that tmpfs could allocate.
But this just make problem harder to reproduce. The
same situation will raise if some process allocates
enough memory. Oh, and him kernel was patched with
some patche2.4.5-ac22.
3. filesystem. virtual memory, swap, kernel
4. Kernel-2.4.7, 2.4.6, 2.4.5, 2.4.4 ... (all with
tmpfs, without one with only shmfs)
5. 
6.
mkdir /mnt/tmp
mount tmpfs /mnt/tmp -o tmpfs 
dd if=/dev/zero if=/mnt/tmp/test

or just use /dev/shm as described  in Configure.help
7. Slackware8 and Slackware7.1
The logs bellow are made in stable state. I cannot
save logs when trashed:( 
I need at least second computer.(maybe later)
The last log if written on paper then on PC.

7.1  
--------------------------------------------------------------------
If some fields are empty or look unusual you may have
an old version.
Compare to the current minimal requirements in
Documentation/Changes.
 
Linux darkstar 2.4.7 #2 Tue Jul 24 19:53:07 EEST 2001
i586 unknown
 
Gnu C                  2.95.3
Gnu make               3.79.1
binutils               2.11.90.0.19
util-linux             2.11f
mount                  2.11b
modutils               2.4.6
e2fsprogs              1.22
reiserfsprogs          3.x.0j
pcmcia-cs              3.1.26
PPP                    2.4.1
Linux C Library        2.2.3
Dynamic linker (ldd)   2.2.3
Procps                 2.0.7
Net-tools              1.60
Kbd                    1.06
Sh-utils               2.0
Modules Loaded         nls_iso8859-1
------------------------------------------------------------------
7.2
------------------------------------------------------------------
processor	: 0
vendor_id	: AuthenticAMD
cpu family	: 5
model		: 6
model name	: AMD-K6tm w/ multimedia extensions
stepping	: 2
cpu MHz		: 200.459
cache size	: 64 KB
fdiv_bug	: no
hlt_bug		: no
f00f_bug	: no
coma_bug	: no
fpu		: yes
fpu_exception	: yes
cpuid level	: 1
wp		: yes
flags		: fpu vme de pse tsc msr mce cx8 mmx
bogomips	: 399.76
------------------------------------------------------------------
7.3
------------------------------------------------------------------
nls_iso8859-1           2880   2 (autoclean)
------------------------------------------------------------------
7.4

00000000-0009ffff : System RAM
000a0000-000bffff : Video RAM area
000c0000-000c7fff : Video ROM
000f0000-000fffff : System ROM
00100000-09ffffff : System RAM
  00100000-001de671 : Kernel code
  001de672-0023509f : Kernel data
e0000000-e3ffffff : S3 Inc. ViRGE/DX or /GX
e4000000-e4ffffff : 3Dfx Interactive, Inc. Voodoo 2
ffff0000-ffffffff : reserved
------------------------------------------------------------------
0000-001f : dma1
0020-003f : pic1
0040-005f : timer
0060-006f : keyboard
0070-007f : rtc
0080-008f : dma page reg
00a0-00bf : pic2
00c0-00df : dma2
00f0-00ff : fpu
0100-0101 : OPL3-SA3
01f0-01f7 : ide0
0213-0213 : isapnp read
02f8-02ff : serial(auto)
0300-0301 : mpu401
03c0-03df : vga+
03f6-03f6 : ide0
03f8-03ff : serial(auto)
0a79-0a79 : isapnp write
0cf8-0cff : PCI conf1
0e80-0e83 : WSS config
0e84-0e87 : MS Sound System
4000-403f : Intel Corporation 82371AB PIIX4 ACPI
5000-501f : Intel Corporation 82371AB PIIX4 ACPI
6400-641f : Intel Corporation 82371AB PIIX4 USB
f000-f00f : Intel Corporation 82371AB PIIX4 IDE
  f000-f007 : ide0
  f008-f00f : ide1
//-----------------------------------------------------------------
7.5
-----------------------------------------------------------------
00:00.0 Host bridge: Intel Corporation 430TX - 82439TX
MTXC (rev 01)
	Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV-
VGASnoop- ParErr- Stepping- SERR- FastB2B-
	Status: Cap- 66Mhz- UDF- FastB2B- ParErr-
DEVSEL=medium >TAbort- <TAbort- <MAbort+ >SERR- <PERR-
	Latency: 32

00:07.0 ISA bridge: Intel Corporation 82371AB PIIX4
ISA (rev 01)
	Control: I/O+ Mem+ BusMaster+ SpecCycle+ MemWINV-
VGASnoop- ParErr- Stepping- SERR- FastB2B-
	Status: Cap- 66Mhz- UDF- FastB2B+ ParErr-
DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR-
	Latency: 0

00:07.1 IDE interface: Intel Corporation 82371AB PIIX4
IDE (rev 01) (prog-if 80 [Master])
	Control: I/O+ Mem- BusMaster+ SpecCycle- MemWINV-
VGASnoop- ParErr- Stepping- SERR- FastB2B-
	Status: Cap- 66Mhz- UDF- FastB2B+ ParErr-
DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR-
	Latency: 32
	Region 4: I/O ports at f000 [size=16]

00:07.2 USB Controller: Intel Corporation 82371AB
PIIX4 USB (rev 01) (prog-if 00 [UHCI])
	Control: I/O+ Mem- BusMaster+ SpecCycle- MemWINV-
VGASnoop- ParErr- Stepping- SERR- FastB2B-
	Status: Cap- 66Mhz- UDF- FastB2B+ ParErr-
DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR-
	Latency: 32
	Interrupt: pin D routed to IRQ 11
	Region 4: I/O ports at 6400 [size=32]

00:07.3 Bridge: Intel Corporation 82371AB PIIX4 ACPI
(rev 01)
	Control: I/O+ Mem+ BusMaster- SpecCycle- MemWINV-
VGASnoop- ParErr- Stepping- SERR- FastB2B-
	Status: Cap- 66Mhz- UDF- FastB2B+ ParErr-
DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR-
	Interrupt: pin ? routed to IRQ 9

00:0b.0 Multimedia video controller: 3Dfx Interactive,
Inc. Voodoo 2 (rev 02)
	Control: I/O- Mem+ BusMaster- SpecCycle- MemWINV-
VGASnoop- ParErr- Stepping- SERR- FastB2B-
	Status: Cap- 66Mhz- UDF- FastB2B+ ParErr- DEVSEL=fast
>TAbort- <TAbort- <MAbort- >SERR- <PERR-
	Region 0: Memory at e4000000 (32-bit, prefetchable)
[size=16M]

00:0c.0 VGA compatible controller: S3 Inc. ViRGE/DX or
/GX (rev 01) (prog-if 00 [VGA])
	Subsystem: S3 Inc. ViRGE/DX
	Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV-
VGASnoop- ParErr- Stepping- SERR- FastB2B-
	Status: Cap- 66Mhz- UDF- FastB2B- ParErr-
DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR-
	Latency: 32 (1000ns min, 63750ns max)
	Interrupt: pin A routed to IRQ 11
	Region 0: Memory at e0000000 (32-bit,
non-prefetchable) [size=64M]
	Expansion ROM at <unassigned> [disabled] [size=64K]
-----------------------------------------------------------------------------
7.6
//
//
7.7 
/proc/meminfo
-----------------------------------------------------------------------------
        total:    used:    free:  shared: buffers: 
cached:
Mem:  163082240 54480896 108601344        0  3723264
40349696
Swap: 139821056        0 139821056
MemTotal:       159260 kB
MemFree:        106056 kB
MemShared:           0 kB
Buffers:          3636 kB
Cached:          39404 kB
SwapCached:          0 kB
Active:           3572 kB
Inact_dirty:     39468 kB
Inact_clean:         0 kB
Inact_target:        0 kB
HighTotal:           0 kB
HighFree:            0 kB
LowTotal:       159260 kB
LowFree:        106056 kB
SwapTotal:      136544 kB
SwapFree:       136544 kB
-----------------------------------------------------------------------------

/proc/swaps
-----------------------------------------------------------------------------
Filename			Type		Size	Used	Priority
/dev/hda4                       partition	136544	0	-1
-----------------------------------------------------------------------------

mount
-----------------------------------------------------------------------------
/dev/hda3 on / type ext2 (rw)
/dev/hda1 on /mnt/hard type vfat (rw)
/dev/hda5 on /mnt/d type vfat (rw)
none on /dev/pts type devpts (rw,gid=5,mode=620)
none on /proc type proc (rw)
tmpfs on /dev/shm type tmpfs (rw)
-----------------------------------------------------------------------------
df
------------------------------------------------------------------
Filesystem           1k-blocks      Used Available
Use% Mounted on
/dev/hda3              1991824   1834820     54188 
98% /
/dev/hda1              2096160   1920352    175808 
92% /mnt/hard
/dev/hda5              3952252   3856036     96216 
98% /mnt/d
tmpfs                   242424         0    242424  
0% /dev/shm

------I wrote this on paper then back on PC. At this
point nothing wok-----
SysRq: Show Memory
Mem_info:
Free pages:        1524kB (    0 kB HighMem)
( Active: 37842, inactive_dirty: 29, inactive_clean:
0, free: 381 (383 766 1149) )
1*4kB 1*8kB 1*16kB 1*32kB 1*64kB 1*128kB 1*256kB
0*512kB 0*1024kB 0*2048kB = 508kB
0*4kB 1*8kB 1*16kB 1*32kB 1*64kB 1*128kB 1*256kB
1*512kB 0*1024kB 0*2048kB = 1016kB)
= 0kB)
Swap cache: add 34136, delete 34136, find 0/0
Free swap:            0kB
40960 pages of RAM
0 pages of HIGHMEM
1147 reserved pages
430 pages shared
0 pages swap cached
0 pages in page table cache
Buffer memory:       60kB
-----------------------------------------
I pressed few times Alt-SysRq-M, and i noted that
Active has changed with +-1



__________________________________________________
Do You Yahoo!?
Make international calls for as low as $.04/minute with Yahoo! Messenger
http://phonecard.yahoo.com/

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: DoS with tmpfs #3
  2001-08-03 16:34 DoS with tmpfs #3 Ivan Kalvatchev
@ 2001-08-04  6:07 ` Rik van Riel
  2001-08-04 18:36   ` Chris Wedgwood
  0 siblings, 1 reply; 12+ messages in thread
From: Rik van Riel @ 2001-08-04  6:07 UTC (permalink / raw)
  To: Ivan Kalvatchev; +Cc: linux-kernel

On Fri, 3 Aug 2001, Ivan Kalvatchev wrote:

> I don't like stuped jokes.

> Oh maybe you have used to work in microsoft and this
> is not a bug but a feature :-{

I don't like insults.  Or people who don't read what
I write but complain about it anyway.

I'll explain things once more. Slowly.

1) you create a tmpfs with a high limit, such that
   (max size tmpfs) + (user memory) > ram + swap

2) you proceed to completely fill up ram and swap

3) now ram and swap is full and the computer has no
   place to put new data

Apart from adding swap space on the fly or going to the
shop to buy you more memory (neither of which is implemented
in the current kernel) there is very little the kernel can
do.

As long as you don't try to use more resources than you
have you will be ok.

regards,

Rik
--
Virtual memory is like a game you can't win;
However, without VM there's truly nothing to lose...

http://www.surriel.com/		http://distro.conectiva.com/

Send all your spam to aardvark@nl.linux.org (spam digging piggy)


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: DoS with tmpfs #3
  2001-08-04  6:07 ` Rik van Riel
@ 2001-08-04 18:36   ` Chris Wedgwood
  2001-08-04 19:53     ` Rik van Riel
  2001-08-06 16:28     ` [Patch] " Christoph Rohland
  0 siblings, 2 replies; 12+ messages in thread
From: Chris Wedgwood @ 2001-08-04 18:36 UTC (permalink / raw)
  To: Rik van Riel; +Cc: Ivan Kalvatchev, linux-kernel

On Sat, Aug 04, 2001 at 03:07:31AM -0300, Rik van Riel wrote:

    1) you create a tmpfs with a high limit, such that
       (max size tmpfs) + (user memory) > ram + swap

maybe, by default, tmpfs should choose a limit of 1/2 ram available or
something?  if this is too small, people can change it



  --cw

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: DoS with tmpfs #3
  2001-08-04 18:36   ` Chris Wedgwood
@ 2001-08-04 19:53     ` Rik van Riel
  2001-08-06 16:28     ` [Patch] " Christoph Rohland
  1 sibling, 0 replies; 12+ messages in thread
From: Rik van Riel @ 2001-08-04 19:53 UTC (permalink / raw)
  To: Chris Wedgwood; +Cc: Ivan Kalvatchev, linux-kernel

On Sun, 5 Aug 2001, Chris Wedgwood wrote:
> On Sat, Aug 04, 2001 at 03:07:31AM -0300, Rik van Riel wrote:
>
>     1) you create a tmpfs with a high limit, such that
>        (max size tmpfs) + (user memory) > ram + swap
>
> maybe, by default, tmpfs should choose a limit of 1/2 ram available or
> something?  if this is too small, people can change it

I guess this would be a decent default; good enough to
keep most people out of trouble and big enough to be
useful.

regards,

Rik
--
Virtual memory is like a game you can't win;
However, without VM there's truly nothing to lose...

http://www.surriel.com/		http://distro.conectiva.com/

Send all your spam to aardvark@nl.linux.org (spam digging piggy)


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [Patch] Re: DoS with tmpfs #3
  2001-08-04 18:36   ` Chris Wedgwood
  2001-08-04 19:53     ` Rik van Riel
@ 2001-08-06 16:28     ` Christoph Rohland
  2001-08-06 16:29       ` [Patch-ac] " Christoph Rohland
  2001-08-07  9:09       ` [Patch2] " Christoph Rohland
  1 sibling, 2 replies; 12+ messages in thread
From: Christoph Rohland @ 2001-08-06 16:28 UTC (permalink / raw)
  To: Chris Wedgwood, Linus Torvalds
  Cc: Rik van Riel, Ivan Kalvatchev, linux-kernel

Hi Chris,

On Sun, 5 Aug 2001, Chris Wedgwood wrote:
> On Sat, Aug 04, 2001 at 03:07:31AM -0300, Rik van Riel wrote:
> 
>     1) you create a tmpfs with a high limit, such that
>        (max size tmpfs) + (user memory) > ram + swap
> 
> maybe, by default, tmpfs should choose a limit of 1/2 ram available
> or something?  if this is too small, people can change it

Actually I would like to give the size mount option a percent
option. So 'mount -t tmpfs -o size=70% ...' would limit the size of
the tmpfs instance to 70% of ram+swap. This would need some changes to
swapoff to first check with tmpfs that there is enough space left and
to swapon to notify tmpfs that there is more room available. This
would make administration really easy but is obviously
2.5 stuff.

Since there are enough persons having trouble with the current
behaviour I append a patch (against 2.4.8-pre4) to implement the
default to be ram/2.

Linus, would you please apply.

Greetings
		Christoph

diff -uNr 8-pre4/mm/shmem.c 8-pre4-def/mm/shmem.c
--- 8-pre4/mm/shmem.c	Sat Jul 21 19:42:11 2001
+++ 8-pre4-def/mm/shmem.c	Mon Aug  6 17:28:31 2001
@@ -754,18 +754,8 @@
 	buf->f_type = TMPFS_MAGIC;
 	buf->f_bsize = PAGE_CACHE_SIZE;
 	spin_lock (&sb->u.shmem_sb.stat_lock);
-	if (sb->u.shmem_sb.max_blocks == ULONG_MAX) {
-		/*
-		 * This is only a guestimate and not honoured.
-		 * We need it to make some programs happy which like to
-		 * test the free space of a file system.
-		 */
-		buf->f_bavail = buf->f_bfree = nr_free_pages() + nr_swap_pages + atomic_read(&buffermem_pages);
-		buf->f_blocks = buf->f_bfree + ULONG_MAX - sb->u.shmem_sb.free_blocks;
-	} else {
-		buf->f_blocks = sb->u.shmem_sb.max_blocks;
-		buf->f_bavail = buf->f_bfree = sb->u.shmem_sb.free_blocks;
-	}
+	buf->f_blocks = sb->u.shmem_sb.max_blocks;
+	buf->f_bavail = buf->f_bfree = sb->u.shmem_sb.free_blocks;
 	buf->f_files = sb->u.shmem_sb.max_inodes;
 	buf->f_ffree = sb->u.shmem_sb.free_inodes;
 	spin_unlock (&sb->u.shmem_sb.stat_lock);
@@ -1013,17 +1003,11 @@
 	return 0;
 }
 
-static int shmem_remount_fs (struct super_block *sb, int *flags, char *data)
+static int shmem_set_size(struct shmem_sb_info *info,
+			  unsigned long max_blocks, unsigned long max_inodes)
 {
 	int error;
-	unsigned long max_blocks, blocks;
-	unsigned long max_inodes, inodes;
-	struct shmem_sb_info *info = &sb->u.shmem_sb;
-
-	max_blocks = info->max_blocks;
-	max_inodes = info->max_inodes;
-	if (shmem_parse_options (data, NULL, &max_blocks, &max_inodes))
-		return -EINVAL;
+	unsigned long blocks, inodes;
 
 	spin_lock(&info->stat_lock);
 	blocks = info->max_blocks - info->free_blocks;
@@ -1043,6 +1027,17 @@
 	return error;
 }
 
+static int shmem_remount_fs (struct super_block *sb, int *flags, char *data)
+{
+	struct shmem_sb_info *info = &sb->u.shmem_sb;
+	unsigned long max_blocks = info->max_blocks;
+	unsigned long max_inodes = info->max_inodes;
+
+	if (shmem_parse_options (data, NULL, &max_blocks, &max_inodes))
+		return -EINVAL;
+	return shmem_set_size(info, max_blocks, max_inodes);
+}
+
 int shmem_sync_file(struct file * file, struct dentry *dentry, int datasync)
 {
 	return 0;
@@ -1053,9 +1048,16 @@
 {
 	struct inode * inode;
 	struct dentry * root;
-	unsigned long blocks = ULONG_MAX;	/* unlimited */
-	unsigned long inodes = ULONG_MAX;	/* unlimited */
+	unsigned long blocks, inodes;
 	int mode   = S_IRWXUGO | S_ISVTX;
+	struct sysinfo si;
+
+	/*
+	 * Per default we only allow half of the physical ram per
+	 * tmpfs instance
+	 */
+	si_meminfo(&si);
+	blocks = inodes = si.totalram / 2;
 
 #ifdef CONFIG_TMPFS
 	if (shmem_parse_options (data, &mode, &blocks, &inodes)) {
@@ -1179,6 +1181,10 @@
 		unregister_filesystem(&tmpfs_fs_type);
 		return PTR_ERR(res);
 	}
+
+	/* The internal instance should not do size checking */
+	if ((error = shmem_set_size(&res->mnt_sb->u.shmem_sb, ULONG_MAX, ULONG_MAX)))
+		printk (KERN_ERR "could not set limits on internal tmpfs\n");
 
 	return 0;
 }


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [Patch-ac] Re: DoS with tmpfs #3
  2001-08-06 16:28     ` [Patch] " Christoph Rohland
@ 2001-08-06 16:29       ` Christoph Rohland
  2001-08-07  9:09       ` [Patch2] " Christoph Rohland
  1 sibling, 0 replies; 12+ messages in thread
From: Christoph Rohland @ 2001-08-06 16:29 UTC (permalink / raw)
  To: Alan Cox; +Cc: linux-kernel

Hi Alan,

On 06 Aug 2001, Christoph Rohland wrote:
> Since there are enough persons having trouble with the current
> behaviour I append a patch (against 2.4.8-pre4) to implement the
> default to be ram/2.

The appended patch is the same against 2.4.7-ac7 plus some further
fixes/cleanups:

- Use PAGE_CACHE_SIZE consistently
- use info->sem instead of inode->i_sem where appropriate
- fix a race in shmem_lock

Greetings
		Christoph


diff -uNr 7-ac7/mm/shmem.c 7-ac7-fix/mm/shmem.c
--- 7-ac7/mm/shmem.c	Mon Aug  6 17:37:28 2001
+++ 7-ac7-fix/mm/shmem.c	Mon Aug  6 18:06:13 2001
@@ -33,7 +33,7 @@
 /* This magic number is used in glibc for posix shared memory */
 #define TMPFS_MAGIC	0x01021994
 
-#define ENTRIES_PER_PAGE (PAGE_SIZE/sizeof(unsigned long))
+#define ENTRIES_PER_PAGE (PAGE_CACHE_SIZE/sizeof(unsigned long))
 
 #define SHMEM_SB(sb) (&sb->u.shmem_sb)
 
@@ -49,7 +49,7 @@
 static spinlock_t shmem_ilock = SPIN_LOCK_UNLOCKED;
 atomic_t shmem_nrpages = ATOMIC_INIT(0);
 
-#define BLOCKS_PER_PAGE (PAGE_SIZE/512)
+#define BLOCKS_PER_PAGE (PAGE_CACHE_SIZE/512)
 
 static void shmem_removepage(struct page *page)
 {
@@ -626,7 +626,7 @@
 	unsigned int idx;
 	struct inode * inode = vma->vm_file->f_dentry->d_inode;
 
-	idx = (address - vma->vm_start) >> PAGE_SHIFT;
+	idx = (address - vma->vm_start) >> PAGE_CACHE_SHIFT;
 	idx += vma->vm_pgoff;
 
 	if (shmem_getpage(inode, idx, &page))
@@ -655,9 +655,9 @@
 	struct page * page;
 	unsigned long idx, size;
 
-	if (info->locked == lock)
-		return;
-	down(&inode->i_sem);
+	down(&info->sem);
+	if (info->locked == lock) 
+		goto out;
 	info->locked = lock;
 	size = (inode->i_size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
 	for (idx = 0; idx < size; idx++) {
@@ -671,7 +671,8 @@
 		}
 		UnlockPage(page);
 	}
-	up(&inode->i_sem);
+out:
+	up(&info->sem);
 }
 
 static int shmem_mmap(struct file * file, struct vm_area_struct * vma)
@@ -962,18 +963,8 @@
 	buf->f_type = TMPFS_MAGIC;
 	buf->f_bsize = PAGE_CACHE_SIZE;
 	spin_lock (&sbinfo->stat_lock);
-	if (sbinfo->max_blocks == ULONG_MAX) {
-		/*
-		 * This is only a guestimate and not honoured.
-		 * We need it to make some programs happy which like to
-		 * test the free space of a file system.
-		 */
-		buf->f_bavail = buf->f_bfree = nr_free_pages() + nr_swap_pages + atomic_read(&buffermem_pages);
-		buf->f_blocks = buf->f_bfree + ULONG_MAX - sbinfo->free_blocks;
-	} else {
-		buf->f_blocks = sbinfo->max_blocks;
-		buf->f_bavail = buf->f_bfree = sbinfo->free_blocks;
-	}
+	buf->f_blocks = sbinfo->max_blocks;
+	buf->f_bavail = buf->f_bfree = sbinfo->free_blocks;
 	buf->f_files = sbinfo->max_inodes;
 	buf->f_ffree = sbinfo->free_inodes;
 	spin_unlock (&sbinfo->stat_lock);
@@ -1129,7 +1120,7 @@
 		return error;
 
 	len = strlen(symname) + 1;
-	if (len > PAGE_SIZE)
+	if (len > PAGE_CACHE_SIZE)
 		return -ENAMETOOLONG;
 		
 	inode = dentry->d_inode;
@@ -1143,10 +1134,10 @@
 		spin_lock (&shmem_ilock);
 		list_add (&info->list, &shmem_inodes);
 		spin_unlock (&shmem_ilock);
-		down(&inode->i_sem);
+		down(&info->sem);
 		page = shmem_getpage_locked(info, inode, 0);
 		if (IS_ERR(page)) {
-			up(&inode->i_sem);
+			up(&info->sem);
 			return PTR_ERR(page);
 		}
 		kaddr = kmap(page);
@@ -1155,7 +1146,7 @@
 		SetPageDirty(page);
 		UnlockPage(page);
 		page_cache_release(page);
-		up(&inode->i_sem);
+		up(&info->sem);
 		inode->i_op = &shmem_symlink_inode_operations;
 	}
 	dir->i_ctime = dir->i_mtime = CURRENT_TIME;
@@ -1253,17 +1244,11 @@
 	return 0;
 }
 
-static int shmem_remount_fs (struct super_block *sb, int *flags, char *data)
+static int shmem_set_size(struct shmem_sb_info *sbinfo,
+			  unsigned long max_blocks, unsigned long max_inodes)
 {
 	int error;
-	unsigned long max_blocks, blocks;
-	unsigned long max_inodes, inodes;
-	struct shmem_sb_info *sbinfo = SHMEM_SB(sb);
-
-	max_blocks = sbinfo->max_blocks;
-	max_inodes = sbinfo->max_inodes;
-	if (shmem_parse_options (data, NULL, &max_blocks, &max_inodes))
-		return -EINVAL;
+	unsigned long blocks, inodes;
 
 	spin_lock(&sbinfo->stat_lock);
 	blocks = sbinfo->max_blocks - sbinfo->free_blocks;
@@ -1283,6 +1268,17 @@
 	return error;
 }
 
+static int shmem_remount_fs (struct super_block *sb, int *flags, char *data)
+{
+	struct shmem_sb_info *sbinfo = &sb->u.shmem_sb;
+	unsigned long max_blocks = sbinfo->max_blocks;
+	unsigned long max_inodes = sbinfo->max_inodes;
+
+	if (shmem_parse_options (data, NULL, &max_blocks, &max_inodes))
+		return -EINVAL;
+	return shmem_set_size(sbinfo, max_blocks, max_inodes);
+}
+
 int shmem_sync_file(struct file * file, struct dentry *dentry, int datasync)
 {
 	return 0;
@@ -1293,10 +1289,17 @@
 {
 	struct inode * inode;
 	struct dentry * root;
-	unsigned long blocks = ULONG_MAX;	/* unlimited */
-	unsigned long inodes = ULONG_MAX;	/* unlimited */
+	unsigned long blocks, inodes;
 	int mode   = S_IRWXUGO | S_ISVTX;
 	struct shmem_sb_info *sbinfo = SHMEM_SB(sb);
+	struct sysinfo si;
+
+	/*
+	 * Per default we only allow half of the physical ram per
+	 * tmpfs instance
+	 */
+	si_meminfo(&si);
+	blocks = inodes = si.totalram / 2;
 
 #ifdef CONFIG_TMPFS
 	if (shmem_parse_options (data, &mode, &blocks, &inodes)) {
@@ -1416,6 +1419,10 @@
 	}
 	shm_mnt = res;
 
+	/* The internal instance should not do size checking */
+	if ((error = shmem_set_size(SHMEM_SB(res->mnt_sb), ULONG_MAX, ULONG_MAX)))
+		printk (KERN_ERR "could not set limits on internal tmpfs\n");
+
 	return 0;
 }
 
@@ -1450,7 +1457,7 @@
 	if (size > (unsigned long long) SHMEM_MAX_BLOCKS << PAGE_CACHE_SHIFT)
 		return ERR_PTR(-EINVAL);
 
-	if (!vm_enough_memory((size) >> PAGE_SHIFT))
+	if (!vm_enough_memory((size) >> PAGE_CACHE_SHIFT))
 		return ERR_PTR(-ENOMEM);
 
 	this.name = name;


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [Patch2] Re: DoS with tmpfs #3
  2001-08-06 16:28     ` [Patch] " Christoph Rohland
  2001-08-06 16:29       ` [Patch-ac] " Christoph Rohland
@ 2001-08-07  9:09       ` Christoph Rohland
  2001-08-08 17:17         ` Ivan Kalvatchev
  1 sibling, 1 reply; 12+ messages in thread
From: Christoph Rohland @ 2001-08-07  9:09 UTC (permalink / raw)
  To: Chris Wedgwood
  Cc: Linus Torvalds, Rik van Riel, Ivan Kalvatchev, linux-kernel

Hi ,

On 06 Aug 2001, Christoph Rohland wrote:
> Since there are enough persons having trouble with the current
> behaviour I append a patch (against 2.4.8-pre4) to implement the
> default to be ram/2.

The following patch is needed on top of the previous one to compile
without CONFIG_TMPFS.

Greetings
		Christoph

--- 8-pre4-def/mm/shmem.c	Tue Aug  7 10:43:14 2001
+++ m8-pre4/mm/shmem.c	Tue Aug  7 10:47:38 2001
@@ -537,6 +537,30 @@
 	return inode;
 }
 
+static int shmem_set_size(struct shmem_sb_info *info,
+			  unsigned long max_blocks, unsigned long max_inodes)
+{
+	int error;
+	unsigned long blocks, inodes;
+
+	spin_lock(&info->stat_lock);
+	blocks = info->max_blocks - info->free_blocks;
+	inodes = info->max_inodes - info->free_inodes;
+	error = -EINVAL;
+	if (max_blocks < blocks)
+		goto out;
+	if (max_inodes < inodes)
+		goto out;
+	error = 0;
+	info->max_blocks  = max_blocks;
+	info->free_blocks = max_blocks - blocks;
+	info->max_inodes  = max_inodes;
+	info->free_inodes = max_inodes - inodes;
+out:
+	spin_unlock(&info->stat_lock);
+	return error;
+}
+
 #ifdef CONFIG_TMPFS
 static ssize_t
 shmem_file_write(struct file *file,const char *buf,size_t count,loff_t *ppos)
@@ -1001,30 +1025,6 @@
 			return 1;
 	}
 	return 0;
-}
-
-static int shmem_set_size(struct shmem_sb_info *info,
-			  unsigned long max_blocks, unsigned long max_inodes)
-{
-	int error;
-	unsigned long blocks, inodes;
-
-	spin_lock(&info->stat_lock);
-	blocks = info->max_blocks - info->free_blocks;
-	inodes = info->max_inodes - info->free_inodes;
-	error = -EINVAL;
-	if (max_blocks < blocks)
-		goto out;
-	if (max_inodes < inodes)
-		goto out;
-	error = 0;
-	info->max_blocks  = max_blocks;
-	info->free_blocks = max_blocks - blocks;
-	info->max_inodes  = max_inodes;
-	info->free_inodes = max_inodes - inodes;
-out:
-	spin_unlock(&info->stat_lock);
-	return error;
 }
 
 static int shmem_remount_fs (struct super_block *sb, int *flags, char *data)


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [Patch2] Re: DoS with tmpfs #3
  2001-08-07  9:09       ` [Patch2] " Christoph Rohland
@ 2001-08-08 17:17         ` Ivan Kalvatchev
  2001-08-09  6:29           ` Helge Hafting
  0 siblings, 1 reply; 12+ messages in thread
From: Ivan Kalvatchev @ 2001-08-08 17:17 UTC (permalink / raw)
  To: linux-kernel


--- Christoph Rohland <cr@sap.com> wrote:
> Hi ,
> 
> On 06 Aug 2001, Christoph Rohland wrote:
> > Since there are enough persons having trouble with
> the current
> > behaviour I append a patch (against 2.4.8-pre4) to
> implement the
> > default to be ram/2.

I didn't look at the chages but i will say this one
more time. Limiting tmpfs size at fixed amount of
space will make the bug harder to reproduce but won't
fix it. The right hack is to limit tmpfs to be with
freepages.high less than available memory(swap+ram).
It won't be hard to code. 
More, there is a big with parameter checking, then i
try to limit with nr_blocks i limit my tmpfs to
160Mpages. So put and sanity check.

__________________________________________________
Do You Yahoo!?
Make international calls for as low as $.04/minute with Yahoo! Messenger
http://phonecard.yahoo.com/

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [Patch2] Re: DoS with tmpfs #3
  2001-08-08 17:17         ` Ivan Kalvatchev
@ 2001-08-09  6:29           ` Helge Hafting
  2001-08-09  7:08             ` Thoughts on tmpfs and swapfs Riley Williams
  2001-08-09 10:22             ` DoS with tmpfs #dynamic Ivan Kalvatchev
  0 siblings, 2 replies; 12+ messages in thread
From: Helge Hafting @ 2001-08-09  6:29 UTC (permalink / raw)
  To: Ivan Kalvatchev, linux-kernel

Ivan Kalvatchev wrote:

> I didn't look at the chages but i will say this one
> more time. Limiting tmpfs size at fixed amount of
> space will make the bug harder to reproduce but won't
> fix it. The right hack is to limit tmpfs to be with
> freepages.high less than available memory(swap+ram).
> It won't be hard to code.

The problem with this is that tmpfs may be mounted before
swap is initialized, so a little less than
swap+ram will become "a little less than just RAM" anyway.

Or do you propose a dynamic limit, changing as swap
is added/removed?  This has problems if some swap is
removed, and suddenly tmpfs usage exceeds its quota.

Helge Hafting

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Thoughts on tmpfs and swapfs
  2001-08-09  6:29           ` Helge Hafting
@ 2001-08-09  7:08             ` Riley Williams
  2001-08-09 10:22             ` DoS with tmpfs #dynamic Ivan Kalvatchev
  1 sibling, 0 replies; 12+ messages in thread
From: Riley Williams @ 2001-08-09  7:08 UTC (permalink / raw)
  To: Helge Hafting; +Cc: Ivan Kalvatchev, Linux Kernel

Hi Helge.

 >> I didn't look at the chages but i will say this one more time.
 >> Limiting tmpfs size at fixed amount of space will make the bug
 >> harder to reproduce but won't fix it. The right hack is to limit
 >> tmpfs to be with freepages.high less than available
 >> memory(swap+ram). It won't be hard to code.

 > The problem with this is that tmpfs may be mounted before swap
 > is initialized, so a little less than swap+ram will become "a
 > little less than just RAM" anyway.

 > Or do you propose a dynamic limit, changing as swap is
 > added/removed? This has problems if some swap is removed, and
 > suddenly tmpfs usage exceeds its quota.

I have to admit that tmpfs is new to me, but I would assume it's a
filing system for temporary files, that works along the lines of a
ramdisk?

If so, I would see the following issues with this idea:

 1. If the idea is to keep temporary files off the hard disk,
    it makes no sense to use swap for them, so any limit on
    the size of tmpfs would need to be limited to the size
    of physical ram.

 2. If the idea is to ensure that temporary files are deleted
    as soon as they are finished with, it makes no sense to
    use physical ram for them, and this effectively becomes
    what I would refer to as swapfs - a filing system where
    the objects within it are stored in swap until such time
    as the last reference is freed, and are then auto-deleted,
    possibly with a short delay to allow for programs run one
    after the other where the first creates a file that is
    read by the second.

 3. If the idea is to do both of the above at the same time,
    any limit on the size of tmpfs would need to be linked to
    the amount of swap present, and the link would need to be
    such that it was not possible to release swap if doing so
    would leave tmpfs over-committed. I can see serious bugs
    with this idea in a hotplug environment.

Comments, anybody?

Best wishes from Riley.


^ permalink raw reply	[flat|nested] 12+ messages in thread

* DoS with tmpfs #dynamic
  2001-08-09  6:29           ` Helge Hafting
  2001-08-09  7:08             ` Thoughts on tmpfs and swapfs Riley Williams
@ 2001-08-09 10:22             ` Ivan Kalvatchev
  1 sibling, 0 replies; 12+ messages in thread
From: Ivan Kalvatchev @ 2001-08-09 10:22 UTC (permalink / raw)
  To: kernelbug


--- Helge Hafting <helgehaf@idb.hist.no> wrote:
> The problem with this is that tmpfs may be mounted
> before
> swap is initialized, so a little less than
> swap+ram will become "a little less than just RAM"
> anyway.
> 
> Or do you propose a dynamic limit, changing as swap
> is added/removed?  This has problems if some swap is
> removed, and suddenly tmpfs usage exceeds its quota.
> 
> Helge Hafting

Yes I mean it. If tmpfs is fixed in any way the
problem will raise. If it is dynamic we have 2
possible ways:
1. First we fill most of tmpfs. Then we start some
program that needs a tones of ram. The program exit
with error and System is stable.
2. We use a lot of memory. The tmpfs decreases it's
size dynamicly and then when trying to fill it up it
return No space on device.

About swap removing. What gonna happen if ram and swap
are full and someone tries to remove the swap. Data
loss? 
P.S.
  Pleace don't forget that ramfs is vulnarable in the
same way. It is rarely used but is DANGEROUS.
Ivan Kalvachev

__________________________________________________
Do You Yahoo!?
Make international calls for as low as $.04/minute with Yahoo! Messenger
http://phonecard.yahoo.com/

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: DoS with tmpfs #3
       [not found] <no.id>
@ 2001-08-03 17:02 ` Alan Cox
  0 siblings, 0 replies; 12+ messages in thread
From: Alan Cox @ 2001-08-03 17:02 UTC (permalink / raw)
  To: Ivan Kalvatchev; +Cc: linux-kernel

> The same horrible think happens to ramfs, but this
> could be expected. Ramfs don't have size check so that
> hack cannot be used for it.  In this case ramfs must
> be marked as dangerous. 

Ramfs and tmpfs in the -ac tree should behave a lot better. The 
fact you see high pages being a factor sounds to me like a VM rather than
a tmpfs bug. Specifically you should have seen KDE apps terminating with
out of memory kills. 

In paticular in the -ac tree ramfs supports setting limits on the max fs
size, which is essential if you want to use it on something like an iPAQ
where ramfs is a real useful fs to have.

tmpfs would I suspect also benefit immensely from quota support

Alan

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2001-08-09 10:23 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-08-03 16:34 DoS with tmpfs #3 Ivan Kalvatchev
2001-08-04  6:07 ` Rik van Riel
2001-08-04 18:36   ` Chris Wedgwood
2001-08-04 19:53     ` Rik van Riel
2001-08-06 16:28     ` [Patch] " Christoph Rohland
2001-08-06 16:29       ` [Patch-ac] " Christoph Rohland
2001-08-07  9:09       ` [Patch2] " Christoph Rohland
2001-08-08 17:17         ` Ivan Kalvatchev
2001-08-09  6:29           ` Helge Hafting
2001-08-09  7:08             ` Thoughts on tmpfs and swapfs Riley Williams
2001-08-09 10:22             ` DoS with tmpfs #dynamic Ivan Kalvatchev
     [not found] <no.id>
2001-08-03 17:02 ` DoS with tmpfs #3 Alan Cox

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).