| 1090 | } |
| 1091 | |
| 1092 | static const char * |
| 1093 | eval_jcc(struct bpf_verifier *bvf, const struct ebpf_insn *ins) |
| 1094 | { |
| 1095 | uint32_t op; |
| 1096 | const char *err; |
| 1097 | struct bpf_eval_state *fst, *tst; |
| 1098 | struct bpf_reg_val *frd, *frs, *trd, *trs; |
| 1099 | struct bpf_reg_val rvf, rvt; |
| 1100 | |
| 1101 | tst = bvf->evst; |
| 1102 | fst = bvf->evin->evst.cur; |
| 1103 | |
| 1104 | frd = fst->rv + ins->dst_reg; |
| 1105 | trd = tst->rv + ins->dst_reg; |
| 1106 | |
| 1107 | if (BPF_SRC(ins->code) == BPF_X) { |
| 1108 | frs = fst->rv + ins->src_reg; |
| 1109 | trs = tst->rv + ins->src_reg; |
| 1110 | } else { |
| 1111 | frs = &rvf; |
| 1112 | trs = &rvt; |
| 1113 | eval_fill_imm(frs, UINT64_MAX, ins->imm); |
| 1114 | eval_fill_imm(trs, UINT64_MAX, ins->imm); |
| 1115 | } |
| 1116 | |
| 1117 | err = eval_defined(trd, trs); |
| 1118 | if (err != NULL) |
| 1119 | return err; |
| 1120 | |
| 1121 | op = BPF_OP(ins->code); |
| 1122 | |
| 1123 | if (op == BPF_JEQ) |
| 1124 | eval_jeq_jne(trd, trs); |
| 1125 | else if (op == EBPF_JNE) |
| 1126 | eval_jeq_jne(frd, frs); |
| 1127 | else if (op == BPF_JGT) |
| 1128 | eval_jgt_jle(trd, trs, frd, frs); |
| 1129 | else if (op == EBPF_JLE) |
| 1130 | eval_jgt_jle(frd, frs, trd, trs); |
| 1131 | else if (op == EBPF_JLT) |
| 1132 | eval_jlt_jge(trd, trs, frd, frs); |
| 1133 | else if (op == BPF_JGE) |
| 1134 | eval_jlt_jge(frd, frs, trd, trs); |
| 1135 | else if (op == EBPF_JSGT) |
| 1136 | eval_jsgt_jsle(trd, trs, frd, frs); |
| 1137 | else if (op == EBPF_JSLE) |
| 1138 | eval_jsgt_jsle(frd, frs, trd, trs); |
| 1139 | else if (op == EBPF_JSLT) |
| 1140 | eval_jslt_jsge(trd, trs, frd, frs); |
| 1141 | else if (op == EBPF_JSGE) |
| 1142 | eval_jslt_jsge(frd, frs, trd, trs); |
| 1143 | |
| 1144 | return NULL; |
| 1145 | } |
| 1146 | |
| 1147 | /* |
| 1148 | * validate parameters for each instruction type. |
nothing calls this directly
no test coverage detected