##// END OF EJS Templates
merge with stable
Matt Mackall -
r28670:ff0d3b6b merge default
parent child Browse files
Show More
@@ -0,0 +1,15 b''
1 Test for CVE-2016-3630
2
3 $ hg init
4
5 >>> open("a.i", "w").write(
6 ... """eJxjYGZgZIAAYQYGxhgom+k/FMx8YKx9ZUaKSOyqo4cnuKb8mbqHV5cBCVTMWb1Cwqkhe4Gsg9AD
7 ... Joa3dYtcYYYBAQ8Qr4OqZAYRICPTSr5WKd/42rV36d+8/VmrNpv7NP1jQAXrQE4BqQUARngwVA=="""
8 ... .decode("base64").decode("zlib"))
9
10 $ hg debugindex a.i
11 rev offset length delta linkrev nodeid p1 p2
12 0 0 19 -1 2 99e0332bd498 000000000000 000000000000
13 1 19 12 0 3 6674f57a23d8 99e0332bd498 000000000000
14 $ hg debugdata a.i 1 2>&1 | grep decoded
15 mpatch.mpatchError: patch cannot be decoded
@@ -122,3 +122,4 b' 158bdc8965720ca4061f8f8d806563cfc7cdb62e'
122 2408645de650d8a29a6ce9e7dce601d8dd0d1474 0 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
@@ -135,3 +135,4 b' 158bdc8965720ca4061f8f8d806563cfc7cdb62e'
135 2408645de650d8a29a6ce9e7dce601d8dd0d1474 3.7
135 2408645de650d8a29a6ce9e7dce601d8dd0d1474 3.7
136 b698abf971e7377d9b7ec7fc8c52df45255b0329 3.7.1
136 b698abf971e7377d9b7ec7fc8c52df45255b0329 3.7.1
137 d493d64757eb45ada99fcb3693e479a51b7782da 3.7.2
137 d493d64757eb45ada99fcb3693e479a51b7782da 3.7.2
138 ae279d4a19e9683214cbd1fe8298cf0b50571432 3.7.3
@@ -352,6 +352,9 b' class commandline(object):'
352 def _run2(self, cmd, *args, **kwargs):
352 def _run2(self, cmd, *args, **kwargs):
353 return self._dorun(util.popen2, cmd, *args, **kwargs)
353 return self._dorun(util.popen2, cmd, *args, **kwargs)
354
354
355 def _run3(self, cmd, *args, **kwargs):
356 return self._dorun(util.popen3, cmd, *args, **kwargs)
357
355 def _dorun(self, openfunc, cmd, *args, **kwargs):
358 def _dorun(self, openfunc, cmd, *args, **kwargs):
356 cmdline = self._cmdline(cmd, *args, **kwargs)
359 cmdline = self._cmdline(cmd, *args, **kwargs)
357 self.ui.debug('running: %s\n' % (cmdline,))
360 self.ui.debug('running: %s\n' % (cmdline,))
@@ -32,61 +32,28 b' class submodule(object):'
32 def hgsubstate(self):
32 def hgsubstate(self):
33 return "%s %s" % (self.node, self.path)
33 return "%s %s" % (self.node, self.path)
34
34
35 class convert_git(common.converter_source):
35 class convert_git(common.converter_source, common.commandline):
36 # Windows does not support GIT_DIR= construct while other systems
36 # Windows does not support GIT_DIR= construct while other systems
37 # cannot remove environment variable. Just assume none have
37 # cannot remove environment variable. Just assume none have
38 # both issues.
38 # both issues.
39 if util.safehasattr(os, 'unsetenv'):
39
40 def gitopen(self, s, err=None):
40 def _gitcmd(self, cmd, *args, **kwargs):
41 prevgitdir = os.environ.get('GIT_DIR')
41 return cmd('--git-dir=%s' % self.path, *args, **kwargs)
42 os.environ['GIT_DIR'] = self.path
42
43 try:
43 def gitrun0(self, *args, **kwargs):
44 if err == subprocess.PIPE:
44 return self._gitcmd(self.run0, *args, **kwargs)
45 (stdin, stdout, stderr) = util.popen3(s)
46 return stdout
47 elif err == subprocess.STDOUT:
48 return self.popen_with_stderr(s)
49 else:
50 return util.popen(s, 'rb')
51 finally:
52 if prevgitdir is None:
53 del os.environ['GIT_DIR']
54 else:
55 os.environ['GIT_DIR'] = prevgitdir
56
45
57 def gitpipe(self, s):
46 def gitrun(self, *args, **kwargs):
58 prevgitdir = os.environ.get('GIT_DIR')
47 return self._gitcmd(self.run, *args, **kwargs)
59 os.environ['GIT_DIR'] = self.path
48
60 try:
49 def gitrunlines0(self, *args, **kwargs):
61 return util.popen3(s)
50 return self._gitcmd(self.runlines0, *args, **kwargs)
62 finally:
63 if prevgitdir is None:
64 del os.environ['GIT_DIR']
65 else:
66 os.environ['GIT_DIR'] = prevgitdir
67
51
68 else:
52 def gitrunlines(self, *args, **kwargs):
69 def gitopen(self, s, err=None):
53 return self._gitcmd(self.runlines, *args, **kwargs)
70 if err == subprocess.PIPE:
71 (sin, so, se) = util.popen3('GIT_DIR=%s %s' % (self.path, s))
72 return so
73 elif err == subprocess.STDOUT:
74 return self.popen_with_stderr(s)
75 else:
76 return util.popen('GIT_DIR=%s %s' % (self.path, s), 'rb')
77
54
78 def gitpipe(self, s):
55 def gitpipe(self, *args, **kwargs):
79 return util.popen3('GIT_DIR=%s %s' % (self.path, s))
56 return self._gitcmd(self._run3, *args, **kwargs)
80
81 def popen_with_stderr(self, s):
82 p = subprocess.Popen(s, shell=True, bufsize=-1,
83 close_fds=util.closefds,
84 stdin=subprocess.PIPE,
85 stdout=subprocess.PIPE,
86 stderr=subprocess.STDOUT,
87 universal_newlines=False,
88 env=None)
89 return p.stdout
90
57
91 def gitread(self, s):
58 def gitread(self, s):
92 fh = self.gitopen(s)
59 fh = self.gitopen(s)
@@ -95,6 +62,7 b' class convert_git(common.converter_sourc'
95
62
96 def __init__(self, ui, path, revs=None):
63 def __init__(self, ui, path, revs=None):
97 super(convert_git, self).__init__(ui, path, revs=revs)
64 super(convert_git, self).__init__(ui, path, revs=revs)
65 common.commandline.__init__(self, ui, 'git')
98
66
99 if os.path.isdir(path + "/.git"):
67 if os.path.isdir(path + "/.git"):
100 path += "/.git"
68 path += "/.git"
@@ -107,20 +75,20 b' class convert_git(common.converter_sourc'
107 if similarity < 0 or similarity > 100:
75 if similarity < 0 or similarity > 100:
108 raise error.Abort(_('similarity must be between 0 and 100'))
76 raise error.Abort(_('similarity must be between 0 and 100'))
109 if similarity > 0:
77 if similarity > 0:
110 self.simopt = '-C%d%%' % similarity
78 self.simopt = ['-C%d%%' % similarity]
111 findcopiesharder = ui.configbool('convert', 'git.findcopiesharder',
79 findcopiesharder = ui.configbool('convert', 'git.findcopiesharder',
112 False)
80 False)
113 if findcopiesharder:
81 if findcopiesharder:
114 self.simopt += ' --find-copies-harder'
82 self.simopt.append('--find-copies-harder')
115 else:
83 else:
116 self.simopt = ''
84 self.simopt = []
117
85
118 common.checktool('git', 'git')
86 common.checktool('git', 'git')
119
87
120 self.path = path
88 self.path = path
121 self.submodules = []
89 self.submodules = []
122
90
123 self.catfilepipe = self.gitpipe('git cat-file --batch')
91 self.catfilepipe = self.gitpipe('cat-file', '--batch')
124
92
125 def after(self):
93 def after(self):
126 for f in self.catfilepipe:
94 for f in self.catfilepipe:
@@ -128,14 +96,14 b' class convert_git(common.converter_sourc'
128
96
129 def getheads(self):
97 def getheads(self):
130 if not self.revs:
98 if not self.revs:
131 heads, ret = self.gitread('git rev-parse --branches --remotes')
99 output, status = self.gitrun('rev-parse', '--branches', '--remotes')
132 heads = heads.splitlines()
100 heads = output.splitlines()
133 if ret:
101 if status:
134 raise error.Abort(_('cannot retrieve git heads'))
102 raise error.Abort(_('cannot retrieve git heads'))
135 else:
103 else:
136 heads = []
104 heads = []
137 for rev in self.revs:
105 for rev in self.revs:
138 rawhead, ret = self.gitread("git rev-parse --verify %s" % rev)
106 rawhead, ret = self.gitrun('rev-parse', '--verify', rev)
139 heads.append(rawhead[:-1])
107 heads.append(rawhead[:-1])
140 if ret:
108 if ret:
141 raise error.Abort(_('cannot retrieve git head "%s"') % rev)
109 raise error.Abort(_('cannot retrieve git head "%s"') % rev)
@@ -195,7 +163,7 b' class convert_git(common.converter_sourc'
195 self.submodules.append(submodule(s['path'], '', s['url']))
163 self.submodules.append(submodule(s['path'], '', s['url']))
196
164
197 def retrievegitmodules(self, version):
165 def retrievegitmodules(self, version):
198 modules, ret = self.gitread("git show %s:%s" % (version, '.gitmodules'))
166 modules, ret = self.gitrun('show', '%s:%s' % (version, '.gitmodules'))
199 if ret:
167 if ret:
200 # This can happen if a file is in the repo that has permissions
168 # This can happen if a file is in the repo that has permissions
201 # 160000, but there is no .gitmodules file.
169 # 160000, but there is no .gitmodules file.
@@ -211,7 +179,7 b' class convert_git(common.converter_sourc'
211 return
179 return
212
180
213 for m in self.submodules:
181 for m in self.submodules:
214 node, ret = self.gitread("git rev-parse %s:%s" % (version, m.path))
182 node, ret = self.gitrun('rev-parse', '%s:%s' % (version, m.path))
215 if ret:
183 if ret:
216 continue
184 continue
217 m.node = node.strip()
185 m.node = node.strip()
@@ -220,15 +188,17 b' class convert_git(common.converter_sourc'
220 if full:
188 if full:
221 raise error.Abort(_("convert from git does not support --full"))
189 raise error.Abort(_("convert from git does not support --full"))
222 self.modecache = {}
190 self.modecache = {}
223 fh = self.gitopen("git diff-tree -z --root -m -r %s %s" % (
191 cmd = ['diff-tree','-z', '--root', '-m', '-r'] + self.simopt + [version]
224 self.simopt, version))
192 output, status = self.gitrun(*cmd)
193 if status:
194 raise error.Abort(_('cannot read changes in %s') % version)
225 changes = []
195 changes = []
226 copies = {}
196 copies = {}
227 seen = set()
197 seen = set()
228 entry = None
198 entry = None
229 subexists = [False]
199 subexists = [False]
230 subdeleted = [False]
200 subdeleted = [False]
231 difftree = fh.read().split('\x00')
201 difftree = output.split('\x00')
232 lcount = len(difftree)
202 lcount = len(difftree)
233 i = 0
203 i = 0
234
204
@@ -290,8 +260,6 b' class convert_git(common.converter_sourc'
290 if f != '.gitmodules' and fdest != '.gitmodules':
260 if f != '.gitmodules' and fdest != '.gitmodules':
291 copies[fdest] = f
261 copies[fdest] = f
292 entry = None
262 entry = None
293 if fh.close():
294 raise error.Abort(_('cannot read changes in %s') % version)
295
263
296 if subexists[0]:
264 if subexists[0]:
297 if subdeleted[0]:
265 if subdeleted[0]:
@@ -338,17 +306,23 b' class convert_git(common.converter_sourc'
338 return c
306 return c
339
307
340 def numcommits(self):
308 def numcommits(self):
341 return len([None for _ in self.gitopen('git rev-list --all')])
309 output, ret = self.gitrunlines('rev-list', '--all')
310 if ret:
311 raise error.Abort(_('cannot retrieve number of commits in %s') \
312 % self.path)
313 return len(output)
342
314
343 def gettags(self):
315 def gettags(self):
344 tags = {}
316 tags = {}
345 alltags = {}
317 alltags = {}
346 fh = self.gitopen('git ls-remote --tags "%s"' % self.path,
318 output, status = self.gitrunlines('ls-remote', '--tags', self.path)
347 err=subprocess.STDOUT)
319
320 if status:
321 raise error.Abort(_('cannot read tags from %s') % self.path)
348 prefix = 'refs/tags/'
322 prefix = 'refs/tags/'
349
323
350 # Build complete list of tags, both annotated and bare ones
324 # Build complete list of tags, both annotated and bare ones
351 for line in fh:
325 for line in output:
352 line = line.strip()
326 line = line.strip()
353 if line.startswith("error:") or line.startswith("fatal:"):
327 if line.startswith("error:") or line.startswith("fatal:"):
354 raise error.Abort(_('cannot read tags from %s') % self.path)
328 raise error.Abort(_('cannot read tags from %s') % self.path)
@@ -356,8 +330,6 b' class convert_git(common.converter_sourc'
356 if not tag.startswith(prefix):
330 if not tag.startswith(prefix):
357 continue
331 continue
358 alltags[tag[len(prefix):]] = node
332 alltags[tag[len(prefix):]] = node
359 if fh.close():
360 raise error.Abort(_('cannot read tags from %s') % self.path)
361
333
362 # Filter out tag objects for annotated tag refs
334 # Filter out tag objects for annotated tag refs
363 for tag in alltags:
335 for tag in alltags:
@@ -374,18 +346,20 b' class convert_git(common.converter_sourc'
374 def getchangedfiles(self, version, i):
346 def getchangedfiles(self, version, i):
375 changes = []
347 changes = []
376 if i is None:
348 if i is None:
377 fh = self.gitopen("git diff-tree --root -m -r %s" % version)
349 output, status = self.gitrunlines('diff-tree', '--root', '-m',
378 for l in fh:
350 '-r', version)
351 if status:
352 raise error.Abort(_('cannot read changes in %s') % version)
353 for l in output:
379 if "\t" not in l:
354 if "\t" not in l:
380 continue
355 continue
381 m, f = l[:-1].split("\t")
356 m, f = l[:-1].split("\t")
382 changes.append(f)
357 changes.append(f)
383 else:
358 else:
384 fh = self.gitopen('git diff-tree --name-only --root -r %s '
359 output, status = self.gitrunlines('diff-tree', '--name-only',
385 '"%s^%s" --' % (version, version, i + 1))
360 '--root', '-r', version,
386 changes = [f.rstrip('\n') for f in fh]
361 '%s^%s' % (version, i + 1), '--')
387 if fh.close():
362 changes = [f.rstrip('\n') for f in output]
388 raise error.Abort(_('cannot read changes in %s') % version)
389
363
390 return changes
364 return changes
391
365
@@ -405,8 +379,8 b' class convert_git(common.converter_sourc'
405 ])
379 ])
406
380
407 try:
381 try:
408 fh = self.gitopen('git show-ref', err=subprocess.PIPE)
382 output, status = self.gitrunlines('show-ref')
409 for line in fh:
383 for line in output:
410 line = line.strip()
384 line = line.strip()
411 rev, name = line.split(None, 1)
385 rev, name = line.split(None, 1)
412 # Process each type of branch
386 # Process each type of branch
@@ -205,7 +205,7 b' static struct flist *decode(const char *'
205 int pos = 0;
205 int pos = 0;
206
206
207 /* assume worst case size, we won't have many of these lists */
207 /* assume worst case size, we won't have many of these lists */
208 l = lalloc(len / 12);
208 l = lalloc(len / 12 + 1);
209 if (!l)
209 if (!l)
210 return NULL;
210 return NULL;
211
211
@@ -215,10 +215,10 b' static struct flist *decode(const char *'
215 lt->start = getbe32(bin + pos);
215 lt->start = getbe32(bin + pos);
216 lt->end = getbe32(bin + pos + 4);
216 lt->end = getbe32(bin + pos + 4);
217 lt->len = getbe32(bin + pos + 8);
217 lt->len = getbe32(bin + pos + 8);
218 if (lt->start > lt->end)
219 break; /* sanity check */
220 lt->data = bin + pos + 12;
218 lt->data = bin + pos + 12;
221 pos += 12 + lt->len;
219 pos += 12 + lt->len;
220 if (lt->start > lt->end || lt->len < 0)
221 break; /* sanity check */
222 lt++;
222 lt++;
223 }
223 }
224
224
@@ -1385,6 +1385,11 b' class gitsubrepo(abstractsubrepo):'
1385 are not supported and very probably fail.
1385 are not supported and very probably fail.
1386 """
1386 """
1387 self.ui.debug('%s: git %s\n' % (self._relpath, ' '.join(commands)))
1387 self.ui.debug('%s: git %s\n' % (self._relpath, ' '.join(commands)))
1388 if env is None:
1389 env = os.environ.copy()
1390 # fix for Git CVE-2015-7545
1391 if 'GIT_ALLOW_PROTOCOL' not in env:
1392 env['GIT_ALLOW_PROTOCOL'] = 'file:git:http:https:ssh'
1388 # unless ui.quiet is set, print git's stderr,
1393 # unless ui.quiet is set, print git's stderr,
1389 # which is mostly progress and useful info
1394 # which is mostly progress and useful info
1390 errpipe = None
1395 errpipe = None
@@ -714,7 +714,7 b' damage git repository by renaming a comm'
714 $ COMMIT_OBJ=1c/0ce3c5886f83a1d78a7b517cdff5cf9ca17bdd
714 $ COMMIT_OBJ=1c/0ce3c5886f83a1d78a7b517cdff5cf9ca17bdd
715 $ mv git-repo4/.git/objects/$COMMIT_OBJ git-repo4/.git/objects/$COMMIT_OBJ.tmp
715 $ mv git-repo4/.git/objects/$COMMIT_OBJ git-repo4/.git/objects/$COMMIT_OBJ.tmp
716 $ hg convert git-repo4 git-repo4-broken-hg 2>&1 | grep 'abort:'
716 $ hg convert git-repo4 git-repo4-broken-hg 2>&1 | grep 'abort:'
717 abort: cannot read tags from git-repo4/.git
717 abort: cannot retrieve number of commits in git-repo4/.git
718 $ mv git-repo4/.git/objects/$COMMIT_OBJ.tmp git-repo4/.git/objects/$COMMIT_OBJ
718 $ mv git-repo4/.git/objects/$COMMIT_OBJ.tmp git-repo4/.git/objects/$COMMIT_OBJ
719 damage git repository by renaming a blob object
719 damage git repository by renaming a blob object
720
720
@@ -729,3 +729,20 b' damage git repository by renaming a tree'
729 $ mv git-repo4/.git/objects/$TREE_OBJ git-repo4/.git/objects/$TREE_OBJ.tmp
729 $ mv git-repo4/.git/objects/$TREE_OBJ git-repo4/.git/objects/$TREE_OBJ.tmp
730 $ hg convert git-repo4 git-repo4-broken-hg 2>&1 | grep 'abort:'
730 $ hg convert git-repo4 git-repo4-broken-hg 2>&1 | grep 'abort:'
731 abort: cannot read changes in 1c0ce3c5886f83a1d78a7b517cdff5cf9ca17bdd
731 abort: cannot read changes in 1c0ce3c5886f83a1d78a7b517cdff5cf9ca17bdd
732
733 test for escaping the repo name (CVE-2016-3069)
734
735 $ git init '`echo pwned >COMMAND-INJECTION`'
736 Initialized empty Git repository in $TESTTMP/`echo pwned >COMMAND-INJECTION`/.git/
737 $ cd '`echo pwned >COMMAND-INJECTION`'
738 $ git commit -q --allow-empty -m 'empty'
739 $ cd ..
740 $ hg convert '`echo pwned >COMMAND-INJECTION`' 'converted'
741 initializing destination converted repository
742 scanning source...
743 sorting...
744 converting...
745 0 empty
746 updating bookmarks
747 $ test -f COMMAND-INJECTION
748 [1]
@@ -1132,4 +1132,36 b' make sure we show changed files, rather '
1132 ? s/foobar.orig
1132 ? s/foobar.orig
1133 ? s/snake.python.orig
1133 ? s/snake.python.orig
1134
1134
1135 test for Git CVE-2016-3068
1136 $ hg init malicious-subrepository
1137 $ cd malicious-subrepository
1138 $ echo "s = [git]ext::sh -c echo% pwned% >&2" > .hgsub
1139 $ git init s
1140 Initialized empty Git repository in $TESTTMP/tc/malicious-subrepository/s/.git/
1141 $ cd s
1142 $ git commit --allow-empty -m 'empty'
1143 [master (root-commit) 153f934] empty
1135 $ cd ..
1144 $ cd ..
1145 $ hg add .hgsub
1146 $ hg commit -m "add subrepo"
1147 $ cd ..
1148 $ env -u GIT_ALLOW_PROTOCOL hg clone malicious-subrepository malicious-subrepository-protected
1149 Cloning into '$TESTTMP/tc/malicious-subrepository-protected/s'...
1150 fatal: transport 'ext' not allowed
1151 updating to branch default
1152 cloning subrepo s from ext::sh -c echo% pwned% >&2
1153 abort: git clone error 128 in s (in subrepo s)
1154 [255]
1155
1156 whitelisting of ext should be respected (that's the git submodule behaviour)
1157 $ env GIT_ALLOW_PROTOCOL=ext hg clone malicious-subrepository malicious-subrepository-clone-allowed
1158 Cloning into '$TESTTMP/tc/malicious-subrepository-clone-allowed/s'...
1159 pwned
1160 fatal: Could not read from remote repository.
1161
1162 Please make sure you have the correct access rights
1163 and the repository exists.
1164 updating to branch default
1165 cloning subrepo s from ext::sh -c echo% pwned% >&2
1166 abort: git clone error 128 in s (in subrepo s)
1167 [255]
General Comments 0
You need to be logged in to leave comments. Login now