qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: alex.bennee@linaro.org
To: qemu-devel@nongnu.org
Cc: patches@linaro.org
Subject: [Qemu-devel] [PATCH 2/2] scripts/qemu-binfmt-check.py: a binfmt checker
Date: Wed,  8 Jan 2014 14:25:34 +0000	[thread overview]
Message-ID: <1389191134-16597-3-git-send-email-alex.bennee@linaro.org> (raw)
In-Reply-To: <1389191134-16597-1-git-send-email-alex.bennee@linaro.org>

From: Alex Bennée <alex.bennee@linaro.org>

This script allows you to check if a given binary will match against any
of the currently registered binfmts on the system.

---

v2 (ajb):
   - cleaned up whitespace and checkpatch fixes
---
 scripts/qemu-binfmt-check.py | 109 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 109 insertions(+)
 create mode 100755 scripts/qemu-binfmt-check.py

diff --git a/scripts/qemu-binfmt-check.py b/scripts/qemu-binfmt-check.py
new file mode 100755
index 0000000..c4309a5
--- /dev/null
+++ b/scripts/qemu-binfmt-check.py
@@ -0,0 +1,109 @@
+#!/usr/bin/python
+#
+# binfmt check script
+#
+# Copyright 2014 Linaro
+#
+# Authors:
+#  Alex Bennee <alex.bennee@linaro.org>
+#
+# This work is licensed under the terms of the GNU GPL, version 2.  See
+# the COPYING file in the top-level directory.
+
+import os
+import re
+import binascii
+
+re_int = re.compile(r"interpreter (.+)$")
+re_off = re.compile(r"offset (\d+)$")
+re_magic = re.compile(r"magic ([\dabcdef]+)")
+re_mask = re.compile(r"mask ([\dabcdef]+)")
+
+# argparse is only available in Python >= 2.7
+from optparse import OptionParser
+parser = OptionParser()
+
+# list of binfmts
+binfmts = []
+
+
+def read_binfmt_spec(f):
+    bfmt = {}
+    with open(f) as fd:
+        content = fd.readlines()
+    for l in content:
+        m = re_int.match(l)
+        if m:
+            bfmt["interpreter"] = m.group(1)
+        m = re_off.match(l)
+        if m:
+            bfmt["offset"] = int(m.group(1))
+        m = re_magic.match(l)
+        if m:
+            bfmt["magic"] = binascii.unhexlify(m.group(1))
+        m = re_mask.match(l)
+        if m:
+            bfmt["mask"] = binascii.unhexlify(m.group(1))
+    print "loaded: %s" % bfmt
+    binfmts.append(bfmt)
+
+
+def load_binfmt_masks():
+    binfmt_dir = "/proc/sys/fs/binfmt_misc"
+    files = os.listdir(binfmt_dir)
+    for f in files:
+        if not f.startswith("status"):
+            fp = "%s/%s" % (binfmt_dir, f)
+            if os.access(fp, os.R_OK):
+                read_binfmt_spec(fp)
+
+
+def check_file_against_binfmt(fmt, f):
+    """
+    Check if a file will match a given binfmt mask
+    """
+    print "checking %s" % (f)
+    nbytes = len(fmt["magic"])
+
+    fd = open(f, "rb")
+    fd.seek(fmt["offset"])
+    header = fd.read(nbytes)
+    magic = fmt["magic"]
+    try:
+        mask = fmt["mask"]
+    except:
+        # TODO, make full mask
+        return
+
+    values = zip(mask, magic, header)
+    failed = False
+    pos = 0
+    for m, g, h in values:
+        mask = ord(m)
+        bits_to_check = ord(h) & mask
+        magic = ord(g)
+        if not bits_to_check == magic:
+            print "failed at %d (%x, %x, %x)" % (pos, mask, magic, bits_to_check)
+            failed = True
+            break
+        pos += 1
+    return not failed
+
+
+def check_file_against_all_binfmts(f):
+    """
+    Check a file against the binfmt masks
+    """
+    path = os.path.abspath(f)
+    print "file is %s" % (path)
+    for b in binfmts:
+        if check_file_against_binfmt(b, path):
+            print "%s will use %s" % (path, b["interpreter"])
+            break
+
+
+if __name__ == "__main__":
+    (opts, args) = parser.parse_args()
+    load_binfmt_masks()
+    for f in args:
+        check_file_against_all_binfmts(f)
-- 
1.8.5.2

      parent reply	other threads:[~2014-01-08 14:25 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-01-08 14:25 [Qemu-devel] [RFC PATCH 0/0] binfmt script patches alex.bennee
2014-01-08 14:25 ` [Qemu-devel] [PATCH 1/2] scripts/qemu-binfmt-conf.sh: re-factor and clean-up alex.bennee
2014-01-08 14:50   ` Andreas Färber
2014-01-08 15:02     ` Alex Bennée
2014-01-08 14:25 ` alex.bennee [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1389191134-16597-3-git-send-email-alex.bennee@linaro.org \
    --to=alex.bennee@linaro.org \
    --cc=patches@linaro.org \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).