From patchwork Sun Sep 29 19:01:28 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jelle van der Waa X-Patchwork-Id: 1240 Return-Path: Delivered-To: patchwork@archlinux.org Received: from apollo.archlinux.org (localhost [127.0.0.1]) by apollo.archlinux.org (Postfix) with ESMTP id 2A99E141FDD65 for ; Sun, 29 Sep 2019 19:01:48 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on apollo X-Spam-Level: X-Spam-Status: No, score=-2.2 required=5.0 tests=DKIM_INVALID=1, DKIM_SIGNED=0.1,MAILING_LIST_MULTI=-1,RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001 autolearn=unavailable autolearn_force=no version=3.4.2 X-Spam-BL-Results: [127.0.0.11] [127.0.9.2] Received: from orion.archlinux.org (orion.archlinux.org [88.198.91.70]) by apollo.archlinux.org (Postfix) with ESMTPS for ; Sun, 29 Sep 2019 19:01:48 +0000 (UTC) Received: from orion.archlinux.org (localhost [127.0.0.1]) by orion.archlinux.org (Postfix) with ESMTP id D2EF9158D66C19; Sun, 29 Sep 2019 19:01:42 +0000 (UTC) Received: from luna.archlinux.org (luna.archlinux.org [IPv6:2a01:4f8:160:3033::2]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-384) server-signature RSA-PSS (4096 bits)) (No client certificate requested) by orion.archlinux.org (Postfix) with ESMTPS; Sun, 29 Sep 2019 19:01:42 +0000 (UTC) Received: from luna.archlinux.org (luna.archlinux.org [127.0.0.1]) by luna.archlinux.org (Postfix) with ESMTP id 9C2532BDC2; Sun, 29 Sep 2019 19:01:42 +0000 (UTC) Authentication-Results: luna.archlinux.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=vdwaa-nl.20150623.gappssmtp.com header.i=@vdwaa-nl.20150623.gappssmtp.com header.b=iAPxDbnf Received: from luna.archlinux.org (luna.archlinux.org [127.0.0.1]) by luna.archlinux.org (Postfix) with ESMTP id 7D7F52BDC1 for ; Sun, 29 Sep 2019 19:01:39 +0000 (UTC) Received: from orion.archlinux.org (orion.archlinux.org [88.198.91.70]) by luna.archlinux.org (Postfix) with ESMTPS for ; Sun, 29 Sep 2019 19:01:39 +0000 (UTC) Received: from orion.archlinux.org (localhost [127.0.0.1]) by orion.archlinux.org (Postfix) with ESMTP id 6250D158D66C16 for ; Sun, 29 Sep 2019 19:01:34 +0000 (UTC) Received: from mail-ed1-x52e.google.com (mail-ed1-x52e.google.com [IPv6:2a00:1450:4864:20::52e]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-384) server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by orion.archlinux.org (Postfix) with ESMTPS for ; Sun, 29 Sep 2019 19:01:34 +0000 (UTC) Received: by mail-ed1-x52e.google.com with SMTP id t3so6639254edw.13 for ; Sun, 29 Sep 2019 12:01:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=vdwaa-nl.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=8gVEeB4T7Tsy/BI/+fbVzMw2i5A2FCBtvKDRSGQg3Zg=; b=iAPxDbnfG/mX2jj17qG4aK/4vlVEpJ+RZQuzvfbqJzPL2KmPd6r2w6xCU0VA+c6c53 WB1YkMWYBbxh4A9zTSWPdqSbAV/2bF12sf0ypTbt7aw2bj3a43rYczV8PsOb7VumxBqE lbgPGmhie+NNlSzuvVwB3+SCkLo879EaKUOcLRgTfBrlQGzGd1+mkH6qe+ACv/n/YQ3v S+K1PxIWZQesciqn9sLKPyL3nf94+nEDUUMju1w2NKjL8L7zJvUT3FQm5YGODXSNwg2h AnPKDLohB2NxadfbuK+Qm3i3iNgakEyyoqsWNWCp4fHSQY919Lv4PI3oal27ArhTQR93 bI5A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=8gVEeB4T7Tsy/BI/+fbVzMw2i5A2FCBtvKDRSGQg3Zg=; b=DFnSAX3CoMKkqmoEGFvvXWx7Wzo+fNwpluxrLMrwquMOyVRvzCdjzRz8h3q8bU7dWV hNz9GuZ9JyBd/Q5QxV0tGFIjcIbCAD5LG+1KnmCObsjWwxx6zB8E1c+Qx97bvl2muE2A DZVK3oZ3+sUJbSNY4NM96e+GJ4hScdwMMI943ntHHreQ9oczPJ3qL/e50Qy4s+s8ErKk 43stHgD+loOyKUwyd7ItniJVWHYXlQs9k3rznZqvTGT4PrRb4ctS7lXpPgXE4f2rTEc+ sMtb/gCb4WRc6XdAEqFlUUh2t3by8wqj0iCow+M9K0TKT91N1EE5wAyWk51RpaJY5s16 Jpwg== X-Gm-Message-State: APjAAAWlWLDLmm0WNDCMR+0qnhSuH1GcGV07vKuLtbQz04srIWFpxF6f af69BBuXa3eteFW/KRBvVXZtuBcqrAzUrw== X-Google-Smtp-Source: APXvYqyNhPYas5yR3tuGYc3ypRqysII/xFFKoCXyy/8wO8oLnQkHzIPeYVBzU7L444ng0L4PzxuWOA== X-Received: by 2002:a05:6402:128c:: with SMTP id w12mr15737780edv.158.1569783692829; Sun, 29 Sep 2019 12:01:32 -0700 (PDT) Received: from localhost.localdomain (83-84-17-34.cable.dynamic.v4.ziggo.nl. [83.84.17.34]) by smtp.gmail.com with ESMTPSA id i23sm230663ejj.32.2019.09.29.12.01.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 29 Sep 2019 12:01:32 -0700 (PDT) From: Jelle van der Waa X-Google-Original-From: Jelle van der Waa To: arch-projects@archlinux.org Date: Sun, 29 Sep 2019 21:01:28 +0200 Message-Id: <20190929190128.25119-1-jelle@vdwaa.nl> X-Mailer: git-send-email 2.23.0 MIME-Version: 1.0 Subject: [arch-projects] [namcap] [PATCH] Add RUNPATH rule X-BeenThere: arch-projects@archlinux.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Arch Linux projects development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: Arch Linux projects development discussion Errors-To: arch-projects-bounces@archlinux.org Sender: "arch-projects" From: Jelle van der Waa Include a rule to check for vulnerable RUNPATH ELF binary entries, which allow arbitrary code execution by loading shared libraries from an attacker controller path. --- Namcap/rules/__init__.py | 1 + Namcap/rules/runpath.py | 71 ++++++++++++++++++++++++++++++++++++++++ namcap-tags | 1 + namcap.1 | 3 ++ 4 files changed, 76 insertions(+) create mode 100644 Namcap/rules/runpath.py diff --git a/Namcap/rules/__init__.py b/Namcap/rules/__init__.py index 525dbc6..ee400e2 100644 --- a/Namcap/rules/__init__.py +++ b/Namcap/rules/__init__.py @@ -44,6 +44,7 @@ from . import ( permissions, py_mtime, rpath, + runpath, scrollkeeper, shebangdepends, sodepends, diff --git a/Namcap/rules/runpath.py b/Namcap/rules/runpath.py new file mode 100644 index 0000000..053923e --- /dev/null +++ b/Namcap/rules/runpath.py @@ -0,0 +1,71 @@ +# namcap rules - runpath +# +# Copyright (C) 2019 Jelle van der Waa +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +from Namcap.util import is_elf +from Namcap.ruleclass import TarballRule + +from elftools.elf.elffile import ELFFile +from elftools.elf.dynamic import DynamicSection + +allowed = ('/usr/lib', '/usr/lib32', '/lib', '$ORIGIN', '${ORIGIN}') +allowed_toplevels = (s + '/' for s in allowed) +warn = ['/usr/local/lib'] + + +def get_runpaths(fileobj): + elffile = ELFFile(fileobj) + for section in elffile.iter_sections(): + if not isinstance(section, DynamicSection): + continue + for tag in section.iter_tags(): + if tag.entry.d_tag != 'DT_RUNPATH': + continue + for path in tag.runpath.split(':'): + yield path + + +class package(TarballRule): + name = "runpath" + description = "Verifies if RUNPATH is secure" + + def analyze(self, pkgingo, tar): + for entry in tar: + if not entry.isfile(): + continue + + fileobj = tar.extractfile(entry) + if not is_elf(fileobj): + continue + + for path in get_runpaths(fileobj): + path_ok = path in allowed + for allowed_toplevel in allowed_toplevels: + if path.startswith(allowed_toplevel): + path_ok = True + + if not path_ok: + self.errors.append(("insecure-runpath %s %s", + (path, entry.name))) + break + + if path in warn and entry.name not in insecure_rpaths: + self.warnings.append(("insecure-runpath %s %s", + (path, entry.name))) + + +# vim: set ts=4 sw=4 noet: diff --git a/namcap-tags b/namcap-tags index 84cc3f7..1f7bc69 100644 --- a/namcap-tags +++ b/namcap-tags @@ -44,6 +44,7 @@ incorrect-owner %s (%s:%s) :: File (%s) is owned by %s:%s invalid-filename :: File name %s contains non standard characters info-dir-file-present %s :: Info directory file (%s) should not be present insecure-rpath %s %s :: Insecure RPATH '%s' in file ('%s') +insecure-runpath %s %s :: Insecure RUNPATH '%s' in file ('%s') libtool-file-present %s :: File (%s) is a libtool file library-no-package-associated %s :: Referenced library '%s' is an uninstalled dependency link-level-dependence %s in %s :: Link-level dependence (%s) in file %s diff --git a/namcap.1 b/namcap.1 index fcea8ed..9243087 100644 --- a/namcap.1 +++ b/namcap.1 @@ -108,6 +108,9 @@ Checks basic file and and directory permissions. It returns warnings about worl .B rpath Gives an error if a binary has RPATH set to something other than /usr/lib .TP +.B runpath +Gives an error if a binary has RUNPATH set to something other than /usr/lib, /usr/lib32 +.TP .B scrollkeeper Verifies that there aren't any scrollkeeper directories .TP