diff --git a/mercurial/subrepo.py b/mercurial/subrepo.py
index 80d7dbda92940c49e0fd66230ae07cd526b3629c_bWVyY3VyaWFsL3N1YnJlcG8ucHk=..071cbeba421217d722a69a5d614ec934684d62d5_bWVyY3VyaWFsL3N1YnJlcG8ucHk= 100644
--- a/mercurial/subrepo.py
+++ b/mercurial/subrepo.py
@@ -359,6 +359,12 @@
                           "in '%s'\n") % vfs.join(dirname))
                 vfs.unlink(vfs.reljoin(dirname, f))
 
+def _auditsubrepopath(repo, path):
+    # auditor doesn't check if the path itself is a symlink
+    pathutil.pathauditor(repo.root)(path)
+    if repo.wvfs.islink(path):
+        raise error.Abort(_("subrepo '%s' traverses symbolic link") % path)
+
 def subrepo(ctx, path, allowwdir=False, allowcreate=True):
     """return instance of the right subrepo class for subrepo in path"""
     # subrepo inherently violates our import layering rules
@@ -369,7 +375,7 @@
     from . import hg as h
     hg = h
 
-    pathutil.pathauditor(ctx.repo().root)(path)
+    _auditsubrepopath(ctx.repo(), path)
     state = ctx.substate[path]
     if state[2] not in types:
         raise error.Abort(_('unknown subrepo type %s') % state[2])
@@ -387,7 +393,7 @@
     from . import hg as h
     hg = h
 
-    pathutil.pathauditor(ctx.repo().root)(path)
+    _auditsubrepopath(ctx.repo(), path)
     state = ctx.substate[path]
     if state[2] not in types:
         raise error.Abort(_('unknown subrepo type %s') % state[2])
diff --git a/tests/test-audit-subrepo.t b/tests/test-audit-subrepo.t
index 80d7dbda92940c49e0fd66230ae07cd526b3629c_dGVzdHMvdGVzdC1hdWRpdC1zdWJyZXBvLnQ=..071cbeba421217d722a69a5d614ec934684d62d5_dGVzdHMvdGVzdC1hdWRpdC1zdWJyZXBvLnQ= 100644
--- a/tests/test-audit-subrepo.t
+++ b/tests/test-audit-subrepo.t
@@ -50,5 +50,4 @@
   $ hg ci -qAm 'add symlink "out"'
   $ hg init ../out
   $ echo 'out = out' >> .hgsub
-BROKEN: should fail
   $ hg ci -qAm 'add subrepo "out"'
@@ -54,6 +53,25 @@
   $ hg ci -qAm 'add subrepo "out"'
+  abort: subrepo 'out' traverses symbolic link
+  [255]
+
+prepare tampered repo (including the commit above):
+
+  $ hg import --bypass -qm 'add subrepo "out"' - <<'EOF'
+  > diff --git a/.hgsub b/.hgsub
+  > new file mode 100644
+  > --- /dev/null
+  > +++ b/.hgsub
+  > @@ -0,0 +1,1 @@
+  > +out = out
+  > diff --git a/.hgsubstate b/.hgsubstate
+  > new file mode 100644
+  > --- /dev/null
+  > +++ b/.hgsubstate
+  > @@ -0,0 +1,1 @@
+  > +0000000000000000000000000000000000000000 out
+  > EOF
   $ cd ../..
 
 on clone (and update):
 
   $ mkdir hgsymdir2
@@ -55,7 +73,6 @@
   $ cd ../..
 
 on clone (and update):
 
   $ mkdir hgsymdir2
-BROKEN: should fail to update
   $ hg clone -q hgsymdir/root hgsymdir2/root
@@ -61,2 +78,4 @@
   $ hg clone -q hgsymdir/root hgsymdir2/root
+  abort: subrepo 'out' traverses symbolic link
+  [255]
   $ ls hgsymdir2
@@ -62,5 +81,4 @@
   $ ls hgsymdir2
-  out
   root
 
 #endif
diff --git a/tests/test-subrepo-git.t b/tests/test-subrepo-git.t
index 80d7dbda92940c49e0fd66230ae07cd526b3629c_dGVzdHMvdGVzdC1zdWJyZXBvLWdpdC50..071cbeba421217d722a69a5d614ec934684d62d5_dGVzdHMvdGVzdC1zdWJyZXBvLWdpdC50 100644
--- a/tests/test-subrepo-git.t
+++ b/tests/test-subrepo-git.t
@@ -400,4 +400,6 @@
 Don't crash if subrepo is a broken symlink
   $ ln -s broken s
   $ hg status -S
+  abort: subrepo 's' traverses symbolic link
+  [255]
   $ hg push -q
@@ -403,4 +405,4 @@
   $ hg push -q
-  abort: subrepo s is missing (in subrepository "s")
+  abort: subrepo 's' traverses symbolic link
   [255]
   $ hg commit --subrepos -qm missing
@@ -405,6 +407,6 @@
   [255]
   $ hg commit --subrepos -qm missing
-  abort: subrepo s is missing (in subrepository "s")
+  abort: subrepo 's' traverses symbolic link
   [255]
   $ rm s
 #endif