From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id C0412A0519; Mon, 22 Jun 2020 16:34:13 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 812BC1D729; Mon, 22 Jun 2020 16:33:55 +0200 (CEST) Received: from mga05.intel.com (mga05.intel.com [192.55.52.43]) by dpdk.org (Postfix) with ESMTP id 09EFE1D716 for ; Mon, 22 Jun 2020 16:33:49 +0200 (CEST) IronPort-SDR: vw6CL2zcbpto1UJflzOOqF2C/yptk48bvNKzDnkX4iYAv+a8y8z8LUuuMMzsYxH7UneqrVRcuY 5/ROuw6OECXg== X-IronPort-AV: E=McAfee;i="6000,8403,9659"; a="228428012" X-IronPort-AV: E=Sophos;i="5.75,267,1589266800"; d="scan'208";a="228428012" X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga105.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Jun 2020 07:33:49 -0700 IronPort-SDR: H3CIvCp8Vc7hCItWQ1j/u5CJURMikIqB4eH50JXfZiXaitSsZFMXdZsnQR737lKYknw48kIfgk HJGqElxykd4A== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.75,267,1589266800"; d="scan'208";a="300860139" Received: from silpixa00399126.ir.intel.com ([10.237.222.84]) by fmsmga004.fm.intel.com with ESMTP; 22 Jun 2020 07:33:48 -0700 From: Bruce Richardson To: dev@dpdk.org Cc: thomas@monjalon.net, david.marchand@redhat.com, Bruce Richardson Date: Mon, 22 Jun 2020 15:33:36 +0100 Message-Id: <20200622143337.562637-4-bruce.richardson@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200622143337.562637-1-bruce.richardson@intel.com> References: <20200618135049.489773-1-bruce.richardson@intel.com> <20200622143337.562637-1-bruce.richardson@intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Subject: [dpdk-dev] [PATCH v2 3/4] eal: don't load drivers from insecure paths X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Any paths on the system which are world-writable are insecure and should not be used for loading drivers. Therefore check each driver path before loading it and error out on insecure ones. Signed-off-by: Bruce Richardson --- v2: rebased to latest head to fix errors on apply in CI testing --- lib/librte_eal/common/eal_common_options.c | 77 +++++++++++++++++++--- 1 file changed, 69 insertions(+), 8 deletions(-) diff --git a/lib/librte_eal/common/eal_common_options.c b/lib/librte_eal/common/eal_common_options.c index 1a836d70f..6978e6744 100644 --- a/lib/librte_eal/common/eal_common_options.c +++ b/lib/librte_eal/common/eal_common_options.c @@ -15,6 +15,7 @@ #include #ifndef RTE_EXEC_ENV_WINDOWS #include +#include #endif #include #include @@ -332,7 +333,14 @@ eal_plugin_add(const char *path) return 0; } -#ifndef RTE_EXEC_ENV_WINDOWS +#ifdef RTE_EXEC_ENV_WINDOWS +int +eal_plugins_init(void) +{ + return 0; +} +#else + static int eal_plugindir_init(const char *path) { @@ -372,12 +380,67 @@ eal_plugindir_init(const char *path) /* XXX this ignores failures from readdir() itself */ return (dent == NULL) ? 0 : -1; } -#endif + +static int +verify_perms(const char *dirpath) +{ + struct stat st; + + /* if not root, check down one level first */ + if (strcmp(dirpath, "/") != 0) { + char copy[PATH_MAX]; + + strlcpy(copy, dirpath, PATH_MAX); + if (verify_perms(dirname(copy)) != 0) + return -1; + } + + /* call stat to check for permissions and ensure not world writable */ + if (stat(dirpath, &st) != 0) { + RTE_LOG(ERR, EAL, "Error with stat on %s, %s\n", + dirpath, strerror(errno)); + return -1; + } + if (st.st_mode & S_IWOTH) { + RTE_LOG(ERR, EAL, + "Error, directory path %s is world-writable and insecure\n", + dirpath); + return -1; + } + + return 0; +} + +static void * +eal_dlopen(const char *pathname) +{ + void *retval = NULL; + char *realp = realpath(pathname, NULL); + + if (realp == NULL) { + RTE_LOG(ERR, EAL, "Error with realpath, %s\n", strerror(errno)); + goto out; + } + if (strnlen(realp, PATH_MAX) == PATH_MAX) { + RTE_LOG(ERR, EAL, "Error, driver path greater than PATH_MAX\n"); + goto out; + } + + /* do permissions checks */ + if (verify_perms(realp) != 0) + goto out; + + retval = dlopen(realp, RTLD_NOW); + if (retval == NULL) + RTE_LOG(ERR, EAL, "%s\n", dlerror()); +out: + free(realp); + return retval; +} int eal_plugins_init(void) { -#ifndef RTE_EXEC_ENV_WINDOWS struct shared_driver *solib = NULL; struct stat sb; @@ -397,17 +460,15 @@ eal_plugins_init(void) } else { RTE_LOG(DEBUG, EAL, "open shared lib %s\n", solib->name); - solib->lib_handle = dlopen(solib->name, RTLD_NOW); - if (solib->lib_handle == NULL) { - RTE_LOG(ERR, EAL, "%s\n", dlerror()); + solib->lib_handle = eal_dlopen(solib->name); + if (solib->lib_handle == NULL) return -1; - } } } -#endif return 0; } +#endif /* * Parse the coremask given as argument (hexadecimal string) and fill -- 2.25.1