26 Apr, 2012

1 commit

  • - 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: Serge Hallyn
    Signed-off-by: Eric W. Biederman

    Eric W. Biederman
     

08 Apr, 2012

2 commits

  • Make it possible to easily switch between strong mandatory
    type checks and relaxed type checks so that the code can
    easily be tested with the type checks and then built
    with the strong type checks disabled so the resulting
    code can be used.

    Require strong mandatory type checks when enabling the user namespace.
    It is very simple to make a typo and use the wrong type allowing
    conversions to/from userspace values to be bypassed by accident,
    the strong type checks prevent this.

    Acked-by: Serge Hallyn
    Signed-off-by: Eric W. Biederman

    Eric W. Biederman
     
  • Start distinguishing between internal kernel uids and gids and
    values that userspace can use. This is done by introducing two
    new types: kuid_t and kgid_t. These types and their associated
    functions are infrastructure are declared in the new header
    uidgid.h.

    Ultimately there will be a different implementation of the mapping
    functions for use with user namespaces. But to keep it simple
    we introduce the mapping functions first to separate the meat
    from the mechanical code conversions.

    Export overflowuid and overflowgid so we can use from_kuid_munged
    and from_kgid_munged in modular code.

    Acked-by: Serge Hallyn
    Signed-off-by: Eric W. Biederman

    Eric W. Biederman