From 3583b5704e953b678fba520ef26afdc1b07fdaf2 Mon Sep 17 00:00:00 2001 From: anthraxx Date: Fri, 1 Oct 2021 19:21:49 +0200 Subject: [PATCH] fix(tempdir): use safe and unpredictable cachedir location The typeinfo module used a static global tempdir location of /tmp/pwndbg that an attacker may control and prepare symlinks of the predictable files that are then written to. --- pwndbg/__init__.py | 1 + pwndbg/tempfile.py | 36 ++++++++++++++++++++++++++++++++++++ pwndbg/typeinfo.py | 8 ++------ 3 files changed, 39 insertions(+), 6 deletions(-) create mode 100644 pwndbg/tempfile.py diff --git a/pwndbg/__init__.py b/pwndbg/__init__.py index 45956f3be..718982341 100755 --- a/pwndbg/__init__.py +++ b/pwndbg/__init__.py @@ -74,6 +74,7 @@ import pwndbg.proc import pwndbg.prompt import pwndbg.regs import pwndbg.stack +import pwndbg.tempfile import pwndbg.typeinfo import pwndbg.ui import pwndbg.version diff --git a/pwndbg/tempfile.py b/pwndbg/tempfile.py new file mode 100644 index 000000000..1d940d875 --- /dev/null +++ b/pwndbg/tempfile.py @@ -0,0 +1,36 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +""" +Common helper and cache for pwndbg tempdir +""" + +import os +import tempfile + +import pwndbg.memoize + + +@pwndbg.memoize.forever +def tempdir(): + """ + Returns a safe and unpredictable temporary directory with pwndbg prefix. + """ + return tempfile.mkdtemp(prefix='pwndbg-') + + +@pwndbg.memoize.forever +def cachedir(namespace=None): + """ + Returns and potentially creates a persistent safe cachedir location + based on XDG_CACHE_HOME or ~/.cache + + Optionally creates a sub namespace inside the pwndbg cache folder. + """ + cachehome = os.getenv('XDG_CACHE_HOME') + if not cachehome: + cachehome = os.path.join(os.getenv('HOME'), '.cache') + cachedir = os.path.join(cachehome, 'pwndbg') + if namespace: + cachedir = os.path.join(cachedir, namespace) + os.makedirs(cachedir, exist_ok=True) + return cachedir diff --git a/pwndbg/typeinfo.py b/pwndbg/typeinfo.py index d23739099..6569fe97b 100644 --- a/pwndbg/typeinfo.py +++ b/pwndbg/typeinfo.py @@ -9,13 +9,13 @@ import glob import os import subprocess import sys -import tempfile import gdb import pwndbg.events import pwndbg.gcc import pwndbg.memoize +import pwndbg.tempfile module = sys.modules[__name__] @@ -95,10 +95,6 @@ def update(): # Call it once so we load all of the types update() -tempdir = tempfile.gettempdir() + '/pwndbg' -if not os.path.exists(tempdir): - os.mkdir(tempdir) - # Trial and error until things work blacklist = ['regexp.h', 'xf86drm.h', 'libxl_json.h', 'xf86drmMode.h', 'caca0.h', 'xenguest.h', '_libxl_types_json.h', 'term_entry.h', 'slcurses.h', @@ -145,7 +141,7 @@ def load(name): {name} foo; '''.format(**locals()) - filename = '%s/%s_%s.cc' % (tempdir, arch, '-'.join(name.split())) + filename = '%s/%s_%s.cc' % (pwndbg.tempfile.cachedir('typeinfo'), arch, '-'.join(name.split())) with open(filename, 'w+') as f: f.write(source)