summaryrefslogtreecommitdiffstats
path: root/meta/recipes-devtools/git/files/CVE-2023-29007.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-devtools/git/files/CVE-2023-29007.patch')
-rw-r--r--meta/recipes-devtools/git/files/CVE-2023-29007.patch159
1 files changed, 159 insertions, 0 deletions
diff --git a/meta/recipes-devtools/git/files/CVE-2023-29007.patch b/meta/recipes-devtools/git/files/CVE-2023-29007.patch
new file mode 100644
index 0000000000..e166c01412
--- /dev/null
+++ b/meta/recipes-devtools/git/files/CVE-2023-29007.patch
@@ -0,0 +1,159 @@
+From 057c07a7b1fae22fdeef26c243f4cfbe3afc90ce Mon Sep 17 00:00:00 2001
+From: Taylor Blau <me@ttaylorr.com>
+Date: Fri, 14 Apr 2023 11:46:59 -0400
+Subject: [PATCH] Merge branch 'tb/config-copy-or-rename-in-file-injection'
+
+Avoids issues with renaming or deleting sections with long lines, where
+configuration values may be interpreted as sections, leading to
+configuration injection. Addresses CVE-2023-29007.
+
+* tb/config-copy-or-rename-in-file-injection:
+ config.c: disallow overly-long lines in `copy_or_rename_section_in_file()`
+ config.c: avoid integer truncation in `copy_or_rename_section_in_file()`
+ config: avoid fixed-sized buffer when renaming/deleting a section
+ t1300: demonstrate failure when renaming sections with long lines
+
+Signed-off-by: Taylor Blau <me@ttaylorr.com>
+
+Upstream-Status: Backport [https://github.com/git/git/commit/528290f8c61222433a8cf02fb7cfffa8438432b4]
+CVE: CVE-2023-29007
+Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com>
+---
+ config.c | 36 +++++++++++++++++++++++++-----------
+ t/t1300-config.sh | 30 ++++++++++++++++++++++++++++++
+ 2 files changed, 55 insertions(+), 11 deletions(-)
+
+diff --git a/config.c b/config.c
+index e7052b3..676b687 100644
+--- a/config.c
++++ b/config.c
+@@ -2987,9 +2987,10 @@ void git_config_set_multivar(const char *key, const char *value,
+ multi_replace);
+ }
+
+-static int section_name_match (const char *buf, const char *name)
++static size_t section_name_match (const char *buf, const char *name)
+ {
+- int i = 0, j = 0, dot = 0;
++ size_t i = 0, j = 0;
++ int dot = 0;
+ if (buf[i] != '[')
+ return 0;
+ for (i = 1; buf[i] && buf[i] != ']'; i++) {
+@@ -3042,6 +3043,8 @@ static int section_name_is_ok(const char *name)
+ return 1;
+ }
+
++#define GIT_CONFIG_MAX_LINE_LEN (512 * 1024)
++
+ /* if new_name == NULL, the section is removed instead */
+ static int git_config_copy_or_rename_section_in_file(const char *config_filename,
+ const char *old_name,
+@@ -3051,11 +3054,12 @@ static int git_config_copy_or_rename_section_in_file(const char *config_filename
+ char *filename_buf = NULL;
+ struct lock_file lock = LOCK_INIT;
+ int out_fd;
+- char buf[1024];
++ struct strbuf buf = STRBUF_INIT;
+ FILE *config_file = NULL;
+ struct stat st;
+ struct strbuf copystr = STRBUF_INIT;
+ struct config_store_data store;
++ uint32_t line_nr = 0;
+
+ memset(&store, 0, sizeof(store));
+
+@@ -3092,16 +3096,25 @@ static int git_config_copy_or_rename_section_in_file(const char *config_filename
+ goto out;
+ }
+
+- while (fgets(buf, sizeof(buf), config_file)) {
+- int i;
+- int length;
++ while (!strbuf_getwholeline(&buf, config_file, '\n')) {
++ size_t i, length;
+ int is_section = 0;
+- char *output = buf;
+- for (i = 0; buf[i] && isspace(buf[i]); i++)
++ char *output = buf.buf;
++
++ line_nr++;
++
++ if (buf.len >= GIT_CONFIG_MAX_LINE_LEN) {
++ ret = error(_("refusing to work with overly long line "
++ "in '%s' on line %"PRIuMAX),
++ config_filename, (uintmax_t)line_nr);
++ goto out;
++ }
++
++ for (i = 0; buf.buf[i] && isspace(buf.buf[i]); i++)
+ ; /* do nothing */
+- if (buf[i] == '[') {
++ if (buf.buf[i] == '[') {
+ /* it's a section */
+- int offset;
++ size_t offset;
+ is_section = 1;
+
+ /*
+@@ -3118,7 +3131,7 @@ static int git_config_copy_or_rename_section_in_file(const char *config_filename
+ strbuf_reset(&copystr);
+ }
+
+- offset = section_name_match(&buf[i], old_name);
++ offset = section_name_match(&buf.buf[i], old_name);
+ if (offset > 0) {
+ ret++;
+ if (new_name == NULL) {
+@@ -3193,6 +3206,7 @@ static int git_config_copy_or_rename_section_in_file(const char *config_filename
+ out_no_rollback:
+ free(filename_buf);
+ config_store_data_clear(&store);
++ strbuf_release(&buf);
+ return ret;
+ }
+
+diff --git a/t/t1300-config.sh b/t/t1300-config.sh
+index 983a0a1..9b67f6b 100755
+--- a/t/t1300-config.sh
++++ b/t/t1300-config.sh
+@@ -616,6 +616,36 @@ test_expect_success 'renaming to bogus section is rejected' '
+ test_must_fail git config --rename-section branch.zwei "bogus name"
+ '
+
++test_expect_success 'renaming a section with a long line' '
++ {
++ printf "[b]\\n" &&
++ printf " c = d %1024s [a] e = f\\n" " " &&
++ printf "[a] g = h\\n"
++ } >y &&
++ git config -f y --rename-section a xyz &&
++ test_must_fail git config -f y b.e
++'
++
++test_expect_success 'renaming an embedded section with a long line' '
++ {
++ printf "[b]\\n" &&
++ printf " c = d %1024s [a] [foo] e = f\\n" " " &&
++ printf "[a] g = h\\n"
++ } >y &&
++ git config -f y --rename-section a xyz &&
++ test_must_fail git config -f y foo.e
++'
++
++test_expect_success 'renaming a section with an overly-long line' '
++ {
++ printf "[b]\\n" &&
++ printf " c = d %525000s e" " " &&
++ printf "[a] g = h\\n"
++ } >y &&
++ test_must_fail git config -f y --rename-section a xyz 2>err &&
++ test_i18ngrep "refusing to work with overly long line in .y. on line 2" err
++'
++
+ cat >> .git/config << EOF
+ [branch "zwei"] a = 1 [branch "vier"]
+ EOF
+--
+2.25.1
+