[PATCH 05 of 11] cmdutil: securely rename a to A on disk
Mads Kiilerich
mads at kiilerich.com
Tue Aug 11 05:33:00 CDT 2009
On 08/11/2009 11:10 AM, Simon Heimberg wrote:
> Am Freitag, den 07.08.2009, 23:20 +0200 schrieb Mads Kiilerich:
>
>> Simon Heimberg wrote, On 08/07/2009 09:43 PM:
>>
>>> # HG changeset patch
>>> # User Simon Heimberg<simohe at besonet.ch>
>>> # Date 1249656995 -7200
>>> # Node ID 50e9f6b4d8878fd867a250c5be2578330b7f4769
>>> # Parent 76406c3720caa61cf9d466b43d2aac68b15ec362
>>> cmdutil: securely rename a to A on disk
>>>
>>>
> [snip]
>
>
>>> +def temprename(src):
>>> + """renames a file to a temporary name
>>> + the new name is returned"""
>>> + for tries in xrange(10):
>>> + temp = '%s-%08x' % (src, random.randint(0, 0xffffffff))
>>> + try:
>>> + os.rename(src, temp)
>>> + return temp
>>> + except IOError:
>>> + continue
>>> + raise IOError, (errno.EEXIST, "No usable temporary filename found")
>>> +
>>>
>>>
>> Does moving a function count as touching it?
>>
> In this case definitively yes, I have already changed some things.
>
>> IF you are touching it anyway then it it would be more secure with an
>> extra "if os.path.exists(temp): continue".
>>
> You are right. I thought os.rename would raise an error when the
> destination file exists. So I removed os.path.exists, but that is wrong.
> The file could be created after os.path.exists is called and before
> os.rename. Is this problematic? Should the file be created with
> tempfile.mkstemp and overwritten with os.rename?
>
I don't think we care about such races. We are in the users working
directory, so if the user wants to shoot while the gun points at his
foot he should be free to do that.
>> This function can also give strange errors on filenames close to the max
>> length. Perhaps we could drop the basename and use a short "random" name
>> in dirname...
>>
> Does this mean the length of the filename or the entire path?
Many file systems have limits for both, but on most file systems the
limits are so high that it doesn't matter.
AFAIK nobody complained, and if someone complain they are close to the
limit anyway, so perhaps we don't care?
> If it is
> the first, temprename could look like this:
>
> def temprename(src):
> """renames a file to a temporary name
> the new name is returned"""
> temp = tempname.mktemp(suffix='tmpmv', dir=os.path.dirname(src))
> os.rename(src, temp)
> return temp
>
> Is there a reason why tempname.mktemp was not used?
>
You mean tempfile.mktemp / tempfile.mkstemp? Dunno. Perhaps the current
code is simpler and faster and stresses the file system less.
/Mads
More information about the Mercurial-devel
mailing list