From cbce25e2fec5f23ead443707bac8672f87b9fdb0 Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Thu, 10 Mar 2016 15:51:31 -0500 Subject: [PATCH] libefivar: make efi loadopt path functions have useful limit checks Make efi_loadopt_pathlen() and efi_loadopt_path() actually bounds check against something useful, not just "does some possibly unallocated space extend into some other possibly unallocated space". Signed-off-by: Peter Jones --- src/loadopt.c | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/src/loadopt.c b/src/loadopt.c index e5b664c..eec4293 100644 --- a/src/loadopt.c +++ b/src/loadopt.c @@ -16,7 +16,10 @@ * You should have received a copy of the GNU General Public License * along with this library. If not, see . */ + #include +#include + #include "dp.h" #include "include/efivar/efiboot-loadopt.h" @@ -147,8 +150,12 @@ __attribute__((__visibility__ ("default"))) efi_loadopt_pathlen(efi_load_option *opt, ssize_t limit) { uint16_t len = opt->file_path_list_length; - if (limit >= 0 && len > limit) - return 0; + if (limit >= 0) { + if (len > limit) + return 0; + if (limit - offsetof(efi_load_option, file_path_list_length) < len) + return 0; + } return len; } @@ -158,11 +165,20 @@ __attribute__((__visibility__ ("default"))) efi_loadopt_path(efi_load_option *opt, ssize_t limit) { char *p = (char *)opt; - efidp dp = (efidp)(p + sizeof (opt->attributes) - + sizeof (opt->file_path_list_length) - + ucs2size(opt->description, -1)); - long long size = (unsigned long)dp - (unsigned long)opt; - if (limit >= 0 && size > limit) + size_t l; + ssize_t desc_limit; + efidp dp; + + l = (size_t)limit; + if (l <= offsetof(efi_load_option, description)) + return NULL; + desc_limit = limit - offsetof(efi_load_option, description); + + dp = (efidp)(p + sizeof (opt->attributes) + + sizeof (opt->file_path_list_length) + + ucs2size(opt->description, desc_limit)); + limit -= (unsigned long)dp - (unsigned long)opt; + if (!efidp_is_valid(dp, limit)) return NULL; return dp; } -- 2.11.0