Skip to content

Commit a9f0f75

Browse files
committed
components: widen sysfs reserved-region leaks to bands via the size sibling
sysfs_qcom_rmtfs_mem, sysfs_cbmem_address, and sysfs_cxl_region read only a base address and emitted a pos=interior sample (no HAS_LO/HI, so it drove no bounds rule), even though each exposes a sibling size attribute. Read that sibling and emit the whole reserved band as a range so the engine excludes it (phys_reservation_exclude): qcom/cbmem -> REGION_RESERVED_MEM, cxl -> REGION_PMEM. Conservative by construction: the size is parsed strictly as 0x%llx and a range is emitted only when end > addr (rules out size 0/1 and any wrap) and the extent is representable in unsigned long (32-bit/PAE safe). A missing, unparseable, zero, or oversized size falls back to the prior base-only sample — a wrong size-format assumption can never widen the band. These are intra-DRAM forbidden regions (lo >= the RAM base), so the carve is phys_floor-safe. test_sysfs_parsers asserts the bands (and the qcom no-size sample fallback).
1 parent f6acd5d commit a9f0f75

4 files changed

Lines changed: 91 additions & 18 deletions

File tree

src/components/sysfs_cbmem_address.c

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -128,9 +128,29 @@ int main(void) {
128128
* coreboot subsystem allocated it. */
129129
snprintf(label, sizeof(label), "%.32s", ent->d_name);
130130

131-
fprintf(stderr, "[+] sysfs_cbmem %s: phys = 0x%016llx\n", label, addr);
132-
kasld_result_sample(KASLD_TYPE_PHYS, REGION_RESERVED_MEM,
133-
(unsigned long)addr, label, CONF_PARSED);
131+
/* The sibling size attribute gives the region extent: emit the whole
132+
* reserved band so the engine can exclude it (phys_reservation_exclude),
133+
* not just a single interior point. Parse it strictly as hex; if the
134+
* attribute is absent, unparseable, zero, or the extent is not
135+
* representable in the word, fall back to a base-only sample (a
136+
* wrong-format size can never widen the band). */
137+
unsigned long long size = 0;
138+
snprintf(path, sizeof(path), "%s/%s/size", base, ent->d_name);
139+
if (read_file_line(path, buf, sizeof(buf)) == 0)
140+
(void)sscanf(buf, "0x%llx", &size);
141+
unsigned long long end = addr + size - 1; /* inclusive last byte */
142+
143+
if (size && end > addr && (unsigned long)end == end) {
144+
fprintf(stderr, "[+] sysfs_cbmem %s: phys = 0x%016llx - 0x%016llx\n",
145+
label, addr, end);
146+
kasld_result_range(KASLD_TYPE_PHYS, REGION_RESERVED_MEM,
147+
(unsigned long)addr, (unsigned long)end, label,
148+
CONF_PARSED);
149+
} else {
150+
fprintf(stderr, "[+] sysfs_cbmem %s: phys = 0x%016llx\n", label, addr);
151+
kasld_result_sample(KASLD_TYPE_PHYS, REGION_RESERVED_MEM,
152+
(unsigned long)addr, label, CONF_PARSED);
153+
}
134154
count++;
135155

136156
#ifdef phys_to_directmap_virt

src/components/sysfs_cxl_region.c

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -126,9 +126,29 @@ int main(void) {
126126
* The region directory name (e.g. "region0") identifies which one. */
127127
snprintf(label, sizeof(label), "%.32s", ent->d_name);
128128

129-
fprintf(stderr, "[+] sysfs_cxl_region %s: phys = 0x%016llx\n", label, addr);
130-
kasld_result_sample(KASLD_TYPE_PHYS, REGION_PMEM, (unsigned long)addr,
131-
label, CONF_PARSED);
129+
/* The sibling size attribute (same %#llx "0x<hex>" format) gives the region
130+
* extent: emit the whole band so the engine can exclude it
131+
* (phys_reservation_exclude), not just a single interior point. Parse it
132+
* strictly as hex; if the attribute is absent, unparseable, zero, or the
133+
* extent is not representable in the word, fall back to a base-only sample
134+
* (a wrong-format size can never widen the band). */
135+
unsigned long long size = 0;
136+
snprintf(path, sizeof(path), "%s/%s/size", base, ent->d_name);
137+
if (read_file_line(path, buf, sizeof(buf)) == 0)
138+
(void)sscanf(buf, "0x%llx", &size);
139+
unsigned long long end = addr + size - 1; /* inclusive last byte */
140+
141+
if (size && end > addr && (unsigned long)end == end) {
142+
fprintf(stderr, "[+] sysfs_cxl_region %s: phys = 0x%016llx - 0x%016llx\n",
143+
label, addr, end);
144+
kasld_result_range(KASLD_TYPE_PHYS, REGION_PMEM, (unsigned long)addr,
145+
(unsigned long)end, label, CONF_PARSED);
146+
} else {
147+
fprintf(stderr, "[+] sysfs_cxl_region %s: phys = 0x%016llx\n", label,
148+
addr);
149+
kasld_result_sample(KASLD_TYPE_PHYS, REGION_PMEM, (unsigned long)addr,
150+
label, CONF_PARSED);
151+
}
132152
count++;
133153

134154
#ifdef phys_to_directmap_virt

src/components/sysfs_qcom_rmtfs_mem.c

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -130,10 +130,31 @@ int main(void) {
130130
* the device-tree node name (e.g. "rmtfs@9c800000") identifies which. */
131131
snprintf(label, sizeof(label), "%.32s", ent->d_name);
132132

133-
fprintf(stderr, "[+] sysfs_qcom_rmtfs_mem %s: phys = 0x%016llx\n", label,
134-
addr);
135-
kasld_result_sample(KASLD_TYPE_PHYS, REGION_RESERVED_MEM,
136-
(unsigned long)addr, label, CONF_PARSED);
133+
/* The sibling size attribute (same %pa "0x<hex>" format) gives the region
134+
* extent: emit the whole reserved band so the engine can exclude it
135+
* (phys_reservation_exclude), not just a single interior point. Parse it
136+
* strictly as hex; if the attribute is absent, unparseable, zero, or the
137+
* extent is not representable in the word, fall back to a base-only sample
138+
* (a wrong-format size can never widen the band). */
139+
unsigned long long size = 0;
140+
snprintf(path, sizeof(path), "%s/%s/size", base, ent->d_name);
141+
if (read_file_line(path, buf, sizeof(buf)) == 0)
142+
(void)sscanf(buf, "0x%llx", &size);
143+
unsigned long long end = addr + size - 1; /* inclusive last byte */
144+
145+
if (size && end > addr && (unsigned long)end == end) {
146+
fprintf(stderr,
147+
"[+] sysfs_qcom_rmtfs_mem %s: phys = 0x%016llx - 0x%016llx\n",
148+
label, addr, end);
149+
kasld_result_range(KASLD_TYPE_PHYS, REGION_RESERVED_MEM,
150+
(unsigned long)addr, (unsigned long)end, label,
151+
CONF_PARSED);
152+
} else {
153+
fprintf(stderr, "[+] sysfs_qcom_rmtfs_mem %s: phys = 0x%016llx\n", label,
154+
addr);
155+
kasld_result_sample(KASLD_TYPE_PHYS, REGION_RESERVED_MEM,
156+
(unsigned long)addr, label, CONF_PARSED);
157+
}
137158
count++;
138159

139160
#ifdef phys_to_directmap_virt

tests/test_sysfs_parsers.c

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -249,31 +249,43 @@ static void test_acpi_mrrm_base(void) {
249249
assert(strstr(cap, "sample=0x100000000") != NULL);
250250
}
251251

252-
/* --- coreboot CBMEM: address is "0x%llx" text --------------------------- */
252+
/* --- coreboot CBMEM: address + sibling size ("0x%llx") -> reserved range. */
253253
static void test_cbmem_address(void) {
254254
stage_text("/sys/bus/coreboot/devices/cbmem-00000abc/address",
255255
"0x100000000\n");
256+
stage_text("/sys/bus/coreboot/devices/cbmem-00000abc/size", "0x10000\n");
256257
run_capture(cbmem_main);
257-
assert(strstr(cap, "P reserved_mem:cbmem-00000abc") != NULL);
258-
assert(strstr(cap, "sample=0x100000000") != NULL);
258+
assert(strstr(cap, "reserved_mem:cbmem-00000abc pos=base conf=parsed "
259+
"lo=0x100000000 hi=0x10000ffff") != NULL);
259260
}
260261

261-
/* --- CXL region: resource is "%#llx" text; -1 means unallocated ---------- */
262+
/* --- CXL region: resource + sibling size ("%#llx") -> pmem range; -1 means
263+
* unallocated and is skipped. ------------------------------------------------
264+
*/
262265
static void test_cxl_region(void) {
263266
stage_text("/sys/bus/cxl/devices/region0/resource", "0x100000000\n");
267+
stage_text("/sys/bus/cxl/devices/region0/size", "0x40000000\n");
264268
/* An unallocated region reports 0xff..ff and must be skipped. */
265269
stage_text("/sys/bus/cxl/devices/region1/resource", "0xffffffffffffffff\n");
266270
run_capture(cxl_main);
267-
assert(strstr(cap, "sample=0x100000000") != NULL);
271+
assert(strstr(cap, "pmem:region0 pos=base conf=parsed lo=0x100000000 "
272+
"hi=0x13fffffff") != NULL);
268273
assert(strstr(cap, "ffffffffffffffff") == NULL);
269274
}
270275

271-
/* --- Qualcomm RMTFS: phys_addr is "%pa" text ("0x%llx") ------------------ */
276+
/* --- Qualcomm RMTFS: phys_addr + sibling size ("%pa" = "0x%llx") -> reserved
277+
* range; a region with no size attribute falls back to a base-only sample. --
278+
*/
272279
static void test_qcom_rmtfs(void) {
273280
stage_text("/sys/class/rmtfs/qcom_rmtfs_mem0/phys_addr", "0x100000000\n");
281+
stage_text("/sys/class/rmtfs/qcom_rmtfs_mem0/size", "0x200000\n");
282+
stage_text("/sys/class/rmtfs/qcom_rmtfs_mem1/phys_addr", "0x200000000\n");
274283
run_capture(qcom_main);
275-
assert(strstr(cap, "P reserved_mem:qcom_rmtfs_mem0") != NULL);
276-
assert(strstr(cap, "sample=0x100000000") != NULL);
284+
assert(strstr(cap, "reserved_mem:qcom_rmtfs_mem0 pos=base conf=parsed "
285+
"lo=0x100000000 hi=0x1001fffff") != NULL);
286+
/* no size sibling -> base-only sample (degrades to the prior behavior) */
287+
assert(strstr(cap, "reserved_mem:qcom_rmtfs_mem1 pos=interior conf=parsed "
288+
"sample=0x200000000") != NULL);
277289
}
278290

279291
/* --- IOMMU reserved_regions: "0x%016llx 0x%016llx <type>" lines.

0 commit comments

Comments
 (0)