Message ID | 20230114085053.72059-3-W_Armin@gmx.de |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:adf:eb09:0:0:0:0:0 with SMTP id s9csp194438wrn; Sat, 14 Jan 2023 00:54:29 -0800 (PST) X-Google-Smtp-Source: AMrXdXs28Wo06hP5X+bELU5siDjhrlUY7jQlENJbeCdmXaJWSsADuBuvOwUUGmBRYljoOQSJ58K8 X-Received: by 2002:a17:902:a9c8:b0:194:4a0e:3024 with SMTP id b8-20020a170902a9c800b001944a0e3024mr12855165plr.62.1673686469248; Sat, 14 Jan 2023 00:54:29 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1673686469; cv=none; d=google.com; s=arc-20160816; b=bmLvpOGidq8KcwLKNDHetmc/JPv109FvLQvkdHSc4LM2cNLEOxsN2DFYoH5o53jxYy lWjZR8kLvWGAXOdi8IO1W+rtm8gqICzpsiMK2IlzWISWD79EPzkYP8vqjgsGyUjZoatQ St7VZc+q01XvjS2mbG1lTuQ/liYuFj1BPC8fQX9ZNGLwstsZy2n1li+LjEykq20aiP8f IWUk10IPy1eMvu1+/lt80oAMUDyBgtUsL/+Pw/i/lqQhbekpeFhXE1DtuUEKst/gDVkZ 8esSZrlrZiXtgktG277ylV6+dmq1qSj8FbZwNtn+GUaKOuFDPGFVbOOo1OSKS2Srali2 om6g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:ui-outboundreport:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=+cNo969/y6+26mQU0yOkafJ8dt7VLhXVpmrhvlqnKWA=; b=XcvqGZyttIo4241+z5KUr8BFt9dMV7qZOBBmkfaLO7roft8d/3GqQSTBEWmEfc9sxR cYqM0yo0SeVTYc0ZnLl1ffyd1hcoJWnV4HwXlnKJa86whoS0S6GzbPYXinr5R8cUBijR 3iPx4eAEu29s3blP9zlQBxCi+Gu8FK0uWDmdvg8To+U3wYWC4gVk0an6Pg5cnMtCGDY4 MotQEZHcoDFsdKPFvkftPgtvCzrUBaoQuYlBVt7rAmpqcD7jVyHnAdrvWC/KCmx3HiQP /TAeiGFIiC3B6a4u3iFGJ19hDVvpQD6r9ppFKzi4c+fCHBim7fRf43M85H2zAjfisRQG L9/Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmx.de header.s=s31663417 header.b=ugaENJWe; 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=gmx.de Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id b2-20020a170902d50200b00192721d6a97si25314714plg.499.2023.01.14.00.54.17; Sat, 14 Jan 2023 00:54:29 -0800 (PST) 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=@gmx.de header.s=s31663417 header.b=ugaENJWe; 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=gmx.de Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229894AbjANIvZ (ORCPT <rfc822;stefanalexe48@gmail.com> + 99 others); Sat, 14 Jan 2023 03:51:25 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41670 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229751AbjANIvH (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Sat, 14 Jan 2023 03:51:07 -0500 Received: from mout.gmx.net (mout.gmx.net [212.227.17.22]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0AC215B99; Sat, 14 Jan 2023 00:51:04 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gmx.de; s=s31663417; t=1673686258; bh=jB33Q3jeI0y5s9Ce2m9M9FDF30UYlvKOmlqfrMJD11U=; h=X-UI-Sender-Class:From:To:Cc:Subject:Date:In-Reply-To:References; b=ugaENJWeI55eqyyb5bGIF1NEu5kzlI89qmpp2KE2QC+lKlPvEezcMeLvQRj7NOkl7 lxN/YZyg7EPhKnzVg58fjuCxiNmamVd8v71NuczHfHGNt+RnC/2/Qlr8ctC07dLBj0 +UoECYUpv6BtOu4dhaWOhAEhS7AIv3iixJUqGvu2nBcRgu1o1NLLRqG92QyVsiFFcR hzaSKxUCAnDUW4PXKSs45e9ZZrWLrV+ZscZUZcj6R1ApdinTAi1JSY4ZfWLEVlQrjI cNzQsQQVm6vni5nKNfb7pkV0JidnGLTOwdA1OMszI+khx8LNfPwCz/WS3PGdhkEdAA OFJDuOdj83uQw== X-UI-Sender-Class: 724b4f7f-cbec-4199-ad4e-598c01a50d3a Received: from esprimo-mx.users.agdsn.de ([141.30.226.129]) by mail.gmx.net (mrgmx104 [212.227.17.168]) with ESMTPSA (Nemesis) id 1MnJhU-1orPq22NYS-00jIKm; Sat, 14 Jan 2023 09:50:58 +0100 From: Armin Wolf <W_Armin@gmx.de> To: rafael@kernel.org, lenb@kernel.org Cc: linux-acpi@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 2/4] ACPI: battery: Fix buffer overread if not NUL-terminated Date: Sat, 14 Jan 2023 09:50:51 +0100 Message-Id: <20230114085053.72059-3-W_Armin@gmx.de> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20230114085053.72059-1-W_Armin@gmx.de> References: <20230114085053.72059-1-W_Armin@gmx.de> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Provags-ID: V03:K1:z5GgtgT7CSW+fcGI445TpQI8PlZHp7xc332KAN0bgoMYytypbq2 1UkqHJbkKuy4aDiYLowSkXz3+/FcoXqcfR8Olxu+tiaeMW/qSMGtfXNUA8Bq10urn80MU4f GGm7zFMPLOZKOF2HIcP6ecnoCTe1+yR43IQ1f/ot3IRmSRYYYkZhW8CFmSS5zGEJiB6Mjfj yWQ6kjPj2nIJULk/2/R7A== UI-OutboundReport: notjunk:1;M01:P0:2wWbPeptUL0=;XKsWl8tIy9Pm/1RdATWuPhINH6T U667nRTbh292keZ+vmvZRyrTovxs5qOA6nR5PnrURzFDKWU7E+qlxFm+f86M0SW5J1IRqB4MV PnUbD5LBLKxpOOXtygJPCXJZBDYF47O02ifsXlsNYX4uWmbGu5Gs1WIAey3hwKgjXFUH1mYAs zi3084Lhy8+If7Ydzr3Xgvpgr+7LB+sJ+4HM9Jeuq/gCMxLFhgIDB8xS9C6vYoX+ufp9cwVvH Y0nDvwVnyrlCNIQO822s+ZMr/H2gGTPrutSLDyU8xmbibb4Sf25ac2JTqutzemz4Rjei0z2zt 7f+/AyA5VH+WlH8yAfQUMUNDNBYlu8xo2PHflmMDR3pd11adBZU/RetK39ELZLKK+M77OiGxt SDEehWz3UKvDszA51UsYx0gPQ9BJj+7uyIWvAg0fnXg9vNqBQAMm9qFbB6+NnMBXPd9+XjS8k tGlB4gYymWWfK+Vts0SEwuNwqnCwhXEPl5sWWnE8IHTQ2MxZgM6AdWzyG/BIYB5GVS5Mfos+t O8sXmLefYlSXUhSBmRQ4Ejtokbb0H27hoZlRog/wV7b9dY1ZsX98TAkzbx61BpLwNQUBrZoUY AFmAWNVe9aaxxcpXK9K3VKpClAEj3dEohVu2lNAtDRuD+bCunYE0fLAknDi5bMewLoR6SUJBX PbAHjjxQUVmt0wPtx5RCEm8hyO8t7JjgNiMh7aH3Urod3ufmDfv0z7WpVWNyMoqEqCDhqtYVH X8d+RgR/gxzKrnnQeziWIPaKhMenfEFdeExdia6wxrQfo90WSBZjAY9rzC0Jj2YtSdnm0To2Y sVyX3Kxo5CpetP5P+FjreA4sJc2W3rzFC71rD6n796dh9eJL4K7tMoFCABv/zRHS3OSDXnUoO yDbeXfaYsj1dToaYkUfWOA8YDUhbHzP0fRwBhIz0fcbRel1IjaHtdBGIADvGXGbVeI/fw7Q98 VkoVTu0iVgM9/XyN89vCvJXkAC4= X-Spam-Status: No, score=-2.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,SPF_PASS 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?1754987463159179903?= X-GMAIL-MSGID: =?utf-8?q?1754987463159179903?= |
Series |
ACPI: battery: Fix various string handling issues
|
|
Commit Message
Armin Wolf
Jan. 14, 2023, 8:50 a.m. UTC
If the buffer containing string data is not NUL-terminated
(which is perfectly legal according to the ACPI specification),
the acpi battery driver might not honor its length.
Fix this by limiting the amount of data to be copied to
the buffer length while also using strscpy() to make sure
that the resulting string is always NUL-terminated.
Also use '\0' instead of a plain 0.
Signed-off-by: Armin Wolf <W_Armin@gmx.de>
---
drivers/acpi/battery.c | 23 ++++++++++++++++-------
1 file changed, 16 insertions(+), 7 deletions(-)
--
2.30.2
Comments
On Sat, Jan 14, 2023 at 9:51 AM Armin Wolf <W_Armin@gmx.de> wrote: > > If the buffer containing string data is not NUL-terminated > (which is perfectly legal according to the ACPI specification), > the acpi battery driver might not honor its length. Note that this is about extracting package entries of type ACPI_TYPE_BUFFER. And please spell ACPI in capitals. > Fix this by limiting the amount of data to be copied to > the buffer length while also using strscpy() to make sure > that the resulting string is always NUL-terminated. OK > Also use '\0' instead of a plain 0. Why? It's a u8, not a char. > Signed-off-by: Armin Wolf <W_Armin@gmx.de> > --- > drivers/acpi/battery.c | 23 ++++++++++++++++------- > 1 file changed, 16 insertions(+), 7 deletions(-) > > diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c > index fb64bd217d82..9f6daa9f2010 100644 > --- a/drivers/acpi/battery.c > +++ b/drivers/acpi/battery.c > @@ -438,15 +438,24 @@ static int extract_package(struct acpi_battery *battery, > if (offsets[i].mode) { > u8 *ptr = (u8 *)battery + offsets[i].offset; I would add u32 len = 32; > > - if (element->type == ACPI_TYPE_STRING || > - element->type == ACPI_TYPE_BUFFER) > + switch (element->type) { And here I would do case ACPI_TYPE_BUFFER: if (len > element->buffer.length + 1) len = element->buffer.length + 1; fallthrough; case ACPI_TYPE_STRING: strscpy(ptr, element->buffer.pointer, len); break; case ACPI_TYPE_INTEGER: and so on. > + case ACPI_TYPE_STRING: > strscpy(ptr, element->string.pointer, 32); > - else if (element->type == ACPI_TYPE_INTEGER) { > - strncpy(ptr, (u8 *)&element->integer.value, > - sizeof(u64)); > + > + break; > + case ACPI_TYPE_BUFFER: > + strscpy(ptr, element->buffer.pointer, > + min_t(u32, element->buffer.length + 1, 32)); > + > + break; > + case ACPI_TYPE_INTEGER: > + strncpy(ptr, (u8 *)&element->integer.value, sizeof(u64)); > ptr[sizeof(u64)] = 0; > - } else > - *ptr = 0; /* don't have value */ > + > + break; > + default: > + *ptr = '\0'; /* don't have value */ > + } > } else { > int *x = (int *)((u8 *)battery + offsets[i].offset); > *x = (element->type == ACPI_TYPE_INTEGER) ? > --
Am 17.01.23 um 15:42 schrieb Rafael J. Wysocki: > On Sat, Jan 14, 2023 at 9:51 AM Armin Wolf <W_Armin@gmx.de> wrote: >> If the buffer containing string data is not NUL-terminated >> (which is perfectly legal according to the ACPI specification), >> the acpi battery driver might not honor its length. > Note that this is about extracting package entries of type ACPI_TYPE_BUFFER. > > And please spell ACPI in capitals. > >> Fix this by limiting the amount of data to be copied to >> the buffer length while also using strscpy() to make sure >> that the resulting string is always NUL-terminated. > OK > >> Also use '\0' instead of a plain 0. > Why? It's a u8, not a char. > >> Signed-off-by: Armin Wolf <W_Armin@gmx.de> >> --- >> drivers/acpi/battery.c | 23 ++++++++++++++++------- >> 1 file changed, 16 insertions(+), 7 deletions(-) >> >> diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c >> index fb64bd217d82..9f6daa9f2010 100644 >> --- a/drivers/acpi/battery.c >> +++ b/drivers/acpi/battery.c >> @@ -438,15 +438,24 @@ static int extract_package(struct acpi_battery *battery, >> if (offsets[i].mode) { >> u8 *ptr = (u8 *)battery + offsets[i].offset; > I would add > > u32 len = 32; > >> - if (element->type == ACPI_TYPE_STRING || >> - element->type == ACPI_TYPE_BUFFER) >> + switch (element->type) { > And here I would do > > case ACPI_TYPE_BUFFER: > if (len > element->buffer.length + 1) > len = element->buffer.length + 1; > > fallthrough; > case ACPI_TYPE_STRING: > strscpy(ptr, element->buffer.pointer, len); > break; > case ACPI_TYPE_INTEGER: > > and so on. But wouldn't this cause the ACPI string object to be accessed the wrong way (buffer.pointer instead of string.pointer)? Armin Wolf >> + case ACPI_TYPE_STRING: >> strscpy(ptr, element->string.pointer, 32); >> - else if (element->type == ACPI_TYPE_INTEGER) { >> - strncpy(ptr, (u8 *)&element->integer.value, >> - sizeof(u64)); >> + >> + break; >> + case ACPI_TYPE_BUFFER: >> + strscpy(ptr, element->buffer.pointer, >> + min_t(u32, element->buffer.length + 1, 32)); >> + >> + break; >> + case ACPI_TYPE_INTEGER: >> + strncpy(ptr, (u8 *)&element->integer.value, sizeof(u64)); >> ptr[sizeof(u64)] = 0; >> - } else >> - *ptr = 0; /* don't have value */ >> + >> + break; >> + default: >> + *ptr = '\0'; /* don't have value */ >> + } >> } else { >> int *x = (int *)((u8 *)battery + offsets[i].offset); >> *x = (element->type == ACPI_TYPE_INTEGER) ? >> --
On Tue, Jan 17, 2023 at 10:01 PM Armin Wolf <W_Armin@gmx.de> wrote: > > Am 17.01.23 um 15:42 schrieb Rafael J. Wysocki: > > > On Sat, Jan 14, 2023 at 9:51 AM Armin Wolf <W_Armin@gmx.de> wrote: > >> If the buffer containing string data is not NUL-terminated > >> (which is perfectly legal according to the ACPI specification), > >> the acpi battery driver might not honor its length. > > Note that this is about extracting package entries of type ACPI_TYPE_BUFFER. > > > > And please spell ACPI in capitals. > > > >> Fix this by limiting the amount of data to be copied to > >> the buffer length while also using strscpy() to make sure > >> that the resulting string is always NUL-terminated. > > OK > > > >> Also use '\0' instead of a plain 0. > > Why? It's a u8, not a char. > > > >> Signed-off-by: Armin Wolf <W_Armin@gmx.de> > >> --- > >> drivers/acpi/battery.c | 23 ++++++++++++++++------- > >> 1 file changed, 16 insertions(+), 7 deletions(-) > >> > >> diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c > >> index fb64bd217d82..9f6daa9f2010 100644 > >> --- a/drivers/acpi/battery.c > >> +++ b/drivers/acpi/battery.c > >> @@ -438,15 +438,24 @@ static int extract_package(struct acpi_battery *battery, > >> if (offsets[i].mode) { > >> u8 *ptr = (u8 *)battery + offsets[i].offset; > > I would add > > > > u32 len = 32; > > > >> - if (element->type == ACPI_TYPE_STRING || > >> - element->type == ACPI_TYPE_BUFFER) > >> + switch (element->type) { > > And here I would do > > > > case ACPI_TYPE_BUFFER: > > if (len > element->buffer.length + 1) > > len = element->buffer.length + 1; > > > > fallthrough; > > case ACPI_TYPE_STRING: > > strscpy(ptr, element->buffer.pointer, len); > > break; > > case ACPI_TYPE_INTEGER: > > > > and so on. > > But wouldn't this cause the ACPI string object to be accessed the wrong way > (buffer.pointer instead of string.pointer)? I meant string.pointer, like in the original code, but this doesn't matter really, because the value of the pointer is the same.
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index fb64bd217d82..9f6daa9f2010 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c @@ -438,15 +438,24 @@ static int extract_package(struct acpi_battery *battery, if (offsets[i].mode) { u8 *ptr = (u8 *)battery + offsets[i].offset; - if (element->type == ACPI_TYPE_STRING || - element->type == ACPI_TYPE_BUFFER) + switch (element->type) { + case ACPI_TYPE_STRING: strscpy(ptr, element->string.pointer, 32); - else if (element->type == ACPI_TYPE_INTEGER) { - strncpy(ptr, (u8 *)&element->integer.value, - sizeof(u64)); + + break; + case ACPI_TYPE_BUFFER: + strscpy(ptr, element->buffer.pointer, + min_t(u32, element->buffer.length + 1, 32)); + + break; + case ACPI_TYPE_INTEGER: + strncpy(ptr, (u8 *)&element->integer.value, sizeof(u64)); ptr[sizeof(u64)] = 0; - } else - *ptr = 0; /* don't have value */ + + break; + default: + *ptr = '\0'; /* don't have value */ + } } else { int *x = (int *)((u8 *)battery + offsets[i].offset); *x = (element->type == ACPI_TYPE_INTEGER) ?