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
prev 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).