Skip to content

Commit 3fa1523

Browse files
committed
rules: floor x86_64 RANDOMIZE_MEMORY budget ceilings to the PUD grain
The page_offset and vmalloc upper bounds from the shared-entropy budget were vaddr_start + remain/3, left un-aligned. Both bases are PUD-granular, so the ragged remainder rendered as a garbage-looking ceiling (e.g. 0xffffa4aaaaaaaaaa) whenever no direct-map leak tightened the window. Floor both to the PUD boundary: sound (the true PUD-aligned base still satisfies the bound), strictly tighter, and clean. Update the pinning test.
1 parent 9b0dc54 commit 3fa1523

2 files changed

Lines changed: 14 additions & 5 deletions

File tree

src/rules/x86_64_randomize_memory_budget.c

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -170,9 +170,13 @@ int rule_x86_64_randomize_memory_budget(const struct evidence_set *ev,
170170
unsigned long remain_lo = span - dm_min - vmalloc_sz;
171171
const enum kasld_confidence cap = kasld_conf_min(CONF_INFERRED, pfn_conf);
172172

173-
/* page_offset upper bound: base_0 = vaddr_start + e_0, e_0 <= remain/3. */
173+
/* page_offset upper bound: base_0 = vaddr_start + e_0, e_0 <= remain/3.
174+
* page_offset_base is PUD-granular, so floor the ceiling to the PUD boundary:
175+
* the true base is a PUD multiple <= this value, so flooring stays sound
176+
* while tightening it and dropping the ragged remain/3 remainder (cf. the
177+
* alignment floor in phys_bits_ceiling). */
174178
if (n < out_max) {
175-
unsigned long upper = lv.vaddr_start + remain_lo / 3;
179+
unsigned long upper = (lv.vaddr_start + remain_lo / 3) & ~(pud - 1);
176180
struct constraint *c = &out[n++];
177181
memset(c, 0, sizeof(*c));
178182
c->q = Q_PAGE_OFFSET;
@@ -203,7 +207,9 @@ int rule_x86_64_randomize_memory_budget(const struct evidence_set *ev,
203207
* (dm_max + 2*(span - vmalloc_size)) / 3 (increasing in dm => dm_max). */
204208
if (n < out_max) {
205209
unsigned long num = dm_max + 2ul * (span - vmalloc_sz);
206-
unsigned long upper = lv.vaddr_start + pud + num / 3;
210+
unsigned long upper = (lv.vaddr_start + pud + num / 3) & ~(pud - 1);
211+
/* vmalloc_base is PUD-granular too; floor to align + tighten (see above).
212+
*/
207213
/* Only emit when it actually sits below the region-group ceiling. */
208214
if (upper < lv.vaddr_end && upper > lv.vaddr_start + dm_min) {
209215
struct constraint *c = &out[n++];

tests/test_engine.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4433,11 +4433,14 @@ static void test_x86_64_randomize_memory_budget(void) {
44334433
* la57's canonical half boundary (this rule does not raise the directmap
44344434
* floor). */
44354435
assert(e.est[Q_PAGE_OFFSET].lo == 0xffff800000000000ul); /* from la57 */
4436-
assert(e.est[Q_PAGE_OFFSET].hi == vs + remain_lo / 3);
4436+
/* Ceilings are floored to the PUD grain (page_offset / vmalloc are
4437+
* PUD-granular), dropping the ragged remain/3 remainder. */
4438+
assert(e.est[Q_PAGE_OFFSET].hi == ((vs + remain_lo / 3) & ~(pud - 1)));
44374439
/* vmalloc: floor + the leak-free budget ceiling (previously unbounded above
44384440
* without a vmemmap witness). */
44394441
assert(e.est[Q_VMALLOC_BASE].lo == vs + dm_min);
4440-
unsigned long va_hi = vs + pud + (dm_max + 2ul * (span - vmalloc_sz)) / 3;
4442+
unsigned long va_hi =
4443+
(vs + pud + (dm_max + 2ul * (span - vmalloc_sz)) / 3) & ~(pud - 1);
44414444
assert(e.est[Q_VMALLOC_BASE].hi == va_hi);
44424445
/* vmemmap: tighter floor. */
44434446
assert(e.est[Q_VMEMMAP_BASE].lo == vs + dm_min + vmalloc_sz);

0 commit comments

Comments
 (0)