Modern operating systems (OSes) have unfettered access to application data, assuming that applications trust them. This assumption, however, is problematic under many scenarios where either the OS provider is not trustworthy or the OS can be compromised due to its large attack surface. Our investigation began with the hypothesis that unfettered access to memory is not fundamentally necessary for the OS to perform its own job, including managing the memory. The result is a system called MProtect that leverages a small piece of software running at a higher privilege level than the OS. MProtect protects the entire user space of a process, requires only a small modification to the OS, and supports major architectures such as ARM, x86 and RISC-V. Unlike prior works that resorted to nested virtualization, which is often undesirable in mobile and embedded systems, MProtect mediates how the OS accesses the memory and handles exceptions. We report an implementation of MProtect called MGuard with ARMv8/Linux and evaluate its performance with both macro and microbenchmarks. We show MGuard has a runtime TCB 2~3 times smaller than related systems and enjoys competitive performance while supporting legitimate OS access to the user space.