From 7e066cb8834233edde5fef6a5bb391fd2124448b Mon Sep 17 00:00:00 2001 From: Konstantin Ryabitsev Date: Thu, 3 Jun 2021 13:04:33 -0400 Subject: Account for in-body headers when trimming body When we discover that a message can only be attested after we trim the body, we *must* set the body to that version, otherwise an attacker could append arbitrary content past the l= value boundary. We already do this in the current form, but we weren't properly handing in-body headers like From: and Subject: that are used to indicate to git the patch author vs. committer. This patch set fixes that and also streamlines a few other places where we were already relying on git mailinfo calls. Signed-off-by: Konstantin Ryabitsev --- b4/mbox.py | 47 ++++++++++++++++------------------------------- 1 file changed, 16 insertions(+), 31 deletions(-) (limited to 'b4/mbox.py') diff --git a/b4/mbox.py b/b4/mbox.py index f575f94..33d7772 100644 --- a/b4/mbox.py +++ b/b4/mbox.py @@ -350,37 +350,22 @@ def save_as_quilt(am_msgs, q_dirname): return pathlib.Path(q_dirname).mkdir(parents=True) patch_filenames = list() - with tempfile.TemporaryDirectory() as tfd: - m_out = os.path.join(tfd, 'm') - p_out = os.path.join(tfd, 'p') - for slug, msg in am_msgs: - # Run each message through git mailinfo - cmdargs = ['mailinfo', '--encoding=UTF-8', '--scissors', m_out, p_out] - ecode, info = b4.git_run_command(None, cmdargs, msg.as_bytes(policy=b4.emlpolicy)) - if not len(info.strip()): - logger.critical('ERROR: Could not get mailinfo from patch %s', msg.get('Subject', '(no subject)')) - continue - patchinfo = dict() - for line in info.split('\n'): - line = line.strip() - if not line: - continue - chunks = line.split(':', 1) - patchinfo[chunks[0]] = chunks[1].strip().encode() - - patch_filename = f'{slug}.patch' - patch_filenames.append(patch_filename) - quilt_out = os.path.join(q_dirname, patch_filename) - with open(quilt_out, 'wb') as fh: - fh.write(b'From: %s <%s>\n' % (patchinfo['Author'], patchinfo['Email'])) - fh.write(b'Subject: %s\n' % patchinfo['Subject']) - fh.write(b'Date: %s\n' % patchinfo['Date']) - fh.write(b'\n') - with open(m_out, 'rb') as mfh: - shutil.copyfileobj(mfh, fh) - with open(p_out, 'rb') as pfh: - shutil.copyfileobj(pfh, fh) - logger.debug(' Wrote: %s', patch_filename) + for slug, msg in am_msgs: + patch_filename = f'{slug}.patch' + patch_filenames.append(patch_filename) + quilt_out = os.path.join(q_dirname, patch_filename) + i, m, p = b4.get_mailinfo(msg.as_bytes(policy=b4.emlpolicy), scissors=True) + with open(quilt_out, 'wb') as fh: + if i.get('Author'): + fh.write(b'From: %s <%s>\n' % (i.get('Author').encode(), i.get('Email').encode())) + else: + fh.write(b'From: %s\n' % i.get('Email').encode()) + fh.write(b'Subject: %s\n' % i.get('Subject').encode()) + fh.write(b'Date: %s\n' % i.get('Date').encode()) + fh.write(b'\n') + fh.write(m) + fh.write(p) + logger.debug(' Wrote: %s', patch_filename) # Write the series file with open(os.path.join(q_dirname, 'series'), 'w') as sfh: for patch_filename in patch_filenames: -- cgit v1.2.3