diff options
-rw-r--r-- | Makefile | 3 | ||||
-rw-r--r-- | README.txt | 4 | ||||
-rw-r--r-- | nmount.c | 234 |
3 files changed, 203 insertions, 38 deletions
@@ -1,2 +1,3 @@ make: - gcc nmount.c -o nmount
\ No newline at end of file + gcc -Wall nmount.c -o nmount + gcc -static nmount.c -o nmount_static
\ No newline at end of file diff --git a/README.txt b/README.txt new file mode 100644 index 0000000..e5ed452 --- /dev/null +++ b/README.txt @@ -0,0 +1,4 @@ + +nmount -t proc -d /proc2 -f nosuid,nodev,noexec +nmount -v -t proc -d /Process -f nosuid,nodev,noexec +nmount -v -t ext4 -s /dev/mmcblk0p7 -d /mnt/disk0 -f nodev,noexec,nosuid
\ No newline at end of file @@ -6,39 +6,47 @@ #include <fcntl.h> #include <getopt.h> #include <signal.h> +#include <string.h> +#include <sys/syscall.h> +#include <unistd.h> +#include <errno.h> + ///////////////////////////////////////////////////////////////////////////////////////// /*FLAGS FROM KERNEL*/ -//#define MS_RDONLY 1 /* Mount read-only */ -//#define MS_NOSUID 2 /* Ignore suid and sgid bits */ -//#define MS_NODEV 4 /* Disallow access to device special files */ -//#define MS_NOEXEC 8 /* Disallow program execution */ -//#define MS_SYNCHRONOUS 16 /* Writes are synced at once */ -//#define MS_REMOUNT 32 /* Alter flags of a mounted FS */ -//#define MS_MANDLOCK 64 /* Allow mandatory locks on an FS */ -//#define MS_DIRSYNC 128 /* Directory modifications are synchronous */ -//#define MS_NOATIME 1024 /* Do not update access times. */ -//#define MS_NODIRATIME 2048 /* Do not update directory access times */ -//#define MS_BIND 4096 -//#define MS_MOVE 8192 -//#define MS_REC 16384 -//#define MS_VERBOSE 32768 /* War is peace. Verbosity is silence. -// MS_VERBOSE is deprecated. */ -//#define MS_SILENT 32768 -//#define MS_POSIXACL (1<<16) /* VFS does not apply the umask */ -//#define MS_UNBINDABLE (1<<17) /* change to unbindable */ -//#define MS_PRIVATE (1<<18) /* change to private */ -//#define MS_SLAVE (1<<19) /* change to slave */ -//#define MS_SHARED (1<<20) /* change to shared */ -//#define MS_RELATIME (1<<21) /* Update atime relative to mtime/ctime. */ -//#define MS_KERNMOUNT (1<<22) /* this is a kern_mount call */ -//#define MS_I_VERSION (1<<23) /* Update inode I_version field */ -//#define MS_STRICTATIME (1<<24) /* Always perform atime updates */ -//#define MS_LAZYTIME (1<<25) /* Update the on-disk [acm]times lazily */ +#define _MS_RDONLY (1<<0) +#define _MS_NOSUID (1<<1) +#define _MS_NODEV (1<<2) +#define _MS_NOEXEC (1<<3) +#define _MS_SYNCHRONOUS (1<<4) +#define _MS_REMOUNT (1<<5) +#define _MS_MANDLOCK (1<<6) +#define _MS_DIRSYNC (1<<7) +#define _MS_NOATIME (1<<10) +#define _MS_NODIRATIME (1<<11) +#define _MS_BIND (1<<12) +#define _MS_MOVE (1<<13) +#define _MS_REC (1<<14) +#define _MS_SILENT (1<<15) +#define _MS_POSIXACL (1<<16) +#define _MS_UNBINDABLE (1<<17) +#define _MS_PRIVATE (1<<18) +#define _MS_SLAVE (1<<19) +#define _MS_SHARED (1<<20) +#define _MS_RELATIME (1<<21) +#define _MS_KERNMOUNT (1<<22) +#define _MS_I_VERSION (1<<23) +#define _MS_STRICTATIME (1<<24) +#define _MS_LAZYTIME (1<<25) #define STRUCT_LEN(VAR,STRUCT) ((sizeof(VAR)/sizeof(STRUCT))-1) +#define max(a,b) \ + ({ __typeof__ (a) _a = (a); \ + __typeof__ (b) _b = (b); \ + _a > _b ? _a : _b; }) + typedef struct vfs_option_params { char *val; char *descr; @@ -60,16 +68,17 @@ typedef struct vfs_options { char *options; char *description; - vfs_option_params **params; + vfs_option_params *params; } vfs_options; vfs_options vfs_options_proc[] = { - {"hidepid=\%u" ,"", &vfs_options_proc_params_hidepid}, - {"gid=\%u" ,"user group that can access process", &vfs_options_proc_params_gid}, + {"hidepid=\%u" ,"", (struct vfs_option_params *)&vfs_options_proc_params_hidepid}, + {"gid=\%u" ,"user group that can access process", (struct vfs_option_params *)&vfs_options_proc_params_gid}, {NULL,NULL,NULL} }; + static const struct vfs { char *name; long flags; @@ -78,7 +87,7 @@ static const struct vfs { } vfstab[] = { {"devtmpfs", 0, "/Device", NULL}, {"mqueue", 0, "/MQueue/", NULL}, - {"proc", 0, "/Process", &vfs_options_proc}, + {"proc", 0, "/Process", (struct vfs_options*)&vfs_options_proc}, {"tmpfs", 0, "/Ram", NULL}, {"sysfs", 0, "/System", NULL}, {"ext4", 0, NULL, NULL}, @@ -86,11 +95,31 @@ static const struct vfs { {NULL, 0, NULL, NULL}, }; +static const struct mount_flags +{ + char *name; + unsigned long bitfield; +} mountflgs[] = { + {"bind",_MS_BIND}, + {"move",_MS_MOVE}, + {"rdonly",_MS_RDONLY}, + {"lazytime",_MS_LAZYTIME}, + {"nodev",_MS_NODEV}, + {"noexec",_MS_NOEXEC}, + {"nosuid",_MS_NOSUID}, + {"remount",_MS_REMOUNT}, + {"silent",_MS_SILENT}, + {"sync",_MS_SYNCHRONOUS}, + {NULL,0}, +}; + typedef struct { - char *f_device; + char *f_source_dir; + char *f_target_dir; char *f_type; char *f_dir; char *f_flags;//g_params.f_output = 1; + unsigned long mount_flags; char *f_options; int f_verbose; int f_helper; @@ -102,9 +131,9 @@ void helper(char *progname) { printf("Usage: %s [OPTS]\n\n" "Version: 0.0.1 \n" - "-d device to mount\n" + "-s source directory\n" + "-d target directory\n" "-t filesystem type\n" - "-d mount directory\n" "-f mount flags\n" "-o mount fs options\n" "-v verbose output\n" @@ -130,6 +159,33 @@ void sig_handler(int signo) exit(0); } +int check_filetype(char *fsname) +{ + int i; + for (i=0;i<STRUCT_LEN(vfstab,struct vfs);i++) + { + if (strncmp(vfstab[i].name,fsname,max(strlen(vfstab[i].name),strlen(fsname))) == 0) + { + return 1; + } + } + + return 0; +} + +unsigned long str2flag(char *opt) +{ + int i; + for (i=0;i<STRUCT_LEN(mountflgs, struct mount_flags);i++) + { + if (strncmp(mountflgs[i].name,opt,strlen(mountflgs[i].name)) == 0) + { + return mountflgs[i].bitfield; + } + } + return 0; +} + int smount( const char *source, const char *target, @@ -137,14 +193,26 @@ int smount( unsigned long mountflags, const void *data) { + int ret=-1; - return 0; + if (g_params.f_verbose) + { + printf("Syscal params:\n"); + printf("source :%s\n",source); + printf("target :%s\n",target); + printf("filesystem :%s\n",filesystemtype); + printf("mountflags :%lu\n",mountflags); + printf("data :%016xxd\n",data); + } + ret = syscall(SYS_mount,source,target,filesystemtype,mountflags,data); + + return ret; } int main(int argc, char **argv) { int c; - int i; + int i,j,k; printf("One big real mount\n"); @@ -153,9 +221,11 @@ int main(int argc, char **argv) printf("cannot register signal handler\n"); exit(1); } + + memset(&g_params,0,sizeof(g_params)); //process arguments - while ((c = getopt(argc, argv, "a")) != -1) + while ((c = getopt(argc, argv, "ad:t:f:o:vs:")) != -1) { switch (c) { @@ -163,7 +233,24 @@ int main(int argc, char **argv) //g_params.f_output = 1; g_params.f_helper = 1; break; - + case 's': + g_params.f_source_dir = optarg; + break; + case 'd': + g_params.f_target_dir = optarg; + break; + case 't': + g_params.f_type = optarg; + break; + case 'f': + g_params.f_flags = optarg; + break; + case 'o': + g_params.f_options = optarg; + break; + case 'v': + g_params.f_verbose = 1; + break; default: helper(argv[0]); exit(1); @@ -175,9 +262,82 @@ int main(int argc, char **argv) for (i=0;i<STRUCT_LEN(vfstab,struct vfs);i++) { printf("%s %s\n",vfstab[i].name,vfstab[i].mountpoint); + if (vfstab[i].options != NULL) + { + j = 0; + while (vfstab[i].options[j].options != NULL) + { + printf("\t%s %s\n", + vfstab[i].options[j].options, + vfstab[i].options[j].description + ); + k = 0; + while(vfstab[i].options[j].params[k].val != NULL) + { + printf("\t\t%s %s\n", + vfstab[i].options[j].params[k].val, + vfstab[i].options[j].params[k].descr + ); + k++; + } + j++; + } + } + } + } + + if (NULL != g_params.f_type) + { + if (check_filetype(g_params.f_type) != 1) + { + printf("Unknow file type %s\n",g_params.f_type); + printf("Supported formats: "); + for (i=0;i<STRUCT_LEN(vfstab,struct vfs);i++) + { + printf("%s ",vfstab[i].name); + } + printf("\n"); + return 1; } } + if (NULL != g_params.f_flags) + { + char *token = strtok(g_params.f_flags,","); + printf("Flags: %d\n",g_params.mount_flags); + while ( token != NULL ) + { + printf("Flags: %s\n",token); + g_params.mount_flags |= str2flag(token); + printf("Flags: %d\n",g_params.mount_flags); + token = strtok(NULL,","); + } + } + + if (NULL != g_params.f_target_dir) + { + mkdir(g_params.f_target_dir, 0000); + } + + if ((NULL != g_params.f_target_dir) && + (NULL != g_params.f_flags) && + (NULL != g_params.f_type) && + (NULL != g_params.f_source_dir)) + { + printf("Flags: %d\n",g_params.mount_flags); + int ret = smount( + g_params.f_source_dir, + g_params.f_target_dir, + g_params.f_type, + g_params.mount_flags, + ""); + int err = errno; + printf("Mount exit code %d\n",ret); + if (ret==-1) + { + printf("Strerr: %d %s\n",err,strerror(err)); + } + } return 0; } |