Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751810AbdIVEKH (ORCPT ); Fri, 22 Sep 2017 00:10:07 -0400 Received: from mail-pf0-f196.google.com ([209.85.192.196]:33985 "EHLO mail-pf0-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750734AbdIVEKF (ORCPT ); Fri, 22 Sep 2017 00:10:05 -0400 X-Google-Smtp-Source: AOwi7QCfxW/o2ZKDowHIXFRuyq53fYbIcNNX9OBlMJJzc0DjxTHTTg2oK0hAWnwYOKu2uCd1zjoArg== Date: Fri, 22 Sep 2017 13:10:10 +0900 Message-ID: <87r2uze5lp.wl-satoru.takeuchi@gmail.com> From: Satoru Takeuchi To: linux-kernel@vger.kernel.org Cc: Jens Axboe , Jan Kara Subject: [PATCH] brd: prevent overflow caused by too large rd_size parameter User-Agent: Wanderlust/2.15.9 (Almost Unreal) SEMI-EPG/1.14.7 (Harue) FLIM/1.14.9 (=?ISO-8859-4?Q?Goj=F2?=) APEL/10.8 EasyPG/1.0.0 Emacs/24.5 (x86_64-pc-linux-gnu) MULE/6.0 (HANACHIRUSATO) MIME-Version: 1.0 (generated by SEMI-EPG 1.14.7 - "Harue") Content-Type: text/plain; charset=US-ASCII Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 1151 Lines: 36 The max value of rd_size parameter is ULONG_MAX from the following commit. Commit 366f4aea649a65c3735d91b4409d84c771811290 ("brd: Switch rd_size to unsigned long") However, this parameter * 1024 will be set as inode->i_size corresponding to brd devices and it's a signed value. To prevent overflow, this parameter should be equal to or smaller than the max value of sector_t >> 11, 10 bits are for 1024 and 1 bit is for sign bit. Signed-off-by: Satoru Takeuchi --- drivers/block/brd.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/block/brd.c b/drivers/block/brd.c index 104b71c..2b00e7d 100644 --- a/drivers/block/brd.c +++ b/drivers/block/brd.c @@ -546,6 +546,14 @@ static int __init brd_init(void) * dynamically. */ + /* + * rd_size * 1024 will be set as its inode->i_size and it's a signed + * value. So rd_size should be equal to or smaller than the max value + * of sector_t >> 11, 10 bits are for 1024 and 1 bit is for sign bit. + */ + if (rd_size >> (sizeof(sector_t) * 8 - 11)) + return -EINVAL; + if (register_blkdev(RAMDISK_MAJOR, "ramdisk")) return -EIO; -- 2.7.4