Message ID | 20221017194447.2579441-1-jane.chu@oracle.com |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:4ac7:0:0:0:0:0 with SMTP id y7csp1618627wrs; Mon, 17 Oct 2022 13:01:16 -0700 (PDT) X-Google-Smtp-Source: AMsMyM5bkUXWGUpsX6iSkxxcZnpN1bM3Ly2z/m1x496kaCPqNqxhCuK1rOKXZ+WM/57QoagwsylZ X-Received: by 2002:a63:2212:0:b0:43b:f03d:856a with SMTP id i18-20020a632212000000b0043bf03d856amr12065305pgi.192.1666036875936; Mon, 17 Oct 2022 13:01:15 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1666036875; cv=pass; d=google.com; s=arc-20160816; b=fYh9x9Po/4PlPh2ouHEHPlq7vkAJbm99TDOGZoKH7Ojzv3A9F4uCxkQRzfomAXArDX u69q7r/7DrRjW+rAWr8YqIfydWZp1eY7To+cv2HSWeGOMpEMsCt1pV/DDlJrE4ncA8Qj TOAu7Wg4opOocRcOAaQDUu2IYpz2wD88sNUFS2+sDe73H6fLgj4lkBOe3qc/UapSEcxX JLeUspGxsZgoMlWk5W7/1hO1WHxcmHZFSy5AyT1ce6f32yvcH64gmoKCZD+Kbl+SdeQw tLFshz1VQ6fSYYH1b7nZuuv11qx428pdRoqLDsnFOx2oW2IEnxjYOHIfp9B9egDaiTJ5 2kjg== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:mime-version:message-id:date:subject:cc:to:from :dkim-signature:dkim-signature; bh=nYBnln3qvMlYaKkUsMs1rDnaohZQO4eL5A8SBO5Hec0=; b=P0Gwe+b830BucEg7y1QjnW74F5C5WMslFaMYSV4Ytx6ng4M1LOaAPjSzImJplri/ZF HUn6/rYdXniwOln6h51U7esGVjIfUIwvg9bkVYYSkp6wzpc3tS/4uCxLxx0cyg3HTqsv 6u/TjZo6i/auVbdMDquaIr0B/fq7s1nBHa7rpgRTCHZChSdB+iTeC4/jmoZnd2fYXTyM UuVJAJRRN3wJyGF8d+3W0DR1nRts38VMY4vwbcf6I+1qU/rAg7p/G5TjrKhu5xtAUZnS YPyOw/cYm0bjVu5EXHG/1gIgMYo0l+RIlugSiL7K0JqRdEg9iz0eOJtpmsPgkx1/u7yr DX1w== ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@oracle.com header.s=corp-2022-7-12 header.b="QBVe2JX/"; dkim=pass header.i=@oracle.onmicrosoft.com header.s=selector2-oracle-onmicrosoft-com header.b=vNaMr5Wm; arc=pass (i=1 spf=pass spfdomain=oracle.com dkim=pass dkdomain=oracle.com dmarc=pass fromdomain=oracle.com); spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=oracle.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id g21-20020a056a00079500b0056304fa365asi11299575pfu.177.2022.10.17.13.01.00; Mon, 17 Oct 2022 13:01:15 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@oracle.com header.s=corp-2022-7-12 header.b="QBVe2JX/"; dkim=pass header.i=@oracle.onmicrosoft.com header.s=selector2-oracle-onmicrosoft-com header.b=vNaMr5Wm; arc=pass (i=1 spf=pass spfdomain=oracle.com dkim=pass dkdomain=oracle.com dmarc=pass fromdomain=oracle.com); spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=oracle.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230450AbiJQTp3 (ORCPT <rfc822;kernel.ruili@gmail.com> + 99 others); Mon, 17 Oct 2022 15:45:29 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36138 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229950AbiJQTpS (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Mon, 17 Oct 2022 15:45:18 -0400 Received: from mx0a-00069f02.pphosted.com (mx0a-00069f02.pphosted.com [205.220.165.32]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D133C719B0 for <linux-kernel@vger.kernel.org>; Mon, 17 Oct 2022 12:45:08 -0700 (PDT) Received: from pps.filterd (m0246629.ppops.net [127.0.0.1]) by mx0b-00069f02.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id 29HJi40D025291; Mon, 17 Oct 2022 19:45:03 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=from : to : cc : subject : date : message-id : content-type : mime-version; s=corp-2022-7-12; bh=nYBnln3qvMlYaKkUsMs1rDnaohZQO4eL5A8SBO5Hec0=; b=QBVe2JX/AiGhMdKzSRcDx5VXA6gZTmp0uWm9ichFvTYuJU5779RusPfZq2k8YsWjVv2K +bp7LkDi1EACpFEyeIEYE1u0TKJD9zCOR4D6H0W2v+jB/g+n0rNsgAoi4i9lFsDOHM1+ xqjiTHZmWdSi/dvqQFUGoomPcVB7cz5WMcjVQNG2W6fVg4HDJYB5KpeuCBq3WZ+BIOyl g+Z73DKE0WeOEcAXJ5M+/o9ao/7hIkUjV3Hr6THdpqf13dBAkT2QoJL00xx7rtZbP6g9 yLk/TXXzAviBurjj7V+9/ldkbeKXQ98P2nrpYBtwVx7OSdrAcB9wQMbf7iEA7sNpuM+a Ng== Received: from phxpaimrmta02.imrmtpd1.prodappphxaev1.oraclevcn.com (phxpaimrmta02.appoci.oracle.com [147.154.114.232]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 3k9aww0fqh-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Mon, 17 Oct 2022 19:45:02 +0000 Received: from pps.filterd (phxpaimrmta02.imrmtpd1.prodappphxaev1.oraclevcn.com [127.0.0.1]) by phxpaimrmta02.imrmtpd1.prodappphxaev1.oraclevcn.com (8.17.1.5/8.17.1.5) with ESMTP id 29HIVeh0019193; Mon, 17 Oct 2022 19:45:02 GMT Received: from nam02-sn1-obe.outbound.protection.outlook.com (mail-sn1anam02lp2043.outbound.protection.outlook.com [104.47.57.43]) by phxpaimrmta02.imrmtpd1.prodappphxaev1.oraclevcn.com (PPS) with ESMTPS id 3k8j0pm558-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Mon, 17 Oct 2022 19:45:02 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=l67gC2TUH0p7r56KxWo/YB9z3g7yirPIIEtrCIRKMPTD07+0HMHiEf1j0G8s+OrughZ2epGvJQnPoJEXDI2FCRlHPWT11pr0wGtLjJjb0kGkSekxgMyN3ZthLoLfzkwSZsvLlTf3d48A8DDrJm9+Na1Rq7XwsMz39w/PBn6GVB/4sLtoKEiI4XTMnZLPaCcI90SUO+pzPLAM8/AHlJx/BKdcEl3ZNPQjYrney5Oumipmyyzqc9aSIk8XM8dILCgko085EkmHGeentKY4Rpi1IXYmq2o2WDEBJIyZqt1kcHGqocd4LdlmaovSQ2Ca2KzBbDyRw9cfRY29JDv+wpFyVg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=nYBnln3qvMlYaKkUsMs1rDnaohZQO4eL5A8SBO5Hec0=; b=CRNjn+f0Ek4PTk61RRzq8+Jzk+XYn5iZgwDGzPt2tsOBgrUlSXBRt4MPwIg8qtjvDuxBhPzBDJQ6I+TAh8z8DgCUMHZY3uxVyOI5tLHPUegNnWN3PYLwNiqut685IRB9KWh6PvGAozX2a6tizF0vb6dt6HH6o0Weyc/24LLf7OQREbfTu/pg7qgKfvTze379aNx6ZgmroBnTljX3SftdEyHq/hBK7Fi7ZejxNW4SrMWWqR1dS9800HxoTEzeNFHA6raZhd8ZGUdpFOpkzUmupF9upj14+uNRRGnDtBCJCUlReoC/5/He3EWCtLbqcmk/CTYefQaTFnzQxIeDvdDxGA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=oracle.com; dmarc=pass action=none header.from=oracle.com; dkim=pass header.d=oracle.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.onmicrosoft.com; s=selector2-oracle-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=nYBnln3qvMlYaKkUsMs1rDnaohZQO4eL5A8SBO5Hec0=; b=vNaMr5WmS23QckuQXgMfnmwsSO6w3ZrNVmOBpIf3yxgGiqUe7LnjJqQk1PeWnxtjH+5HaX3UmaM203lruwNUUyL6+kY9T2izuTfM+y0XV5g9YnJRh7Ao6ukIpb76pN23+N/YtYEPztsY0l1XrubyqOISVnorEh8p8TRUa/ohKOY= Received: from SJ0PR10MB4429.namprd10.prod.outlook.com (2603:10b6:a03:2d1::14) by CH2PR10MB4215.namprd10.prod.outlook.com (2603:10b6:610:7e::7) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5723.30; Mon, 17 Oct 2022 19:44:59 +0000 Received: from SJ0PR10MB4429.namprd10.prod.outlook.com ([fe80::b281:7552:94f5:4606]) by SJ0PR10MB4429.namprd10.prod.outlook.com ([fe80::b281:7552:94f5:4606%7]) with mapi id 15.20.5723.033; Mon, 17 Oct 2022 19:44:59 +0000 From: Jane Chu <jane.chu@oracle.com> To: pmladek@suse.com, rostedt@goodmis.org, senozhatsky@chromium.org, andriy.shevchenko@linux.intel.com, linux@rasmusvillemoes.dk, linux-kernel@vger.kernel.org Cc: jane.chu@oracle.com Subject: [PATCH v2] vsprintf: protect kernel from panic due to non-canonical pointer dereference Date: Mon, 17 Oct 2022 13:44:47 -0600 Message-Id: <20221017194447.2579441-1-jane.chu@oracle.com> X-Mailer: git-send-email 2.18.4 Content-Type: text/plain X-ClientProxiedBy: SA9PR03CA0028.namprd03.prod.outlook.com (2603:10b6:806:20::33) To SJ0PR10MB4429.namprd10.prod.outlook.com (2603:10b6:a03:2d1::14) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SJ0PR10MB4429:EE_|CH2PR10MB4215:EE_ X-MS-Office365-Filtering-Correlation-Id: cb64f30e-14de-408b-53b7-08dab078133c X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: 8SFvkzBrx05K5gBQy+oWMRr62HfycZT/poHAbOfG6ucygf4gnIGcXFj2ld8ElpPXjkG1yQDe3BOEhphS9blrkxI3vud0TY4pC8Qj71Y2h9HnjGVYv9zWttUzqx9HAUI0+fT7G4VCoymPCzGPp/AzZEG1Qx8NvKWZBprfVXkZqlws3wn9GFjdgzGJyzzC5VcKYwsTd/vE62VtcWeNEOwGUegP+DipGKN9d+11b8NpaAYec65mVO8wa//BOwd7VHRkQ+tTb8lc4lYtjrzMelIEIGcyMZD8Ij/kdQslFYLjuYFbQ/l9yJsxnomcvEbrx1vleI6ce7QnT91es0kYmmUhi9+qg/rrn3j9ESC+XznTXbZfV7ThBe7Quuqa5NSZ1Wg/Yc8z0oucda6fcLISbEKnyM8Mjt3laIsGNiOti4nATkf4XSrPFwd8tywj+q1PuJIeAdJUsUDVaYwgv7Ojkc/fRjznsTuRDP/l+GtncfhW6P8sWOhlvO7KOEogDhLJ0b4YPh/DQUd+iFXLw+QgyH+zq5ppiEOMplzjlKF2tO1Tw3beG6quOeKqaNmZ41peMXA2rj7IjzzlMFF4xce11dzmzmQV4FfWqJs77mWbwFcf6NsltGJBybV9S6/RPm+hBE6tfkjfm40/ZDW5eTh+qRWWPF/yDqLwSQ/M03L+yB0MVPs94IvxQSCLm8xhIvvYZuSDu0u8h1900D/Kf2oTwPTp+w== X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:SJ0PR10MB4429.namprd10.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230022)(366004)(396003)(39860400002)(136003)(376002)(346002)(451199015)(38100700002)(86362001)(6666004)(107886003)(41300700001)(6506007)(52116002)(316002)(6512007)(5660300002)(8936002)(4326008)(6486002)(478600001)(44832011)(36756003)(66476007)(8676002)(4744005)(66946007)(66556008)(186003)(1076003)(2616005)(2906002);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: xBELa0ei9x3pF3Z3K6F5/0kzzB+3GTp2U0TduH8J+2cl82pY/LzSxE9djvg7gUo0+TuJqNb9Rqigtq1MVtCiC9P8UnWNk1jneY8u2ttudK2CnMk0132vjfOHmTl6mJYnIGXIGurAJ6gsqItzzDc/9Vxlj9DdOUQttUvVaC8gs6wNqIglmBwIFJqXxC1UxPBWjAIK6dvCQUyPBpozq7LCBu51WadZmJEe7ZLm4FWnPf5o5+NoLpZl/psJ3D0FVZy7A1DSNwJSQ2gsAY0p+g66AfP5pfYTc8EvWQIJN5pFbQh/3/yva8tFNCqGe4mpgsFtvpirQ50+lXUjd+qjCajLzfaQ2JL6yMNUATHUcFofd3xUj8Rfz0MkLJlZoMjI8wQ8SQtTbn8LbF/dM93qTvUiPgny1Dr+HY0jzd0ZVuTtcpugjxW0AgEHpRbiq3l6R43Jdd74M5mfy9nHLA3EyPRVGEYYLhQR1KOcY+39sMocIhTj1S1CvaZOJCaQSCTmmUIE4r0WuJM23SbMAAAZi7KTSJWO2x+tfuF1GvXDSXfyB49y88f815SO+nBhDkMFZSB6hKbXHQ7mvkGe5+1vS3oDzzs62MuiycfE2FgciB7/nU1duq2PZob9fXgP+J+vKSbexpXb4LjUcYKOg0zfrnrVBtVhjgKhf0KY25FaG/PLhNNDBKf9WyrjfW5YltlkDrf5Go0vIBQJmtqbwE814Kfv7pIX1Sx2HGlxtuVU9E+MFTticQ9P305tBAXewpflZrAWrdndrIBmG4mIpsDIG7Am9UlladWO1M3KBZtwTA6Gt9UqHTK40S38yuN74xHkQ1OQB223JsAzGavNbmErO8aGi9DJrYAzh1jBjHFuJdpHABBYEQpPaas7PbpUDun3sO/3ny4j/k9hj5zZvD+DszKmGBWxUnb0Pdf/VnUvPozTAoKcIKWYTWnWXAjPtgsUAD7lkq5aFiv4JubFqVNxHDvc1id9zDfwtX0oeZ7l+n7WcjqIFWHYzKyTCm8TzTxgoLlQce3Gepaa7vkezqFto0PYOvP4QSGqkMp+E4VoyQ8mABJTV6340Ne+VxQQliVP1KJ1/QVWDEK2rmmv+vKGM2sjE1voVtG+YENCA6qRiAnq1224Gzu5atRML45fspC7QZLtzPzZ6kq+sRS2RHCWTzJZGKS8RuQvlNq+Tm0TMhGMcrq3BrtsTsMr7vmYVWoxTD4QbLqterb8mYrsZvxcUmh52gk2j0dlKt6C62vHmoEeBB+Y+Derj0RmPmUduVD5OXM9hqCYh2u8nb+YXwQ34Tb7XpAH5UWGCv6NEk0ZDoZYUwAsLW9qtuLnCuLASoBY63QuaIC/c+xkMMkmeIoRAb6BUb8Q2v92+psbuFUL1E1iqQrxGWCD6mjUWgRA5OnXlcAdadaX4dLfYJc545xnDhRNHGoU2JykxfRRl3tnCePNf49qB6fSDQOr7jS17XihImEl0gmD4a3t3pH1DNpjeiE5aBqjeuFgpqFe9A5cyu6a926je1mHq8YGEBe4YTXz/5ZeTzzebnrsvEVmGyOuk1EjEwisvV90WukSECf6yl8FIFa3D6G0yx2349X1LsXj3QBHNQwr/cupJjo7vbAYBZIsew== X-OriginatorOrg: oracle.com X-MS-Exchange-CrossTenant-Network-Message-Id: cb64f30e-14de-408b-53b7-08dab078133c X-MS-Exchange-CrossTenant-AuthSource: SJ0PR10MB4429.namprd10.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 17 Oct 2022 19:44:59.3329 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 4e2c6054-71cb-48f1-bd6c-3a9705aca71b X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: kyWJBuniu+GNrCK27SlpJe+UjHoPA9PIVj2xUZF1zxhqhqV+chyOLiexpYODtONFkoWJ2E1fhYECvgV9iMNKvQ== X-MS-Exchange-Transport-CrossTenantHeadersStamped: CH2PR10MB4215 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.895,Hydra:6.0.545,FMLib:17.11.122.1 definitions=2022-10-17_13,2022-10-17_02,2022-06-22_01 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 spamscore=0 bulkscore=0 mlxscore=0 suspectscore=0 mlxlogscore=999 phishscore=0 malwarescore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2209130000 definitions=main-2210170113 X-Proofpoint-GUID: D6Hl7ionjuajXnW6wsRnf-pXPwmZ2LXk X-Proofpoint-ORIG-GUID: D6Hl7ionjuajXnW6wsRnf-pXPwmZ2LXk X-Spam-Status: No, score=-2.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,SPF_NONE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: <linux-kernel.vger.kernel.org> X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1746963705611837473?= X-GMAIL-MSGID: =?utf-8?q?1746966283517732467?= |
Series |
[v2] vsprintf: protect kernel from panic due to non-canonical pointer dereference
|
|
Commit Message
Jane Chu
Oct. 17, 2022, 7:44 p.m. UTC
While debugging a separate issue, it was found that an invalid string
pointer could very well contain a non-canical address, such as
0x7665645f63616465. In that case, this line of defense isn't enough
to protect the kernel from crashing due to general protection fault
if ((unsigned long)ptr < PAGE_SIZE || IS_ERR_VALUE(ptr))
return "(efault)";
So run one more round of check via kern_addr_valid(). On architectures
that provide meaningful implementation, this line of check effectively
catches non-canonical pointers, etc.
Signed-off-by: Jane Chu <jane.chu@oracle.com>
---
lib/vsprintf.c | 3 +++
1 file changed, 3 insertions(+)
Comments
On Mon, Oct 17, 2022 at 01:44:47PM -0600, Jane Chu wrote: > While debugging a separate issue, it was found that an invalid string > pointer could very well contain a non-canical address, such as non-canical? > 0x7665645f63616465. In that case, this line of defense isn't enough > to protect the kernel from crashing due to general protection fault > > if ((unsigned long)ptr < PAGE_SIZE || IS_ERR_VALUE(ptr)) > return "(efault)"; > > So run one more round of check via kern_addr_valid(). On architectures > that provide meaningful implementation, this line of check effectively > catches non-canonical pointers, etc. OK, but I don't see how this is useful in the form of returning efault here. Ideally we should inform user that the pointer is wrong and how it's wrong. But. It will crash somewhere else at some point, right? I mean that there is no guarantee that kernel has protection in every single place against dangling / invalid pointers. One way or another it will crash. That said, honestly I have no idea how this patch may be considered anything but band-aid. OTOH, I don't see a harm. Perhaps others will share their opinions.
On 10/17/2022 1:27 PM, Andy Shevchenko wrote: > On Mon, Oct 17, 2022 at 01:44:47PM -0600, Jane Chu wrote: >> While debugging a separate issue, it was found that an invalid string >> pointer could very well contain a non-canical address, such as > > non-canical? Sorry, typo, will fix. > >> 0x7665645f63616465. In that case, this line of defense isn't enough >> to protect the kernel from crashing due to general protection fault >> >> if ((unsigned long)ptr < PAGE_SIZE || IS_ERR_VALUE(ptr)) >> return "(efault)"; >> >> So run one more round of check via kern_addr_valid(). On architectures >> that provide meaningful implementation, this line of check effectively >> catches non-canonical pointers, etc. > > OK, but I don't see how this is useful in the form of returning efault here. > Ideally we should inform user that the pointer is wrong and how it's wrong. > But. It will crash somewhere else at some point, right? Broadly speaking, yes. It's not a perfect line of defense, but again, the bug scenario is a "cat" of some sysfs attributes that leads to panic. Does it make sense for kernel to protect itself against panic triggered by a "cat" from user if it could? I mean that there > is no guarantee that kernel has protection in every single place against > dangling / invalid pointers. One way or another it will crash. > > That said, honestly I have no idea how this patch may be considered > anything but band-aid. OTOH, I don't see a harm. Perhaps others will > share their opinions. > 3+ years ago, commit 3e5903eb9cff7 ("vsprintf: Prevent crash when dereferencing invalid pointers") provided the similar level of protection as this patch. But it was soon revised by commit 2ac5a3bf7042a ("vsprintf: Do not break early boot with probing addresses"), and that's why the string() utility no longer detects non-canonical string pointer. I only thought that kern_addr_valid() is less of a heavy hammer, and could be safely deployed. thanks, -jane
Hi Jane,
Thank you for the patch! Perhaps something to improve:
[auto build test WARNING on linus/master]
[also build test WARNING on v6.1-rc1 next-20221018]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Jane-Chu/vsprintf-protect-kernel-from-panic-due-to-non-canonical-pointer-dereference/20221018-034659
patch link: https://lore.kernel.org/r/20221017194447.2579441-1-jane.chu%40oracle.com
patch subject: [PATCH v2] vsprintf: protect kernel from panic due to non-canonical pointer dereference
config: i386-randconfig-a005
compiler: gcc-11 (Debian 11.3.0-8) 11.3.0
reproduce (this is a W=1 build):
# https://github.com/intel-lab-lkp/linux/commit/63a24b7174d63b2daa240f00f66913649cb8ae84
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review Jane-Chu/vsprintf-protect-kernel-from-panic-due-to-non-canonical-pointer-dereference/20221018-034659
git checkout 63a24b7174d63b2daa240f00f66913649cb8ae84
# save the config file
mkdir build_dir && cp config build_dir/.config
make W=1 O=build_dir ARCH=i386 SHELL=/bin/bash
If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <lkp@intel.com>
All warnings (new ones prefixed by >>):
lib/vsprintf.c: In function 'va_format':
lib/vsprintf.c:1688:9: warning: function 'va_format' might be a candidate for 'gnu_printf' format attribute [-Wsuggest-attribute=format]
1688 | buf += vsnprintf(buf, end > buf ? end - buf : 0, va_fmt->fmt, va);
| ^~~
lib/vsprintf.c: In function 'dentry_name':
>> lib/vsprintf.c:937:18: warning: array subscript -1 is below array bounds of 'const char *[4]' [-Warray-bounds]
937 | s = array[--i];
| ~~~~~^~~~~
lib/vsprintf.c:908:21: note: while referencing 'array'
908 | const char *array[4], *s;
| ^~~~~
vim +937 lib/vsprintf.c
6eea242f9bcdf8 Petr Mladek 2019-04-17 903
4b6ccca701ef59 Al Viro 2013-09-03 904 static noinline_for_stack
4b6ccca701ef59 Al Viro 2013-09-03 905 char *dentry_name(char *buf, char *end, const struct dentry *d, struct printf_spec spec,
4b6ccca701ef59 Al Viro 2013-09-03 906 const char *fmt)
4b6ccca701ef59 Al Viro 2013-09-03 907 {
4b6ccca701ef59 Al Viro 2013-09-03 908 const char *array[4], *s;
4b6ccca701ef59 Al Viro 2013-09-03 909 const struct dentry *p;
4b6ccca701ef59 Al Viro 2013-09-03 910 int depth;
4b6ccca701ef59 Al Viro 2013-09-03 911 int i, n;
4b6ccca701ef59 Al Viro 2013-09-03 912
4b6ccca701ef59 Al Viro 2013-09-03 913 switch (fmt[1]) {
4b6ccca701ef59 Al Viro 2013-09-03 914 case '2': case '3': case '4':
4b6ccca701ef59 Al Viro 2013-09-03 915 depth = fmt[1] - '0';
4b6ccca701ef59 Al Viro 2013-09-03 916 break;
4b6ccca701ef59 Al Viro 2013-09-03 917 default:
4b6ccca701ef59 Al Viro 2013-09-03 918 depth = 1;
4b6ccca701ef59 Al Viro 2013-09-03 919 }
4b6ccca701ef59 Al Viro 2013-09-03 920
4b6ccca701ef59 Al Viro 2013-09-03 921 rcu_read_lock();
4b6ccca701ef59 Al Viro 2013-09-03 922 for (i = 0; i < depth; i++, d = p) {
3e5903eb9cff70 Petr Mladek 2019-04-17 923 if (check_pointer(&buf, end, d, spec)) {
3e5903eb9cff70 Petr Mladek 2019-04-17 924 rcu_read_unlock();
3e5903eb9cff70 Petr Mladek 2019-04-17 925 return buf;
3e5903eb9cff70 Petr Mladek 2019-04-17 926 }
3e5903eb9cff70 Petr Mladek 2019-04-17 927
6aa7de059173a9 Mark Rutland 2017-10-23 928 p = READ_ONCE(d->d_parent);
6aa7de059173a9 Mark Rutland 2017-10-23 929 array[i] = READ_ONCE(d->d_name.name);
4b6ccca701ef59 Al Viro 2013-09-03 930 if (p == d) {
4b6ccca701ef59 Al Viro 2013-09-03 931 if (i)
4b6ccca701ef59 Al Viro 2013-09-03 932 array[i] = "";
4b6ccca701ef59 Al Viro 2013-09-03 933 i++;
4b6ccca701ef59 Al Viro 2013-09-03 934 break;
4b6ccca701ef59 Al Viro 2013-09-03 935 }
4b6ccca701ef59 Al Viro 2013-09-03 936 }
4b6ccca701ef59 Al Viro 2013-09-03 @937 s = array[--i];
4b6ccca701ef59 Al Viro 2013-09-03 938 for (n = 0; n != spec.precision; n++, buf++) {
4b6ccca701ef59 Al Viro 2013-09-03 939 char c = *s++;
4b6ccca701ef59 Al Viro 2013-09-03 940 if (!c) {
4b6ccca701ef59 Al Viro 2013-09-03 941 if (!i)
4b6ccca701ef59 Al Viro 2013-09-03 942 break;
4b6ccca701ef59 Al Viro 2013-09-03 943 c = '/';
4b6ccca701ef59 Al Viro 2013-09-03 944 s = array[--i];
4b6ccca701ef59 Al Viro 2013-09-03 945 }
4b6ccca701ef59 Al Viro 2013-09-03 946 if (buf < end)
4b6ccca701ef59 Al Viro 2013-09-03 947 *buf = c;
4b6ccca701ef59 Al Viro 2013-09-03 948 }
4b6ccca701ef59 Al Viro 2013-09-03 949 rcu_read_unlock();
cfccde04e28d26 Rasmus Villemoes 2016-01-15 950 return widen_string(buf, n, end, spec);
4b6ccca701ef59 Al Viro 2013-09-03 951 }
4b6ccca701ef59 Al Viro 2013-09-03 952
On Mon 2022-10-17 21:12:04, Jane Chu wrote: > On 10/17/2022 1:27 PM, Andy Shevchenko wrote: > > On Mon, Oct 17, 2022 at 01:44:47PM -0600, Jane Chu wrote: > >> While debugging a separate issue, it was found that an invalid string > >> pointer could very well contain a non-canical address, such as > > > > non-canical? > > Sorry, typo, will fix. > > > > >> 0x7665645f63616465. In that case, this line of defense isn't enough > >> to protect the kernel from crashing due to general protection fault > >> > >> if ((unsigned long)ptr < PAGE_SIZE || IS_ERR_VALUE(ptr)) > >> return "(efault)"; > >> > >> So run one more round of check via kern_addr_valid(). On architectures > >> that provide meaningful implementation, this line of check effectively > >> catches non-canonical pointers, etc. > > > > OK, but I don't see how this is useful in the form of returning efault here. > > Ideally we should inform user that the pointer is wrong and how it's wrong. > > But. It will crash somewhere else at some point, right? > Broadly speaking, yes. It's not a perfect line of defense, but again, > the bug scenario is a "cat" of some sysfs attributes that leads to > panic. Does it make sense for kernel to protect itself against panic > triggered by a "cat" from user if it could? From my view, the check might be useful. I agree with Andy that the broken pointer would cause crash later anyway. But the check in vsprintf() would allow to see a message that the pointer was wrong before the system crashes. That said, this was much more important in the past when printk() called vsprintf() under logbuf_lock. Nested printk() calls were redirected to per-CPU buffers and eventually lost. It works better now when printk() uses lockless ringbuffer and vsprintf() is called twice there. The first call is used to get the string length so that it could reserve the needed space in the ring buffer. If vsprintf() crashes during the 1st call then it would be possible to print the nested Oops messages. > I mean that there > > is no guarantee that kernel has protection in every single place against > > dangling / invalid pointers. One way or another it will crash. > > > > That said, honestly I have no idea how this patch may be considered > > anything but band-aid. OTOH, I don't see a harm. Perhaps others will > > share their opinions. > > > > 3+ years ago, commit 3e5903eb9cff7 ("vsprintf: Prevent crash when > dereferencing invalid pointers") provided the similar level of > protection as this patch. But it was soon revised by commit > 2ac5a3bf7042a ("vsprintf: Do not break early boot with probing > addresses"), and that's why the string() utility no longer detects > non-canonical string pointer. > > I only thought that kern_addr_valid() is less of a heavy hammer, and > could be safely deployed. Hmm, I see that kern_addr_valid() is available (defined) only on some architectures. This patch would break build on architectures where it is not defined. Also it is used only when reading /proc/kcore. It means that it is not tested during early boot. I wonder if it actually works during the very early boot. Result: The patch is not usable as is. IMHO, it is not worth the effort to get it working. Especially when printk() should be able to show Oops inside vsprintf() these days. Regards, Petr
On 10/18/2022 12:40 AM, Petr Mladek wrote: > On Mon 2022-10-17 21:12:04, Jane Chu wrote: >> On 10/17/2022 1:27 PM, Andy Shevchenko wrote: >>> On Mon, Oct 17, 2022 at 01:44:47PM -0600, Jane Chu wrote: >>>> While debugging a separate issue, it was found that an invalid string >>>> pointer could very well contain a non-canical address, such as >>> >>> non-canical? >> >> Sorry, typo, will fix. >> >>> >>>> 0x7665645f63616465. In that case, this line of defense isn't enough >>>> to protect the kernel from crashing due to general protection fault >>>> >>>> if ((unsigned long)ptr < PAGE_SIZE || IS_ERR_VALUE(ptr)) >>>> return "(efault)"; >>>> >>>> So run one more round of check via kern_addr_valid(). On architectures >>>> that provide meaningful implementation, this line of check effectively >>>> catches non-canonical pointers, etc. >>> >>> OK, but I don't see how this is useful in the form of returning efault here. >>> Ideally we should inform user that the pointer is wrong and how it's wrong. >>> But. It will crash somewhere else at some point, right? >> Broadly speaking, yes. It's not a perfect line of defense, but again, >> the bug scenario is a "cat" of some sysfs attributes that leads to >> panic. Does it make sense for kernel to protect itself against panic >> triggered by a "cat" from user if it could? > > From my view, the check might be useful. I agree with Andy that the > broken pointer would cause crash later anyway. But the check > in vsprintf() would allow to see a message that the pointer was > wrong before the system crashes. > > That said, this was much more important in the past when printk() > called vsprintf() under logbuf_lock. Nested printk() calls > were redirected to per-CPU buffers and eventually lost. > > It works better now when printk() uses lockless ringbuffer and > vsprintf() is called twice there. The first call is used > to get the string length so that it could reserve the needed > space in the ring buffer. If vsprintf() crashes during the 1st call > then it would be possible to print the nested Oops messages. > > >> I mean that there >>> is no guarantee that kernel has protection in every single place against >>> dangling / invalid pointers. One way or another it will crash. >>> >>> That said, honestly I have no idea how this patch may be considered >>> anything but band-aid. OTOH, I don't see a harm. Perhaps others will >>> share their opinions. >>> >> >> 3+ years ago, commit 3e5903eb9cff7 ("vsprintf: Prevent crash when >> dereferencing invalid pointers") provided the similar level of >> protection as this patch. But it was soon revised by commit >> 2ac5a3bf7042a ("vsprintf: Do not break early boot with probing >> addresses"), and that's why the string() utility no longer detects >> non-canonical string pointer. >> >> I only thought that kern_addr_valid() is less of a heavy hammer, and >> could be safely deployed. > > Hmm, I see that kern_addr_valid() is available (defined) only on some > architectures. This patch would break build on architectures where it > is not defined. > > Also it is used only when reading /proc/kcore. It means that it is not > tested during early boot. I wonder if it actually works during > the very early boot. > > Result: > > The patch is not usable as is. > > IMHO, it is not worth the effort to get it working. Especially when > printk() should be able to show Oops inside vsprintf() these days. Yes, kern_addr_valid() is used by read_kcore() which is architecturally independent and applies everywhere, so does that imply that it is defined in all architectures? I guess the early boot scenario is different in that, potentially unkind users aren't involved, hence a broken kernel is broken and need a fix. The scenario concerned here is with users could potentially exploit a kernel issue with DOS attack. Then we have the scenario that the kernel bug itself is confined, in that, had the sysfs not been accessed, the OOB pointer won't be produced. So in this case, "(efault)" is a lot more desirable than panic. > > Regards, > Petr Thanks! -jane
On Tue 2022-10-18 19:36:41, Jane Chu wrote: > On 10/18/2022 12:40 AM, Petr Mladek wrote: > > On Mon 2022-10-17 21:12:04, Jane Chu wrote: > >> On 10/17/2022 1:27 PM, Andy Shevchenko wrote: > >>> On Mon, Oct 17, 2022 at 01:44:47PM -0600, Jane Chu wrote: > >>>> While debugging a separate issue, it was found that an invalid string > >>>> pointer could very well contain a non-canical address, such as > >>> > >>> non-canical? > >> > >> Sorry, typo, will fix. > >> > >>> > >>>> 0x7665645f63616465. In that case, this line of defense isn't enough > >>>> to protect the kernel from crashing due to general protection fault > >>>> > >>>> if ((unsigned long)ptr < PAGE_SIZE || IS_ERR_VALUE(ptr)) > >>>> return "(efault)"; > >>>> > >>>> So run one more round of check via kern_addr_valid(). On architectures > >>>> that provide meaningful implementation, this line of check effectively > >>>> catches non-canonical pointers, etc. > >>> > >>> OK, but I don't see how this is useful in the form of returning efault here. > >>> Ideally we should inform user that the pointer is wrong and how it's wrong. > >>> But. It will crash somewhere else at some point, right? > >> Broadly speaking, yes. It's not a perfect line of defense, but again, > >> the bug scenario is a "cat" of some sysfs attributes that leads to > >> panic. Does it make sense for kernel to protect itself against panic > >> triggered by a "cat" from user if it could? > > > > From my view, the check might be useful. I agree with Andy that the > > broken pointer would cause crash later anyway. But the check > > in vsprintf() would allow to see a message that the pointer was > > wrong before the system crashes. > > > > That said, this was much more important in the past when printk() > > called vsprintf() under logbuf_lock. Nested printk() calls > > were redirected to per-CPU buffers and eventually lost. > > > > It works better now when printk() uses lockless ringbuffer and > > vsprintf() is called twice there. The first call is used > > to get the string length so that it could reserve the needed > > space in the ring buffer. If vsprintf() crashes during the 1st call > > then it would be possible to print the nested Oops messages. > > > > > >> I mean that there > >>> is no guarantee that kernel has protection in every single place against > >>> dangling / invalid pointers. One way or another it will crash. > >>> > >>> That said, honestly I have no idea how this patch may be considered > >>> anything but band-aid. OTOH, I don't see a harm. Perhaps others will > >>> share their opinions. > >>> > >> > >> 3+ years ago, commit 3e5903eb9cff7 ("vsprintf: Prevent crash when > >> dereferencing invalid pointers") provided the similar level of > >> protection as this patch. But it was soon revised by commit > >> 2ac5a3bf7042a ("vsprintf: Do not break early boot with probing > >> addresses"), and that's why the string() utility no longer detects > >> non-canonical string pointer. > >> > >> I only thought that kern_addr_valid() is less of a heavy hammer, and > >> could be safely deployed. > > > > Hmm, I see that kern_addr_valid() is available (defined) only on some > > architectures. This patch would break build on architectures where it > > is not defined. > > > > Also it is used only when reading /proc/kcore. It means that it is not > > tested during early boot. I wonder if it actually works during > > the very early boot. > > > > Result: > > > > The patch is not usable as is. > > > > IMHO, it is not worth the effort to get it working. Especially when > > printk() should be able to show Oops inside vsprintf() these days. > > Yes, kern_addr_valid() is used by read_kcore() which is architecturally > independent and applies everywhere, so does that imply that it is > defined in all architectures? It is more complicated. fs/proc/kcore.c is built when CONFIG_PROC_KCORE is set. It is defined in fs/proc/Kconfig as: config PROC_KCORE bool "/proc/kcore support" if !ARM depends on PROC_FS && MMU So, it is not built on ARM. More importantly, kern_addr_valid() seems to be implemented only for x86_64. It is always true (1) on all other architectures, see $> git grep kern_addr_valid arch/alpha/include/asm/pgtable.h:#define kern_addr_valid(addr) (1) arch/arc/include/asm/pgtable-bits-arcv2.h:#define kern_addr_valid(addr) (1) arch/arm/include/asm/pgtable-nommu.h:#define kern_addr_valid(addr) (1) arch/arm/include/asm/pgtable.h:#define kern_addr_valid(addr) (1) [...] Wait, it is actually always false (0) on x86 when SPARSEMEM is used, see arch/x86/include/asm/pgtable_32.h: #ifdef CONFIG_FLATMEM #define kern_addr_valid(addr) (1) #else #define kern_addr_valid(kaddr) (0) #endif > I guess the early boot scenario is different in that, potentially unkind > users aren't involved, hence a broken kernel is broken and need a fix. The important thing is that kern_addr_valid() must return valid results even during early boot. Otherwise, vsprintf() would not work during the early boot which is not expected. > The scenario concerned here is with users could potentially exploit a > kernel issue with DOS attack. Then we have the scenario that the kernel > bug itself is confined, in that, had the sysfs not been accessed, the > OOB pointer won't be produced. So in this case, "(efault)" is a lot > more desirable than panic. Please, provide more details about the bug when invalid pointer was passed. As Andy wrote, even if we catch the bad pointer in vsprintf(), the kernel would most likely kernel crash anyway. Best Regards, Petr
Hi, Petr, Sorry, I didn't catch this email prior to sending out v3. [..] >> >> Yes, kern_addr_valid() is used by read_kcore() which is architecturally >> independent and applies everywhere, so does that imply that it is >> defined in all architectures? > > It is more complicated. fs/proc/kcore.c is built when > CONFIG_PROC_KCORE is set. It is defined in fs/proc/Kconfig as: > > config PROC_KCORE > bool "/proc/kcore support" if !ARM > depends on PROC_FS && MMU > > So, it is not built on ARM. Indeed, it's defined on ARM though. > > More importantly, kern_addr_valid() seems to be implemented only for x86_64. > It is always true (1) on all other architectures, see > > $> git grep kern_addr_valid > arch/alpha/include/asm/pgtable.h:#define kern_addr_valid(addr) (1) > arch/arc/include/asm/pgtable-bits-arcv2.h:#define kern_addr_valid(addr) (1) > arch/arm/include/asm/pgtable-nommu.h:#define kern_addr_valid(addr) (1) > arch/arm/include/asm/pgtable.h:#define kern_addr_valid(addr) (1) > [...] > > Wait, it is actually always false (0) on x86 when SPARSEMEM is used, > see arch/x86/include/asm/pgtable_32.h: > > #ifdef CONFIG_FLATMEM > #define kern_addr_valid(addr) (1) > #else > #define kern_addr_valid(kaddr) (0) > #endif > Thanks for pointing this out. Let me do some digging ... > >> I guess the early boot scenario is different in that, potentially unkind >> users aren't involved, hence a broken kernel is broken and need a fix. > > The important thing is that kern_addr_valid() must return valid > results even during early boot. Otherwise, vsprintf() would not work > during the early boot which is not expected. Yes, agreed. > >> The scenario concerned here is with users could potentially exploit a >> kernel issue with DOS attack. Then we have the scenario that the kernel >> bug itself is confined, in that, had the sysfs not been accessed, the >> OOB pointer won't be produced. So in this case, "(efault)" is a lot >> more desirable than panic. > > Please, provide more details about the bug when invalid pointer was > passed. As Andy wrote, even if we catch the bad pointer in vsprintf(), > the kernel would most likely kernel crash anyway. Hopefully the comment in v3 clarifies the bug, please let me know. thanks! -jane > > Best Regards, > Petr
On 10/19/2022 1:02 PM, Jane Chu wrote: > Hi, Petr, > > Sorry, I didn't catch this email prior to sending out v3. > > [..] >>> >>> Yes, kern_addr_valid() is used by read_kcore() which is architecturally >>> independent and applies everywhere, so does that imply that it is >>> defined in all architectures? >> >> It is more complicated. fs/proc/kcore.c is built when >> CONFIG_PROC_KCORE is set. It is defined in fs/proc/Kconfig as: >> >> config PROC_KCORE >> bool "/proc/kcore support" if !ARM >> depends on PROC_FS && MMU >> >> So, it is not built on ARM. > > Indeed, it's defined on ARM though. > >> >> More importantly, kern_addr_valid() seems to be implemented only for x86_64. >> It is always true (1) on all other architectures, see >> >> $> git grep kern_addr_valid >> arch/alpha/include/asm/pgtable.h:#define kern_addr_valid(addr) (1) >> arch/arc/include/asm/pgtable-bits-arcv2.h:#define kern_addr_valid(addr) (1) >> arch/arm/include/asm/pgtable-nommu.h:#define kern_addr_valid(addr) (1) >> arch/arm/include/asm/pgtable.h:#define kern_addr_valid(addr) (1) >> [...] >> >> Wait, it is actually always false (0) on x86 when SPARSEMEM is used, >> see arch/x86/include/asm/pgtable_32.h: >> >> #ifdef CONFIG_FLATMEM >> #define kern_addr_valid(addr) (1) >> #else >> #define kern_addr_valid(kaddr) (0) >> #endif >> > > Thanks for pointing this out. Let me do some digging ... So I tried to dig, the history of kern_addr_valid() and its connection with PROC_KCORE went way back, I'm unable to find out why on old memory models such as x86 SPARSEMEM & DISCONTIGMEM, kern_addr_valid() is defined as '(0)'. My guess is perhaps PROC_KCORE isn't supported on those memory model, and having kern_addr_valid() to reject the start address is a convenient way to fail the load - just a guess, with no evidence for support. Anyway a generic use of kern_addr_valid() will break platforms with SPARSEMEM & DISCONTIGMEM memory model. And this is beside the fact that kern_addr_valid() is going away, and I don't see a good replacement. I understand folks' rejecting the patch on the ground of dereferencing bogus pointers anywhere in the kernel including vsprintf() is not worth protecting. I'm not going to insist on any further, I'd just like to thank all of you who've spent time reviewing the patch, and providing comments and explanations. Regards, -jane
diff --git a/lib/vsprintf.c b/lib/vsprintf.c index c414a8d9f1ea..b38c12ef1e45 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -698,6 +698,9 @@ static const char *check_pointer_msg(const void *ptr) if ((unsigned long)ptr < PAGE_SIZE || IS_ERR_VALUE(ptr)) return "(efault)"; + if (!kern_addr_valid((unsigned long)ptr)) + return "(efault)"; + return NULL; }