- 论坛徽章:
- 0
|
我的目标是用一个进程创建新的命名空间,在这个进程里做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[i]!='\0') && n<=len )
- {
- if( (src[i]==32)||(src[i]==9)||(src[i]==10) )
- {
- if(spacelen==0)
- {
- dest[j]=' ';
- spacelen++;
- i++;
- j++;
- }
- else
- i++;
- n++;
- continue;
- }
- dest[j]=src[i];
- i++;
- j++;
- n++;
- spacelen = 0;
- }
- dest[j]='\0';
- }
- char * my_itoa(int value,char *string,int radix)
- {
- char zm[37]="0123456789abcdefghijklmnopqrstuvwxyz";
- char aa[100]={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[i++]=zm[sum%radix];
- sum/=radix;
- }
- for(int j=i-1;j>=0;j--)
- {
- *cp++=aa[j];
- }
- *cp='\0';
- return string;
- }
- //按空格切分字符串。假设sub数组的长度够用
- int splitestr(const char *src,char sub[][256],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[i]!='\0' )
- {
- if (src[i]!=' ')
- {
- i++;
- len++;
- }
- if(src[i]==' ' )
- {
- i++;
- tmp = (char *)&src[flag];
- strncpy(sub[j],tmp,len);
- j++;
- flag = i;
- len =0;
- }
- }
- tmp = (char *)&src[flag];
- strncpy(sub[j],tmp,len);
- *argc = j+1;
- return 0;
- }
- int get_ns_id(pid_t pid,const char *ns_type)
- {
- char tmp[20] = {0};
- my_itoa(pid,tmp,10);
- char cmd[50] = {0};
- strcat(cmd,"ls -l /proc/");
- strcat(cmd,tmp);
- strcat(cmd,"/ns/");
- FILE *stream;
- char buf[1000] = {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[1000] = {0};
- system(cmd);
- read(fd,buf,1000);
- close(fd);
- dup2(old_fd,STDOUT_FILENO); // 还原屏幕输出默认文件描述符指向
- */
- //printf("buf:%s\n",buf);
- char search[20] = {0};
- strcat(search,ns_type);
- strcat(search,"[");
- char *first_pos = strstr(buf,search);
- char *last_pos = strstr(first_pos,"]");
- char ns_name[20] = {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[200] = {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[50] = {0};
- strcat(path,"/proc/");
- char tmp[20] = {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[10][256] = {0};
- splitestr(cmd2,args,&argc);
- char * argv[10] = {0};
- for(int i=0;i< argc;i++)
- {
- argv[i] = args[i];
- printf("%s\n",argv[i]);
- }
- if (execvp(argv[0], argv) < 0)
- perror("execl error\n");
- close(mnt_fd);
- }
- if (waitpid(pid, 0, 0) < 0)
- perror("wait error\n");
- }
- static char child_stack[1048576];
- 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[100] = {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;
- }
复制代码
|
|