From patchwork Thu Aug 8 19:40:52 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yann Droneaud X-Patchwork-Id: 2841364 Return-Path: X-Original-To: patchwork-linux-rdma@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 7B2D7BF546 for ; Thu, 8 Aug 2013 19:53:20 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 747A02035C for ; Thu, 8 Aug 2013 19:53:19 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id A6D302034A for ; Thu, 8 Aug 2013 19:53:14 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S966242Ab3HHTw7 (ORCPT ); Thu, 8 Aug 2013 15:52:59 -0400 Received: from smtp25.services.sfr.fr ([93.17.128.118]:64189 "EHLO smtp25.services.sfr.fr" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S966159Ab3HHTw4 (ORCPT ); Thu, 8 Aug 2013 15:52:56 -0400 Received: from filter.sfr.fr (localhost [127.0.0.1]) by msfrf2506.sfr.fr (SMTP Server) with ESMTP id 2977470000B7; Thu, 8 Aug 2013 21:42:59 +0200 (CEST) Received: from localhost.localdomain (187.20.90.92.rev.sfr.net [92.90.20.187]) by msfrf2506.sfr.fr (SMTP Server) with ESMTP id EF48970000A7; Thu, 8 Aug 2013 21:42:56 +0200 (CEST) X-SFR-UUID: 20130808194256980.EF48970000A7@msfrf2506.sfr.fr Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by localhost.localdomain (8.14.7/8.14.7) with ESMTP id r78Jgt3C003083; Thu, 8 Aug 2013 21:42:55 +0200 Received: (from ydroneaud@localhost) by localhost.localdomain (8.14.7/8.14.7/Submit) id r78Jgt8q003082; Thu, 8 Aug 2013 21:42:55 +0200 From: Yann Droneaud To: linux-rdma@vger.kernel.org Cc: Yann Droneaud Subject: [PATCH libibverbs v2 09/11] Check owner/permissions of config directory/files Date: Thu, 8 Aug 2013 21:40:52 +0200 Message-Id: X-Mailer: git-send-email 1.8.3.1 In-Reply-To: References: In-Reply-To: References: MIME-Version: 1.0 Sender: linux-rdma-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-rdma@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Introduces secure_perms() function to check owner/group and permissions on configuration directory and files. When running an application as root (or setuid), this function will disallow access to configuration directory/files owned by user different from root. It allows current user to use its own configuration directory/files or the ones owned by 'root'. It rejects directory/files writable by all. The behavior of the function 'secure_perms()' was proposed for scrutiny on StackOverflow[1]. It was reviewed by few people, who doesn't found any flaw in the implementation. Note: IBV_CONFIG_DIR is allowed to be a symlink. In case of symlink, the linked directory is opened, its file descriptor is used to check its parameters and is used as base directory with fstatat() and openat(). Once the parameters of the directory are known to be safe, someone moving around the IBV_CONFIG_DIR symlink will have no effect for the current application. Weakness addressed: - CWE-282: Improper Ownership Management - CWE-283: Unverified Ownership - CWE-426: Untrusted Search Path - CWE-427: Uncontrolled Search Path Element - CWE-552: Files or Directories Accessible to External Parties Secure coding: - FIO15-C. Ensure that file operations are performed in a secure directory Links: - [1] c - How to ensure correct file permissions Signed-off-by: Yann Droneaud --- src/init.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/src/init.c b/src/init.c index c2e7bfb..75171e3 100644 --- a/src/init.c +++ b/src/init.c @@ -235,6 +235,29 @@ static void load_drivers(void) } } +static int secure_perms(const struct stat *buf) +{ + uid_t uid; + gid_t gid; + + uid = geteuid(); + gid = getegid(); + + if ((buf->st_mode & S_IWOTH) != 0) { + return 0; + } + + if ((buf->st_gid != 0) && (buf->st_gid != gid)) { + return 0; + } + + if ((buf->st_uid != 0) && (buf->st_uid != uid)) { + return 0; + } + + return 1; +} + static void read_config_file(int conf_dirfd, const char *name) { int fd; @@ -265,6 +288,12 @@ static void read_config_file(int conf_dirfd, const char *name) goto out; } + if (!secure_perms(&buf)) { + fprintf(stderr, PFX "Warning: unsecure config file '%s/%s'.\n", + IBV_CONFIG_DIR, name); + goto out; + } + conf = fdopen(fd, "r" STREAM_CLOEXEC); if (!conf) { fprintf(stderr, PFX "Warning: couldn't read config file '%s/%s'.\n", @@ -344,6 +373,12 @@ static void read_config(void) goto out; } + if (!secure_perms(&buf)) { + fprintf(stderr, PFX "Warning: unsecure config directory '%s'.\n", + IBV_CONFIG_DIR); + goto out; + } + conf_dir = fdopendir(conf_dirfd); if (!conf_dir) { fprintf(stderr, PFX "Warning: couldn't open config directory '%s'.\n",