Loading drivers/firmware/efivars.c +30 −16 Original line number Original line Diff line number Diff line Loading @@ -192,19 +192,22 @@ utf16_strncmp(const efi_char16_t *a, const efi_char16_t *b, size_t len) } } static bool static bool validate_device_path(struct efi_variable *var, int match, u8 *buffer, int len) validate_device_path(struct efi_variable *var, int match, u8 *buffer, unsigned long len) { { struct efi_generic_dev_path *node; struct efi_generic_dev_path *node; int offset = 0; int offset = 0; node = (struct efi_generic_dev_path *)buffer; node = (struct efi_generic_dev_path *)buffer; while (offset < len) { if (len < sizeof(*node)) offset += node->length; if (offset > len) return false; return false; while (offset <= len - sizeof(*node) && node->length >= sizeof(*node) && node->length <= len - offset) { offset += node->length; if ((node->type == EFI_DEV_END_PATH || if ((node->type == EFI_DEV_END_PATH || node->type == EFI_DEV_END_PATH2) && node->type == EFI_DEV_END_PATH2) && node->sub_type == EFI_DEV_END_ENTIRE) node->sub_type == EFI_DEV_END_ENTIRE) Loading @@ -222,7 +225,8 @@ validate_device_path(struct efi_variable *var, int match, u8 *buffer, int len) } } static bool static bool validate_boot_order(struct efi_variable *var, int match, u8 *buffer, int len) validate_boot_order(struct efi_variable *var, int match, u8 *buffer, unsigned long len) { { /* An array of 16-bit integers */ /* An array of 16-bit integers */ if ((len % 2) != 0) if ((len % 2) != 0) Loading @@ -232,19 +236,27 @@ validate_boot_order(struct efi_variable *var, int match, u8 *buffer, int len) } } static bool static bool validate_load_option(struct efi_variable *var, int match, u8 *buffer, int len) validate_load_option(struct efi_variable *var, int match, u8 *buffer, unsigned long len) { { u16 filepathlength; u16 filepathlength; int i, desclength = 0; int i, desclength = 0, namelen; namelen = utf16_strnlen(var->VariableName, sizeof(var->VariableName)); /* Either "Boot" or "Driver" followed by four digits of hex */ /* Either "Boot" or "Driver" followed by four digits of hex */ for (i = match; i < match+4; i++) { for (i = match; i < match+4; i++) { if (hex_to_bin(var->VariableName[i] & 0xff) < 0) if (var->VariableName[i] > 127 || hex_to_bin(var->VariableName[i] & 0xff) < 0) return true; return true; } } /* A valid entry must be at least 6 bytes */ /* Reject it if there's 4 digits of hex and then further content */ if (len < 6) if (namelen > match + 4) return false; /* A valid entry must be at least 8 bytes */ if (len < 8) return false; return false; filepathlength = buffer[4] | buffer[5] << 8; filepathlength = buffer[4] | buffer[5] << 8; Loading @@ -253,7 +265,7 @@ validate_load_option(struct efi_variable *var, int match, u8 *buffer, int len) * There's no stored length for the description, so it has to be * There's no stored length for the description, so it has to be * found by hand * found by hand */ */ desclength = utf16_strsize((efi_char16_t *)(buffer + 6), len) + 2; desclength = utf16_strsize((efi_char16_t *)(buffer + 6), len - 6) + 2; /* Each boot entry must have a descriptor */ /* Each boot entry must have a descriptor */ if (!desclength) if (!desclength) Loading @@ -275,7 +287,8 @@ validate_load_option(struct efi_variable *var, int match, u8 *buffer, int len) } } static bool static bool validate_uint16(struct efi_variable *var, int match, u8 *buffer, int len) validate_uint16(struct efi_variable *var, int match, u8 *buffer, unsigned long len) { { /* A single 16-bit integer */ /* A single 16-bit integer */ if (len != 2) if (len != 2) Loading @@ -285,7 +298,8 @@ validate_uint16(struct efi_variable *var, int match, u8 *buffer, int len) } } static bool static bool validate_ascii_string(struct efi_variable *var, int match, u8 *buffer, int len) validate_ascii_string(struct efi_variable *var, int match, u8 *buffer, unsigned long len) { { int i; int i; Loading @@ -303,7 +317,7 @@ validate_ascii_string(struct efi_variable *var, int match, u8 *buffer, int len) struct variable_validate { struct variable_validate { char *name; char *name; bool (*validate)(struct efi_variable *var, int match, u8 *data, bool (*validate)(struct efi_variable *var, int match, u8 *data, int len); unsigned long len); }; }; static const struct variable_validate variable_validate[] = { static const struct variable_validate variable_validate[] = { Loading @@ -325,7 +339,7 @@ static const struct variable_validate variable_validate[] = { }; }; static bool static bool validate_var(struct efi_variable *var, u8 *data, int len) validate_var(struct efi_variable *var, u8 *data, unsigned long len) { { int i; int i; u16 *unicode_name = var->VariableName; u16 *unicode_name = var->VariableName; Loading Loading
drivers/firmware/efivars.c +30 −16 Original line number Original line Diff line number Diff line Loading @@ -192,19 +192,22 @@ utf16_strncmp(const efi_char16_t *a, const efi_char16_t *b, size_t len) } } static bool static bool validate_device_path(struct efi_variable *var, int match, u8 *buffer, int len) validate_device_path(struct efi_variable *var, int match, u8 *buffer, unsigned long len) { { struct efi_generic_dev_path *node; struct efi_generic_dev_path *node; int offset = 0; int offset = 0; node = (struct efi_generic_dev_path *)buffer; node = (struct efi_generic_dev_path *)buffer; while (offset < len) { if (len < sizeof(*node)) offset += node->length; if (offset > len) return false; return false; while (offset <= len - sizeof(*node) && node->length >= sizeof(*node) && node->length <= len - offset) { offset += node->length; if ((node->type == EFI_DEV_END_PATH || if ((node->type == EFI_DEV_END_PATH || node->type == EFI_DEV_END_PATH2) && node->type == EFI_DEV_END_PATH2) && node->sub_type == EFI_DEV_END_ENTIRE) node->sub_type == EFI_DEV_END_ENTIRE) Loading @@ -222,7 +225,8 @@ validate_device_path(struct efi_variable *var, int match, u8 *buffer, int len) } } static bool static bool validate_boot_order(struct efi_variable *var, int match, u8 *buffer, int len) validate_boot_order(struct efi_variable *var, int match, u8 *buffer, unsigned long len) { { /* An array of 16-bit integers */ /* An array of 16-bit integers */ if ((len % 2) != 0) if ((len % 2) != 0) Loading @@ -232,19 +236,27 @@ validate_boot_order(struct efi_variable *var, int match, u8 *buffer, int len) } } static bool static bool validate_load_option(struct efi_variable *var, int match, u8 *buffer, int len) validate_load_option(struct efi_variable *var, int match, u8 *buffer, unsigned long len) { { u16 filepathlength; u16 filepathlength; int i, desclength = 0; int i, desclength = 0, namelen; namelen = utf16_strnlen(var->VariableName, sizeof(var->VariableName)); /* Either "Boot" or "Driver" followed by four digits of hex */ /* Either "Boot" or "Driver" followed by four digits of hex */ for (i = match; i < match+4; i++) { for (i = match; i < match+4; i++) { if (hex_to_bin(var->VariableName[i] & 0xff) < 0) if (var->VariableName[i] > 127 || hex_to_bin(var->VariableName[i] & 0xff) < 0) return true; return true; } } /* A valid entry must be at least 6 bytes */ /* Reject it if there's 4 digits of hex and then further content */ if (len < 6) if (namelen > match + 4) return false; /* A valid entry must be at least 8 bytes */ if (len < 8) return false; return false; filepathlength = buffer[4] | buffer[5] << 8; filepathlength = buffer[4] | buffer[5] << 8; Loading @@ -253,7 +265,7 @@ validate_load_option(struct efi_variable *var, int match, u8 *buffer, int len) * There's no stored length for the description, so it has to be * There's no stored length for the description, so it has to be * found by hand * found by hand */ */ desclength = utf16_strsize((efi_char16_t *)(buffer + 6), len) + 2; desclength = utf16_strsize((efi_char16_t *)(buffer + 6), len - 6) + 2; /* Each boot entry must have a descriptor */ /* Each boot entry must have a descriptor */ if (!desclength) if (!desclength) Loading @@ -275,7 +287,8 @@ validate_load_option(struct efi_variable *var, int match, u8 *buffer, int len) } } static bool static bool validate_uint16(struct efi_variable *var, int match, u8 *buffer, int len) validate_uint16(struct efi_variable *var, int match, u8 *buffer, unsigned long len) { { /* A single 16-bit integer */ /* A single 16-bit integer */ if (len != 2) if (len != 2) Loading @@ -285,7 +298,8 @@ validate_uint16(struct efi_variable *var, int match, u8 *buffer, int len) } } static bool static bool validate_ascii_string(struct efi_variable *var, int match, u8 *buffer, int len) validate_ascii_string(struct efi_variable *var, int match, u8 *buffer, unsigned long len) { { int i; int i; Loading @@ -303,7 +317,7 @@ validate_ascii_string(struct efi_variable *var, int match, u8 *buffer, int len) struct variable_validate { struct variable_validate { char *name; char *name; bool (*validate)(struct efi_variable *var, int match, u8 *data, bool (*validate)(struct efi_variable *var, int match, u8 *data, int len); unsigned long len); }; }; static const struct variable_validate variable_validate[] = { static const struct variable_validate variable_validate[] = { Loading @@ -325,7 +339,7 @@ static const struct variable_validate variable_validate[] = { }; }; static bool static bool validate_var(struct efi_variable *var, u8 *data, int len) validate_var(struct efi_variable *var, u8 *data, unsigned long len) { { int i; int i; u16 *unicode_name = var->VariableName; u16 *unicode_name = var->VariableName; Loading