# HG changeset patch # User Thomas Arendsen Hein # Date 1141495305 -3600 # Node ID bdfb524d728af0427d930795a8ae852a3e4e8f0e # Parent 24881eaebee3cfebd3fc1894fbb5ad6bcfd319eb Validate paths before reading or writing files in repository or working dir. Fixes security relevant issue134. diff -r 24881eaebee3 -r bdfb524d728a mercurial/commands.py --- a/mercurial/commands.py Fri Mar 03 13:41:12 2006 -0800 +++ b/mercurial/commands.py Sat Mar 04 19:01:45 2006 +0100 @@ -1014,7 +1014,7 @@ def debugancestor(ui, index, rev1, rev2): """find the ancestor revision of two revisions in a given index""" - r = revlog.revlog(util.opener(os.getcwd()), index, "") + r = revlog.revlog(util.opener(os.getcwd(), audit=False), index, "") a = r.ancestor(r.lookup(rev1), r.lookup(rev2)) ui.write("%d:%s\n" % (r.rev(a), hex(a))) @@ -1100,7 +1100,8 @@ def debugdata(ui, file_, rev): """dump the contents of an data file revision""" - r = revlog.revlog(util.opener(os.getcwd()), file_[:-2] + ".i", file_) + r = revlog.revlog(util.opener(os.getcwd(), audit=False), + file_[:-2] + ".i", file_) try: ui.write(r.revision(r.lookup(rev))) except KeyError: @@ -1108,7 +1109,7 @@ def debugindex(ui, file_): """dump the contents of an index file""" - r = revlog.revlog(util.opener(os.getcwd()), file_, "") + r = revlog.revlog(util.opener(os.getcwd(), audit=False), file_, "") ui.write(" rev offset length base linkrev" + " nodeid p1 p2\n") for i in range(r.count()): @@ -1119,7 +1120,7 @@ def debugindexdot(ui, file_): """dump an index DAG as a .dot file""" - r = revlog.revlog(util.opener(os.getcwd()), file_, "") + r = revlog.revlog(util.opener(os.getcwd(), audit=False), file_, "") ui.write("digraph G {\n") for i in range(r.count()): e = r.index[i] diff -r 24881eaebee3 -r bdfb524d728a mercurial/localrepo.py --- a/mercurial/localrepo.py Fri Mar 03 13:41:12 2006 -0800 +++ b/mercurial/localrepo.py Sat Mar 04 19:01:45 2006 +0100 @@ -1679,6 +1679,7 @@ remove.sort() for f in remove: self.ui.note(_("removing %s\n") % f) + util.audit_path(f) try: util.unlink(self.wjoin(f)) except OSError, inst: diff -r 24881eaebee3 -r bdfb524d728a mercurial/util.py --- a/mercurial/util.py Fri Mar 03 13:41:12 2006 -0800 +++ b/mercurial/util.py Sat Mar 04 19:01:45 2006 +0100 @@ -363,7 +363,14 @@ else: shutil.copy(src, dst) -def opener(base): +def audit_path(path): + """Abort if path contains dangerous components""" + parts = os.path.normcase(path).split(os.sep) + if (os.path.splitdrive(path)[0] or parts[0] in ('.hg', '') + or os.pardir in parts): + raise Abort(_("path contains illegal component: %s\n") % path) + +def opener(base, audit=True): """ return a function that opens files relative to base @@ -371,6 +378,7 @@ remote file access from higher level code. """ p = base + audit_p = audit def mktempcopy(name): d, fn = os.path.split(name) @@ -401,6 +409,8 @@ self.close() def o(path, mode="r", text=False, atomic=False): + if audit_p: + audit_path(path) f = os.path.join(p, path) if not text: