On Fri, Oct 20, 2023 at 05:52:43PM +0000, Justin Stitt wrote: > strncpy() is deprecated for use on NUL-terminated destination strings > [1] and as such we should prefer more robust and less ambiguous > interfaces. > > We expect ec_fw_string to be NUL-terminated based on its use with format > strings in thinkpad_acpi.c: > 11241 | pr_notice("ThinkPad firmware release %s doesn't match the known patterns\n", > 11242 | ec_fw_string); > > Moreover, NUL-padding is not required since ec_fw_string is explicitly > zero-initialized: > 11185 | char ec_fw_string[18] = {0}; > > When carefully copying bytes from one buffer to another in > pre-determined blocks (like what's happening here with dmi_data): > > | static void find_new_ec_fwstr(const struct dmi_header *dm, void *private) > | { > | char *ec_fw_string = (char *) private; > | const char *dmi_data = (const char *)dm; > | /* > | * ThinkPad Embedded Controller Program Table on newer models > | * > | * Offset | Name | Width | Description > | * ---------------------------------------------------- > | * 0x00 | Type | BYTE | 0x8C > | * 0x01 | Length | BYTE | > | * 0x02 | Handle | WORD | Varies > | * 0x04 | Signature | BYTEx6 | ASCII for "LENOVO" > | * 0x0A | OEM struct offset | BYTE | 0x0B > | * 0x0B | OEM struct number | BYTE | 0x07, for this structure > | * 0x0C | OEM struct revision | BYTE | 0x01, for this format > | * 0x0D | ECP version ID | STR ID | > | * 0x0E | ECP release date | STR ID | > | */ > | > | /* Return if data structure not match */ > | if (dm->type != 140 || dm->length < 0x0F || > | memcmp(dmi_data + 4, "LENOVO", 6) != 0 || > | dmi_data[0x0A] != 0x0B || dmi_data[0x0B] != 0x07 || > | dmi_data[0x0C] != 0x01) > | return; > | > | /* fwstr is the first 8byte string */ > | strncpy(ec_fw_string, dmi_data + 0x0F, 8); > > ... we shouldn't be using a C string api. Let's instead use memcpy() as > this more properly relays the intended behavior. > > Do note that ec_fw_string will still end up being NUL-terminated since > we are memcpy'ing only 8 bytes into a buffer full of 18 zeroes. There's > still some trailing NUL-bytes there. To ensure this behavior, let's add > a BUILD_BUG_ON checking the length leaves space for at least one > trailing NUL-byte. > > Link: https://www.kernel.org/doc/html/latest/process/deprecated.html#strncpy-on-nul-terminated-strings [1] > Link: https://github.com/KSPP/linux/issues/90 > Cc: Kees Cook <keescook@xxxxxxxxxxxx> > Signed-off-by: Justin Stitt <justinstitt@xxxxxxxxxx> This looks like the best choice given how this code is designed. The "char *private" prototype is weird since there's only one user, but okay. :P Reviewed-by: Kees Cook <keescook@xxxxxxxxxxxx> -- Kees Cook