Skip Menu |
 

Date: Thu, 25 Sep 2014 08:02:44 -0700
From: Tsu-Phong Wu <tsu-phong.wu@oracle.com>
To: krb5-bugs@mit.edu
Subject: rename() failure in src/util/profile/prof_file.c:write_data_to_file()
CC: "WU,TSU-PHONG" <tsu-phong.wu@oracle.com>
Hi,

Like to report a bug with simple fix below:

unlink(old_file);
if (make_hard_link(outfile, old_file) == 0) {
/* Okay, got the hard link. Yay. Now we've got our
backup version, so just put the new version in
place. */
if (rename(new_file, outfile)) {
/* Weird, the rename didn't work. But the old version
should still be in place, so no special cleanup is
needed. */
<<<<<
unlink(old_file); <<<<< In case of rename() failure,
outfile should be fine.
<<<<< But old_file is extra from above make_hard_link(), and should be
removed.
retval = errno;
goto errout;
}
} else if (errno == ENOENT && can_create) {
It looks like the intent of this code is to leave behind the .bak file
(old_file) on success. So why is it necessary to remove it on rename
failure?

Also, are you seeing undesirable behavior in practice? If so, under what
circumstances?
Date: Thu, 25 Sep 2014 10:33:07 -0700 (PDT)
From: Tsu-Phong Wu <tsu-phong.wu@oracle.com>
To: <rt-comment@krbdev.mit.edu>
CC: Tsu-phong Wu <tsu-phong.wu@oracle.com>
Subject: Re: [krbdev.mit.edu #8020] rename() failure in src/util/profile/prof_file.c:write_data_to_file()
RT-Send-Cc:
Download (untitled) / with headers
text/plain 1.1KiB
On success, OK to leave .bak file as rename() will break the link so that krb5.conf has a link count of 1.

If do nothing upon rename() failure, krb5.conf will end up with a link count of 2.

We Oracle has modified the open() of krb5.conf with a bunch options including O_NOLINKS.
If rename() failed and link count of krb5.conf is > 1, open() of krb5.conf fails with EMLINK (The O_NOLINKS flag is set and the named file has a link count greater than 1).

The .bak is removed right before the make_hard_link(). So if the new krb5.conf can not be kept because combined make_hard_link() & rename() have failed, seems clean not to keep the extra "linked" .bak around.

Thanks.
Tsu-Phong

Show quoted text
----- Original Message -----
From: rt-comment@krbdev.mit.edu
To: tsu-phong.wu@oracle.com
Sent: Thursday, September 25, 2014 10:14:52 AM GMT -08:00 US/Canada Pacific
Subject: [krbdev.mit.edu #8020] rename() failure in src/util/profile/prof_file.c:write_data_to_file()

It looks like the intent of this code is to leave behind the .bak file
(old_file) on success. So why is it necessary to remove it on rename
failure?

Also, are you seeing undesirable behavior in practice? If so, under what
circumstances?
Under what circumstances does the rename fail after the hard link succeeds?

What is the reasoning for using O_NOLINKS when reading krb5.conf? (If you
can determine the reasoning; I realize that it might be an old change.)

It seems that even with the proposed change, there will always be a short
window where an open with O_NOLINKS will fail while a profile file is being
updated. So there will still be a reliability issue associated with using
O_NOLINKS. To remove that issue, we would have to eliminate the backup
file or create it using a copy operation.
Date: Fri, 26 Sep 2014 09:59:13 -0700 (PDT)
From: Tsu-Phong Wu <tsu-phong.wu@oracle.com>
To: <rt-comment@krbdev.mit.edu>
Subject: Re: [krbdev.mit.edu #8020] rename() failure in src/util/profile/prof_file.c:write_data_to_file()
RT-Send-Cc:
Download (untitled) / with headers
text/plain 1.8KiB
Show quoted text
> Under what circumstances does the rename fail after the hard link succeeds?

I think it happens this way,

Process A opened krb5.conf for normal operation (krb5.conf opened)

An UI could trigger profile update write_data_to_profile()
created new krb5.conf.$$$
deleted krb5.conf.bak
link(krb5.conf, krb5.conf.bak)
rename(krb5.conf.$$$, krb5.conf)
rename() failed as krb5.conf was open
so write_data_to_profile() failed and
left the extra "link" on krb5.conf and krb5.conf.$$$

Process A finished and closed krb5.conf.

Process A can no longer open krb5.conf due to the link count > 1

Next profile update would cleaned up the above mess and
process A can open krb5.conf again.

Above scenario can happen anytime and last for however long until next profile update.

In one recent scenario there were "Too many links" messages in our log spanning a 7 months period starting Dec 2013.

Show quoted text
> What is the reasoning for using O_NOLINKS when reading krb5.conf? (If you
> can determine the reasoning; I realize that it might be an old change.)

O_NOLINKS and O_NOFOLLOW were introduced in a new API in 2000 in order to prevent redirecting to the wrong file via hard or symbolic links.

Show quoted text
> It seems that even with the proposed change, there will always be a short
> window where an open with O_NOLINKS will fail while a profile file is being
> updated. So there will still be a reliability issue associated with using
> O_NOLINKS. To remove that issue, we would have to eliminate the backup
> file or create it using a copy operation.

We are always trying to get it more reliable, so we can either shorten the window or eliminate the window with more changed lines.

Thanks.
Tsu-Phong

Show quoted text
> ______________________________________________
> krb5-bugs mailing list
> krb5-bugs@mit.edu
> https://mailman.mit.edu/mailman/listinfo/krb5-bugs
rename does not fail when the target file is open, so that sequence of
events would not cause this problem to arise in practice.

I don't understand the explanation for why you would open krb5.conf with
O_NOLINKS. Profiles are read out of well-controlled paths like
/etc/krb5.conf or /var/krb5kdc/kdc.conf, not uncontrolled paths under /tmp.
There is no way an attacker could redirect someone to the wrong file.