Paging prevents user-mode accesses to supervisor-mode addresses; in addition, there are features that can prevent supervisor-mode accesses to user-mode addresses. (These features are supervisor-mode execution prevention — SMEP — and supervisor-mode access prevention — SMAP.)

With these mode-based protections, paging can prevent malicious software from directly reading or writing memory inappropriately. To enforce these protections, the processor must traverse the hierarchy of paging structures in memory. Unprivileged software can use timing information resulting from this traversal to determine details about the paging structures, and these details may be used to determine the layout of supervisor memory.

LASS is an independent mechanism that enforces the same mode-based protections as paging but without traversing the paging structures. Because the protections enforced by LASS are applied before paging, “probes” by malicious software will provide no paging-based timing information.

LASS is based on a linear-address organization established by many operating systems: all linear addresses whose most significant bit is 0 (“low” or “positive” addresses) are user-mode addresses, while all linear addresses whose most significant bit is 1 (“high” or “negative” addresses) are supervisor-mode addresses. An operating system should enable LASS only if it uses this organization of linear addresses.

LASS violation

What's the difference between LASS violation and page fault?

Like paging, LASS violations typically result in faults. Instead of page faults (#PF), an access causing a LASS violation results in the same fault that would occur if the access used an address that was not canonical relative to the current paging mode.

Will LASS violation always cause a fault?

No. Some accesses do not cause faults when they would violate the mode-based protections established by paging. These include

  • prefetches (e.g., those resulting from execution of one of the PREFETCHh instructions),
  • executions of the CLDEMOTE instruction, and
  • accesses resulting from the speculative fetch or execution of an instruction. Such an access may cause a LASS violation; if it does, the access is not performed but no fault occurs. (When such an access would violate the mode-based protections of paging, the access is not performed but no page fault occurs.)

Model-based protections

Every access to a linear address is either a supervisor-mode access or a user-mode access.

A linear address’s access rights include an indication of whether address is a supervisor-mode address or a user-mode address.

Canonicality violations

LASS won't influent the interface of original paging mechanism

Instead of page faults (#PF), an access causing a LASS violation results in the same fault that would occur if the access used an address that was not canonical relative to the current paging mode. In most cases, this is a general protection exception (#GP); for stack accesses (those due to stack-oriented instructions, as well as accesses that implicitly or explicitly use the SS segment register), it would be a stack fault (#SS).

LASS QA

In 64-bit mode, LASS violations have priority just below that of canonicality violations, why?

LASS Misc

Test CPUID:

cpuid -l 0x7 -s 1 -1 -r # bit 6 of EAX

Instruction Fetches

A user-mode instruction fetch causes a LASS violation if it would fetch an instruction using a linear address of which bit 63 is 1. (我认为这种对应的是用户程序手动设置 RIP 为 upper half 去执行 kernel code 的情况)。

A supervisor-mode instruction fetch causes a LASS violation if it would accesses a linear address of which bit 63 is 0. (对应 kernel 设置 RIP 为 lower half 拖执行 user code 的情况)。

The 1st difference between LASS and Paging: Paging blocks supervisor-mode instruction fetches from user-mode linear addresses only if CR4.SMEP=1. Such instructions fetches cause LASS violations regardless of the setting of CR4.SMEP.

If a processor enumerates CPUID.(EAX=07H.ECX=1):EAX.LASS[bit 6] as 1, software can set CR4.LASS[bit 27]. Setting CR4.LASS to 1 enables LASS in IA-32e mode (when IA32_EFER.LMA = 1). LASS is not used in legacy mode, even if CR4.LASS = 1.

Violations of these protections are called LASS violations.

An access causing a LASS violation results in the same fault that would occur if the access used an address that was not canonical relative to the current paging mode.

For a linear address with only 32 bits (or 16 bits), the processor treats bit 63 as if it were 0.

The 2nd difference between LASS and Paging: An instruction that loads RIP (a branch instruction) causes a general-protection exception (#GP) as a fault if it would load RIP with a value that is not canonical relative to the current paging mode; RIP is not updated, and the fault is reported on the branch instruction. In contrast, branch instructions do not check the target RIP for LASS violations, and thus LASS does not prevent branch instructions from completing. Fetch of the next instruction (at the target RIP) may cause a LASS violation and a #GP. In that case, the fault is reported on the branch target, not the branch instruction.

Data Access

A linear-address access is a data access if it is not for the fetch of an instruction. Such an access

  • is a user-mode access if CPL = 3 and the access is not one that implicitly accesses a system data structure (e.g., the global descriptor table);
  • it is a supervisor-mode access if CPL < 3 or if it implicitly accesses a system data structure.

User-mode data access

A user-mode data access causes a LASS violation if it would access a linear address of which bit 63 is 1.

Supervisor-mode data access

A supervisor-mode data access may cause a LASS violation if it would access a linear address of which bit 63 is 0. (Causes a LASS violation only if CR4.SMAP = 1 && (RFLAGS.AC = 0 || the access implicitly accesses a system data structure).

So that means, if you want to temporally disable the "supervisor-mode data access to lower half" LASS , you can simply set CR4.SMAP to 1.