Message ID | b94e6fbe-28ef-4017-a88e-2c3c40d59a8c@googlegroups.com |
---|---|
State | Changes Requested |
Headers | show |
Series | [libubootenv] uboot_env: fix checking of i and m type variable attributes | expand |
Hi Uwe, On 02/08/19 13:31, Uwe Schuster wrote: > This patch fixes format checking for variables with i and m type > attributes reported by me in > https://groups.google.com/d/msg/swupdate/ShdD10dl7Pc/ULUYSpFDCAAJ > . > I copied the code which does the same task from original u-boot sources > so there might be a license issue with that (LGPL-GPL). I'm not a > license expert so feel free to fix that. Thanks for the patch, but it cannkot be applied - I could not include any code that change the license of the library. No u-boot code is allowed, else the library becomes GPLv2. Best regards, Stefano Babic > --- > src/uboot_env.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++++- > 1 file changed, 78 insertions(+), 1 deletion(-) > > diff --git a/src/uboot_env.c b/src/uboot_env.c > index 91f94e7..09d210d 100644 > --- a/src/uboot_env.c > +++ b/src/uboot_env.c > @@ -113,6 +113,78 @@ static char access_tostring(access_attribute a) > return 'a'; > } > > + > +static inline int is_hex_prefix(const char *value) > +{ > + return value[0] == '0' && (value[1] == 'x' || value[1] == 'X'); > +} > + > +static void skip_num(int hex, const char *value, const char **end, > + int max_digits) > +{ > + int i; > + > + if (hex && is_hex_prefix(value)) > + value += 2; > + > + for (i = max_digits; i != 0; i--) { > + if (hex && !isxdigit(*value)) > + break; > + if (!hex && !isdigit(*value)) > + break; > + value++; > + } > + if (end != NULL) > + *end = value; > +} > + > +static int eth_validate_ethaddr_str(const char *addr) > +{ > + const char *end; > + const char *cur; > + int i; > + > + cur = addr; > + for (i = 0; i < 6; i++) { > + skip_num(1, cur, &end, 2); > + if (cur == end) > + return -1; > + if (cur + 2 == end && is_hex_prefix(cur)) > + return -1; > + if (i != 5 && *end != ':') > + return -1; > + if (i == 5 && *end != '\0') > + return -1; > + cur = end + 1; > + } > + > + return 0; > +} > + > +static int eth_validate_ipaddr_str(const char *addr) > +{ > + const char *end; > + const char *cur; > + int i; > + > + /* To not confuse things, checking is done the same as in u-boot > sources, > + despite the fact that e.g. 192.1 is also a valid IP address */ > + > + cur = addr; > + for (i = 0; i < 4; i++) { > + skip_num(0, cur, &end, 3); > + if (cur == end) > + return -1; > + if (i != 3 && *end != '.') > + return -1; > + if (i == 3 && *end != '\0') > + return -1; > + cur = end + 1; > + } > + > + return 0; > +} > + > static struct var_entry *__libuboot_get_env(struct vars *envs, const > char *varname) > { > struct var_entry *entry; > @@ -1115,13 +1187,18 @@ static bool libuboot_validate_flags(struct > var_entry *entry, const char *value) > } > break; > case TYPE_ATTR_BOOL: > - ok_access = (value[0] == '1' || value[0] == 'y' || value[0] == > 't' || > + ok_type = (value[0] == '1' || value[0] == 'y' || value[0] == 't' || > value[0] == 'Y' || value[0] == 'T' || > value[0] == '0' || value[0] == 'n' || value[0] == 'f' || > value[0] == 'N' || value[0] == 'F') && (strlen(value) != 1); > break; > case TYPE_ATTR_IP: > + if ( 0 != eth_validate_ipaddr_str(value) ) > + ok_type = false; > + break; > case TYPE_ATTR_MAC: > + if ( 0 != eth_validate_ethaddr_str(value) ) > + ok_type = false; > break; > } > return ok_type; > -- > 2.17.1 > > > -- > You received this message because you are subscribed to the Google > Groups "swupdate" group. > To unsubscribe from this group and stop receiving emails from it, send > an email to swupdate+unsubscribe@googlegroups.com > <mailto:swupdate+unsubscribe@googlegroups.com>. > To view this discussion on the web visit > https://groups.google.com/d/msgid/swupdate/b94e6fbe-28ef-4017-a88e-2c3c40d59a8c%40googlegroups.com > <https://groups.google.com/d/msgid/swupdate/b94e6fbe-28ef-4017-a88e-2c3c40d59a8c%40googlegroups.com?utm_medium=email&utm_source=footer>.
Hi Stefano, In the meantime I have rewritten the code on my own to not violate any license. Maybe you can consider to use it now? Regards, Uwe --- src/uboot_env.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 62 insertions(+), 1 deletion(-) diff --git a/src/uboot_env.c b/src/uboot_env.c index d7329fa..5e7ee95 100644 --- a/src/uboot_env.c +++ b/src/uboot_env.c @@ -113,6 +113,62 @@ static char access_tostring(access_attribute a) return 'a'; } + +/* attribution to https://stackoverflow.com/questions/4792035 + and https://stackoverflow.com/users/454406/daniel-gehriger + */ +static int validate_ethaddr_str(const char *eth_addr) +{ + int i = 0; + int s = 0; + + while (eth_addr && *eth_addr) { + if (isxdigit(*eth_addr)) { + i++; + } + else if (*eth_addr == ':') { + if (i == 0 || i / 2 - 1 != s) + break; + ++s; + } + else + s = -1; + + ++eth_addr; + } + + if (i == 12 && (s == 5)) + return 0; + else + return -1; +} + +/* attribution to https://stackoverflow.com/questions/791982 + and https://stackoverflow.com/users/952747/deepmax + */ +static int validate_ipaddr_str(const char *ip_addr) +{ + int len = strlen(ip_addr); + + if (len < 7 || len > 15) + return -1; + + char tail[16]; + tail[0] = 0; + + unsigned int d[4]; + int c = sscanf(ip_addr, "%3u.%3u.%3u.%3u%s", &d[0], &d[1], &d[2], &d[3], tail); + + if (c != 4 || tail[0]) + return -1; + + for (int i = 0; i < 4; i++) + if (d[i] > 255) + return -1; + + return 0; +} + static struct var_entry *__libuboot_get_env(struct vars *envs, const char *varname) { struct var_entry *entry; @@ -1146,13 +1202,18 @@ static bool libuboot_validate_flags(struct var_entry *entry, const char *value) } break; case TYPE_ATTR_BOOL: - ok_access = (value[0] == '1' || value[0] == 'y' || value[0] == 't' || + ok_type = (value[0] == '1' || value[0] == 'y' || value[0] == 't' || value[0] == 'Y' || value[0] == 'T' || value[0] == '0' || value[0] == 'n' || value[0] == 'f' || value[0] == 'N' || value[0] == 'F') && (strlen(value) != 1); break; case TYPE_ATTR_IP: + if ( 0 != validate_ipaddr_str(value) ) + ok_type = false; + break; case TYPE_ATTR_MAC: + if ( 0 != validate_ethaddr_str(value) ) + ok_type = false; break; } #if !defined(NDEBUG)
diff --git a/src/uboot_env.c b/src/uboot_env.c index 91f94e7..09d210d 100644 --- a/src/uboot_env.c +++ b/src/uboot_env.c @@ -113,6 +113,78 @@ static char access_tostring(access_attribute a) return 'a'; } + +static inline int is_hex_prefix(const char *value) +{ + return value[0] == '0' && (value[1] == 'x' || value[1] == 'X'); +} + +static void skip_num(int hex, const char *value, const char **end, + int max_digits) +{ + int i; + + if (hex && is_hex_prefix(value)) + value += 2; + + for (i = max_digits; i != 0; i--) { + if (hex && !isxdigit(*value)) + break; + if (!hex && !isdigit(*value)) + break; + value++; + } + if (end != NULL) + *end = value; +} + +static int eth_validate_ethaddr_str(const char *addr) +{ + const char *end; + const char *cur; + int i; + + cur = addr; + for (i = 0; i < 6; i++) { + skip_num(1, cur, &end, 2); + if (cur == end) + return -1; + if (cur + 2 == end && is_hex_prefix(cur)) + return -1; + if (i != 5 && *end != ':') + return -1; + if (i == 5 && *end != '\0') + return -1; + cur = end + 1; + } + + return 0; +} + +static int eth_validate_ipaddr_str(const char *addr) +{ + const char *end; + const char *cur; + int i; + + /* To not confuse things, checking is done the same as in u-boot sources, + despite the fact that e.g. 192.1 is also a valid IP address */ + + cur = addr; + for (i = 0; i < 4; i++) { + skip_num(0, cur, &end, 3); + if (cur == end) + return -1; + if (i != 3 && *end != '.') + return -1; + if (i == 3 && *end != '\0') + return -1; + cur = end + 1; + } + + return 0; +} + static struct var_entry *__libuboot_get_env(struct vars *envs, const char *varname)