Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'perf-urgent-2025-03-22' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull x86 perf events fix from Ingo Molnar:
"Fix an information leak regression in the AMD IBS PMU code"

* tag 'perf-urgent-2025-03-22' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
perf/amd/ibs: Prevent leaking sensitive data to userspace

+78 -6
+78 -6
arch/x86/events/amd/ibs.c
··· 941 941 data_src->mem_lock = PERF_MEM_LOCK_LOCKED; 942 942 } 943 943 944 + /* Be careful. Works only for contiguous MSRs. */ 945 + #define ibs_fetch_msr_idx(msr) (msr - MSR_AMD64_IBSFETCHCTL) 944 946 #define ibs_op_msr_idx(msr) (msr - MSR_AMD64_IBSOPCTL) 945 947 946 948 static void perf_ibs_get_data_src(struct perf_ibs_data *ibs_data, ··· 1038 1036 return 1; 1039 1037 } 1040 1038 1039 + static bool perf_ibs_is_kernel_data_addr(struct perf_event *event, 1040 + struct perf_ibs_data *ibs_data) 1041 + { 1042 + u64 sample_type_mask = PERF_SAMPLE_ADDR | PERF_SAMPLE_RAW; 1043 + union ibs_op_data3 op_data3; 1044 + u64 dc_lin_addr; 1045 + 1046 + op_data3.val = ibs_data->regs[ibs_op_msr_idx(MSR_AMD64_IBSOPDATA3)]; 1047 + dc_lin_addr = ibs_data->regs[ibs_op_msr_idx(MSR_AMD64_IBSDCLINAD)]; 1048 + 1049 + return unlikely((event->attr.sample_type & sample_type_mask) && 1050 + op_data3.dc_lin_addr_valid && kernel_ip(dc_lin_addr)); 1051 + } 1052 + 1053 + static bool perf_ibs_is_kernel_br_target(struct perf_event *event, 1054 + struct perf_ibs_data *ibs_data, 1055 + int br_target_idx) 1056 + { 1057 + union ibs_op_data op_data; 1058 + u64 br_target; 1059 + 1060 + op_data.val = ibs_data->regs[ibs_op_msr_idx(MSR_AMD64_IBSOPDATA)]; 1061 + br_target = ibs_data->regs[br_target_idx]; 1062 + 1063 + return unlikely((event->attr.sample_type & PERF_SAMPLE_RAW) && 1064 + op_data.op_brn_ret && kernel_ip(br_target)); 1065 + } 1066 + 1067 + static bool perf_ibs_swfilt_discard(struct perf_ibs *perf_ibs, struct perf_event *event, 1068 + struct pt_regs *regs, struct perf_ibs_data *ibs_data, 1069 + int br_target_idx) 1070 + { 1071 + if (perf_exclude_event(event, regs)) 1072 + return true; 1073 + 1074 + if (perf_ibs != &perf_ibs_op || !event->attr.exclude_kernel) 1075 + return false; 1076 + 1077 + if (perf_ibs_is_kernel_data_addr(event, ibs_data)) 1078 + return true; 1079 + 1080 + if (br_target_idx != -1 && 1081 + perf_ibs_is_kernel_br_target(event, ibs_data, br_target_idx)) 1082 + return true; 1083 + 1084 + return false; 1085 + } 1086 + 1087 + static void perf_ibs_phyaddr_clear(struct perf_ibs *perf_ibs, 1088 + struct perf_ibs_data *ibs_data) 1089 + { 1090 + if (perf_ibs == &perf_ibs_op) { 1091 + ibs_data->regs[ibs_op_msr_idx(MSR_AMD64_IBSOPDATA3)] &= ~(1ULL << 18); 1092 + ibs_data->regs[ibs_op_msr_idx(MSR_AMD64_IBSDCPHYSAD)] = 0; 1093 + return; 1094 + } 1095 + 1096 + ibs_data->regs[ibs_fetch_msr_idx(MSR_AMD64_IBSFETCHCTL)] &= ~(1ULL << 52); 1097 + ibs_data->regs[ibs_fetch_msr_idx(MSR_AMD64_IBSFETCHPHYSAD)] = 0; 1098 + } 1099 + 1041 1100 static int perf_ibs_handle_irq(struct perf_ibs *perf_ibs, struct pt_regs *iregs) 1042 1101 { 1043 1102 struct cpu_perf_ibs *pcpu = this_cpu_ptr(perf_ibs->pcpu); ··· 1111 1048 int offset, size, check_rip, offset_max, throttle = 0; 1112 1049 unsigned int msr; 1113 1050 u64 *buf, *config, period, new_config = 0; 1051 + int br_target_idx = -1; 1114 1052 1115 1053 if (!test_bit(IBS_STARTED, pcpu->state)) { 1116 1054 fail: ··· 1166 1102 if (perf_ibs == &perf_ibs_op) { 1167 1103 if (ibs_caps & IBS_CAPS_BRNTRGT) { 1168 1104 rdmsrl(MSR_AMD64_IBSBRTARGET, *buf++); 1105 + br_target_idx = size; 1169 1106 size++; 1170 1107 } 1171 1108 if (ibs_caps & IBS_CAPS_OPDATA4) { ··· 1193 1128 regs.flags |= PERF_EFLAGS_EXACT; 1194 1129 } 1195 1130 1196 - if (perf_ibs == &perf_ibs_op) 1197 - perf_ibs_parse_ld_st_data(event->attr.sample_type, &ibs_data, &data); 1198 - 1199 1131 if ((event->attr.config2 & IBS_SW_FILTER_MASK) && 1200 - (perf_exclude_event(event, &regs) || 1201 - ((data.sample_flags & PERF_SAMPLE_ADDR) && 1202 - event->attr.exclude_kernel && kernel_ip(data.addr)))) { 1132 + perf_ibs_swfilt_discard(perf_ibs, event, &regs, &ibs_data, br_target_idx)) { 1203 1133 throttle = perf_event_account_interrupt(event); 1204 1134 goto out; 1135 + } 1136 + /* 1137 + * Prevent leaking physical addresses to unprivileged users. Skip 1138 + * PERF_SAMPLE_PHYS_ADDR check since generic code prevents it for 1139 + * unprivileged users. 1140 + */ 1141 + if ((event->attr.sample_type & PERF_SAMPLE_RAW) && 1142 + perf_allow_kernel(&event->attr)) { 1143 + perf_ibs_phyaddr_clear(perf_ibs, &ibs_data); 1205 1144 } 1206 1145 1207 1146 if (event->attr.sample_type & PERF_SAMPLE_RAW) { ··· 1217 1148 }; 1218 1149 perf_sample_save_raw_data(&data, event, &raw); 1219 1150 } 1151 + 1152 + if (perf_ibs == &perf_ibs_op) 1153 + perf_ibs_parse_ld_st_data(event->attr.sample_type, &ibs_data, &data); 1220 1154 1221 1155 /* 1222 1156 * rip recorded by IbsOpRip will not be consistent with rsp and rbp