Skip to content

Commit b0dc5e8

Browse files
Kristofer Älvringdahlerlend
authored andcommitted
Bug#30668886 Missing out-of-bounds check caused false read
A missing out-of-bounds check in wild_case_match caused a pointer to read out of bounds. RB: 23965
1 parent 6616674 commit b0dc5e8

File tree

2 files changed

+76
-7
lines changed

2 files changed

+76
-7
lines changed

sql/auth/sql_auth_cache.cc

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -619,23 +619,26 @@ int wild_case_compare(CHARSET_INFO *cs, const char *str, size_t str_len,
619619

620620
while (wildstr != wildstr_end && str != str_end) {
621621
while (wildstr != wildstr_end && *wildstr != wild_many &&
622-
*wildstr != wild_one) {
622+
*wildstr != wild_one && str != str_end) {
623623
if (*wildstr == wild_prefix && wildstr[1]) wildstr++;
624624
if (my_toupper(cs, *wildstr++) != my_toupper(cs, *str++)) return 1;
625625
}
626626
if (wildstr == wildstr_end) {
627627
return str != str_end;
628628
}
629+
if (str == str_end) {
630+
if (*wildstr == '%' && wildstr + 1 == wildstr_end)
631+
return 0; /* % match empty string */
632+
return (wildstr != wildstr_end);
633+
}
629634
if (*wildstr++ == wild_one) {
630635
++str;
631636
if (str == str_end) /* One char; skip */
632637
{
633638
return wildstr != wildstr_end;
634639
}
635-
} else { /* Found '*' */
636-
if (wildstr == wildstr_end) {
637-
return 0; /* '*' as last char: OK */
638-
}
640+
} else { /* Found wild_many */
641+
if (wildstr == wildstr_end) return 0; // empty matches wild_many
639642
flag = (*wildstr != wild_many && *wildstr != wild_one);
640643
do {
641644
if (flag) {
@@ -646,8 +649,9 @@ int wild_case_compare(CHARSET_INFO *cs, const char *str, size_t str_len,
646649
if (str == str_end) return 1;
647650
}
648651
if (wild_case_compare(cs, str, str_end - str, wildstr,
649-
wildstr_end - wildstr) == 0)
652+
wildstr_end - wildstr) == 0) {
650653
return 0;
654+
}
651655
++str;
652656
} while (str != str_end);
653657
return 1;

unittest/gunit/wild_case_compare-t.cc

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
1+
/* Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved.
22
33
This program is free software; you can redistribute it and/or modify
44
it under the terms of the GNU General Public License, version 2.0,
@@ -52,7 +52,69 @@ TEST_F(WildCaseCompareTest, BasicTest) {
5252
wild_case_compare(system_charset_info, "aaaa_users_lost_aaaa", ""));
5353
EXPECT_EQ(0, wild_case_compare(system_charset_info, "aaaa", "%%%%"));
5454
EXPECT_EQ(1, wild_case_compare(system_charset_info, "\\_\\_\\_", "_\\_\\_"));
55+
EXPECT_EQ(0, wild_case_compare(system_charset_info, "xyz", "%"));
56+
EXPECT_EQ(0, wild_case_compare(system_charset_info, "xyz", "%%"));
57+
EXPECT_EQ(0, wild_case_compare(system_charset_info, "xyz", ("%%%")));
58+
EXPECT_EQ(0, wild_case_compare(system_charset_info, "xyz", ("xyz")));
59+
EXPECT_EQ(0, wild_case_compare(system_charset_info, "xyz", "%yz"));
60+
EXPECT_EQ(0, wild_case_compare(system_charset_info, "xyz", "x%z"));
61+
EXPECT_EQ(0, wild_case_compare(system_charset_info, "xyz", "xy%"));
62+
EXPECT_EQ(0, wild_case_compare(system_charset_info, "xyz", "___"));
63+
EXPECT_EQ(0, wild_case_compare(system_charset_info, "xyz", "__z"));
64+
EXPECT_EQ(0, wild_case_compare(system_charset_info, "xyz", "xyz"));
65+
EXPECT_EQ(0, wild_case_compare(system_charset_info, "xyz", "_yz"));
66+
EXPECT_EQ(0, wild_case_compare(system_charset_info, "xyz", "x_z"));
67+
EXPECT_EQ(0, wild_case_compare(system_charset_info, "xyz", "xy_"));
68+
EXPECT_EQ(0, wild_case_compare(system_charset_info, "xyz", "x__"));
69+
EXPECT_EQ(1, wild_case_compare(system_charset_info, "xyza", "___"));
70+
EXPECT_EQ(1, wild_case_compare(system_charset_info, "xyza", "__z"));
71+
EXPECT_EQ(1, wild_case_compare(system_charset_info, "xyza", "xyz"));
72+
EXPECT_EQ(1, wild_case_compare(system_charset_info, "xyza", "_yz"));
73+
EXPECT_EQ(1, wild_case_compare(system_charset_info, "xyza", "x_z"));
74+
EXPECT_EQ(1, wild_case_compare(system_charset_info, "xyza", "xy_"));
75+
EXPECT_EQ(1, wild_case_compare(system_charset_info, "xyza", "x__"));
76+
EXPECT_EQ(1, wild_case_compare(system_charset_info, "xyz", "xyzz"));
77+
EXPECT_EQ(1, wild_case_compare(system_charset_info, "xyz", "%yzz"));
78+
EXPECT_EQ(1, wild_case_compare(system_charset_info, "xyz", "x%zz"));
79+
EXPECT_EQ(1, wild_case_compare(system_charset_info, "xyz", "x%%zz"));
80+
EXPECT_EQ(1, wild_case_compare(system_charset_info, "xyz", "x%%%zz"));
81+
82+
EXPECT_EQ(0, wild_case_compare(system_charset_info, "xyz_", "xyz_"));
83+
EXPECT_EQ(0, wild_case_compare(system_charset_info, "xyz_", "xyz\\_"));
84+
EXPECT_EQ(0, wild_case_compare(system_charset_info, "xy_z_", "xy\\_z\\_"));
85+
EXPECT_EQ(0, wild_case_compare(system_charset_info, "xy%z%", "xy\\%z\\%"));
86+
EXPECT_EQ(0, wild_case_compare(system_charset_info, "xy%za", "xy\\%z%"));
87+
EXPECT_EQ(0, wild_case_compare(system_charset_info, "xy%zaaaaa", "xy\\%z%"));
88+
EXPECT_EQ(0,
89+
wild_case_compare(system_charset_info,
90+
"xy%zabcdefghiljklomnopqrstuvwxyz", "xy\\%z%"));
91+
EXPECT_EQ(1,
92+
wild_case_compare(system_charset_info,
93+
"xy%aabcdefghiljklomnopqrstuvwxyz", "xy\\%z%"));
94+
EXPECT_EQ(0, wild_case_compare(system_charset_info, "xy%zaa%aa", "xy\\%z%"));
95+
EXPECT_EQ(0, wild_case_compare(system_charset_info, "%", "\\%"));
96+
EXPECT_EQ(0, wild_case_compare(system_charset_info, "_", "\\_"));
97+
EXPECT_EQ(0, wild_case_compare(system_charset_info, "___", "\\_\\_\\_"));
5598
EXPECT_EQ(0, wild_case_compare(system_charset_info, "___", "_\\_\\_"));
99+
EXPECT_EQ(0, wild_case_compare(system_charset_info, "___", "__\\_"));
100+
EXPECT_EQ(1,
101+
wild_case_compare(system_charset_info, "\\_\\_\\_", "\\_\\_\\_"));
102+
EXPECT_EQ(1,
103+
wild_case_compare(system_charset_info, "\\%\\%\\%", "\\%\\%\\%"));
104+
EXPECT_EQ(1, wild_case_compare(system_charset_info, "\\%\\%\\%", "\\%\\%"));
105+
EXPECT_EQ(1, wild_case_compare(system_charset_info, "\\%\\%\\%", "\\%"));
106+
EXPECT_EQ(0, wild_case_compare(system_charset_info, "\\%\\%\\%", "%"));
107+
EXPECT_EQ(1, wild_case_compare(system_charset_info, "\\\\", "\\\\"));
108+
EXPECT_EQ(0, wild_case_compare(system_charset_info, "\\\\", "\\\\\\\\"));
109+
EXPECT_EQ(0, wild_case_compare(system_charset_info, "åäö", "åäö"));
110+
EXPECT_EQ(0, wild_case_compare(system_charset_info, "xyz", "xyz%"));
111+
EXPECT_EQ(0, wild_case_compare(system_charset_info, "", "%"));
112+
EXPECT_EQ(1, wild_case_compare(system_charset_info, "", ""));
113+
114+
EXPECT_EQ(0, wild_case_compare(system_charset_info, "db1", "db_"));
115+
EXPECT_EQ(1, wild_case_compare(system_charset_info, "dbbb1", "db_"));
116+
EXPECT_EQ(1, wild_case_compare(system_charset_info, "dddddb1", "db_"));
117+
EXPECT_EQ(1, wild_case_compare(system_charset_info, "dddddb1", "db%"));
56118
EXPECT_EQ(0, wild_case_compare(system_charset_info, "___", "___"));
57119
EXPECT_EQ(0, wild_case_compare(system_charset_info, "", "%"));
58120
EXPECT_EQ(1, wild_case_compare(system_charset_info, "", ""));
@@ -64,5 +126,8 @@ TEST_F(WildCaseCompareTest, BasicTest) {
64126
EXPECT_EQ(1, wild_case_compare(system_charset_info, "", "db_aaaa"));
65127
EXPECT_EQ(1, wild_case_compare(system_charset_info, "", "db%aaaa"));
66128
EXPECT_EQ(1, wild_case_compare(system_charset_info, "", "db%aa_aa"));
129+
EXPECT_EQ(0, wild_case_compare(system_charset_info, "aaaAA_*", "%A_*"));
130+
EXPECT_EQ(1, wild_case_compare(system_charset_info, "aaaAA_", "%A_*"));
131+
EXPECT_EQ(1, wild_case_compare(system_charset_info, "aaF", "%F_*-*=<"));
67132
}
68133
} // namespace wild_case_compare_unittest

0 commit comments

Comments
 (0)