hc
2024-01-03 2f7c68cb55ecb7331f2381deb497c27155f32faf
kernel/tools/testing/selftests/bpf/verifier/search_pruning.c
....@@ -154,3 +154,39 @@
154154 .result_unpriv = ACCEPT,
155155 .insn_processed = 15,
156156 },
157
+/* The test performs a conditional 64-bit write to a stack location
158
+ * fp[-8], this is followed by an unconditional 8-bit write to fp[-8],
159
+ * then data is read from fp[-8]. This sequence is unsafe.
160
+ *
161
+ * The test would be mistakenly marked as safe w/o dst register parent
162
+ * preservation in verifier.c:copy_register_state() function.
163
+ *
164
+ * Note the usage of BPF_F_TEST_STATE_FREQ to force creation of the
165
+ * checkpoint state after conditional 64-bit assignment.
166
+ */
167
+{
168
+ "write tracking and register parent chain bug",
169
+ .insns = {
170
+ /* r6 = ktime_get_ns() */
171
+ BPF_EMIT_CALL(BPF_FUNC_ktime_get_ns),
172
+ BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
173
+ /* r0 = ktime_get_ns() */
174
+ BPF_EMIT_CALL(BPF_FUNC_ktime_get_ns),
175
+ /* if r0 > r6 goto +1 */
176
+ BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_6, 1),
177
+ /* *(u64 *)(r10 - 8) = 0xdeadbeef */
178
+ BPF_ST_MEM(BPF_DW, BPF_REG_FP, -8, 0xdeadbeef),
179
+ /* r1 = 42 */
180
+ BPF_MOV64_IMM(BPF_REG_1, 42),
181
+ /* *(u8 *)(r10 - 8) = r1 */
182
+ BPF_STX_MEM(BPF_B, BPF_REG_FP, BPF_REG_1, -8),
183
+ /* r2 = *(u64 *)(r10 - 8) */
184
+ BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_FP, -8),
185
+ /* exit(0) */
186
+ BPF_MOV64_IMM(BPF_REG_0, 0),
187
+ BPF_EXIT_INSN(),
188
+ },
189
+ .flags = BPF_F_TEST_STATE_FREQ,
190
+ .errstr = "invalid read from stack off -8+1 size 8",
191
+ .result = REJECT,
192
+},