linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Re: setrlimit and RLIM_INFINITY causing fsck failure, 2.4.18
  2002-03-19 17:45 setrlimit and RLIM_INFINITY causing fsck failure, 2.4.18 Peter Hartley
@ 2002-03-19 14:15 ` Andreas Dilger
  2002-03-19 18:20   ` Peter Hartley
  2002-03-19 18:30   ` Alan Cox
  2002-03-19 18:17 ` Alan Cox
  2002-03-20  0:10 ` Theodore Tso
  2 siblings, 2 replies; 10+ messages in thread
From: Andreas Dilger @ 2002-03-19 14:15 UTC (permalink / raw)
  To: Peter Hartley; +Cc: linux-kernel

On Mar 19, 2002  17:45 -0000, Peter Hartley wrote:
> In particular, this means that an e2fsck 1.27 built against such a glibc
> will fail with SIGXFS every time on any block device bigger than 2Gbytes.
> This is because:
> 
>  * e2fsck calls setrlimit(RLIMIT_FSIZE, RLIM_INFINITY) in
>    an attempt to unset the limit. RLIM_INFINITY here is
>    0xFFFFFFFF. This is IMO the Right Thing.

It is only the right thing if the original limit was not 0xFFFFFFFF.
Otherwise, it is just adding to the problem, because the problem only
happens when you try to SET the limit.

> Surely the only Right Things to do in the kernel are (a) invent a new
> setrlimit call that corrects the RLIM_INFINITY value, or (b) have the
> current setrlimit call correct the RLIM_INFINITY value unconditionally.

(c) rlimit should not apply to block devices.

There were patches for this floating around, and I thought they made it
into 2.4.18, but they did not.

I do agree that we should also fix "setrlimit" to do the 0x7FFFFFFF to
0xFFFFFFFF correction.

Cheers, Andreas
--
Andreas Dilger  \ "If a man ate a pound of pasta and a pound of antipasto,
                 \  would they cancel out, leaving him still hungry?"
http://www-mddsp.enel.ucalgary.ca/People/adilger/               -- Dogbert


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

* setrlimit and RLIM_INFINITY causing fsck failure, 2.4.18
@ 2002-03-19 17:45 Peter Hartley
  2002-03-19 14:15 ` Andreas Dilger
                   ` (2 more replies)
  0 siblings, 3 replies; 10+ messages in thread
From: Peter Hartley @ 2002-03-19 17:45 UTC (permalink / raw)
  To: linux-kernel

When setrlimit/getrlimit were changed to take unsigned rather than signed
limits, a new syscall was invented for getrlimit that returned the signed
values that old programs expected. But no new syscall was invented for
setrlimit; both old and new programs come to the same function (in
kernel/sys.c). This was, according to the glibc source, at about 2.3.25
time.

This breaks any old program which tries to set a limit of RLIM_INFINITY.
Such a program will end up passing a 0x7FFFFFFF to sys_setrlimit, which will
be dutifully placed in the current->rlim array. Once there it will
completely fail to compare equal to the kernel's RLIM_INFINITY value,
0xFFFFFFFF.

"Old" in this context means any program linked against a glibc that was
built against 2.2 headers.

In particular, this means that an e2fsck 1.27 built against such a glibc
will fail with SIGXFS every time on any block device bigger than 2Gbytes.
This is because:

 * e2fsck calls setrlimit(RLIMIT_FSIZE, RLIM_INFINITY) in
   an attempt to unset the limit. RLIM_INFINITY here is
   0xFFFFFFFF. This is IMO the Right Thing.
 * glibc knows nothing about the new unsigned limits, because
   it's compiled against 2.2 headers. So it clips the limit
   value to 0x7FFFFFFF to "correct" it before calling the
   setrlimit syscall. This is IMO still the Right Thing,
   because it's trying to call the old syscall as if to run
   a new program on a 2.2 kernel.
 * The kernel writes the 0x7FFFFFFF value uninterpreted into
   the current->rlim array. This is IMO the bug.

Surely the only Right Things to do in the kernel are (a) invent a new
setrlimit call that corrects the RLIM_INFINITY value, or (b) have the
current setrlimit call correct the RLIM_INFINITY value unconditionally.

Answer (b) breaks programs that deliberately set a limit of 0x7FFFFFFF, but
it's less intrusive than answer (a). The patch for (b) is fairly trivial and
I'll rustle one up if people agree it's the Right Thing.

Complete test situation that reproduced the bug: 2.2.20 system (with
glibc-2.2.5, and 2.2.20 headers in /usr/include) compiling a glibc-2.2.5 and
e2fsprogs-1.27 which are then run on a 2.4.18 system. (As e2fsck is
statically linked, it gets the compile host's glibc, of course.) Root fs is
a 4.5Gbyte ext2 on a 5Gbyte Quantum IDE.

So for my purposes I can fix this by upgrading my compile host to a glibc
that's built against 2.4.18 headers, but I still reckon there's a kernel bug
here.

        Peter


PS. Please CC me on replies, as I only read the list on an archive site. Ta.



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

* Re: setrlimit and RLIM_INFINITY causing fsck failure, 2.4.18
  2002-03-19 17:45 setrlimit and RLIM_INFINITY causing fsck failure, 2.4.18 Peter Hartley
  2002-03-19 14:15 ` Andreas Dilger
@ 2002-03-19 18:17 ` Alan Cox
  2002-03-20  0:10 ` Theodore Tso
  2 siblings, 0 replies; 10+ messages in thread
From: Alan Cox @ 2002-03-19 18:17 UTC (permalink / raw)
  To: Peter Hartley; +Cc: linux-kernel

> Answer (b) breaks programs that deliberately set a limit of 0x7FFFFFFF, but
> it's less intrusive than answer (a). The patch for (b) is fairly trivial and
> I'll rustle one up if people agree it's the Right Thing.

(b) is a standards violation

> So for my purposes I can fix this by upgrading my compile host to a glibc
> that's built against 2.4.18 headers, but I still reckon there's a kernel bug
> here.

Its a compatibility bug. The original submission when it was changed did
try to address this. Originally its a kernel bug because the standards
always said that it was unsigned


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

* Re: setrlimit and RLIM_INFINITY causing fsck failure, 2.4.18
  2002-03-19 14:15 ` Andreas Dilger
@ 2002-03-19 18:20   ` Peter Hartley
  2002-03-19 18:44     ` Alan Cox
  2002-03-19 18:30   ` Alan Cox
  1 sibling, 1 reply; 10+ messages in thread
From: Peter Hartley @ 2002-03-19 18:20 UTC (permalink / raw)
  To: Andreas Dilger; +Cc: linux-kernel

Andreas Dilger wrote:
> On Mar 19, 2002  17:45 -0000, Peter Hartley wrote:
> > In particular, this means that an e2fsck 1.27 built against such a glibc
> > will fail with SIGXFS every time on any block device bigger than
2Gbytes.
> > This is because:
> >
> >  * e2fsck calls setrlimit(RLIMIT_FSIZE, RLIM_INFINITY) in
> >    an attempt to unset the limit. RLIM_INFINITY here is
> >    0xFFFFFFFF. This is IMO the Right Thing.
>
> It is only the right thing if the original limit was not 0xFFFFFFFF.
> Otherwise, it is just adding to the problem, because the problem only
> happens when you try to SET the limit.

True. (Old programs *will* perceive the value as 0xFFFFFFFF if it is
RLIM_INFINITY; the kernel clips it to 0x7FFFFFFF in sys_old_getrlimit() but
glibc expands it again in __new_getrlimit().)

> > Surely the only Right Things to do in the kernel are (a) invent a new
> > setrlimit call that corrects the RLIM_INFINITY value, or (b) have the
> > current setrlimit call correct the RLIM_INFINITY value unconditionally.
>
> (c) rlimit should not apply to block devices.
>
> There were patches for this floating around, and I thought they made it
> into 2.4.18, but they did not.

Looking a bit closer at the particular SIGXFS that kills fsck (in
generic_file_write) there's some S_ISBLK stuff going on just below.

Is the fix just as simple as: (untested) (and with a mailer than mangles
tabs)

--- filemap.c~ Mon Feb 25 19:38:13 2002
+++ filemap.c Tue Mar 19 18:20:40 2002
@@ -2885,9 +2885,9 @@
   * Check whether we've reached the file size limit.
   */
  err = -EFBIG;

- if (limit != RLIM_INFINITY) {
+ if (limit != RLIM_INFINITY && !S_ISBLK(inode->i_mode)) {
   if (pos >= limit) {
    send_sig(SIGXFSZ, current, 0);
    goto out;
   }

All this rlimit stuff is a bit wonky in the presence of 64-bit file sizes
anyway. Perhaps if we fix just the block-device case we can brush the rest
under the carpet?

        Peter



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

* Re: setrlimit and RLIM_INFINITY causing fsck failure, 2.4.18
  2002-03-19 14:15 ` Andreas Dilger
  2002-03-19 18:20   ` Peter Hartley
@ 2002-03-19 18:30   ` Alan Cox
  1 sibling, 0 replies; 10+ messages in thread
From: Alan Cox @ 2002-03-19 18:30 UTC (permalink / raw)
  To: Andreas Dilger; +Cc: Peter Hartley, linux-kernel

> (c) rlimit should not apply to block devices.

Also correct.

> There were patches for this floating around, and I thought they made it
> into 2.4.18, but they did not.

I saw some stuff. I may even have looked at merging it with -ac. Not sure
if it got fixed finally there or not. A resend of those diffs would be
good.

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

* Re: setrlimit and RLIM_INFINITY causing fsck failure, 2.4.18
  2002-03-19 18:20   ` Peter Hartley
@ 2002-03-19 18:44     ` Alan Cox
  2002-03-20 10:12       ` [PATCH] " Peter Hartley
  0 siblings, 1 reply; 10+ messages in thread
From: Alan Cox @ 2002-03-19 18:44 UTC (permalink / raw)
  To: Peter Hartley; +Cc: Andreas Dilger, linux-kernel

> Is the fix just as simple as: (untested) (and with a mailer than mangles
> tabs)

Test it and see 8)

> All this rlimit stuff is a bit wonky in the presence of 64-bit file sizes
> anyway. Perhaps if we fix just the block-device case we can brush the rest
> under the carpet?

For 64bit platforms life is ok, for the x86 rlimit64 might make sense. Im
not sure if it ever appeared in any standards 8(


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

* Re: setrlimit and RLIM_INFINITY causing fsck failure, 2.4.18
  2002-03-19 17:45 setrlimit and RLIM_INFINITY causing fsck failure, 2.4.18 Peter Hartley
  2002-03-19 14:15 ` Andreas Dilger
  2002-03-19 18:17 ` Alan Cox
@ 2002-03-20  0:10 ` Theodore Tso
  2002-03-20  2:04   ` Benjamin LaHaise
  2002-03-20 10:09   ` Peter Hartley
  2 siblings, 2 replies; 10+ messages in thread
From: Theodore Tso @ 2002-03-20  0:10 UTC (permalink / raw)
  To: Peter Hartley; +Cc: linux-kernel

On Tue, Mar 19, 2002 at 05:45:24PM -0000, Peter Hartley wrote:
> 
> But no new syscall was invented for setrlimit; both old and new
> programs come to the same function (in kernel/sys.c). This was,
> according to the glibc source, at about 2.3.25 time.

Yes.  This resulted in a very nasty ABI change, since in effect
RLIM_INFINITY changed on us.  It's rather embarassing, actually, since
this is the sort of thing that I generally complain about happening
with various user-land libraries (such as glibc, ncurses, libgal,
etc.) and I used to say that kernel programmers were generally a lot
more careful about such things.  Well, I can't say that any more....

> 
>  * e2fsck calls setrlimit(RLIMIT_FSIZE, RLIM_INFINITY) in
>    an attempt to unset the limit. RLIM_INFINITY here is
>    0xFFFFFFFF. This is IMO the Right Thing.

I did this because I was tired of bug reports from users who were
losing due to other programs that were attempting to set the limit of
RLIMIT_FSIZE, and screwing up because they were compiled with 2.2
headers.  (Or rather, were compiled with a glibc which was compiled
against 2.2 headers.)n

>  * glibc knows nothing about the new unsigned limits, because
>    it's compiled against 2.2 headers. So it clips the limit
>    value to 0x7FFFFFFF to "correct" it before calling the
>    setrlimit syscall. This is IMO still the Right Thing,
>    because it's trying to call the old syscall as if to run
>    a new program on a 2.2 kernel.

Unfortunately, all of my testing was done under systems where the
glibc was already compiled under 2.4 headers, so I didn't realize that
glibc would try to be "helpful" and correct the limit used by rlimit.
(In other words, the e2fsprogs workaround was only worked in the case
where other programs were losing because they were using the 2.2
kernel ABI, but the libc was using the 2.4 kernel ABI.  Sigh.)

So obviously, the way I need to fix e2fsprogs is to fork a child
process, check to see whether or not I can safely call setrlimit, and
if not, exit without trying to set it.  :-( This is a really dirty
hack, but I don't see any other way fixing user-land programs that are
trying to work around this ABI mess.  (And since distributions are
already shipping 2.4 kernels, this is a mess that userspace programs
are going to have to deal with for a non-trivial amount of time.)

> Surely the only Right Things to do in the kernel are (a) invent a new
> setrlimit call that corrects the RLIM_INFINITY value, or (b) have the
> current setrlimit call correct the RLIM_INFINITY value unconditionally.
> 
> Answer (b) breaks programs that deliberately set a limit of 0x7FFFFFFF, but
> it's less intrusive than answer (a). The patch for (b) is fairly trivial and
> I'll rustle one up if people agree it's the Right Thing.

I think we should do (b) as soon as possible, but it'll still be a
program since most distributions are either shipping CD-ROM's with 2.4
kernels on them already (sigh).

The other fix is that the filesize limit *really* shouldn't apply to
block devices.  We should probably do both fixes.

							- Ted

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

* Re: setrlimit and RLIM_INFINITY causing fsck failure, 2.4.18
  2002-03-20  0:10 ` Theodore Tso
@ 2002-03-20  2:04   ` Benjamin LaHaise
  2002-03-20 10:09   ` Peter Hartley
  1 sibling, 0 replies; 10+ messages in thread
From: Benjamin LaHaise @ 2002-03-20  2:04 UTC (permalink / raw)
  To: Theodore Tso, Peter Hartley, linux-kernel

On Tue, Mar 19, 2002 at 07:10:18PM -0500, Theodore Tso wrote:
> The other fix is that the filesize limit *really* shouldn't apply to
> block devices.  We should probably do both fixes.

The filesize limit did not apply to block devices until ~2.4.10, so 
this manifestation of the bug is a recent introduction.

The whole rlimit mess itself is a might bit awful since it and the 
nonstandard 2.2 file size extensions resulted in a horribly conflicting 
glob of problems.  *sigh*

		-ben
-- 
"A man with a bass just walked in,
 and he's putting it down
 on the floor."

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

* Re: setrlimit and RLIM_INFINITY causing fsck failure, 2.4.18
  2002-03-20  0:10 ` Theodore Tso
  2002-03-20  2:04   ` Benjamin LaHaise
@ 2002-03-20 10:09   ` Peter Hartley
  1 sibling, 0 replies; 10+ messages in thread
From: Peter Hartley @ 2002-03-20 10:09 UTC (permalink / raw)
  To: Theodore Tso; +Cc: linux-kernel

Theodore Tso wrote:
> On Tue, Mar 19, 2002 at 05:45:24PM -0000, Peter Hartley wrote:
> >  * glibc knows nothing about the new unsigned limits, because
> >    it's compiled against 2.2 headers. So it clips the limit
> >    value to 0x7FFFFFFF to "correct" it before calling the
> >    setrlimit syscall. This is IMO still the Right Thing,
> >    because it's trying to call the old syscall as if to run
> >    a new program on a 2.2 kernel.
>
> Unfortunately, all of my testing was done under systems where the
> glibc was already compiled under 2.4 headers, so I didn't realize that
> glibc would try to be "helpful" and correct the limit used by rlimit.
> (In other words, the e2fsprogs workaround was only worked in the case
> where other programs were losing because they were using the 2.2
> kernel ABI, but the libc was using the 2.4 kernel ABI.  Sigh.)
>
> So obviously, the way I need to fix e2fsprogs is to fork a child
> process, check to see whether or not I can safely call setrlimit, and
> if not, exit without trying to set it.  :-( This is a really dirty
> hack, but I don't see any other way fixing user-land programs that are
> trying to work around this ABI mess.

I don't think you can tell whether it's safe to call setrlimit (unless you
mean having e2fsck call the *syscall* directly, which is icky). The
getrlimit in a 2.2-headered glibc returns 0x7FFFFFFF whether the kernel's
idea of the value is 0x7FFFFFFF or 0xFFFFFFFF. I still like Andreas Dilger's
idea that you only set the limit if it's not already RLIM_INFINITY as
returned by glibc.

If PAM, or something else, has already set the 0x7FFFFFFF value, there
appears to be no way of setting the 0xFFFFFFFF value via a 2.2-headered
glibc :-( and you'd need to go for the syscall :-((

        Peter



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

* [PATCH] Re: setrlimit and RLIM_INFINITY causing fsck failure, 2.4.18
  2002-03-19 18:44     ` Alan Cox
@ 2002-03-20 10:12       ` Peter Hartley
  0 siblings, 0 replies; 10+ messages in thread
From: Peter Hartley @ 2002-03-20 10:12 UTC (permalink / raw)
  To: Alan Cox; +Cc: Andreas Dilger, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 322 bytes --]

AC wrote:
> Test it and see 8)

OK, did do. Patch attached. The occurrence in filemap.c was the one killing
fsck, but I went looking for other occurrences of SIGXFS and made sure they
did the right thing too.

This doesn't address any other wonkiness of rlimit, it just stops it
applying to block devices.

        Peter


[-- Attachment #2: sigxfs-vs-blkdev.patch --]
[-- Type: application/octet-stream, Size: 1737 bytes --]

diff -u3 -r linux/fs/buffer.c linux.pdh/fs/buffer.c
--- linux/fs/buffer.c	Mon Feb 25 19:38:08 2002
+++ linux.pdh/fs/buffer.c	Tue Mar 19 19:23:43 2002
@@ -1834,7 +1834,7 @@
 
 	err = -EFBIG;
         limit = current->rlim[RLIMIT_FSIZE].rlim_cur;
-	if (limit != RLIM_INFINITY && size > (loff_t)limit) {
+	if (limit != RLIM_INFINITY && size > (loff_t)limit && !S_ISBLK(inode->i_mode)) {
 		send_sig(SIGXFSZ, current, 0);
 		goto out;
 	}
diff -u3 -r linux/mm/filemap.c linux.pdh/mm/filemap.c
--- linux/mm/filemap.c	Mon Feb 25 19:38:13 2002
+++ linux.pdh/mm/filemap.c	Tue Mar 19 19:21:17 2002
@@ -2885,8 +2885,8 @@
 	 * Check whether we've reached the file size limit.
 	 */
 	err = -EFBIG;
-	
-	if (limit != RLIM_INFINITY) {
+
+	if (limit != RLIM_INFINITY && !S_ISBLK(inode->i_mode)) {
 		if (pos >= limit) {
 			send_sig(SIGXFSZ, current, 0);
 			goto out;
diff -u3 -r linux/mm/memory.c linux.pdh/mm/memory.c
--- linux/mm/memory.c	Mon Feb 25 19:38:13 2002
+++ linux.pdh/mm/memory.c	Tue Mar 19 19:22:45 2002
@@ -1059,7 +1059,7 @@
 
 do_expand:
 	limit = current->rlim[RLIMIT_FSIZE].rlim_cur;
-	if (limit != RLIM_INFINITY && offset > limit)
+	if (limit != RLIM_INFINITY && offset > limit && !S_ISBLK(inode->i_mode))
 		goto out_sig;
 	if (offset > inode->i_sb->s_maxbytes)
 		goto out;
diff -u3 -r linux/mm/shmem.c linux.pdh/mm/shmem.c
--- linux/mm/shmem.c	Mon Feb 25 19:38:14 2002
+++ linux.pdh/mm/shmem.c	Tue Mar 19 19:23:17 2002
@@ -780,7 +780,7 @@
 	 * Check whether we've reached the file size limit.
 	 */
 	err = -EFBIG;
-	if (limit != RLIM_INFINITY) {
+	if (limit != RLIM_INFINITY && !S_ISBLK(inode->i_mode)) {
 		if (pos >= limit) {
 			send_sig(SIGXFSZ, current, 0);
 			goto out;

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

end of thread, other threads:[~2002-03-20 10:36 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-03-19 17:45 setrlimit and RLIM_INFINITY causing fsck failure, 2.4.18 Peter Hartley
2002-03-19 14:15 ` Andreas Dilger
2002-03-19 18:20   ` Peter Hartley
2002-03-19 18:44     ` Alan Cox
2002-03-20 10:12       ` [PATCH] " Peter Hartley
2002-03-19 18:30   ` Alan Cox
2002-03-19 18:17 ` Alan Cox
2002-03-20  0:10 ` Theodore Tso
2002-03-20  2:04   ` Benjamin LaHaise
2002-03-20 10:09   ` Peter Hartley

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