home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #18 / NN_1992_18.iso / spool / comp / unix / internal / 1720 < prev    next >
Encoding:
Text File  |  1992-08-20  |  6.6 KB  |  135 lines

  1. Newsgroups: comp.unix.internals
  2. Path: sparky!uunet!charon.amdahl.com!pacbell.com!mips!sdd.hp.com!caen!hellgate.utah.edu!fcom.cc.utah.edu!park.uvcc.edu!ns.novell.com!gateway.novell.com!thisbe.Eng.Sandy.Novell.COM!terry
  3. From: terry@thisbe.Eng.Sandy.Novell.COM (Terry Lambert)
  4. Subject: Re: cd-ing to a dir using a process, then staying there on exit.
  5. Message-ID: <1992Aug20.224718.12476@gateway.novell.com>
  6. Sender: news@gateway.novell.com (NetNews)
  7. Nntp-Posting-Host: thisbe.eng.sandy.novell.com
  8. Organization: Novell NPD -- Sandy, UT
  9. References: <BtA8CG.ME4@encore.com> <1992Aug20.163507.4449@gateway.novell.com> <1992Aug20.190826.7119@prl.dec.com>
  10. Date: Thu, 20 Aug 1992 22:47:18 GMT
  11. Lines: 122
  12.  
  13. In article <1992Aug20.190826.7119@prl.dec.com> boyd@prl.dec.com (Boyd Roberts) writes:
  14. >If you're going to post any such pretense get the details right:
  15. >
  16. >In article <1992Aug20.163507.4449@gateway.novell.com>, terry@thisbe.Eng.Sandy.Novell.COM (Terry Lambert) writes:
  17. >> 
  18. >> 5)    Get the locked vnode number for the process' cwd from the u struct.
  19. >> 
  20. >
  21. >The [igv]node will most probably _not_ be locked, and the u-area
  22. >holds a pointer to it.
  23.  
  24. Sorry; I meant "pointer".  In ufs_inode.c in the routine iget(), (which
  25. is used to get the vnode pointer), VN_HOLD() is called on the vnode, locking
  26. it.  On Solaris 2.0 and NCRs SMP 5.4.0 R2, this is mediated by a mutex.  In
  27. Unisys' SMP 5.4.0 R2, the inode access is mediated by a mutex.  In all
  28. cases, vp->v_count is either set to 1 (an initial reference) or incremented
  29. (a reference from a cache hit in the dnlc).  This is the locking to which
  30. I was referring (as opposed to the inode locking, which will also take place,
  31. and the fact that the vnode address returned is the address of the vnode
  32. within the in core inode).  This can easily be demonstrated (follows).  The
  33. problem which is potentially going to kill you is the decrement v_count to
  34. zero, which could happen if you were attempting to remove the vnode reference
  35. and replace it with something else, rather than just swapping it between the
  36. parent and the child (as I have suggested).
  37.  
  38.     1)    Login as root to UNIX terminal #1
  39.     2)    Login as root to UNIX terminal #2
  40.     3)    Mount a mountable file system on /mnt from terminal #1
  41.     4)    cd to /mnt on UNIX terminal #2
  42.     5)    Unmount /mnt from UNIX terminal #1
  43.     6)    See the "busy" message from a non-0 vp->v_count
  44. -OR-
  45.     1)    Download UFS source from gatekeeper.dec.com
  46.     2)    look at ufs_inode.c, function iget().
  47.  
  48. >> 7)    To avoid having to reverse map the parent's cwd to a file name and
  49. >>     to avoid dorking the reference count on the vnodes and locking up
  50. >>     your file system, swap cwd's between the parent and the child
  51. >>     process.  Do this by writing the childs vnode number into the
  52. >>     parent's u struct, and the parent's into the childs.  This is the
  53. >>     sneaky bit.
  54. >
  55. >It's a _pointer_ and all of this will break for a variety of reasons.
  56.  
  57. Again, *sorry*... *meant* "pointer"!  Sheesh; like someone doing this would
  58. not have to look at the /usr/include/sys/vnode.h or
  59. /usr/include/sys/fs/ufs_inode.h files and see it for themselves!
  60.  
  61. Not because it's a pointer.  As a matter of fact, the pointer is a reference
  62. to a kernel space address, which, as we all know is invariant for all user
  63. processes.  This is beacause vnodes aren't mapped out of the processes
  64. address space, they are mapped from the inode cache (since vnodes are
  65. declared as objects rather than pointers to objects).  Since we are
  66. referencing from /dev/kmem (and possibly /dev/swap, depending on the box),
  67. the addresses can be looked up *without kernel to user page translation*
  68. or vice versa.  Thus the pointer is a simple lseek() offset, which we
  69. don't care about, since we want to swap the pointer *values*, not
  70. *contents* (ie: we never need to dereference the things).
  71.  
  72. The one thing that might bite you is accessing things as other than longs,
  73. since a lot of processors hate unaligned data access (which is why you
  74. can crash some boxes by cat'ing /dev/kmem).  Fortuantely, these values will
  75. be aligned in the kernel on such architectures.
  76.  
  77. Using the kstuff package (Ftp from wuarchive.wustl.edu), I wrote something
  78. that does this in less than 20 minutes on a Sun SPARCStation IPX (so it
  79. didn't break, as predicted)... but the idea itself, and the concept of
  80. having to have write access to /dev/kmem for it s so radioactive (many,
  81. many bogons!) in the first place, I doubt if I would ever use it anywhere
  82. for any reason, or even if there is any potential legitimate use for it at
  83. all.
  84.  
  85. A better (but more expensive in terms of having to really remap pages) is
  86. to write a system call to do it.  This is fairly easy on the Sun, as well,
  87. as the u struct is permanently mapped to different kernel addresses for
  88. each process (unlike SysV, that likes to map the struct into the same
  89. (and in many cases on the 386, user writable) area for all users, and it's
  90. relatively easy to assume the parents credentials and make the chdir() call
  91. on the parent's behalf.  The nifty thing about this is that you just need
  92. to declare 3 int's as parameters to the "chpdir()" call (my parental chdir())
  93. and then call the real chdir() from within the system call on the parent's
  94. behalf.  When you are done, zap everything back, and return to the caller.
  95.  
  96. Sequence of events:
  97.  
  98.     1)    Find the parent u struct offset for cwd for the parent.
  99.     2)    Swap child, parent cwd's
  100.     3)    Save child credentials
  101.     4)    Copy parent credentials to user
  102.     5)    Call chdir to change "childs" dir
  103.     6)    Restore childs credentials
  104.     7)    Swap child, parent cwd's (paren has new cwd, child has same
  105.         cwd as started with)
  106.     8)    Return to caller (child).
  107.  
  108. By virtue of kernel serialization, we don't even have a problem if the
  109. child is executing and the parent is running in the background.
  110.  
  111. Note: This is not recommended for processes which are children of init. 8-).
  112.  
  113. The system call implementation (I decided to make it hard on myself and
  114. reverse engineer loadable system calls from the SPARCPrinter drivers rather
  115. than just modding /sys/os/init_sysent.c) took about 30 minutes, most of
  116. that dedicated to the loading of the calls.
  117.  
  118. Note that the first method has the advantage of potentially working under
  119. AIX, since the u struct is not directly available to loaded system calls in
  120. AIX.  The second has the advantage of not being really dangerous to let normal
  121. users use, since you can check if the parent is init before allowing it to
  122. proceed.  If you disallow differences in parent and child credentials, then
  123. you don't even have to do the credentials swap.
  124.  
  125. In any case, both implementations work... I'd have to posit that it's
  126. possible to do.
  127.  
  128.                     Terry Lambert
  129.                     terry_lambert@gateway.novell.com
  130.                     terry@icarus.weber.edu
  131.  
  132. ---
  133. Disclaimer:  Any opinions in this posting are my own and not those of
  134. my present or previous employers.
  135.