Fixed fields are not fixed, leading to buffer overflows and tar explosions.
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
Duplicity |
Fix Released
|
Medium
|
Unassigned |
Bug Description
The problem is in /usr/lib64/
for value, fieldsize in (
(" ", 8),
):
l = len(value)
and possibly elsewhere; I haven't exactly done a full code audit here.
The problem is that %011o, or whatever, doesn't stop the field from being *bigger* than 11 characters, so that for example if you have a file like this:
# stat [customer file]
File: `[customer file]'
Size: 20366 Blocks: 48 IO Block: 4096 regular file
Device: fd00h/64768d Inode: 2755310 Links: 1
Access: (0777/-rwxrwxrwx) Uid: ( 1006/ UNKNOWN) Gid: ( 1000/articulate
Access: 8330-03-21 02:25:15.000000000 -0800
Modify: 8330-03-21 02:25:15.000000000 -0800
Change: 2009-07-25 18:18:49.000000000 -0700
(note the mtime) which is an mtime of:
# date -r [customer file] +%s
200709051915
Which converts to:
>>> ("%011o" % 200709051915 )
'2727314213013'
13 characters, which drives the next field into the field after it, leaving a blank space in the "type" field, but *no error on creation*, which means that a full works just fine, but if you try to do an incremental or restore you get:
Traceback (most recent call last):
File "/usr/bin/
with_
File "/usr/bin/
fn()
File "/usr/bin/
incremental
File "/usr/bin/
globals.
File "/usr/bin/
globals.
File "/usr/lib64/
data = block_iter.
File "/usr/lib64/
result = self.process(
File "/usr/lib64/
for new_path, sig_path in collated:
File "/usr/lib64/
relem2 = riter2.next()
File "/usr/lib64/
refresh_
File "/usr/lib64/
new_triple = get_triple(
File "/usr/lib64/
path = path_iter_
File "/usr/lib64/
ropath.
File "/usr/lib64/
raise PathException(
PathException: Unknown tarinfo type
because not only are the field widths not fixed, but the expansion isn't checked, and the type error isn't printed in a useful fashion, which means that there's no indication *which* file is causing the problem, or even that a file is what caused it.
Since this is a pure overflow bug, I imagine it could be used to cause security problems, but I haven't investigated.
-Robin
Related branches
- duplicity-team: Pending requested
-
Diff: 4277 lines (+2257/-1404)13 files modifiedduplicity/diffdir.py (+10/-12)
duplicity/dup_temp.py (+12/-0)
duplicity/gpg.py (+14/-0)
duplicity/patchdir.py (+10/-9)
duplicity/path.py (+8/-8)
duplicity/tarfile.py (+2154/-1271)
duplicity/util.py (+27/-0)
rdiffdir (+0/-1)
tarfile-CHANGES (+3/-0)
tarfile-LICENSE (+1/-1)
testing/diffdirtest.py (+4/-2)
testing/patchdirtest.py (+10/-17)
testing/test_tarfile.py (+4/-83)
description: | updated |
Changed in duplicity: | |
assignee: | Kenneth Loafman (kenneth-loafman) → nobody |
status: | In Progress → Confirmed |
Changed in duplicity: | |
status: | Confirmed → In Progress |
Changed in duplicity: | |
assignee: | Michael Terry (mterry) → nobody |
milestone: | none → 0.6.16 |
status: | In Progress → Fix Committed |
Changed in duplicity: | |
status: | Fix Committed → Fix Released |
Allow me to suggest, by the way, that the easy way to fix this is: every time you create a header, immediately dissect it, and make sure all the values match. If not, error and clearly state the problem file.
-Robin