Learning NameFS, MDB — Pt. II
Here is an important excerpt from Solaris Internals, present in both the old version and the new (up to Solaris 10):
Application code that creates a door to a function typically creates a file in the file system to which the door descriptor can be attached, using the standard open(2) and fattach(3c) APIs, to make the door more easily accessible to other processes. The fattach(3C) API has traditionally been used for STREAMS code, where it is desirable to associate a STREAM or STREAMS-based pipe with a file in the file system name space; to make the descriptor easily accessible to other processes on the system. The binding of object to file name has already been solved. fattach(3C) is implemented with a pseudo file system called namefs, the name file system. namefs allows the mounting of filesystems on nondirectory mount points, as opposed to the traditional mounting of a filesystem that requires the selected mount point to be a directory file. Currently, fattach is the only client application of namefs; it calls the mount(2) system call, passing namefs as the file system and a pointer to a namefs file descriptor. The mount system call enter the VFS switch table through the VFS_MOUNT macro and enters the namefs mount code, nm_mount()
The most important points made:
.) fattach is the only client application of namefs
.) namefs allows mounting on files rather than directories. (but what does that mean.. Can I navigate it like I would a directory or… ?? what is this strange file system??
.) Can I pass any kind of file desciptor through a file this way?? Not just STREAMS or doors??
Before I go read up on fattach() and programmatically creating these namefs mount points, I want to catch up summarizing some of my mdb activity.
MDB
these are some cool commands:
> ::nm -n namefs Value Size Type Bind Other Shndx Name 0x0000000000000000|0x0000000000000000|NOTY |LOCL |0x0 |UNDEF | 0x00000000780989f4|0x0000000000001274|FUNC |GLOB |0x0 |1 |_fini 0x00000000780989fc|0x0000000000000018|FUNC |GLOB |0x0 |1 |_info 0x00000000780989d4|0x0000000000001274|FUNC |GLOB |0x0 |1 |_init 0x0000000078041db8|0x0000000000000048|OBJT |GLOB |0x0 |3 |dummyvfsops 0x0000000078041e28|0x0000000000000018|OBJT |LOCL |0x0 |3 |modlfs 0x0000000078041e40|0x0000000000000040|OBJT |LOCL |0x0 |3 |modlinkage 0x000000007801fc70|0x0000000000000008|OBJT |GLOB |0x0 |ABS |namedev 0x0000000078098128|0x0000000000000068|FUNC |GLOB |0x0 |1 |namefind 0x000000007801fc7c|0x0000000000000004|OBJT |GLOB |0x0 |ABS |namefstype 0x00000000780988f0|0x00000000000000e4|FUNC |GLOB |0x0 |1 |nameinit 0x00000000780980a0|0x0000000000000028|FUNC |GLOB |0x0 |1 |nameinsert 0x000000007801fc78|0x0000000000000004|OBJT |GLOB |0x0 |ABS |namenode_shift 0x00000000780980c8|0x0000000000000060|FUNC |GLOB |0x0 |1 |nameremove 0x000000007801fc80|0x00000000000000a0|OBJT |GLOB |0x0 |ABS |namevfs 0x0000000078099080|0x00000000000000cc|FUNC |LOCL |0x0 |1 |nm_access 0x0000000078098c34|0x00000000000000d0|FUNC |LOCL |0x0 |1 |nm_close 0x000000007809914c|0x000000000000007c|FUNC |LOCL |0x0 |1 |nm_create 0x000000007809923c|0x0000000000000018|FUNC |LOCL |0x0 |1 |nm_fid 0x000000007801fd20|0x0000000000000200|OBJT |GLOB |0x0 |ABS |nm_filevp_hash 0x00000000780991d0|0x000000000000001c|FUNC |LOCL |0x0 |1 |nm_fsync 0x0000000078098d9c|0x0000000000000088|FUNC |LOCL |0x0 |1 |nm_getattr 0x00000000780991ec|0x0000000000000050|FUNC |LOCL |0x0 |1 |nm_inactive 0x0000000078098d64|0x0000000000000038|FUNC |LOCL |0x0 |1 |nm_ioctl 0x00000000780991c8|0x0000000000000008|FUNC |LOCL |0x0 |1 |nm_link 0x00000000780982c8|0x00000000000003c4|FUNC |LOCL |0x0 |1 |nm_mount 0x0000000078098a14|0x0000000000000220|FUNC |GLOB |0x0 |1 |nm_open 0x00000000780992dc|0x0000000000000038|FUNC |LOCL |0x0 |1 |nm_poll 0x0000000078098d04|0x0000000000000030|FUNC |LOCL |0x0 |1 |nm_read 0x00000000780992a4|0x0000000000000038|FUNC |LOCL |0x0 |1 |nm_realvp 0x0000000078098800|0x0000000000000030|FUNC |LOCL |0x0 |1 |nm_root 0x0000000078099254|0x000000000000001c|FUNC |LOCL |0x0 |1 |nm_rwlock 0x0000000078099270|0x000000000000001c|FUNC |LOCL |0x0 |1 |nm_rwunlock 0x000000007809928c|0x0000000000000018|FUNC |LOCL |0x0 |1 |nm_seek 0x0000000078098e24|0x000000000000025c|FUNC |LOCL |0x0 |1 |nm_setattr 0x0000000078098830|0x0000000000000070|FUNC |LOCL |0x0 |1 |nm_statvfs 0x00000000780988a0|0x0000000000000050|FUNC |LOCL |0x0 |1 |nm_sync 0x0000000078098190|0x00000000000000e8|FUNC |LOCL |0x0 |1 |nm_umountall 0x000000007809868c|0x0000000000000174|FUNC |LOCL |0x0 |1 |nm_unmount 0x0000000078098278|0x0000000000000050|FUNC |GLOB |0x0 |1 |nm_unmountall 0x0000000078041e80|0x0000000000000158|OBJT |GLOB |0x0 |3 |nm_vnodeops 0x0000000078098d34|0x0000000000000030|FUNC |LOCL |0x0 |1 |nm_write 0x0000000078041d70|0x0000000000000048|OBJT |GLOB |0x0 |3 |nmvfsops 0x000000007801fc68|0x0000000000000008|OBJT |GLOB |0x0 |ABS |ntable_lock 0x0000000078041e00|0x0000000000000028|OBJT |LOCL |0x0 |3 |vfw > ::fsinfo VFSP TYP DATA OPS MOUNT 10445550 2 30000130018 ufs_vfsops / 30000513868 5 300000856c8 prvfsops /proc 300005137c8 15 3000051f978 mntvfsops /etc/mnttab 30000513728 12 0 fdvfsops ?? 30000513688 4 30000b58028 nmvfsops /etc/sysevent/syseve... 30000513548 11 30000b493c8 tmp_vfsops /var/run 300005135e8 4 30000c31318 nmvfsops /etc/sysevent/devfsa... 300005134a8 4 30000c30f58 nmvfsops ?? 30000513408 4 30000c30e18 nmvfsops /etc/sysevent/piclev... 30000513368 4 30000c302d8 nmvfsops ?? 30000513228 11 30000b495f8 tmp_vfsops /tmp 30000513188 4 300012d2920 nmvfsops ?? 300005130e8 4 300012d2ba0 nmvfsops ?? 30000513048 4 300012d26a0 nmvfsops ?? 30000512fa8 18 3000051e6e8 auto_vfsops /net 30000512f08 18 3000051e638 auto_vfsops /home 30000512e68 18 3000051e588 auto_vfsops /xfn 30000512d28 4 30001438938 nmvfsops ?? 30000512dc8 4 30001438bb8 nmvfsops /etc/.name_service_doo 30000512c88 4 30001438578 nmvfsops /var/spool/lp/fifos/... 30000512b48 7 300016ccc00 nfs_vfsops ?? 300005128c8 4 30001438438 nmvfsops ?? 30000512aa8 10 30000aabce0 lo_vfsops ??/root_fnnode/home/... 30000512be8 4 30001634308 nmvfsops ?? > $<vfslist vfs 10445550 root: root: next op vnodecovered 30000513868 ufs_vfsops 0 root+0x18: flag bsize fstype 20 8192 2 root+0x24: fsid data dev 220000000000002 30000130018 8800000000 root+0x40: bcount nsubmounts list 0 16 0 root+0x58: hash 30000512aa8 root+0x60: reflock root+0x60: sleepq count 0 0 root+0x6c: count 0 vfs 30000513868 0x30000513868: next op vnodecovered 300005137c8 prvfsops 300010c2d78 0x30000513880: flag bsize fstype 0 512 5 0x3000051388c: fsid data dev 40c000000000005 300000856c8 10300000000 0x300005138a8: bcount nsubmounts list 4294967296 0 1ea300001ea3 0x300005138c0: hash 0 0x300005138c8: reflock 0x300005138c8: sleepq count 0 0 0x300005138d4: count 0 vfs 300005137c8 0x300005137c8: next op vnodecovered 30000513728 mntvfsops 300010c2618 0x300005137e0: flag bsize fstype 0 512 15 0x300005137ec: fsid data dev 41800000000000f 3000051f978 10600000000 0x30000513808: bcount nsubmounts list 4294967296 0 12bb000012bb 0x30000513820: hash 0 0x30000513828: reflock 0x30000513828: sleepq count 0 0 0x30000513834: count 0 vfs 30000513728 0x30000513728: next op vnodecovered 30000513688 fdvfsops 30000b42fa8 0x30000513740: flag bsize fstype 0 1024 12 0x3000051374c: fsid data dev 41c00000000000c 0 10700000000 0x30000513768: bcount nsubmounts list 4294967296 0 1c0700001c07 0x30000513780: hash 30000513548 0x30000513788: reflock 0x30000513788: sleepq count 0 0 0x30000513794: count 0 vfs 30000513688 0x30000513688: next op vnodecovered 30000513548 nmvfsops 300008be280 0x300005136a0: flag bsize fstype 42 1024 4 0x300005136ac: fsid data dev 428000000000004 30000b58028 10a00000000 0x300005136c8: bcount nsubmounts list 0 0 e0000000e00 0x300005136e0: hash 300005135e8 0x300005136e8: reflock 0x300005136e8: sleepq count 0 0 0x300005136f4: count 0
I dunno if I’m getting somewhere with this:
int fattach(int fildes, const char *path) { struct namefd namefdp; struct door_info dinfo; int s; /* Only STREAMS and doors allowed to be mounted */ if ((s = isastream(fildes)) == 1 || _door_info(fildes, &dinfo) == 0) { namefdp.fd = fildes; return (mount((char *)NULL, path, MS_DATA|MS_NOMNTTAB, (const char *)"namefs", (char *)&namefdp, sizeof (struct namefd))); } else if (s == 0) { /* Not a STREAM */ errno = EINVAL; return (-1); } else { /* errno already set */ return (-1); } }
*supposed* to be limited to DOORS and STREAMS, but this could easily be replicated into my own program which did not do the check above. I have this code because I obtained Solaris 2.8 source code from eMule.
Invisible Symlinks
And now I have created what I call invisible symlinks
#include <sys/types.h> #include <errno.h> #include <stdio.h> #include <stropts.h> #include <sys/vnode.h> #include <sys/door.h> #include <sys/fs/namenode.h> #include <sys/mount.h> #include <fcntl.h> int myfattach(int fildes, const char *path) { struct namefd namefdp; namefdp.fd = fildes; return (mount((char *)NULL, path, MS_DATA|MS_NOMNTTAB, (const char *)"namefs", (char *)&namefdp, sizeof (struct namefd))); } main() { int fd1, fd2,fd3; char path1[] = "/tmp/namefs/1"; char path2[] = "/tmp/namefs/2"; char path3[] = "/tmp/namefs/3"; int s; fd1 = open (path1, O_RDWR|O_CREAT ); fd2 = open (path2, O_RDWR|O_CREAT ); //fd3 = open (path3, O_RDWR|O_CREAT ); //close(fd2); /* Only STREAMS and doors allowed to be mounted */ int r = myfattach(fd1, path2); printf ("1st mount = %d\n", r); r = myfattach(fd2,path1); printf ("2nd mount = %d\n", r); getchar(); fdetach(path2); fdetach(path1); }
Before running the code:
-bash-4.3$ pwd /tmp/namefs -bash-4.3$ ls -l total 0 -bash-4.3$
After running the code up until getchar():
-bash-4.3$ ls -l total 0 -rwx--s--- 1 bazz 0 Oct 28 07:02 1 -rwx--s--- 1 bazz 0 Oct 28 07:02 2 -bash-4.3$ echo '1' > 1 -bash-4.3$ ls -l total 0 -rwx--s--- 1 bazz 0 Oct 28 07:02 1 -rwx--s--- 1 bazz 0 Oct 28 07:02 2 -bash-4.3$ echo '2' > 2 -bash-4.3$ cat 1 1 -bash-4.3$ cat 2 2
I am not sure why they are setGID.. A: They are just the normal access permissions of O_CREAT.. I tried it without do any fattach() stuff.. HOWEVER, the setGID bit stays in the normal test.. where it gets changed to x bit in the fattach example. A: This is because I did not explicity close() the fd’s. When I explicitly close them in both examples, the SetGID bit stays..
Note The absence of change in file size…
After closing down the program: fdetach()
-bash-4.3$ ls -l total 16 -rwx--x--- 1 bazz 2 Oct 28 07:02 1 -rwx--x--- 1 bazz 2 Oct 28 07:02 2 -bash-4.3$ cat 1 2 -bash-4.3$ cat 2 1 -bash-4.3$
pretty cool huh…
/* By BAzz This code bypasses the "Only STREAMS and doors allowed to be mounted" as NameFS nodes thing. Kind of creates invisible symlinks :) */ #include <sys/types.h> #include <errno.h> #include <stdio.h> #include <stropts.h> #include <sys/vnode.h> #include <sys/door.h> #include <sys/fs/namenode.h> #include <sys/mount.h> #include <fcntl.h> int myfattach(int fildes, const char *path) { struct namefd namefdp; namefdp.fd = fildes; return (mount((char *)NULL, path, MS_DATA|MS_NOMNTTAB, (const char *)"namefs", (char *)&namefdp, sizeof (struct namefd))); } main() { int fd1, fd2,fd3; char path1[] = "/tmp/namefs/1"; char path2[] = "/tmp/namefs/2"; char path3[] = "/tmp/namefs/3"; int s; fd1 = open (path1, O_RDWR|O_CREAT ); fd2 = open (path2, O_RDWR|O_CREAT ); //fd3 = open (path3, O_RDWR|O_CREAT ); //close(fd2); int r = myfattach(fd1, path2); printf ("1st mount = %d\n", r); r = myfattach(fd2,path1); printf ("2nd mount = %d\n", r); getchar(); fdetach(path2); fdetach(path1); close (fd1); close(fd2); }
Leave a Reply