2000-11-27 04:06:28

by Peter Cordes

[permalink] [raw]
Subject: access() says EROFS even for device files if /dev is mounted RO


While doing some hdparm hacking, after booting with init=/bin/sh, I noticed
that open(1) doesn't work when / is mounted read only. It complains that it
"Cannot open /dev/tty2 read/write"...

I straced it:

execve("/usr/bin/open", ["open"], [/* 13 vars */]) = 0
...
brk(0x804c000) = 0x804c000
open("/dev/tty", O_RDWR) = -1 ENXIO (No such device or address)
open("/dev/tty0", O_RDWR) = 4
ioctl(4, KDGKBTYPE, 0xbffffcdb) = 0
ioctl(4, VT_GETSTATE, 0xbffffda4) = 0
ioctl(4, VT_OPENQRY, 0xbffffd90) = 0
open("/dev/tty2", O_RDWR) = 5
close(5) = 0


access("/dev/tty2", R_OK|W_OK) = -1 EROFS (Read-only file system)


write(2, "Cannot open /dev/tty2 read/write"..., 57) = 57
_exit(5) = ?


However, this is wrong. You _can_ write to device files on read-only
filesystems. (open shouldn't bother calling access(), but the kernel should
definitely give the right answer!) Running
(bash < /dev/tty2 &>/dev/tty2 &)
will work (but for reasons unknown to me it won't do job control or handle
^C, etc.)

I'm pretty sure the problem is in linux/fs/open.c, in sys_access():
...
int res = -EINVAL;
...
dentry = namei(filename);
res = PTR_ERR(dentry);
if (!IS_ERR(dentry)) {
res = permission(dentry->d_inode, mode);
/* SuS v2 requires we report a read only fs too */

if(!res && (mode & S_IWOTH) && IS_RDONLY(dentry->d_inode))

res = -EROFS;
dput(dentry);
}
...
return res;

I think the if( !res ... ) line is the problem. I think the fix is to
add a check that the file is not a device file, socket, named pipe, or a
symlink to a file on a non-readonly FS (unless permission already follow
links? There's probably some file type I didn't think of that needs to get
checked, too.).

I'm don't know what macro to use, since I don't have much kernel hacking
experience (yet ;), so I'll leave the fix for someone who knows what
they're doing :->

BTW, this is in a 2.2.17 kernel on an IA32 machine.

Please CC me on any replies, since I'm not subscribed to the list.

--
#define X(x,y) x##y
Peter Cordes ; e-mail: X([email protected]. , ns.ca)

"The gods confound the man who first found out how to distinguish the hours!
Confound him, too, who in this place set up a sundial, to cut and hack
my day so wretchedly into small pieces!" -- Plautus, 200 BCE


2000-11-27 13:13:37

by Andries Brouwer

[permalink] [raw]
Subject: Re: access() says EROFS even for device files if /dev is mounted RO

On Sun, Nov 26, 2000 at 11:35:22PM -0400, Peter Cordes wrote:

> While doing some hdparm hacking, after booting with init=/bin/sh, I noticed
> that open(1) doesn't work when / is mounted read only.

Already long ago open(1) was renamed to openvt(1), so it may be that
have a very old version. See a recent kbd or console-tools.

> access("/dev/tty2", R_OK|W_OK) = -1 EROFS (Read-only file system)

> However, this is wrong. You _can_ write to device files on read-only
> filesystems. (open shouldn't bother calling access(), but the kernel should
> definitely give the right answer!)

You misunderstand the function of access(). The standard says

[EROFS] write access shall fail if write access is requested
for a file on a read-only file system

It does not look at whether you ask write access to a directory
or a special device file (and whether the filesystem was mounted nodev or not).

So, probably you found a flaw in openvt: the use of access is almost always
a bug - it doesnt tell you what you want to know. You may send me a patch
if you want to.

On the other hand, on recent kernels access() doesnt fail in this situation.
That is a kernel bug, I suppose. Will investigate later.

Andries - [email protected]

2000-11-27 22:17:52

by Rogier Wolff

[permalink] [raw]
Subject: Re: access() says EROFS even for device files if /dev is mounted RO

Andries Brouwer wrote:
> > access("/dev/tty2", R_OK|W_OK) = -1 EROFS (Read-only file system)

> You misunderstand the function of access(). The standard says
>
> [EROFS] write access shall fail if write access is requested
> for a file on a read-only file system

The intent of the "access" call is to tell you if you will be able to
open the given pathname for the requested permissions. That this is
inherently racey is not the fault of the access system call.

The INTENT of this paragraph from the standard is to specify when to
return the error value EROFS. The "for a -=file=-" part to me
indicates that a valid interpretation is that this does not apply to
device nodes.

Roger.

--
** [email protected] ** http://www.BitWizard.nl/ ** +31-15-2137555 **
*-- BitWizard writes Linux device drivers for any device you may have! --*
* There are old pilots, and there are bold pilots.
* There are also old, bald pilots.

2000-11-28 00:40:02

by Andries Brouwer

[permalink] [raw]
Subject: Re: access() says EROFS even for device files if /dev is mounted RO

On Mon, Nov 27, 2000 at 10:47:06PM +0100, Rogier Wolff wrote:
> Andries Brouwer wrote:
> > > access("/dev/tty2", R_OK|W_OK) = -1 EROFS (Read-only file system)
>
> > You misunderstand the function of access(). The standard says
> >
> > [EROFS] write access shall fail if write access is requested
> > for a file on a read-only file system
>
> The intent of the "access" call is to tell you if you will be able to
> open the given pathname for the requested permissions. That this is
> inherently racey is not the fault of the access system call.
>
> The INTENT of this paragraph from the standard is to specify when to
> return the error value EROFS. The "for a -=file=-" part to me
> indicates that a valid interpretation is that this does not apply to
> device nodes.

You optimist!
A standard is not a text that should be read with the attitude
"they write this but I know that they really meant that".
A standard is precise.

In particular it defines the concepts used. For file it says:

File
An object that can be written to, or read from, or both.
A file has certain attributes, including access permissions and type.
File types include regular file, character special file, block special
file, FIFO special file, symbolic link, socket, and directory.
Other types of files may be supported by the implementation.

Andries

2000-11-28 14:35:11

by Rogier Wolff

[permalink] [raw]
Subject: Re: access() says EROFS even for device files if /dev is mounted RO

Andries Brouwer wrote:
> On Mon, Nov 27, 2000 at 10:47:06PM +0100, Rogier Wolff wrote:
> > Andries Brouwer wrote:
> > > > access("/dev/tty2", R_OK|W_OK) = -1 EROFS (Read-only file system)
> >
> > > You misunderstand the function of access(). The standard says
> > >
> > > [EROFS] write access shall fail if write access is requested
> > > for a file on a read-only file system
> >
> > The intent of the "access" call is to tell you if you will be able to
> > open the given pathname for the requested permissions. That this is
> > inherently racey is not the fault of the access system call.
> >
> > The INTENT of this paragraph from the standard is to specify when to
> > return the error value EROFS. The "for a -=file=-" part to me
> > indicates that a valid interpretation is that this does not apply to
> > device nodes.
>
> You optimist!
> A standard is not a text that should be read with the attitude
> "they write this but I know that they really meant that".
> A standard is precise.
>
> In particular it defines the concepts used. For file it says:
>
> File
> An object that can be written to, or read from, or both.
> A file has certain attributes, including access permissions and type.
> File types include regular file, character special file, block special
> file, FIFO special file, symbolic link, socket, and directory.
> Other types of files may be supported by the implementation.

Ok, so if you read the standard carefully you get a bogus result.

Question: Was it meant this way, or did someone just make a mistake
(which happened to slip through and get approved into the standard)?

I happen to think the second.

- Is it desirable to have a write-open of a device on a read-only
fail? I don't think so. You can't open the initial console etc etc.

- Is it desirable to have access (W_OK) and "open-for-write" return
different results? I don't think so.

- Are there other systems that adhere to the standard as written?

Roger.

--
** [email protected] ** http://www.BitWizard.nl/ ** +31-15-2137555 **
*-- BitWizard writes Linux device drivers for any device you may have! --*
* There are old pilots, and there are bold pilots.
* There are also old, bald pilots.

2000-11-28 22:07:49

by Andries Brouwer

[permalink] [raw]
Subject: Re: access() says EROFS even for device files if /dev is mounted RO

On Tue, Nov 28, 2000 at 03:04:31PM +0100, Rogier Wolff wrote:

> Ok, so if you read the standard carefully you get a bogus result.

Why bogus? Things could have been otherwise, but the important
part is that all Unices do things the same way.

> Question: Was it meant this way, or did someone just make a mistake
> (which happened to slip through and get approved into the standard)?
>
> I happen to think the second.
>
> - Is it desirable to have a write-open of a device on a read-only
> fail? I don't think so. You can't open the initial console etc etc.

Nevertheless the standard requires this.

> - Is it desirable to have access (W_OK) and "open-for-write" return
> different results? I don't think so.

Nevertheless there have never been systems where access and open
behaved identically. An easy example is given by directories
that have write access when a w bit is set, but return EISDIR
upon open-for-write.

Andries

2000-11-28 23:27:37

by Peter Cordes

[permalink] [raw]
Subject: Re: access() says EROFS even for device files if /dev is mounted RO

On Mon, Nov 27, 2000 at 01:42:51PM +0100, Andries Brouwer wrote:
> On Sun, Nov 26, 2000 at 11:35:22PM -0400, Peter Cordes wrote:
>
> > While doing some hdparm hacking, after booting with init=/bin/sh, I noticed
> > that open(1) doesn't work when / is mounted read only.
>
> Already long ago open(1) was renamed to openvt(1), so it may be that
> have a very old version. See a recent kbd or console-tools.

In the Debian package, on my Woody system, open is a symlink to openvt.
I've got console-tools 0.2.3. The source uses access here:

/* Maybe we are suid root, and the -c option was given.
Check that the real user can access this VT.
We assume getty has made any in use VT non accessable */
if (access(vtname, R_OK | W_OK) < 0)
{
fprintf(stderr, _("Cannot open %s read/write (%s)\n"), vtname,
strerror(errno));
return (5);
}

That code could be "fixed" to work with the current kernel behaviour by
checking that errno != EROFS. I thought access was supposed to tell you
whether open will work, except for directories, where you do different
things to write to them. (I've seen your messages up to Tue, 28 Nov 2000
22:37:21 +0100, but I'm replying to this one, so you don't have to repeat
your arguments for me :)


> > access("/dev/tty2", R_OK|W_OK) = -1 EROFS (Read-only file system)
>
> > However, this is wrong. You _can_ write to device files on read-only
> > filesystems. (open shouldn't bother calling access(), but the kernel should
> > definitely give the right answer!)
>
> You misunderstand the function of access(). The standard says
>
> [EROFS] write access shall fail if write access is requested
> for a file on a read-only file system
>
> It does not look at whether you ask write access to a directory
> or a special device file (and whether the filesystem was mounted nodev or not).

In the case of a directory, "writing" to it is creating or deleting files
in it: the list of filename:inode changes. If the dir is on a read-only FS,
you can't write, so access() should fail. Writing to a device file doesn't
change anything stored with the file, so it works even if the file is on a
read-only FS.

> So, probably you found a flaw in openvt: the use of access is almost always
> a bug - it doesnt tell you what you want to know. You may send me a patch
> if you want to.

What do you think access is for then? Is it defined by the standard in
such a way that it isn't useful for anything?

I'm of the opinion that Linux should work in the way that is most useful,
as long as that doesn't stop us from running stuff written for other unices.
Unix is mostly good, but parts of it suck. There's no reason to keep the
parts that suck, except when needed for compatibility. Changing the
behaviour of access here would not introduce security holes in anything, so
I think it should be changed to the more sensible way.

(That last paragraph is purely my opinion. I'm pretty sure not everyone
shares it!)

--
#define X(x,y) x##y
Peter Cordes ; e-mail: X([email protected]. , ns.ca)

"The gods confound the man who first found out how to distinguish the hours!
Confound him, too, who in this place set up a sundial, to cut and hack
my day so wretchedly into small pieces!" -- Plautus, 200 BCE

2000-11-28 23:54:11

by Alexander Viro

[permalink] [raw]
Subject: Re: access() says EROFS even for device files if /dev is mounted RO



On Tue, 28 Nov 2000, Peter Cordes wrote:

> I'm of the opinion that Linux should work in the way that is most useful,
> as long as that doesn't stop us from running stuff written for other unices.
> Unix is mostly good, but parts of it suck. There's no reason to keep the
> parts that suck, except when needed for compatibility. Changing the
> behaviour of access here would not introduce security holes in anything, so
> I think it should be changed to the more sensible way.
>
> (That last paragraph is purely my opinion. I'm pretty sure not everyone
> shares it!)

The funny thing being, access() _was_ consistent with open(). Relevant code
(I doubt that AT&T will care):

/*
* open system call
*/
open()
{
register struct inode *ip;
register struct a {
char *fname;
int rwmode;
} *uap;

uap = (struct a *)u.u_ap;
ip = namei(uchar, 0);
if(ip == NULL)
return;
open1(ip, ++uap->rwmode, 0);
}

open1(ip, mode, trf)
register struct inode *ip;
register mode;
{
register struct file *fp;
int i;

if(trf != 2) {
if(mode&FREAD)
access(ip, IREAD);
if(mode&FWRITE) {
access(ip, IWRITE);
if((ip->i_mode&IFMT) == IFDIR)
u.u_error = EISDIR;
}
}
if(u.u_error)
goto out;
....
out:
iput(ip);
}

access(ip, mode)
register struct inode *ip;
{
register m;

m = mode;
if(m == IWRITE) {
if(getfs(ip->i_dev)->s_ronly != 0) {
u.u_error = EROFS;
return(1);
}
....
}

See what happens? open() calls open1(ip, mode, 0), we check that rtf is
not 2 and call access(ip, mode). Which sets u.u_error to EROFS and we
return from open1() (and open()). Failing. So behaviour of access()
was pretty and consistent with open().

When opening devices for write became allowed even for r/o filesystems
access() also had to be changed. And changed it was, back in mid-80s.
It's way older than Linux. Changing one of them and leaving another
as-is means introducing a bug. If standard admits one but not another -
standard is buggy. Again, when 4.*BSD (and 2.*BSD) allowed opening devices
for write even for nodes on r/o filesystems they did change access().

If standard in question doesn't allow such use of open() - too fscking bad.
For standard. Because I'll take the ability to boot from r/o media and
install the system (kinda requires ability to run mkfs) over POSIX/SuS
compliance any day.

<looking into SuS> Oh, lovely...
[EROFS]
The named file resides on a read-only file system and either
O_WRONLY, O_RDWR, O_CREAT (if file does not exist) or O_TRUNC
is set in the oflag argument.

Wonderful. Andries, care to try pushing _that_ kind of standard-compliance?
It _is_ consistent, all right. And utterly wrong.

2000-11-29 12:32:30

by Hugh Dickins

[permalink] [raw]
Subject: Re: access() says EROFS even for device files if /dev is mounted RO

On Tue, 28 Nov 2000, Andries Brouwer wrote:
> On Tue, Nov 28, 2000 at 03:04:31PM +0100, Rogier Wolff wrote:
>
> > Ok, so if you read the standard carefully you get a bogus result.
>
> Why bogus? Things could have been otherwise, but the important
> part is that all Unices do things the same way.

Yes, and I think you'll have difficulty, Andries, finding
any other Unices which interpret the standard as you and
Linux do: Solaris, HP-UX, UnixWare and OpenServer all allow
writing to a device node (or FIFO) on read-only filesystem.

Hugh

2000-11-29 13:10:38

by Alexander Viro

[permalink] [raw]
Subject: Re: access() says EROFS even for device files if /dev is mounted RO



On Wed, 29 Nov 2000, Hugh Dickins wrote:

> On Tue, 28 Nov 2000, Andries Brouwer wrote:
> > On Tue, Nov 28, 2000 at 03:04:31PM +0100, Rogier Wolff wrote:
> >
> > > Ok, so if you read the standard carefully you get a bogus result.
> >
> > Why bogus? Things could have been otherwise, but the important
> > part is that all Unices do things the same way.
>
> Yes, and I think you'll have difficulty, Andries, finding
> any other Unices which interpret the standard as you and
> Linux do: Solaris, HP-UX, UnixWare and OpenServer all allow
> writing to a device node (or FIFO) on read-only filesystem.

Hold on. What do they return upon access()? I've looked through the
available kernel sources and results are:
has r/o filesystems access() open()
v3: no
v5, v6: yes N/A EROFS
v7: yes EROFS EROFS
PDP versions of BSD prior to 2.10, Ultrix 3.1, SysIII, PWB: same as v7
4.4BSD: yes ok ok
{Free,Net,Open}BSD, Linux prior to 2.2.6 and post 2.4.0-test9-pre7: ditto
2.10BSD, 2.10.1BSD, 2.11BSD: ditto
4.3-Tahoe and later: ditto, judging by date of 2.10 release.

What you are saying is that recent SysV variants have
yes ? ok
Nice, but what do they do on access()? If they do not return EROFS for
devices - that's it, standard needs to be fixed and 2.2 should drop the
special-casing in sys_access().

2000-11-29 14:56:05

by Richard B. Johnson

[permalink] [raw]
Subject: Re: access() says EROFS even for device files if /dev is mounted RO

On Wed, 29 Nov 2000, Hugh Dickins wrote:

> On Tue, 28 Nov 2000, Andries Brouwer wrote:
> > On Tue, Nov 28, 2000 at 03:04:31PM +0100, Rogier Wolff wrote:
> >
> > > Ok, so if you read the standard carefully you get a bogus result.
> >
> > Why bogus? Things could have been otherwise, but the important
> > part is that all Unices do things the same way.
>
> Yes, and I think you'll have difficulty, Andries, finding
> any other Unices which interpret the standard as you and
> Linux do: Solaris, HP-UX, UnixWare and OpenServer all allow
> writing to a device node (or FIFO) on read-only filesystem.
>
> Hugh
>

So does Linux. There may be a problem with access(), or a problem
with interpreting what it's supposed to do, but device-files and
FIFOs can be opened for write on a read/only file-system.

Script started on Wed Nov 29 09:14:36 2000
# mount -o remount,ro /alt
# cd /alt
# >foo
bash: foo: Read-only file system
# cd dev
# ls >tty # Write to /dev/tty
FIRE hdb ptybe ptyte sda ttybb ttytb vcs31
GPIB hdb1 ptybf ptytf sda1 ttybc ttytc vcs32
MAKEDEV hdb10 ptyc0 ptyu0 sda10 ttybd ttytd vcs33
MAKEDEV.new hdb11 ptyc1 ptyu1 sda11 ttybe ttyte vcs34
NVRAM hdb12 ptyc2 ptyu2 sda12 ttybf ttytf vcs35
VXI hdb13 ptyc3 ptyu3 sda13 ttyc0 ttyu0 vcs36
[Snipped...]


hda9 ptybd ptytd scd1 ttyba ttyta vcs30
# exit
exit

Script done on Wed Nov 29 09:15:49 2000

Linux `man` states that access() checks, in addition to a file, but
also any "file-system object". However, SunOS 5.5.1 talks about files
only.

It may be that access() is not supposed to be used to check the
accessibility of devices, and that only the Linux man page is incorrect.

Cheers,
Dick Johnson

Penguin : Linux version 2.4.0 on an i686 machine (799.54 BogoMips).

"Memory is like gasoline. You use it up when you are running. Of
course you get it all back when you reboot..."; Actual explanation
obtained from the Micro$oft help desk.


2000-11-29 15:06:18

by Joseph K. Malek

[permalink] [raw]
Subject: Broken NTFS

Hi all,

I have a broken NTFS, due to my own mistake of mounting the
partition RW and moving a file instead of copying it....I've been poking
around for an NTFS editing tool; only to find that this is easier said
than done. Does anyone have an NTFS repair tool for winnt 4 (I already
have the ddk), or any idea where I can find one?

thanks in advance!

--

.oO0Oo.|.oO0Oo.|.oO0Oo.|.oO0Oo.|.oO0Oo.|.oO0Oo.
This message was made from 100% post-consumer
recycled magnetic domains. No binary trees were
destroyed to make it.

2000-11-29 16:18:48

by Hugh Dickins

[permalink] [raw]
Subject: Re: access() says EROFS even for device files if /dev is mounted RO

On Wed, 29 Nov 2000, Alexander Viro wrote:
>
> On Wed, 29 Nov 2000, Hugh Dickins wrote:
>
> > Yes, and I think you'll have difficulty, Andries, finding
> > any other Unices which interpret the standard as you and
> > Linux do: Solaris, HP-UX, UnixWare and OpenServer all allow
> > writing to a device node (or FIFO) on read-only filesystem.
>
> has r/o filesystems access() open()
> What you are saying is that recent SysV variants have
> yes ? ok
> Nice, but what do they do on access()? If they do not return EROFS for
> devices - that's it, standard needs to be fixed and 2.2 should drop the
> special-casing in sys_access().

Sorry, I missed the point at issue here, and what changed when.
Assuming (perhaps wrongly) it's independent of filesystem type,

Solaris yes ok ok
HP-UX yes EROFS ok

I don't have UnixWare or OpenServer at hand to test,
guess UnixWare as Solaris, can report OpenServer tomorrow.
But it looks like a Floridan answer.

Hugh

2000-11-29 16:49:19

by Alexander Viro

[permalink] [raw]
Subject: Re: access() says EROFS even for device files if /dev is mounted RO



On Wed, 29 Nov 2000, Hugh Dickins wrote:

> Sorry, I missed the point at issue here, and what changed when.
> Assuming (perhaps wrongly) it's independent of filesystem type,
>
> Solaris yes ok ok
> HP-UX yes EROFS ok
>
> I don't have UnixWare or OpenServer at hand to test,
> guess UnixWare as Solaris, can report OpenServer tomorrow.
> But it looks like a Floridan answer.

It looks like

AT&T versions up to SysIII (at least), all UCB versions, Ultrix,
4.4BSD-derived systems, Solaris, pre-2.2.6 Linux, current 2.4.* Linux:
if access() says EROFS - open() will also fail with EROFS.

HP-UX and 2.2.6-2.2.18-pre*: give false alarm on access() even though they
allow open().

I would say that the latter group is badly outnumbered _and_ broken. It's one
thing when standard sets the bogus historical behaviour in stone, but
here we introduced bogus behaviour due to misreading the vague language
used in standard. Historically, on systems that allow write access to devices
on r/o filesystems access() doesn't return EROFS for devices. Moreover, that's
what one might reasonably expect and there are programs relying on that.
Principle of minimal surprise and all such...

2000-11-29 16:53:19

by Tigran Aivazian

[permalink] [raw]
Subject: Re: access() says EROFS even for device files if /dev is mounted RO

On Wed, 29 Nov 2000, Hugh Dickins wrote:
> Sorry, I missed the point at issue here, and what changed when.
> Assuming (perhaps wrongly) it's independent of filesystem type,
>
> Solaris yes ok ok
> HP-UX yes EROFS ok
>
> I don't have UnixWare or OpenServer at hand to test,
> guess UnixWare as Solaris, can report OpenServer tomorrow.
> But it looks like a Floridan answer.

Hugh,

The classical interpretation of the access(2) system call is "do the same
type of permission check as open(2) would do but using real uid in the
credentials instead of effective (or on Linux fs) uid". So, the typical
logic of access() would be:

duplicate credential structure
replace euid with ruid (or with fsuid on Linux)
install this tmp credential in the LWP (or task in Linux)
do the same sort of lookupname() as open() would do
restore saved credentials back

All I am saying is that if open on HP/UX allows writing but access denies
it, it is definitely a bug (in HP/UX). Let's remember why access(2) was
invented at all -- to allow setuid-privileged programs to do permission
checks based on real uid instead of relying on open(2) to fail. This
should make it clear that the two (access(2) and open(2)) should behave
identically modulo the euid->ruid transformation.

Regards,
Tigran

PS. This is the sort of dicussion where openly showing snippets of
proprietary UNIX source code would benefit but, alas, we can't...

2000-11-29 16:54:19

by Tigran Aivazian

[permalink] [raw]
Subject: Re: access() says EROFS even for device files if /dev is mounted RO

just to add (obvious!) -- whenever "uid" was mentioned I implied "uid and
gid"...

On Wed, 29 Nov 2000, Tigran Aivazian wrote:

> On Wed, 29 Nov 2000, Hugh Dickins wrote:
> > Sorry, I missed the point at issue here, and what changed when.
> > Assuming (perhaps wrongly) it's independent of filesystem type,
> >
> > Solaris yes ok ok
> > HP-UX yes EROFS ok
> >
> > I don't have UnixWare or OpenServer at hand to test,
> > guess UnixWare as Solaris, can report OpenServer tomorrow.
> > But it looks like a Floridan answer.
>
> Hugh,
>
> The classical interpretation of the access(2) system call is "do the same
> type of permission check as open(2) would do but using real uid in the
> credentials instead of effective (or on Linux fs) uid". So, the typical
> logic of access() would be:
>
> duplicate credential structure
> replace euid with ruid (or with fsuid on Linux)
> install this tmp credential in the LWP (or task in Linux)
> do the same sort of lookupname() as open() would do
> restore saved credentials back
>
> All I am saying is that if open on HP/UX allows writing but access denies
> it, it is definitely a bug (in HP/UX). Let's remember why access(2) was
> invented at all -- to allow setuid-privileged programs to do permission
> checks based on real uid instead of relying on open(2) to fail. This
> should make it clear that the two (access(2) and open(2)) should behave
> identically modulo the euid->ruid transformation.
>
> Regards,
> Tigran
>
> PS. This is the sort of dicussion where openly showing snippets of
> proprietary UNIX source code would benefit but, alas, we can't...
>
>

2000-11-29 17:09:22

by Tigran Aivazian

[permalink] [raw]
Subject: Re: access() says EROFS even for device files if /dev is mounted RO

On Wed, 29 Nov 2000, Alexander Viro wrote:
> Historically, on systems that allow write access to devices
> on r/o filesystems access() doesn't return EROFS for devices. Moreover, that's
> what one might reasonably expect and there are programs relying on that.
> Principle of minimal surprise and all such...

That is precisely the point I was making in my previous email. But both
that email and yours asnwer only one question:

a) should access(2) behave identical to open(2) (with switched uid)? The
answer is Yes.

but the main question still remains unanswered:

b) what should be the return of access(W_OK) (or, the same, open() for
write with switched uid) for devices on a readonly-mounted filesystems?

Should the majority win? I.e. should we say OK, as we do now?

Regards,
Tigran


2000-11-29 17:13:02

by Alexander Viro

[permalink] [raw]
Subject: Re: access() says EROFS even for device files if /dev is mounted RO



On Wed, 29 Nov 2000, Tigran Aivazian wrote:

> All I am saying is that if open on HP/UX allows writing but access denies
> it, it is definitely a bug (in HP/UX). Let's remember why access(2) was
> invented at all -- to allow setuid-privileged programs to do permission
> checks based on real uid instead of relying on open(2) to fail. This
> should make it clear that the two (access(2) and open(2)) should behave
> identically modulo the euid->ruid transformation.

Umm... Correction: open() may fail when access() succeeds (e.g. if you've
got too many opened descriptors, etc.), but it shouldn't be other way
round. However, if access() returns an error open() should also fail.

> Regards,
> Tigran
>
> PS. This is the sort of dicussion where openly showing snippets of
> proprietary UNIX source code would benefit but, alas, we can't...

Considering your previous workplace... How does official SVR{4,5} behave?

2000-11-29 17:20:02

by Hugh Dickins

[permalink] [raw]
Subject: Re: access() says EROFS even for device files if /dev is mounted RO

On Wed, 29 Nov 2000, Tigran Aivazian wrote:
>
> The classical interpretation of the access(2) system call is "do the same
> type of permission check as open(2) would do but using real uid in the
> credentials instead of effective (or on Linux fs) uid".
....
> All I am saying is that if open on HP/UX allows writing but access denies
> it, it is definitely a bug (in HP/UX).

Oh, I agree fervently with you and Al on this,
just felt my opinion could be left out of it.

Hugh

2000-11-29 17:23:32

by Alexander Viro

[permalink] [raw]
Subject: Re: access() says EROFS even for device files if /dev is mounted RO



On Wed, 29 Nov 2000, Tigran Aivazian wrote:

> That is precisely the point I was making in my previous email. But both
> that email and yours asnwer only one question:
>
> a) should access(2) behave identical to open(2) (with switched uid)? The
> answer is Yes.
>
> but the main question still remains unanswered:
>
> b) what should be the return of access(W_OK) (or, the same, open() for
> write with switched uid) for devices on a readonly-mounted filesystems?
>
> Should the majority win? I.e. should we say OK, as we do now?

We should, but we don't. 2.4 does the right thing. 2.2 got the following
change back in 2.2.6:
res = PTR_ERR(dentry);
if (!IS_ERR(dentry)) {
res = permission(dentry->d_inode, mode);
+ /* SuS v2 requires we report a read only fs too */
+ if(!res && (mode & S_IWOTH) && IS_RDONLY(dentry->d_inode))
+ res = -EROFS;
dput(dentry);
}
... and that's what really ticks me off - permission() does the right
tests in case of read-only fs (ignoring the r/o vs. r/w for devices and
FIFOs), but sys_access() explicitly overrides that.

IMO we should revert that in 2.2. HP/UX is probably hopeless - if they
will ever start caring about bogus behaviour access() will not be anywhere
near the top of their list ;-/

2000-11-29 17:27:02

by Tigran Aivazian

[permalink] [raw]
Subject: Re: access() says EROFS even for device files if /dev is mounted RO

On Wed, 29 Nov 2000, Alexander Viro wrote:
> Considering your previous workplace... How does official SVR{4,5} behave?

Under SCO UnixWare 7.1.1 you can happily write to devices in a readonly
mounted (vxfs) filesystem. You can also happily access(W_OK) them. Just
tried, right now (ok, it should have been obvious from the src but I trust
my hands more than my eyes :)

If I read the src right, AIX 4.3 and Monterey64 should do the same. OSR504
looks the same but Hugh knows it a lot better than me (he wrote most of
it!) so I defer to him to verify.

Regards,
Tigran

2000-11-29 17:36:25

by Tigran Aivazian

[permalink] [raw]
Subject: Re: access() says EROFS even for device files if /dev is mounted RO

On Wed, 29 Nov 2000, Tigran Aivazian wrote:

> On Wed, 29 Nov 2000, Alexander Viro wrote:
> > Considering your previous workplace... How does official SVR{4,5} behave?
>
> Under SCO UnixWare 7.1.1 you can happily write to devices in a readonly
> mounted (vxfs) filesystem. You can also happily access(W_OK) them. Just
> tried, right now (ok, it should have been obvious from the src but I trust
> my hands more than my eyes :)

just for the benefit of linux-kernel listeners who may be unaware of what
SVR5 is, which Al mentioned. SCO UnixWare 7.x _is_ the official SVR5 or as
it is called in the boot message "System V Release 5 from SCO".

Regards,
Tigran

2000-11-29 17:48:36

by Andries E. Brouwer

[permalink] [raw]
Subject: Re: access() says EROFS even for device files if /dev is mounted RO

From [email protected] Wed Nov 29 17:52:57 2000

> Should the majority win? I.e. should we say OK, as we do now?

We should, but we don't. 2.4 does the right thing.
2.2 got the following change back in 2.2.6:

res = PTR_ERR(dentry);
if (!IS_ERR(dentry)) {
res = permission(dentry->d_inode, mode);
+ /* SuS v2 requires we report a read only fs too */
+ if(!res && (mode & S_IWOTH) && IS_RDONLY(dentry->d_inode))
+ res = -EROFS;
dput(dentry);
}
... and that's what really ticks me off - permission() does the right
tests in case of read-only fs (ignoring the r/o vs. r/w for devices and
FIFOs), but sys_access() explicitly overrides that.

IMO we should revert that in 2.2. HP/UX is probably hopeless - if they
will ever start caring about bogus behaviour access() will not be anywhere
near the top of their list ;-/

Yes. Alan, it seems we all agree that

--- open.c~ Tue Jan 4 19:12:23 2000
+++ open.c Wed Nov 29 18:14:14 2000
@@ -305,9 +305,6 @@
res = PTR_ERR(dentry);
if (!IS_ERR(dentry)) {
res = permission(dentry->d_inode, mode);
- /* SuS v2 requires we report a read only fs too */
- if(!res && (mode & S_IWOTH) && IS_RDONLY(dentry->d_inode))
- res = -EROFS;
dput(dentry);
}

is a good idea.

Andries

2000-11-29 19:03:53

by Jeff V. Merkey

[permalink] [raw]
Subject: Re: Broken NTFS

On Wed, Nov 29, 2000 at 06:33:36AM -0800, Joseph K. Malek wrote:
> Hi all,
>
> I have a broken NTFS, due to my own mistake of mounting the
> partition RW and moving a file instead of copying it....I've been poking
> around for an NTFS editing tool; only to find that this is easier said
> than done. Does anyone have an NTFS repair tool for winnt 4 (I already
> have the ddk), or any idea where I can find one?
>

I have a tool that will repair the damage caused to an NTFS volume by
Linux. Questions:

1. Did you boot NT on the drive and did it become RAW?
2. Have you run checkdisk against the drive, and if so, what happened?

If you answer yes to #1, you have probably already experienced permanent
data loss on the device. Older NTFS versions on Linux would make changes
to the MFT without clearing the old journal file, then leave the drive
marked as "clean" to NT. What can happen in this case is that NTFS
on W2K will see the logfile, then attempt to roll out the changes. In NT
the MFT is updated real time and the logfile is transacted after the fact.
This can (but not always) cause massive data loss on NTFS drives. Anton
has fixed a lot of these issues on the newer code, but Linux NTFS
is still a very dangerous piece of software to use R/W (R/O works
OK).

Do you need this tool?


Jeff

> thanks in advance!
>
> --
>
> .oO0Oo.|.oO0Oo.|.oO0Oo.|.oO0Oo.|.oO0Oo.|.oO0Oo.
> This message was made from 100% post-consumer
> recycled magnetic domains. No binary trees were
> destroyed to make it.
>
> -
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to [email protected]
> Please read the FAQ at http://www.tux.org/lkml/

2000-12-01 17:43:45

by Olivier Galibert

[permalink] [raw]
Subject: Re: access() says EROFS even for device files if /dev is mounted RO

On Wed, Nov 29, 2000 at 04:40:29PM +0000, Tigran Aivazian wrote:
> b) what should be the return of access(W_OK) (or, the same, open() for
> write with switched uid) for devices on a readonly-mounted filesystems?
>
> Should the majority win? I.e. should we say OK, as we do now?

My gut feeling on this is that when you mount a filesystem readonly
you mean "I don't want the filesystem to be modifiable". Opening a
device for write never modifies the filesystem directly. Devices are
gateways to resources external to the filesystem, the write permission
means something different for them.

Same is for sockets/pipes btw.

And I really wonder how you plan to fsck / if it has been uncleanly
unmounted and includes /dev.

OG.

2000-12-01 18:30:51

by Richard B. Johnson

[permalink] [raw]
Subject: Re: access() says EROFS even for device files if /dev is mounted RO

On Fri, 1 Dec 2000, Olivier Galibert wrote:

> On Wed, Nov 29, 2000 at 04:40:29PM +0000, Tigran Aivazian wrote:
> > b) what should be the return of access(W_OK) (or, the same, open() for
> > write with switched uid) for devices on a readonly-mounted filesystems?
> >
> > Should the majority win? I.e. should we say OK, as we do now?
>
> My gut feeling on this is that when you mount a filesystem readonly
> you mean "I don't want the filesystem to be modifiable". Opening a
> device for write never modifies the filesystem directly. Devices are
> gateways to resources external to the filesystem, the write permission
> means something different for them.
>
> Same is for sockets/pipes btw.
>
> And I really wonder how you plan to fsck / if it has been uncleanly
> unmounted and includes /dev.
>
> OG.
> -

There is a mount option to disallow access to special files, i.e.,
devices; MS_NODEV. A read-only file-system defaults to allowing
access to device special files because it has to. Your console,
your virtual terminal, /dev/tty, the root file-system raw device,
etc., all have to be 'writable' before the root file-system is remounted
read/write.

/dev/special files, are not really 'files'. They are a trick to
associate a major/minor number with a file descriptor. They
cannot be 'extended' or modified because you are not writing to
them, hense `fsck` isn't a problem. The access time and ownership
may have been modified, but that is synchronous.


Cheers,
Dick Johnson

Penguin : Linux version 2.4.0 on an i686 machine (799.54 BogoMips).

"Memory is like gasoline. You use it up when you are running. Of
course you get it all back when you reboot..."; Actual explanation
obtained from the Micro$oft help desk.