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