Thursday, April 30, 2020

Re: RCS file ownership?

Being neither a C programmer nor a Texinfo fan, checking GNU RCS is a
bit painful, and my conclusions aren't guaranteed.


AFAICT, GNU RCS (v5.9.4, ca. 2015, examined) creates a temp file,
unlinks the target file, then renames the temp file. I beleve this
guarantees(-ish, modulo "special" filesystems including NFS and
FreeBSD's directory-SUID behaviour) that resulting file ownership =
euid.

The GNU docs mention the repo owner in passing a few times but do not
have a section describing multi-user operation.

The Tichy docs also don't mention file ownership. I'm trying to review
the O'Donovan book, too, but it's been a long time since I had to tool
up to handle raw PS... not quite there yet.

Purdue RCS appears to be the direct ancestor of GNU RCS.

I'm not sure which other implementations you'd be worried about - I
thought OpenBSD's RCS was the direct descendant of NetBSD's and shares
common lineage with the other *BSDs?

All in all, it looks like RCS and its docs were written in the era when
UNIX machines were - more or less by universally - used by multiple
people, and you just had an innate sense of how multi-user file
ownership would work. Most of my UNIX machines now resemble appliances,
and exactly zero of them are multi-user in the classical sense.

-Adam


On 2020-04-29 21:53, Theo de Raadt wrote:
> Sorry, but my mail goes further.
>
> It says it should be correct. For some definition of correct. It
> should either behave somehow for a logical reason, or it should behave
> in the historical fashion. Or once the historical behaviour is looked
> at, if there is an argument that is wrong, then it should be changed
> with logic about "this is an improvement" backing the argument.
>
> I think it is wrong to document how *this* rcs implimentation behaves,
> without comparing it against others.
>
> My guess is 50% that the others don't unlink, but rewrite the file.
>
> And the changes it might require to be compatible are not substantial.
> At most a 20 line diff, to a few programs in the family.
>
> athompso@athompso.net wrote:
>
>> Thank you for that detail!
>>
>> Addressing this one corner case would require substantial changes, I
>> think. Not worth
>> it, in my opinion.
>>
>> I think it would be worthwhile describing the multi-user mode of
>> operation of RCS in
>> the manual, as it's currently completely absent/omitted. Patch coming
>> soon, maybe
>> tomorrow if I can make time.
>>
>> -Adam
>>
>> On Apr. 29, 2020 21:28, Theo de Raadt <deraadt@openbsd.org> wrote:
>>
>> athompso@athompso.net wrote:
>>
>> > Heh, good point. Didn't even occur to me because as it happens, I
>> am
>> > running as root and would like to not change the ownership.-Adam
>> > On Apr. 29, 2020 13:32, Anders Andersson <pipatron@gmail.com>
>> wrote:
>> >
>> > On Wed, Apr 29, 2020 at 7:46 PM Adam Thompson
>> <athompso@athompso.net>
>> > wrote:
>> > >
>> > > When I use co(1) with "-l" to check out a file (and/or "ci -l")
>> is
>> > there
>> > > any way to preserve file ownership and *not* have it reset to
>> the
>> > user
>> > > running co(1) or ci(1)?
>> > > I don't see anything in rcs(1), co(1) or ci(1) that even
>> mentions
>> > the
>> > > fact that the file will wind up owned by the user running the
>> > command.
>> > > Ideas? Pointers to documentation?
>> >
>> > How could it possibly do anything else unless you always run co
>> as
>> > root?
>>
>> Our rcs tools do:
>>
>> 52628 co RET kbind 0
>> 52628 co CALL unlink(0x7f7ffffed1f3)
>> 52628 co NAMI "ls.c"
>> 52628 co RET unlink -1 errno 2 No such file or directory
>> 52628 co CALL open
>> (0x7f7ffffed1f3,0x601<O_WRONLY|O_CREAT|O_TRUNC>,0100444<S_IRUSR\
>> |S_IRGRP|S_IROTH|S_IFREG>)
>> 52628 co NAMI "ls.c"
>> 52628 co RET open 4
>> 52628 co CALL kbind(0x7f7ffffec908,24,0x847da2a816b5d817)
>>
>> Which appears to be this:
>>
>> else {
>> (void)unlink(dst);
>>
>> if ((fd = open(dst, O_WRONLY|O_CREAT|O_TRUNC, mode))
>> == -1)
>> err(1, "%s", dst);
>>
>> I don't know what older or gnu rcs do. I guess whichever way this is
>> done
>> it must balance concerns between atomicity of concurrent reads
>> performed
>> by earlier processes, versus replacement of a potentially active
>> file.
>>
>> If the latter is chosen, it would unlink(), perform the open more
>> carefully, check that it is in the right place with fstat, but then
>> it needs some work for ftruncate (to get rid of extra file contents
>> at the end). If the open() failed, it might try an unlink followed
>> by
>> open()?
>>
>> Other rcs implimentations need to be checked. It is better if they
>> work
>> the same.
>>

No comments:

Post a Comment