lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <CAN6A1te-MnOHni2FyNySWOEOwzVkKN7kf-sTeOTXYvMF901ssw@mail.gmail.com>
Date:	Fri, 6 Feb 2015 15:10:26 +0200
From:	Iulia Manda <iulia.manda21@...il.com>
To:	gnomes@...rguk.ukuu.org.uk
Cc:	Josh Triplett <josh@...htriplett.org>,
	Paul McKenney <paulmck@...ux.vnet.ibm.com>,
	peterz@...radead.org, mhocko@...e.cz, akpm@...ux-foundation.org,
	linux-kernel@...r.kernel.org,
	Serge Hallyn <serge.hallyn@...onical.com>,
	dvhart@...ux.intel.com, tim.bird@...ymobile.com
Subject: Re: [PATCH v3] kernel: Conditionally support non-root users, groups
 and capabilities

On 6 February 2015 at 02:03, Iulia Manda <iulia.manda21@...il.com> wrote:
> There are a lot of embedded systems that run most or all of their functionality
> in init, running as root:root. For these systems, supporting multiple users is
> not necessary.
>
> This patch adds a new symbol, CONFIG_MULTIUSER, that makes support for non-root
> users, non-root groups, and capabilities optional. It is enabled under
> CONFIG_EXPERT menu.
>
> When this symbol is not defined, UID and GID are zero in any possible case
> and processes always have all capabilities.
>
> The following syscalls are compiled out: setuid, setregid, setgid,
> setreuid, setresuid, getresuid, setresgid, getresgid, setgroups, getgroups,
> setfsuid, setfsgid, capget, capset.
>
> Also, groups.c is compiled out completely.
>
> This change saves about 25 KB on a defconfig build.
>
> The kernel was booted in Qemu. All the common functionalities work. Adding
> users/groups is not possible, failing with -ENOSYS.
>
> Bloat-o-meter output:
> add/remove: 7/87 grow/shrink: 19/397 up/down: 1675/-26325 (-24650)
>

Forgot to add:

Signed-off-by: Iulia Manda <iulia.manda21@...il.com>
Reviewed-by: Josh Triplett <josh@...htriplett.org>

> ---
> Changes since v2:
>         - rename symbol;
>         - make SECURITY dependent on MULTIUSER
>

+ make symbols depend on MULTIUSER instead of selecting it.

>  arch/s390/Kconfig                     |    1 +
>  drivers/staging/lustre/lustre/Kconfig |    1 +
>  fs/nfsd/Kconfig                       |    1 +
>  include/linux/capability.h            |   29 +++++++++++++++++++++++++++
>  include/linux/cred.h                  |   23 ++++++++++++++++++----
>  include/linux/uidgid.h                |   12 +++++++++++
>  init/Kconfig                          |   19 +++++++++++++++++-
>  kernel/Makefile                       |    4 +++-
>  kernel/capability.c                   |   35 ++++++++++++++++++---------------
>  kernel/cred.c                         |    3 +++
>  kernel/groups.c                       |    3 ---
>  kernel/sys.c                          |    2 ++
>  kernel/sys_ni.c                       |   14 +++++++++++++
>  net/sunrpc/Kconfig                    |    2 ++
>  security/Kconfig                      |    1 +
>  15 files changed, 125 insertions(+), 25 deletions(-)
>
> diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
> index 68b68d7..71fb2d1 100644
> --- a/arch/s390/Kconfig
> +++ b/arch/s390/Kconfig
> @@ -324,6 +324,7 @@ config COMPAT
>         select COMPAT_BINFMT_ELF if BINFMT_ELF
>         select ARCH_WANT_OLD_COMPAT_IPC
>         select COMPAT_OLD_SIGACTION
> +       depends on MULTIUSER
>         help
>           Select this option if you want to enable your system kernel to
>           handle system-calls from ELF binaries for 31 bit ESA.  This option
> diff --git a/drivers/staging/lustre/lustre/Kconfig b/drivers/staging/lustre/lustre/Kconfig
> index 6725467..62c7bba 100644
> --- a/drivers/staging/lustre/lustre/Kconfig
> +++ b/drivers/staging/lustre/lustre/Kconfig
> @@ -10,6 +10,7 @@ config LUSTRE_FS
>         select CRYPTO_SHA1
>         select CRYPTO_SHA256
>         select CRYPTO_SHA512
> +       depends on MULTIUSER
>         help
>           This option enables Lustre file system client support. Choose Y
>           here if you want to access a Lustre file system cluster. To compile
> diff --git a/fs/nfsd/Kconfig b/fs/nfsd/Kconfig
> index 7339515..df0a5d9 100644
> --- a/fs/nfsd/Kconfig
> +++ b/fs/nfsd/Kconfig
> @@ -6,6 +6,7 @@ config NFSD
>         select SUNRPC
>         select EXPORTFS
>         select NFS_ACL_SUPPORT if NFSD_V2_ACL
> +       depends on MULTIUSER
>         help
>           Choose Y here if you want to allow other computers to access
>           files residing on this system using Sun's Network File System
> diff --git a/include/linux/capability.h b/include/linux/capability.h
> index aa93e5e..0c0ae0d 100644
> --- a/include/linux/capability.h
> +++ b/include/linux/capability.h
> @@ -205,6 +205,7 @@ static inline kernel_cap_t cap_raise_nfsd_set(const kernel_cap_t a,
>                            cap_intersect(permitted, __cap_nfsd_set));
>  }
>
> +#ifdef CONFIG_MULTIUSER
>  extern bool has_capability(struct task_struct *t, int cap);
>  extern bool has_ns_capability(struct task_struct *t,
>                               struct user_namespace *ns, int cap);
> @@ -213,6 +214,34 @@ extern bool has_ns_capability_noaudit(struct task_struct *t,
>                                       struct user_namespace *ns, int cap);
>  extern bool capable(int cap);
>  extern bool ns_capable(struct user_namespace *ns, int cap);
> +#else
> +static inline bool has_capability(struct task_struct *t, int cap)
> +{
> +        return true;
> +}
> +static inline bool has_ns_capability(struct task_struct *t,
> +                             struct user_namespace *ns, int cap)
> +{
> +        return true;
> +}
> +static inline bool has_capability_noaudit(struct task_struct *t, int cap)
> +{
> +        return true;
> +}
> +static inline bool has_ns_capability_noaudit(struct task_struct *t,
> +                                     struct user_namespace *ns, int cap)
> +{
> +        return true;
> +}
> +static inline bool capable(int cap)
> +{
> +       return true;
> +}
> +static inline bool ns_capable(struct user_namespace *ns, int cap)
> +{
> +       return true;
> +}
> +#endif /* CONFIG_MULTIUSER */
>  extern bool capable_wrt_inode_uidgid(const struct inode *inode, int cap);
>  extern bool file_ns_capable(const struct file *file, struct user_namespace *ns, int cap);
>
> diff --git a/include/linux/cred.h b/include/linux/cred.h
> index 2fb2ca2..8b6c083 100644
> --- a/include/linux/cred.h
> +++ b/include/linux/cred.h
> @@ -62,9 +62,27 @@ do {                                                 \
>                 groups_free(group_info);                \
>  } while (0)
>
> -extern struct group_info *groups_alloc(int);
>  extern struct group_info init_groups;
> +#ifdef CONFIG_MULTIUSER
> +extern struct group_info *groups_alloc(int);
>  extern void groups_free(struct group_info *);
> +
> +extern int in_group_p(kgid_t);
> +extern int in_egroup_p(kgid_t);
> +#else
> +static inline void groups_free(struct group_info *group_info)
> +{
> +}
> +
> +static inline int in_group_p(kgid_t grp)
> +{
> +        return 1;
> +}
> +static inline int in_egroup_p(kgid_t grp)
> +{
> +        return 1;
> +}
> +#endif
>  extern int set_current_groups(struct group_info *);
>  extern void set_groups(struct cred *, struct group_info *);
>  extern int groups_search(const struct group_info *, kgid_t);
> @@ -74,9 +92,6 @@ extern bool may_setgroups(void);
>  #define GROUP_AT(gi, i) \
>         ((gi)->blocks[(i) / NGROUPS_PER_BLOCK][(i) % NGROUPS_PER_BLOCK])
>
> -extern int in_group_p(kgid_t);
> -extern int in_egroup_p(kgid_t);
> -
>  /*
>   * The security context of a task
>   *
> diff --git a/include/linux/uidgid.h b/include/linux/uidgid.h
> index 2d1f9b6..0ee05da 100644
> --- a/include/linux/uidgid.h
> +++ b/include/linux/uidgid.h
> @@ -29,6 +29,7 @@ typedef struct {
>  #define KUIDT_INIT(value) (kuid_t){ value }
>  #define KGIDT_INIT(value) (kgid_t){ value }
>
> +#ifdef CONFIG_MULTIUSER
>  static inline uid_t __kuid_val(kuid_t uid)
>  {
>         return uid.val;
> @@ -38,6 +39,17 @@ static inline gid_t __kgid_val(kgid_t gid)
>  {
>         return gid.val;
>  }
> +#else
> +static inline uid_t __kuid_val(kuid_t uid)
> +{
> +       return 0;
> +}
> +
> +static inline gid_t __kgid_val(kgid_t gid)
> +{
> +       return 0;
> +}
> +#endif
>
>  #define GLOBAL_ROOT_UID KUIDT_INIT(0)
>  #define GLOBAL_ROOT_GID KGIDT_INIT(0)
> diff --git a/init/Kconfig b/init/Kconfig
> index 9afb971..b0332c2 100644
> --- a/init/Kconfig
> +++ b/init/Kconfig
> @@ -394,6 +394,7 @@ endchoice
>
>  config BSD_PROCESS_ACCT
>         bool "BSD Process Accounting"
> +       depends on MULTIUSER
>         help
>           If you say Y here, a user level program will be able to instruct the
>           kernel (via a special system call) to write process accounting
> @@ -420,6 +421,7 @@ config BSD_PROCESS_ACCT_V3
>  config TASKSTATS
>         bool "Export task/process statistics through netlink"
>         depends on NET
> +       depends on MULTIUSER
>         default n
>         help
>           Export selected statistics for tasks/processes through the
> @@ -1140,6 +1142,7 @@ config CHECKPOINT_RESTORE
>
>  menuconfig NAMESPACES
>         bool "Namespaces support" if EXPERT
> +       depends on MULTIUSER
>         default !EXPERT
>         help
>           Provides the way to make tasks work with different objects using
> @@ -1352,11 +1355,25 @@ menuconfig EXPERT
>
>  config UID16
>         bool "Enable 16-bit UID system calls" if EXPERT
> -       depends on HAVE_UID16
> +       depends on HAVE_UID16 && MULTIUSER
>         default y
>         help
>           This enables the legacy 16-bit UID syscall wrappers.
>
> +config MULTIUSER
> +       bool "Multiple users, groups and capabilities support" if EXPERT
> +       default y
> +       help
> +         This option enables support for non-root users, groups and
> +         capabilities.
> +
> +         If you say N here, all processes will run with UID 0, GID 0, and all
> +         possible capabilities.  Saying N here also compiles out support for
> +         system calls related to UIDs, GIDs, and capabilities, such as setuid,
> +         setgid, and capset.
> +
> +         If unsure, say Y here.
> +
>  config SGETMASK_SYSCALL
>         bool "sgetmask/ssetmask syscalls support" if EXPERT
>         def_bool PARISC || MN10300 || BLACKFIN || M68K || PPC || MIPS || X86 || SPARC || CRIS || MICROBLAZE || SUPERH
> diff --git a/kernel/Makefile b/kernel/Makefile
> index a59481a..554d34e 100644
> --- a/kernel/Makefile
> +++ b/kernel/Makefile
> @@ -9,7 +9,9 @@ obj-y     = fork.o exec_domain.o panic.o \
>             extable.o params.o \
>             kthread.o sys_ni.o nsproxy.o \
>             notifier.o ksysfs.o cred.o reboot.o \
> -           async.o range.o groups.o smpboot.o
> +           async.o range.o smpboot.o
> +
> +obj-$(CONFIG_MULTIUSER) += groups.o
>
>  ifdef CONFIG_FUNCTION_TRACER
>  # Do not trace debug files and internal ftrace files
> diff --git a/kernel/capability.c b/kernel/capability.c
> index 989f5bf..638b0b3 100644
> --- a/kernel/capability.c
> +++ b/kernel/capability.c
> @@ -35,6 +35,7 @@ static int __init file_caps_disable(char *str)
>  }
>  __setup("no_file_caps", file_caps_disable);
>
> +#ifdef CONFIG_MULTIUSER
>  /*
>   * More recent versions of libcap are available from:
>   *
> @@ -386,6 +387,24 @@ bool ns_capable(struct user_namespace *ns, int cap)
>  }
>  EXPORT_SYMBOL(ns_capable);
>
> +
> +/**
> + * capable - Determine if the current task has a superior capability in effect
> + * @cap: The capability to be tested for
> + *
> + * Return true if the current task has the given superior capability currently
> + * available for use, false if not.
> + *
> + * This sets PF_SUPERPRIV on the task if the capability is available on the
> + * assumption that it's about to be used.
> + */
> +bool capable(int cap)
> +{
> +       return ns_capable(&init_user_ns, cap);
> +}
> +EXPORT_SYMBOL(capable);
> +#endif /* CONFIG_MULTIUSER */
> +
>  /**
>   * file_ns_capable - Determine if the file's opener had a capability in effect
>   * @file:  The file we want to check
> @@ -412,22 +431,6 @@ bool file_ns_capable(const struct file *file, struct user_namespace *ns,
>  EXPORT_SYMBOL(file_ns_capable);
>
>  /**
> - * capable - Determine if the current task has a superior capability in effect
> - * @cap: The capability to be tested for
> - *
> - * Return true if the current task has the given superior capability currently
> - * available for use, false if not.
> - *
> - * This sets PF_SUPERPRIV on the task if the capability is available on the
> - * assumption that it's about to be used.
> - */
> -bool capable(int cap)
> -{
> -       return ns_capable(&init_user_ns, cap);
> -}
> -EXPORT_SYMBOL(capable);
> -
> -/**
>   * capable_wrt_inode_uidgid - Check nsown_capable and uid and gid mapped
>   * @inode: The inode in question
>   * @cap: The capability in question
> diff --git a/kernel/cred.c b/kernel/cred.c
> index e0573a4..ec1c076 100644
> --- a/kernel/cred.c
> +++ b/kernel/cred.c
> @@ -29,6 +29,9 @@
>
>  static struct kmem_cache *cred_jar;
>
> +/* init to 2 - one for init_task, one to ensure it is never freed */
> +struct group_info init_groups = { .usage = ATOMIC_INIT(2) };
> +
>  /*
>   * The initial credentials for the initial task
>   */
> diff --git a/kernel/groups.c b/kernel/groups.c
> index 664411f..74d431d 100644
> --- a/kernel/groups.c
> +++ b/kernel/groups.c
> @@ -9,9 +9,6 @@
>  #include <linux/user_namespace.h>
>  #include <asm/uaccess.h>
>
> -/* init to 2 - one for init_task, one to ensure it is never freed */
> -struct group_info init_groups = { .usage = ATOMIC_INIT(2) };
> -
>  struct group_info *groups_alloc(int gidsetsize)
>  {
>         struct group_info *group_info;
> diff --git a/kernel/sys.c b/kernel/sys.c
> index ea9c881..3094e0f 100644
> --- a/kernel/sys.c
> +++ b/kernel/sys.c
> @@ -319,6 +319,7 @@ out_unlock:
>   * SMP: There are not races, the GIDs are checked only by filesystem
>   *      operations (as far as semantic preservation is concerned).
>   */
> +#ifdef CONFIG_MULTIUSER
>  SYSCALL_DEFINE2(setregid, gid_t, rgid, gid_t, egid)
>  {
>         struct user_namespace *ns = current_user_ns();
> @@ -809,6 +810,7 @@ change_okay:
>         commit_creds(new);
>         return old_fsgid;
>  }
> +#endif /* CONFIG_MULTIUSER */
>
>  /**
>   * sys_getpid - return the thread group id of the current process
> diff --git a/kernel/sys_ni.c b/kernel/sys_ni.c
> index 5adcb0a..7995ef5 100644
> --- a/kernel/sys_ni.c
> +++ b/kernel/sys_ni.c
> @@ -159,6 +159,20 @@ cond_syscall(sys_uselib);
>  cond_syscall(sys_fadvise64);
>  cond_syscall(sys_fadvise64_64);
>  cond_syscall(sys_madvise);
> +cond_syscall(sys_setuid);
> +cond_syscall(sys_setregid);
> +cond_syscall(sys_setgid);
> +cond_syscall(sys_setreuid);
> +cond_syscall(sys_setresuid);
> +cond_syscall(sys_getresuid);
> +cond_syscall(sys_setresgid);
> +cond_syscall(sys_getresgid);
> +cond_syscall(sys_setgroups);
> +cond_syscall(sys_getgroups);
> +cond_syscall(sys_setfsuid);
> +cond_syscall(sys_setfsgid);
> +cond_syscall(sys_capget);
> +cond_syscall(sys_capset);
>
>  /* arch-specific weak syscall entries */
>  cond_syscall(sys_pciconfig_read);
> diff --git a/net/sunrpc/Kconfig b/net/sunrpc/Kconfig
> index fb78117..9068e72 100644
> --- a/net/sunrpc/Kconfig
> +++ b/net/sunrpc/Kconfig
> @@ -1,9 +1,11 @@
>  config SUNRPC
>         tristate
> +       depends on MULTIUSER
>
>  config SUNRPC_GSS
>         tristate
>         select OID_REGISTRY
> +       depends on MULTIUSER
>
>  config SUNRPC_BACKCHANNEL
>         bool
> diff --git a/security/Kconfig b/security/Kconfig
> index beb86b5..bf4ec46 100644
> --- a/security/Kconfig
> +++ b/security/Kconfig
> @@ -21,6 +21,7 @@ config SECURITY_DMESG_RESTRICT
>  config SECURITY
>         bool "Enable different security models"
>         depends on SYSFS
> +       depends on MULTIUSER
>         help
>           This allows you to choose different security modules to be
>           configured into your kernel.
> --
> 1.7.10.4
>
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ