This is the mail archive of the
ecos-patches@sourceware.org
mailing list for the eCos project.
Re: RAMFS fixes: file permissions and lseek()
- From: Dan Jakubiec <dan dot jakubiec at systech dot com>
- To: Andrew Lunn <andrew at lunn dot ch>
- Cc: eCos Patch List <ecos-patches at sources dot redhat dot com>
- Date: Mon, 03 Oct 2005 14:19:08 -1000
- Subject: Re: RAMFS fixes: file permissions and lseek()
- References: <433C8BE7.5030403@systech.com> <20051002141450.GC10088@lunn.ch>
Hi Andrew,
Thanks for the review and the comments. Your suggestions look like good
improvements. My responses and questions:
Andrew Lunn wrote:
OK. But i really thing it is the application which is broken. eCos has
no concept of filesystem security, there is no way to set permissions,
owners, groups etc. So any application which uses this is probably
broken.
Well, perhaps... But consider this: we ran into this permissions
problem when porting a POSIX application to eCos. The application
happened to be the eCos mk_romfs.c host-side utility for generating
ROMFS images. [our eCos environment needs the ability to generate ROMFS
images at runtime based on our RAMFS root filesystem]
This POSIX app (like others I'm sure), checks each file to make sure it
is readable prior to building its ROMFS image. Without the fix, the
POSIX app won't proceed with the ROMFS generation because it expects
that its planned open() calls will fail. We could hack mk_romfs to
behave differently under eCos, but I think there is a more elegant solution.
The RAMFS fix is rather reasonable because although file/directory
permissions can not be *set* (nor enforced), than can still be read by
applications and therefore should reflect the reality of the file
security. In the eCos RAMFS filesystem:
1. All files are readable and writable by anyone, so files should at
minimum report a permissions mask of 666.
2. The executable bit is debatable. However, I don't think it hurts
to set it so I did. This will keep happy those ported apps which
expect to find executable files with correct perms. Of course,
these files aren't truly executable. If you think 666 is more
logical here, then I'm open to your thinking. 777 just seemed
more all-encompassing.
3. For directories: all directories are readable, writable, and
viewable by all. So 777 seemed the most appropriate.
4. A permission mask of 000 seems wrong on all accounts. Because
although it won't protect the files from being used, it will
misrepresent their true read/write characteristics in the stat() call.
I fixed this differently, in a more efficient way. For the default
"SIMPLE" allocation mechanism, there was already a memzero setting the
contents to zero. It just needed tweeking a little. For the "BLOCK"
allocation mechanism i implemented true holes. So you can do something
like
fd = open("foobar", O_RDWR);
lseek(fd, 1024*1024, SEEK_SET);
write(fd, '1', 1);
and it will only allocation one 256 byte block, not a megabyte.
This sound like a better fix, but I had once concern. I haven't
familiarized myself with the BLOCK approach, so perhaps you can fill in
the blanks here. According to POSIX, once you write() to the file at
the post-EOF position, all reads between the old EOF and the new write
data must now return byte 0x00 in each unwritten location. In other
words, the act of the write() is supposed to increase the file size by
the number of write bytes plus the gap size. In other words:
1. fd = open()
2. write(fd, "hi", 2); //lpos at 2
3. lseek(fd, 4, SEEK_SET); //lpos at 4
4. write(fd, "you", 3); //lpos at 7
5. lseek(fd, 0, SEEK_SET); //lpos at 0
6. read(fd, buffer, 100) ==> read() returns 7, buffer contains
"hi\x00\x00you"
I will study your improvements, but will they indeed return the 0x00
bytes as required by POSIX?
Thanks,
--
Dan Jakubiec
Systech Corporation