From ba8ca443051f93a74c0d03d62e70402036f967a5 Mon Sep 17 00:00:00 2001 From: Philip Withnall Date: Thu, 4 Feb 2021 13:58:32 +0000 Subject: [PATCH 08/11] gkeyfilesettingsbackend: Handle long keys when converting paths Previously, the code in `convert_path()` could not handle keys longer than `G_MAXINT`, and would overflow if that was exceeded. Convert the code to use `gsize` and `g_memdup2()` throughout, and change from identifying the position of the final slash in the string using a signed offset `i`, to using a pointer to the character (and `strrchr()`). This allows the slash to be at any position in a `G_MAXSIZE`-long string, without sacrificing a bit of the offset for indicating whether a slash was found. Signed-off-by: Philip Withnall Helps: #2319 Upstream-Status: Backport [https://mirrors.ocf.berkeley.edu/ubuntu/pool/main/g/glib2.0/glib2.0_2.64.6-1~ubuntu20.04.3.debian.tar.xz] CVE: CVE-2021-27219 Signed-off-by: Neetika Singh Signed-off-by: Ranjitsinh Rathod --- gio/gkeyfilesettingsbackend.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/gio/gkeyfilesettingsbackend.c b/gio/gkeyfilesettingsbackend.c index cd5765afd..25b057672 100644 --- a/gio/gkeyfilesettingsbackend.c +++ b/gio/gkeyfilesettingsbackend.c @@ -33,6 +33,7 @@ #include "gfilemonitor.h" #include "gsimplepermission.h" #include "gsettingsbackendinternal.h" +#include "gstrfuncsprivate.h" #include "giomodule-priv.h" #include "gportalsupport.h" @@ -145,8 +146,8 @@ convert_path (GKeyfileSettingsBackend *kfsb, gchar **group, gchar **basename) { - gint key_len = strlen (key); - gint i; + gsize key_len = strlen (key); + const gchar *last_slash; if (key_len < kfsb->prefix_len || memcmp (key, kfsb->prefix, kfsb->prefix_len) != 0) @@ -155,38 +156,36 @@ convert_path (GKeyfileSettingsBackend *kfsb, key_len -= kfsb->prefix_len; key += kfsb->prefix_len; - for (i = key_len; i >= 0; i--) - if (key[i] == '/') - break; + last_slash = strrchr (key, '/'); if (kfsb->root_group) { /* if a root_group was specified, make sure the user hasn't given * a path that ghosts that group name */ - if (i == kfsb->root_group_len && memcmp (key, kfsb->root_group, i) == 0) + if (last_slash != NULL && (last_slash - key) == kfsb->root_group_len && memcmp (key, kfsb->root_group, last_slash - key) == 0) return FALSE; } else { /* if no root_group was given, ensure that the user gave a path */ - if (i == -1) + if (last_slash == NULL) return FALSE; } if (group) { - if (i >= 0) + if (last_slash != NULL) { - *group = g_memdup (key, i + 1); - (*group)[i] = '\0'; + *group = g_memdup2 (key, (last_slash - key) + 1); + (*group)[(last_slash - key)] = '\0'; } else *group = g_strdup (kfsb->root_group); } if (basename) - *basename = g_memdup (key + i + 1, key_len - i); + *basename = g_memdup2 (last_slash + 1, key_len - (last_slash - key)); return TRUE; } -- GitLab