使用clone函数+CLONE_NEWNS函数创建挂载命名空间,为啥别的进程还是能看见挂载信息
我的目标是用一个进程创建新的命名空间,在这个进程里做mount操作,达到只有同命名空间里的进程能看到挂载情况的目的。可是,这个效果就是没有,执行进程后,shell 里执行ls ,还是能看到挂载的文件。这是怎么回事呢?请高手指点!代码如下:
#define _GNU_SOURCE
#include <stdio.h> /* for convenience */
#include <stdlib.h> /* for convenience */
#include <string.h> /* for convenience */
#include <unistd.h> /* for convenience */
#include <errno.h>
#include <pwd.h>
#include <sched.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/wait.h>
#include <sys/mount.h>
#define MAXLINE 10
/*若某字符串中有多个空格,tab标志,换行符或者回车符 */
/*且这些字符可能接连出现,则将此字符串中的多个连续的*/
/*不可显示字符压缩为一个空格*/
/*参数len看似多余,其实有大用。如果源址与目的地址*/
/*重叠的情况下,可消除可能出现的死循环*/
void shrink(char *src,char *dest,size_t len)
{
int i= 0,j=0;
int n= 0;
int spacelen = 0;
while( (src!='\0') && n<=len )
{
if( (src==32)||(src==9)||(src==10) )
{
if(spacelen==0)
{
dest=' ';
spacelen++;
i++;
j++;
}
else
i++;
n++;
continue;
}
dest=src;
i++;
j++;
n++;
spacelen = 0;
}
dest='\0';
}
char * my_itoa(int value,char *string,int radix)
{
char zm="0123456789abcdefghijklmnopqrstuvwxyz";
char aa={0};
int sum=value;
char *cp=string;
int i=0;
if(radix<2||radix>36)//增加了对错误的检测
{
//cout<<"error data!"<<endl;
return string;
}
if(value<0)
{
//cout<<"error data!"<<endl;
return string;
}
while(sum>0)
{
aa=zm;
sum/=radix;
}
for(int j=i-1;j>=0;j--)
{
*cp++=aa;
}
*cp='\0';
return string;
}
//按空格切分字符串。假设sub数组的长度够用
int splitestr(const char *src,char sub[],int * argc)
{
/*split a string by space key*/
int i=0;
int j=0;
int len=0;
int flag=0;
char *tmp=NULL;
while( src!='\0' )
{
if (src!=' ')
{
i++;
len++;
}
if(src==' ' )
{
i++;
tmp = (char *)&src;
strncpy(sub,tmp,len);
j++;
flag = i;
len =0;
}
}
tmp = (char *)&src;
strncpy(sub,tmp,len);
*argc = j+1;
return 0;
}
int get_ns_id(pid_t pid,const char *ns_type)
{
char tmp = {0};
my_itoa(pid,tmp,10);
char cmd = {0};
strcat(cmd,"ls -l /proc/");
strcat(cmd,tmp);
strcat(cmd,"/ns/");
FILE *stream;
char buf = {0};
stream = popen(cmd, "r" ); //将命令的输出 通过管道读取(“r”参数)到FILE* stream
fread( buf, sizeof(char), sizeof(buf), stream); //将刚刚FILE* stream的数据流读取到buf中
pclose( stream );
/*
mode_t f_attrib = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH;
char * tmpfile = tmpnam(0);
printf("tmpfile:%s\n",tmpfile);
int fd = open(tmpfile, O_RDWR|O_CREAT,f_attrib);
if(fd == -1)
perror("open tmpfile error");
int old_fd=dup(STDOUT_FILENO);//保存屏幕输出的文件描述符,用于恢复
dup2(fd,STDOUT_FILENO); //输出重定向
char buf = {0};
system(cmd);
read(fd,buf,1000);
close(fd);
dup2(old_fd,STDOUT_FILENO);// 还原屏幕输出默认文件描述符指向
*/
//printf("buf:%s\n",buf);
char search = {0};
strcat(search,ns_type);
strcat(search,"[");
char *first_pos = strstr(buf,search);
char *last_pos = strstr(first_pos,"]");
char ns_name = {0};
strncpy(ns_name, first_pos+strlen(search), last_pos-(first_pos+strlen(search)) );
//printf("ns_name:%s\n",ns_name);
return atoi(ns_name);
}
void my_system(const char * cmd)
{
char cmd2 = {0};
strcpy(cmd2,cmd);
shrink(cmd2,cmd2,strlen(cmd2));
pid_t pid;
if ((pid = fork()) < 0)
{
perror("fork error\n");
}
else if (pid == 0)
{
setuid(0);
char path = {0};
strcat(path,"/proc/");
char tmp = {0};
pid_t parent_pid = getppid();
my_itoa(parent_pid,tmp,10);
strcat(path,tmp);
strcat(path,"/ns/mnt");
//get mount id of parent
int mnt_fd = open(path,O_RDONLY);
if (mnt_fd == -1)
perror("open mnt");
if (setns(mnt_fd, CLONE_NEWNS) == -1)
perror("setns error");
int argc = 0;
char args = {0};
splitestr(cmd2,args,&argc);
char * argv = {0};
for(int i=0;i< argc;i++)
{
argv = args;
printf("%s\n",argv);
}
if (execvp(argv, argv) < 0)
perror("execl error\n");
close(mnt_fd);
}
if (waitpid(pid, 0, 0) < 0)
perror("wait error\n");
}
static char child_stack;
static int child_fn()
{
setuid(0);
//if (unshare(CLONE_NEWNS) < 0)
//{
// perrpr("unshare");
//}
char pass[] = {'1','2','3','4','5','6'};
mode_t f_attrib = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH;
char * tmpfile = tmpnam(0);
int fd = open(tmpfile, O_RDWR|O_CREAT,f_attrib);
write(fd,pass,sizeof(pass));
int old_fd=dup(STDIN_FILENO);//保存描述符,用于恢复
dup2(fd,STDIN_FILENO);
lseek(0,0,SEEK_SET);
//char cmd2 = {0};
my_system("cryptsetup luksOpen /home/wxf/dss/sdb1 dss_encrypted_partition");
close(fd);
unlink(tmpfile);
dup2(old_fd,STDIN_FILENO);// 还原文件描述符
//my_system("mkfs.ext4 /dev/mapper/dss_encrypted_partition");
my_system("mount --make-private/dev/mapper/dss_encrypted_partition /mnt/dssdir");
//my_system("mount /dev/mapper/dss_encrypted_partition /mnt/dssdir");
while(1)
{
sleep(10);
}
return 0;
}
int main(int argc, char *argv[])
{
pid_t child_pid = clone(child_fn, child_stack+1048576,CLONE_NEWNS, 0);// 0x00020000 CLONE_NEWNS
if(child_pid == -1)
perror("clone error");
return 0;
}
页:
[1]