From patchwork Tue May 12 18:30:55 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Luis R. Rodriguez" X-Patchwork-Id: 6390411 X-Patchwork-Delegate: kvalo@adurom.com Return-Path: X-Original-To: patchwork-linux-wireless@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 600E89F374 for ; Tue, 12 May 2015 18:40:20 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 6EDC620416 for ; Tue, 12 May 2015 18:40:19 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 52923203FB for ; Tue, 12 May 2015 18:40:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933706AbbELSjr (ORCPT ); Tue, 12 May 2015 14:39:47 -0400 Received: from mail-pa0-f44.google.com ([209.85.220.44]:35605 "EHLO mail-pa0-f44.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933013AbbELSjq (ORCPT ); Tue, 12 May 2015 14:39:46 -0400 Received: by pabtp1 with SMTP id tp1so22200428pab.2; Tue, 12 May 2015 11:39:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=xaqw78TeEaLoD/GW2z7fjyOgkxJ4yBGDP5CjC9kIaBI=; b=hmhoksMYlK0B8NVWB9amWYhmoOdVNDEJQI96I9qpTFd6JYh9c3+56CeLZC/mY9QH4G eLNb2T0PDX9af2qCFtKv00Wd+5+YtJVg+zBOdQUFpnktgo2FnO3OUvlfgjml7UEPO8fV MB3NqudfAjijpUsbgVpucKlBIZZkaQkaWaS5yYCSrXQLsCPkvtUHeeHIRWv6MofthcXB JwBEuHXFyxJTH47jPgiShcS/VzsKbHqUPc6/NfP8luj4rfLbbwuFpOFE3+LJPeMnpCWG W1YS+ARNJ7LOvydk3z3gnUG6a07ULJWAFiYCmGBuQAZBPbuHsuhIHhpyDdyWl8IOf5B9 Bj8w== X-Received: by 10.70.128.36 with SMTP id nl4mr30664086pdb.43.1431455984518; Tue, 12 May 2015 11:39:44 -0700 (PDT) Received: from mcgrof@gmail.com (c-98-234-145-61.hsd1.ca.comcast.net. [98.234.145.61]) by mx.google.com with ESMTPSA id nz7sm16923673pbb.40.2015.05.12.11.39.42 (version=TLSv1 cipher=RC4-SHA bits=128/128); Tue, 12 May 2015 11:39:43 -0700 (PDT) Received: by mcgrof@gmail.com (sSMTP sendmail emulation); Tue, 12 May 2015 11:37:34 -0700 From: "Luis R. Rodriguez" To: ming.lei@canonical.com, rusty@rustcorp.com.au Cc: dhowells@redhat.com, seth.forshee@canonical.com, torvalds@linux-foundation.org, linux-kernel@vger.kernel.org, pebolle@tiscali.nl, linux-wireless@vger.kernel.org, "Luis R. Rodriguez" , Kyle McMartin Subject: [PATCH v2 3/5] firmware: check for possible file truncation early Date: Tue, 12 May 2015 11:30:55 -0700 Message-Id: <1431455457-25322-4-git-send-email-mcgrof@do-not-panic.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1431455457-25322-1-git-send-email-mcgrof@do-not-panic.com> References: <1431455457-25322-1-git-send-email-mcgrof@do-not-panic.com> Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org X-Spam-Status: No, score=-6.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID,T_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 From: "Luis R. Rodriguez" Instead of waiting until the last second to fail on a request_firmware*() calls due to filename truncation we can do an early check upon boot and immediatley avoid any possible issues upfront. Cc: Linus Torvalds Cc: Ming Lei Cc: Rusty Russell Cc: David Howells Cc: Kyle McMartin Signed-off-by: Luis R. Rodriguez --- drivers/base/firmware_class.c | 49 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 46 insertions(+), 3 deletions(-) diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index 99385fc..448388b 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c @@ -38,6 +38,20 @@ MODULE_AUTHOR("Manuel Estrada Sainz"); MODULE_DESCRIPTION("Multi purpose firmware loading support"); MODULE_LICENSE("GPL"); +static size_t __read_mostly max_sysdata_path_size; + +static int sysdata_validate_filename(const char *name) +{ + if (!name) + return -EINVAL; + /* POSIX.1 2.4: an empty pathname is invalid, match other checks */ + if (name[0] == '\0') + return -ENOENT; + if (strlen(name) > (PATH_MAX - max_sysdata_path_size)) + return -ENAMETOOLONG; + return 0; +} + /* Builtin firmware support */ #ifdef CONFIG_FW_LOADER @@ -1105,9 +1119,6 @@ _request_firmware(const struct firmware **firmware_p, const char *name, if (!firmware_p) return -EINVAL; - if (!name || name[0] == '\0') - return -EINVAL; - ret = _request_firmware_prepare(&fw, name, device); if (ret <= 0) /* error or already assigned */ goto out; @@ -1185,6 +1196,10 @@ request_firmware(const struct firmware **firmware_p, const char *name, { int ret; + ret = sysdata_validate_filename(name); + if (ret) + return ret; + /* Need to pin this module until return */ __module_get(THIS_MODULE); ret = _request_firmware(firmware_p, name, device, @@ -1210,6 +1225,10 @@ int request_firmware_direct(const struct firmware **firmware_p, { int ret; + ret = sysdata_validate_filename(name); + if (ret) + return ret; + __module_get(THIS_MODULE); ret = _request_firmware(firmware_p, name, device, FW_OPT_UEVENT | FW_OPT_NO_WARN); @@ -1288,8 +1307,13 @@ request_firmware_nowait( const char *name, struct device *device, gfp_t gfp, void *context, void (*cont)(const struct firmware *fw, void *context)) { + int ret; struct firmware_work *fw_work; + ret = sysdata_validate_filename(name); + if (ret) + return ret; + fw_work = kzalloc(sizeof(struct firmware_work), gfp); if (!fw_work) return -ENOMEM; @@ -1668,8 +1692,27 @@ static void __init fw_cache_init(void) #endif } +static size_t __init get_max_sysdata_path(void) +{ + size_t max_size = 0; + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(fw_path); i++) { + size_t path_size; + /* skip the unset customized path */ + if (!fw_path[i][0]) + continue; + path_size = strlen(fw_path[i]); + if (path_size > max_size) + max_size = path_size; + } + + return max_size; +} + static int __init firmware_class_init(void) { + max_sysdata_path_size = get_max_sysdata_path(); fw_cache_init(); #ifdef CONFIG_FW_LOADER_USER_HELPER register_reboot_notifier(&fw_shutdown_nb);