From patchwork Mon Sep 9 01:54:42 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Koichiro Den X-Patchwork-Id: 1982277 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.ubuntu.com (client-ip=185.125.189.65; helo=lists.ubuntu.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=patchwork.ozlabs.org) Received: from lists.ubuntu.com (lists.ubuntu.com [185.125.189.65]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4X290N3FSXz1y1l for ; Mon, 9 Sep 2024 11:55:47 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=lists.ubuntu.com) by lists.ubuntu.com with esmtp (Exim 4.86_2) (envelope-from ) id 1snTcw-0000mD-T2; Mon, 09 Sep 2024 01:55:38 +0000 Received: from smtp-relay-internal-0.internal ([10.131.114.225] helo=smtp-relay-internal-0.canonical.com) by lists.ubuntu.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1snTcu-0000m2-W8 for kernel-team@lists.ubuntu.com; Mon, 09 Sep 2024 01:55:37 +0000 Received: from mail-pf1-f197.google.com (mail-pf1-f197.google.com [209.85.210.197]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-0.canonical.com (Postfix) with ESMTPS id D01433F5AB for ; Mon, 9 Sep 2024 01:55:36 +0000 (UTC) Received: by mail-pf1-f197.google.com with SMTP id d2e1a72fcca58-718d873b1e8so2863260b3a.3 for ; Sun, 08 Sep 2024 18:55:36 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1725846935; x=1726451735; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Sh3alkrCqWzm2GZa5skGnWhD79yErI9D+d9WLJy2qqo=; b=SV6ZzETl1NqfQ2VMVrs7BIYoktn1yx+yB9R7z1XxIGAyuU8Jq0tttHiRE4RYBwulUq PtZgQrA3LaHQRm0cc1C3CGq+uVELfNCtFqNd0FwvYZb29EvFf0DhF1vH9JzwFdt+m5i+ zRAjzWse25fP31z8mXQf/ae4ABfvb7n9GUS8wxtaARSPjNqYn8XEYZDzUJlEXHjzV87f 9odpaRYK7QaETMAmSYKXgHfLScPynXCCdAyltDp866BvFiS1QJifOB4iNLhJaxeLQDHO oAy5z0ULA9uBsUq5AhEjnySk0tP9xusM4sW5h2AaJdNAviB2LrIEBTfjbHlASbrq7wG7 +4/A== X-Gm-Message-State: AOJu0YxAs9ssSQHwadUMsTjsmSXuOKCJFQjA8zyamBhnNjZ/sPv71zVz o0zlZRtLo7RM7gpc5vh/WPXm3l5/4xj9LtbRuekRdMjaBESmXk8PmopvDun2RaALk4f8PPRcvvf XrMxHatGSY8w7JwfGYj4eD4a/MqeFJaSPmVD+unwcKW2RHYxNvNPFl5IKCFW00vhwdll/W9ca8r aWvIRkdLQbOg== X-Received: by 2002:a05:6a00:a29:b0:717:85d4:939c with SMTP id d2e1a72fcca58-718d5f52c04mr13567325b3a.23.1725846934832; Sun, 08 Sep 2024 18:55:34 -0700 (PDT) X-Google-Smtp-Source: AGHT+IFJgwKLewFalKKnYHltljkV8e5h+rYjHRAPlZLA44w0cs5HPEGjzyzanCnA4H+YK2DGhk7oTg== X-Received: by 2002:a05:6a00:a29:b0:717:85d4:939c with SMTP id d2e1a72fcca58-718d5f52c04mr13567294b3a.23.1725846934121; Sun, 08 Sep 2024 18:55:34 -0700 (PDT) Received: from localhost.localdomain ([240f:74:7be:1:8492:650d:69e1:396a]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-718e58965bdsm2563382b3a.29.2024.09.08.18.55.33 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 08 Sep 2024 18:55:33 -0700 (PDT) From: Koichiro Den To: kernel-team@lists.ubuntu.com Subject: [SRU][F][PATCH 1/1] PM / devfreq: Fix buffer overflow in trans_stat_show Date: Mon, 9 Sep 2024 10:54:42 +0900 Message-ID: <20240909015506.959578-2-koichiro.den@canonical.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240909015506.959578-1-koichiro.den@canonical.com> References: <20240909015506.959578-1-koichiro.den@canonical.com> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Christian Marangi Fix buffer overflow in trans_stat_show(). Convert simple snprintf to the more secure scnprintf with size of PAGE_SIZE. Add condition checking if we are exceeding PAGE_SIZE and exit early from loop. Also add at the end a warning that we exceeded PAGE_SIZE and that stats is disabled. Return -EFBIG in the case where we don't have enough space to write the full transition table. Also document in the ABI that this function can return -EFBIG error. Link: https://lore.kernel.org/all/20231024183016.14648-2-ansuelsmth@gmail.com/ Cc: stable@vger.kernel.org Closes: https://bugzilla.kernel.org/show_bug.cgi?id=218041 Fixes: e552bbaf5b98 ("PM / devfreq: Add sysfs node for representing frequency transition information.") Signed-off-by: Christian Marangi Signed-off-by: Chanwoo Choi (backported from commit 08e23d05fa6dc4fc13da0ccf09defdd4bbc92ff4) [koichiroden: crafted a custom diff that suits our tree. The key missing commits missing from our tree are as follows: commit b5d281f6c16d ("PM / devfreq: Rework freq_table to be local to devfreq struct") commit a03dacb0316f ("PM / devfreq: Add cpu based scaling support to passive governor") commit 483d557ee9a3 ("PM / devfreq: Clean up the devfreq instance name in sysfs attr") commit 1ebd0bc0e8ad ("PM / devfreq: Move statistics to separate struct devfreq_stats") commit 14a343968199 ("PM / devfreq: Add clearing transitions stats") commit b76b3479dab9 ("PM / devfreq: Change time stats to 64-bit") commit 5c0f6c795957 ("PM / devfreq: Add new interrupt_driven flag for governors")] CVE-2023-52614 Signed-off-by: Koichiro Den --- Documentation/ABI/testing/sysfs-class-devfreq | 2 + drivers/devfreq/devfreq.c | 60 +++++++++++++------ 2 files changed, 43 insertions(+), 19 deletions(-) diff --git a/Documentation/ABI/testing/sysfs-class-devfreq b/Documentation/ABI/testing/sysfs-class-devfreq index 75897e2fde43..f95b69551b60 100644 --- a/Documentation/ABI/testing/sysfs-class-devfreq +++ b/Documentation/ABI/testing/sysfs-class-devfreq @@ -61,6 +61,8 @@ Description: In order to activate this ABI, the devfreq target device driver should provide the list of available frequencies with its profile. + If the transition table is bigger than PAGE_SIZE, reading + this will return an -EFBIG error. What: /sys/class/devfreq/.../userspace/set_freq Date: September 2011 diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c index 31e6cb5211bc..7a6115c23ec8 100644 --- a/drivers/devfreq/devfreq.c +++ b/drivers/devfreq/devfreq.c @@ -1403,12 +1403,12 @@ static ssize_t trans_stat_show(struct device *dev, struct device_attribute *attr, char *buf) { struct devfreq *devfreq = to_devfreq(dev); - ssize_t len; + ssize_t len = 0; int i, j; unsigned int max_state = devfreq->profile->max_state; if (max_state == 0) - return sprintf(buf, "Not Supported.\n"); + return scnprintf(buf, PAGE_SIZE, "Not Supported.\n"); mutex_lock(&devfreq->lock); if (!devfreq->stop_polling && @@ -1418,32 +1418,54 @@ static ssize_t trans_stat_show(struct device *dev, } mutex_unlock(&devfreq->lock); - len = sprintf(buf, " From : To\n"); - len += sprintf(buf + len, " :"); - for (i = 0; i < max_state; i++) - len += sprintf(buf + len, "%10lu", - devfreq->profile->freq_table[i]); + len += scnprintf(buf + len, PAGE_SIZE - len, " From : To\n"); + len += scnprintf(buf + len, PAGE_SIZE - len, " :"); + for (i = 0; i < max_state; i++) { + if (len >= PAGE_SIZE - 1) + break; + len += scnprintf(buf + len, PAGE_SIZE - len, "%10lu", + devfreq->profile->freq_table[i]); + } + if (len >= PAGE_SIZE - 1) + return PAGE_SIZE - 1; - len += sprintf(buf + len, " time(ms)\n"); + len += scnprintf(buf + len, PAGE_SIZE - len, " time(ms)\n"); for (i = 0; i < max_state; i++) { + if (len >= PAGE_SIZE - 1) + break; if (devfreq->profile->freq_table[i] == devfreq->previous_freq) { - len += sprintf(buf + len, "*"); + len += scnprintf(buf + len, PAGE_SIZE - len, "*"); } else { - len += sprintf(buf + len, " "); + len += scnprintf(buf + len, PAGE_SIZE - len, " "); + } + if (len >= PAGE_SIZE - 1) + break; + + len += scnprintf(buf + len, PAGE_SIZE - len, "%10lu:", + devfreq->profile->freq_table[i]); + for (j = 0; j < max_state; j++) { + if (len >= PAGE_SIZE - 1) + break; + len += scnprintf(buf + len, PAGE_SIZE - len, "%10u", + devfreq->trans_table[(i * max_state) + j]); } - len += sprintf(buf + len, "%10lu:", - devfreq->profile->freq_table[i]); - for (j = 0; j < max_state; j++) - len += sprintf(buf + len, "%10u", - devfreq->trans_table[(i * max_state) + j]); - len += sprintf(buf + len, "%10u\n", - jiffies_to_msecs(devfreq->time_in_state[i])); + if (len >= PAGE_SIZE - 1) + break; + len += scnprintf(buf + len, PAGE_SIZE - len, "%10u\n", + jiffies_to_msecs(devfreq->time_in_state[i])); + } + + if (len < PAGE_SIZE - 1) + len += scnprintf(buf + len, PAGE_SIZE - len, "Total transition : %u\n", + devfreq->total_trans); + + if (len >= PAGE_SIZE - 1) { + pr_warn_once("devfreq transition table exceeds PAGE_SIZE. Disabling\n"); + return -EFBIG; } - len += sprintf(buf + len, "Total transition : %u\n", - devfreq->total_trans); return len; } static DEVICE_ATTR_RO(trans_stat);