#!/usr/bin/python
# Copyright (C) 2009, Canonical, Ltd.
# Author: Kees Cook <kees@ubuntu.com>
# License: GPLv3
#
# Attempt to sanitize the dd arguments, even though this still allows for arbitrary read/write
# and DoS of any LVs.

import sys, os, glob

if len(sys.argv)<3:
    print >>sys.stderr, "Invalid arguments"
    sys.exit(1)

opts = dict()
for arg in sys.argv[1:]:
    for opt in ['if','of']:
        if arg.startswith(opt+'='):
            if opts.has_key(opt):
                print >>sys.stderr, "Option '%s' repeated" % (opt)
                sys.exit(1)
            opts.setdefault(opt,arg.split('=',1)[1])
if 'if' not in opts or 'of' not in opts:
    print >>sys.stderr, "Missing 'if' or 'of' arguments"
    sys.exit(1)

# Allowed:
# - /dev/zero -> anywhere
# - devmapper -> anywhere
# - anywhere -> devmapper
if opts['if'] != '/dev/zero':
    found = False

    for device in [opts['if'], opts['of']]:
        try:
            src = os.stat(device)
        except:
            continue
        for dm in glob.glob('/dev/mapper/*'):
            if dm.endswith('/control'):
                continue
            if os.stat(dm).st_rdev == src.st_rdev:
                found = True
                break
        if found:
            break

    if not found:
        print >>sys.stderr, "Source is not /dev/zero or source/target is not a devmapper device"
        sys.exit(1)

args = ['/bin/dd'] + sys.argv[1:]
os.execl('/bin/dd', *args)
