diff mbox series

[libubootenv] uboot_env: fix checking of i and m type variable attributes

Message ID b94e6fbe-28ef-4017-a88e-2c3c40d59a8c@googlegroups.com
State New
Headers show
Series [libubootenv] uboot_env: fix checking of i and m type variable attributes | expand

Commit Message

Uwe Schuster Aug. 2, 2019, 11:31 a.m. UTC
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.
---
 src/uboot_env.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 78 insertions(+), 1 deletion(-)

 {
     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;

Comments

Stefano Babic Aug. 2, 2019, 12:08 p.m. UTC | #1
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>.
Uwe Schuster March 11, 2020, 2:40 p.m. UTC | #2
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 mbox series

Patch

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)