• Eric W. Biederman's avatar
    userns: Rework the user_namespace adding uid/gid mapping support · 22d917d8
    Eric W. Biederman authored
    - Convert the old uid mapping functions into compatibility wrappers
    - Add a uid/gid mapping layer from user space uid and gids to kernel
      internal uids and gids that is extent based for simplicty and speed.
      * Working with number space after mapping uids/gids into their kernel
        internal version adds only mapping complexity over what we have today,
        leaving the kernel code easy to understand and test.
    - Add proc files /proc/self/uid_map /proc/self/gid_map
      These files display the mapping and allow a mapping to be added
      if a mapping does not exist.
    - Allow entering the user namespace without a uid or gid mapping.
      Since we are starting with an existing user our uids and gids
      still have global mappings so are still valid and useful they just don't
      have local mappings.  The requirement for things to work are global uid
      and gid so it is odd but perfectly fine not to have a local uid
      and gid mapping.
      Not requiring global uid and gid mappings greatly simplifies
      the logic of setting up the uid and gid mappings by allowing
      the mappings to be set after the namespace is created which makes the
      slight weirdness worth it.
    - Make the mappings in the initial user namespace to the global
      uid/gid space explicit.  Today it is an identity mapping
      but in the future we may want to twist this for debugging, similar
      to what we do with jiffies.
    - Document the memory ordering requirements of setting the uid and
      gid mappings.  We only allow the mappings to be set once
      and there are no pointers involved so the requirments are
      trivial but a little atypical.
    
    Performance:
    
    In this scheme for the permission checks the performance is expected to
    stay the same as the actuall machine instructions should remain the same.
    
    The worst case I could think of is ls -l on a large directory where
    all of the stat results need to be translated with from kuids and
    kgids to uids and gids.  So I benchmarked that case on my laptop
    with a dual core hyperthread Intel i5-2520M cpu with 3M of cpu cache.
    
    My benchmark consisted of going to single user mode where nothing else
    was running. On an ext4 filesystem opening 1,000,000 files and looping
    through all of the files 1000 times and calling fstat on the
    individuals files.  This was to ensure I was benchmarking stat times
    where the inodes were in the kernels cache, but the inode values were
    not in the processors cache.  My results:
    
    v3.4-rc1:         ~= 156ns (unmodified v3.4-rc1 with user namespace support disabled)
    v3.4-rc1-userns-: ~= 155ns (v3.4-rc1 with my user namespace patches and user namespace support disabled)
    v3.4-rc1-userns+: ~= 164ns (v3.4-rc1 with my user namespace patches and user namespace support enabled)
    
    All of the configurations ran in roughly 120ns when I performed tests
    that ran in the cpu cache.
    
    So in summary the performance impact is:
    1ns improvement in the worst case with user namespace support compiled out.
    8ns aka 5% slowdown in the worst case with user namespace support compiled in.
    Acked-by: default avatarSerge Hallyn <serge.hallyn@canonical.com>
    Signed-off-by: default avatarEric W. Biederman <ebiederm@xmission.com>
    22d917d8
base.c 87.4 KB