1package dns 2 3import ( 4 "net" 5 "testing" 6) 7 8// TestPackDataOpt tests generated using fuzz.go and with a message pack 9// containing the following bytes: 10// "0000\x00\x00000000\x00\x00/00000" + 11// "0\x00\v\x00#\b00000000\x00\x00)000" + 12// "000\x00\x1c00\x00\x0000\x00\x01000\x00\x00\x00\b" + 13// "\x00\v\x00\x02\x0000000000" 14// That bytes sequence created the overflow error. 15func TestPackDataOpt(t *testing.T) { 16 type args struct { 17 option []EDNS0 18 msg []byte 19 off int 20 } 21 tests := []struct { 22 name string 23 args args 24 want int 25 wantErr bool 26 wantErrMsg string 27 }{ 28 { 29 name: "overflow", 30 args: args{ 31 option: []EDNS0{ 32 &EDNS0_LOCAL{Code: 0x3030, Data: []uint8{}}, 33 &EDNS0_LOCAL{Code: 0x3030, Data: []uint8{0x30}}, 34 &EDNS0_LOCAL{Code: 0x3030, Data: []uint8{}}, 35 &EDNS0_SUBNET{ 36 Code: 0x0, Family: 0x2, 37 SourceNetmask: 0x0, SourceScope: 0x30, 38 Address: net.IP{0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}}, 39 }, 40 msg: []byte{ 41 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x2, 42 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2f, 0x30, 43 0x30, 0x30, 0x30, 0x30, 0x30, 0x00, 0x0b, 0x00, 44 0x23, 0x08, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 45 0x30, 0x30, 0x00, 0x00, 0x29, 0x30, 0x30, 0x30, 46 0x30, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x00, 47 0x00, 0x30, 0x30, 0x00, 0x01, 0x30, 0x00, 0x00, 48 0x00, 49 }, 50 off: 54, 51 }, 52 wantErr: true, 53 wantErrMsg: "dns: overflow packing opt", 54 want: 57, 55 }, 56 } 57 for _, tt := range tests { 58 t.Run(tt.name, func(t *testing.T) { 59 got, err := packDataOpt(tt.args.option, tt.args.msg, tt.args.off) 60 if (err != nil) != tt.wantErr { 61 t.Errorf("packDataOpt() error = %v, wantErr %v", err, tt.wantErr) 62 return 63 } 64 if err != nil && tt.wantErrMsg != err.Error() { 65 t.Errorf("packDataOpt() error msg = %v, wantErrMsg %v", err.Error(), tt.wantErrMsg) 66 return 67 } 68 if got != tt.want { 69 t.Errorf("packDataOpt() = %v, want %v", got, tt.want) 70 } 71 }) 72 } 73} 74 75// TestCrashNSEC tests generated using fuzz.go and with a message pack 76// containing the following bytes: 77// "0000\x00\x00000000\x00\x00/00000" + 78// "0\x00\v\x00#\b00000\x00\x00\x00\x00\x00\x1a000" + 79// "000\x00\x00\x00\x00\x1a000000\x00\x00\x00\x00\x1a0" + 80// "00000\x00\v00\a0000000\x00" 81// That byte sequence, when Unpack() and subsequential Pack() created a 82// panic: runtime error: slice bounds out of range 83// which was attributed to the fact that NSEC RR length computation was different (and smaller) 84// then when within packDataNsec. 85func TestCrashNSEC(t *testing.T) { 86 compression := make(map[string]struct{}) 87 nsec := &NSEC{ 88 Hdr: RR_Header{ 89 Name: ".", 90 Rrtype: 0x2f, 91 Class: 0x3030, 92 Ttl: 0x30303030, 93 Rdlength: 0xb, 94 }, 95 NextDomain: ".", 96 TypeBitMap: []uint16{ 97 0x2302, 0x2303, 0x230a, 0x230b, 98 0x2312, 0x2313, 0x231a, 0x231b, 99 0x2322, 0x2323, 100 }, 101 } 102 expectedLength := 19 103 l := nsec.len(0, compression) 104 if l != expectedLength { 105 t.Fatalf("expected length of %d, got %d", expectedLength, l) 106 } 107} 108 109// TestCrashNSEC3 tests generated using fuzz.go and with a message pack 110// containing the following bytes: 111// "0000\x00\x00000000\x00\x00200000" + 112// "0\x00\v0000\x00\x00#\x0300\x00\x00\x00\x1a000" + 113// "000\x00\v00\x0200\x00\x03000\x00" 114// That byte sequence, when Unpack() and subsequential Pack() created a 115// panic: runtime error: slice bounds out of range 116// which was attributed to the fact that NSEC3 RR length computation was 117// different (and smaller) then within NSEC3.pack (which relies on 118// packDataNsec). 119func TestCrashNSEC3(t *testing.T) { 120 compression := make(map[string]struct{}) 121 nsec3 := &NSEC3{ 122 Hdr: RR_Header{ 123 Name: ".", 124 Rrtype: 0x32, 125 Class: 0x3030, 126 Ttl: 0x30303030, 127 Rdlength: 0xb, 128 }, 129 Hash: 0x30, 130 Flags: 0x30, 131 Iterations: 0x3030, 132 SaltLength: 0x0, 133 Salt: "", 134 HashLength: 0x0, 135 NextDomain: ".", 136 TypeBitMap: []uint16{ 137 0x2302, 0x2303, 0x230a, 0x230b, 138 }, 139 } 140 expectedLength := 24 141 l := nsec3.len(0, compression) 142 if l != expectedLength { 143 t.Fatalf("expected length of %d, got %d", expectedLength, l) 144 } 145} 146 147// TestNewRRCommentLengthCrasherString test inputs to NewRR that generated crashes. 148func TestNewRRCommentLengthCrasherString(t *testing.T) { 149 tests := []struct { 150 name string 151 in string 152 err string 153 }{ 154 155 { 156 "HINFO1", " HINFO ;;;;;;;;;;;;;" + 157 ";;;;;;;;\x00\x19;;;;;;;;;;" + 158 ";\u007f;;;;;;;;;;;;;;;;;;" + 159 ";;}mP_Qq_3sJ_1_84X_5" + 160 "45iW_3K4p8J8_v9_LT3_" + 161 "6_0l_3D4VT3xq6N_3K__" + 162 "_U_xX2m;;;;;;(;;;;;;" + 163 ";;;;;;;;;;;;;;;\x1d;;;;" + 164 ";;;;;;-0x804dBDe8ba " + 165 "\t \t\tr HINFO \" \t\t\tve" + 166 "k1xH11e__P6_dk1_51bo" + 167 "g8gJK1V_O_v84_Bw4_1_" + 168 "72jQ3_0J3V_S5iYn4h5X" + 169 "R_2n___51J nN_ \t\tm " + 170 "aa_XO4_5\t \t\t \t\tg6b" + 171 "p_KI_1_YWc_K8c2b___A" + 172 "e_Y1m__4Y_R_avy6t08x" + 173 "b5Cp9_7uS_yLa\t\t\t d " + 174 "EKe1Q83vS___ a \t\t " + 175 "\tmP_Qq_3sJ_1_84X_545" + 176 "iW_3K4p8J8_v9_LT3_6_" + 177 "0l_3D4VT3xq6N_3K___U" + 178 "_xX2\"\" \t \t_fL Ogl5" + 179 "_09i_9__3O7C__QMAG2U" + 180 "35IO8RRU6aJ9_6_57_6_" + 181 "b05BMoX5I__4833_____" + 182 "yfD_2_OPs__sqzM_pqQi" + 183 "_\t\t \tN__GuY4_Trath_0" + 184 "yy___cAK_a__0J0q5 L_" + 185 "p63Fzdva_Lb_29V7_R__" + 186 "Go_H2_8m_4__FJM5B_Y5" + 187 "Slw_ghp_55l_X2_Pnt6Y" + 188 "_Wd_hM7jRZ_\t\t \tm \t" + 189 " \t\ta md rK \x00 7_\"sr " + 190 "- sg o -0x804dBDe8b" + 191 "a \t \t\tN_W6J3PBS_W__C" + 192 "yJu__k6F_jY0INI_LC27" + 193 "7x14b_1b___Y8f_K_3y_" + 194 "0055yaP_LKu_72g_T_32" + 195 "iBk1Zm_o 9i1P44_S0_" + 196 "_4AXUpo2__H55tL_g78_" + 197 "8V_8l0yg6bp_KI_1_YWc" + 198 "_K8c2b \t \tmaa_XO4_5" + 199 "rg6bp_KI_1_YWc_K8c2b" + 200 " _C20w i_4 \t\t u_k d" + 201 " rKsg09099 \"\"2335779" + 202 "05047986112651e025 \t" + 203 " \t\tN_W6J3PBS_W__CyJu" + 204 "__k6F_jY0INI_LC277x1" + 205 "4b_1b___Y8f_K_3y_005" + 206 "5yaP_LKu_72g_T_32iBk" + 207 "1Zm_o 9i1P44_S0__4A" + 208 "XUpo2__H55tL_g78_8V_" + 209 "8l0y_9K9_C__6af__wj_" + 210 "UbSYy_ge29S_s_Qe259q" + 211 "_kGod \t\t\t\t :0xb1AF1F" + 212 "b71D2ACeaB3FEce2ssg " + 213 "o dr-0x804dBDe8ba \t " + 214 "\t\t$ Y5 _BzOc6S_Lk0K" + 215 "y43j1TzV__9367tbX56_" + 216 "6B3__q6_v8_4_0_t_2q_" + 217 "nJ2gV3j9_tkOrx_H__a}" + 218 "mT 0g6bp_KI_1_YWc_K8" + 219 "c2b\t_ a\t \t54KM8f9_63" + 220 "zJ2Q_c1_C_Zf4ICF4m0q" + 221 "_RVm_3Zh4vr7yI_H2 a" + 222 " m 0yq__TiqA_FQBv_SS" + 223 "_Hm_8T8__M8F2_53TTo_" + 224 "k_o2__u_W6Vr__524q9l" + 225 "9CQsC_kOU___g_94 \"" + 226 " ~a_j_16_6iUSu_96V1W" + 227 "5r01j____gn157__8_LO" + 228 "0y_08Jr6OR__WF8__JK_" + 229 "N_wx_k_CGB_SjJ9R74i_" + 230 "7_1t_6 m NULLNULLNUL" + 231 "L \t \t\t\t drK\t\x00 7_\"\" 5" + 232 "_5_y732S43__D_8U9FX2" + 233 "27_k\t\tg6bp_KI_1_YWc_" + 234 "K8c2b_J_wx8yw1CMw27j" + 235 "___f_a8uw_ Er9gB_L2 " + 236 "\t\t \t\t\tm aa_XO4_5 Y_" + 237 " I_T7762_zlMi_n8_FjH" + 238 "vy62p__M4S_8__r092af" + 239 "P_T_vhp6__SA_jVF13c5" + 240 "2__8J48K__S4YcjoY91X" + 241 "_iNf06 am aa_XO4_5\t" + 242 " d _ am_SYY4G__2h4QL" + 243 "iUIDd \t\t \tXXp__KFjR" + 244 "V__JU3o\"\" d \t_Iks_ " + 245 "aa_XO4_5<g6bp_KI_1_Y" + 246 "Wc_K8c2b _BzOc6S_Lk0" + 247 "Ky43j1TzV__9367tbX56" + 248 "_6B3__q6_v8_4_0_t_2q" + 249 "_nJ2gV3j9_tkOrx_H__ " + 250 "a\t_Iks_ \\ ma 0_58_r1" + 251 "y8jib_FaV_C_e \t \td\"\"" + 252 " ^Dy_0 \t\t \t ;;;;;;;" + 253 ";;;;;;;;;;;", 254 `dns: bad HINFO Fields: "comment length insufficient for parsing" at line: 1:1951`, 255 }, 256 } 257 258 for _, tc := range tests { 259 t.Run(tc.name, func(t *testing.T) { 260 _, err := NewRR(tc.in) 261 if err == nil { 262 t.Errorf("Expecting error for crasher line %s", tc.in) 263 } 264 if tc.err != err.Error() { 265 t.Errorf("Expecting error %s, got %s", tc.err, err.Error()) 266 } 267 }) 268 } 269} 270