Exercise 2: The Quota Doesn't Apply to create_process() — Possible Solution ==================================================================== THE TEST ------------------------------ mem = PhysicalMemoryFramed(num_frames=20) kernel = KernelWithQuota(mem) # MAX_PAGES_PER_PROCESS = 3 proc = kernel.create_process(num_pages=5) # more than the quota, created directly RESULT ------------------------------ a process created directly with 5 pages (quota is 3): owns 5 real pages proc is not None, and len(proc.owned_frames) == 5 -- the process was created successfully with MORE pages than the quota allows, and nothing rejected or trimmed the request. WHY THE QUOTA HAS NO EFFECT HERE ------------------------------ create_process(), inherited unchanged from the plain Kernel class, allocates pages with a direct loop calling self.mem.alloc_frame() for each one: for vpn in range(num_pages): pfn = self.mem.alloc_frame() ... This code never calls self.sys_allocate_page() -- the ONLY place MAX_PAGES_PER_PROCESS is ever checked. KernelWithQuota adds sys_allocate_page() as an entirely separate method; it doesn't override create_process() at all, and create_process() has no idea sys_allocate_page() (or the quota check inside it) even exists. Two genuinely different code paths both grant pages to a process, and only one of them was ever taught about the quota. WHY THIS IS A REAL, HONEST GAP -- NOT A FIX APPLIED HERE ------------------------------ This is deliberately left unfixed and reported as a finding, not patched, because it illustrates something genuinely important about enforcing policy in a real kernel: a rule like "no process gets more than N pages" has to be enforced EVERYWHERE memory is granted, not just on the one code path someone happened to add a check to. Chapter 4's own memory-leak bug (forgetting to free frames on termination) and this exercise's own quota gap are the same shape of problem: a real invariant the system is supposed to maintain, quietly undermined by a code path nobody remembered to update consistently. A genuinely fixed version would need create_process() itself to either call through sys_allocate_page() for each page, or duplicate the same check -- and either choice is a real design decision, not just a one-line patch. WHY THIS WORKS AS AN ANSWER ------------------------------ Deliberately testing the CREATION path rather than the syscall path the chapter's own Finding 3 tested exposes a gap that a test of only sys_allocate_page() itself would never have found -- confirming policy enforcement is a property of a SPECIFIC code path here, not a property of the kernel as a whole, which is an important and honest distinction to notice before assuming a real system is actually safe.