Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #107517

Re: Remove directory tree without following symlinks

From Nobody <nobody@nowhere.invalid>
Newsgroups comp.lang.python
Subject Re: Remove directory tree without following symlinks
Date 2016-04-23 17:29 +0100
Organization A noiseless patient Spider
Message-ID <pan.2016.04.23.16.29.05.118000@nowhere.invalid> (permalink)
References <571a3ba2$0$1597$c3e8da3$5496439d@news.astraweb.com>

Show all headers | View raw


On Sat, 23 Apr 2016 00:56:33 +1000, Steven D'Aprano wrote:

> I want to remove a directory, including all files and subdirectories under
> it, but without following symlinks. I want the symlinks to be deleted, not
> the files pointed to by those symlinks.

Note that this is non-trivial to do securely, i.e. where an adversary has
write permission on any of the directories involved. Due to the potential
for race conditions between checking whether a name refers to a directory
and recursing into it, the process can be tricked into deleting any
directory tree for which it has the appropriate permissions.

The solution requires:

1. That you always chdir() into each directory and remove entries using
their plain filename, rather than trying to remove entries from a
higher-level directory using a relative path.

2. When chdir()ing into each subdirectory, you need to do e.g.:

	st1 = os.stat(".")
	os.chdir(subdir)
	st2 = os.stat("..")
	if st1.st_dev != st2.st_dev or st1.st_ino != st2.st_ino:
	    raise SomeKindOfException()

If the test fails, it means that the directory you just chdir()d into
isn't actually a subdirectory of the one you just left, e.g. because the
directory entry was replaced between checking it and chdir()ing into it.

On Linux, an alternative is to use fchdir() rather than chdir(), which
changes to a directory specified by an open file descriptor for that
directory rather than by name. Provided that the directory was open()ed
without any race condition (e.g. using O_NOFOLLOW), subsequent fstat() and
fchdir() calls are guaranteed to use the same directory regardless of any
filesystem changes.

Back to comp.lang.python | Previous | NextPrevious in thread | Next in thread | Find similar | Unroll thread


Thread

Remove directory tree without following symlinks Steven D'Aprano <steve@pearwood.info> - 2016-04-23 00:56 +1000
  Re: Remove directory tree without following symlinks Random832 <random832@fastmail.com> - 2016-04-22 11:09 -0400
    Re: Remove directory tree without following symlinks Steven D'Aprano <steve@pearwood.info> - 2016-04-23 03:14 +1000
      RE: Remove directory tree without following symlinks Albert-Jan Roskam <sjeik_appie@hotmail.com> - 2016-04-22 17:39 +0000
      Re: Remove directory tree without following symlinks eryk sun <eryksun@gmail.com> - 2016-04-22 13:28 -0500
      RE: Remove directory tree without following symlinks Albert-Jan Roskam <sjeik_appie@hotmail.com> - 2016-04-23 09:34 +0000
      Re: Remove directory tree without following symlinks eryk sun <eryksun@gmail.com> - 2016-04-23 15:22 -0500
      Re: Remove directory tree without following symlinks eryk sun <eryksun@gmail.com> - 2016-04-24 14:42 -0500
  Re: Remove directory tree without following symlinks Paul Rubin <no.email@nospam.invalid> - 2016-04-23 01:13 -0700
    Re: Remove directory tree without following symlinks Steven D'Aprano <steve@pearwood.info> - 2016-04-23 20:24 +1000
      Re: Remove directory tree without following symlinks Gregory Ewing <greg.ewing@canterbury.ac.nz> - 2016-04-23 23:37 +1200
      Re: Remove directory tree without following symlinks Random832 <random832@fastmail.com> - 2016-04-23 17:04 -0400
  Re: Remove directory tree without following symlinks Nobody <nobody@nowhere.invalid> - 2016-04-23 17:29 +0100
    Re: Remove directory tree without following symlinks Random832 <random832@fastmail.com> - 2016-04-23 17:07 -0400

csiph-web