Com namespaces de usuário Linux, por que clonar () mount / proc, mas unshare () não pode?

1

Estou tentando fazer com que um usuário não raiz monte /proc em um namespace de usuário do Linux.

Se eu criar um namespace por meio de clone() , posso montar /proc .

No entanto, se eu criar um namespace por meio de unshare() , a chamada para mount() falhará com Operation not permitted .

Por que o mount() se comporta de maneira diferente quando o namespace é criado com clone() em oposição a unshare() ?

O código abaixo demonstra a diferença.

#define   _GNU_SOURCE
#include  <errno.h>
#include  <sched.h>
#include  <stdio.h>
#include  <stdlib.h>
#include  <string.h>
#include  <unistd.h>
#include  <sys/syscall.h>
#include  <sys/mount.h>
#include  <sys/types.h>
#include  <sys/stat.h>
#include  <sys/wait.h>
#include  <fcntl.h>


#define STACK_SIZE (1024 * 1024)

static char child_stack[STACK_SIZE];    /* Space for child's stack */


void  try  ( const char * msg, int rv )  {
  printf ( "%-8s  %6d  %s\n", msg, rv, strerror ( rv < 0 ? errno : 0 ) );
}


int  child  ( void * arg )  {
  try(  "mount_1",   mount   (  "PROC", "/proc", "proc", 0, NULL  ));
  try(  "umount_1",  umount  (  "/proc"                           ));
  return  0;
}


int  main  ()  {

  int  clone_flags  =  0;

  clone_flags  |=  CLONE_NEWNET;
  clone_flags  |=  CLONE_NEWNS;
  clone_flags  |=  CLONE_NEWPID;
  clone_flags  |=  CLONE_NEWUSER;

  try(  "clone",    clone    (  child, child_stack + STACK_SIZE,
                                clone_flags | SIGCHLD, NULL       ));
  try(  "wait",     wait     (  NULL                              ));
  try(  "unshare",  unshare  (  clone_flags                       ));
  try(  "mount_2",  mount    (  "PROC", "/proc", "proc", 0, NULL  ));

  return  0;

}

Saída:

clone      31478  Success
mount_1        0  Success
umount_1       0  Success
wait       31478  Success
unshare        0  Success
mount_2       -1  Operation not permitted

Eu estou rodando no Ubuntu 18.04 com o kernel Linux 4.15.0-20-generic . Estou executando o código acima como não-raiz.

    
por mpb 10.11.2018 / 01:19

1 resposta

3

Acho que você ainda está no namespace do PID "errado", e isso significa que você não tem permissão para montar a instância do procfs.

CLONE_NEWPID [...] The calling process is not moved into the new namespace. The first child created by the calling process will have the process ID 1 and will assume the role of init(1) in the new namespace.

http://man7.org/linux/man-pages/man2/unshare.2.html

Compare

CLONE_NEWPID [...] If CLONE_NEWPID is set, then create the process in a new PID namespace.

http://man7.org/linux/man-pages/man2/clone.2.html

    
por 10.11.2018 / 01:37