home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.unix.internals
- 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
- From: terry@thisbe.Eng.Sandy.Novell.COM (Terry Lambert)
- Subject: Re: cd-ing to a dir using a process, then staying there on exit.
- Message-ID: <1992Aug20.224718.12476@gateway.novell.com>
- Sender: news@gateway.novell.com (NetNews)
- Nntp-Posting-Host: thisbe.eng.sandy.novell.com
- Organization: Novell NPD -- Sandy, UT
- References: <BtA8CG.ME4@encore.com> <1992Aug20.163507.4449@gateway.novell.com> <1992Aug20.190826.7119@prl.dec.com>
- Date: Thu, 20 Aug 1992 22:47:18 GMT
- Lines: 122
-
- In article <1992Aug20.190826.7119@prl.dec.com> boyd@prl.dec.com (Boyd Roberts) writes:
- >If you're going to post any such pretense get the details right:
- >
- >In article <1992Aug20.163507.4449@gateway.novell.com>, terry@thisbe.Eng.Sandy.Novell.COM (Terry Lambert) writes:
- >>
- >> 5) Get the locked vnode number for the process' cwd from the u struct.
- >>
- >
- >The [igv]node will most probably _not_ be locked, and the u-area
- >holds a pointer to it.
-
- Sorry; I meant "pointer". In ufs_inode.c in the routine iget(), (which
- is used to get the vnode pointer), VN_HOLD() is called on the vnode, locking
- it. On Solaris 2.0 and NCRs SMP 5.4.0 R2, this is mediated by a mutex. In
- Unisys' SMP 5.4.0 R2, the inode access is mediated by a mutex. In all
- cases, vp->v_count is either set to 1 (an initial reference) or incremented
- (a reference from a cache hit in the dnlc). This is the locking to which
- I was referring (as opposed to the inode locking, which will also take place,
- and the fact that the vnode address returned is the address of the vnode
- within the in core inode). This can easily be demonstrated (follows). The
- problem which is potentially going to kill you is the decrement v_count to
- zero, which could happen if you were attempting to remove the vnode reference
- and replace it with something else, rather than just swapping it between the
- parent and the child (as I have suggested).
-
- 1) Login as root to UNIX terminal #1
- 2) Login as root to UNIX terminal #2
- 3) Mount a mountable file system on /mnt from terminal #1
- 4) cd to /mnt on UNIX terminal #2
- 5) Unmount /mnt from UNIX terminal #1
- 6) See the "busy" message from a non-0 vp->v_count
- -OR-
- 1) Download UFS source from gatekeeper.dec.com
- 2) look at ufs_inode.c, function iget().
-
- >> 7) To avoid having to reverse map the parent's cwd to a file name and
- >> to avoid dorking the reference count on the vnodes and locking up
- >> your file system, swap cwd's between the parent and the child
- >> process. Do this by writing the childs vnode number into the
- >> parent's u struct, and the parent's into the childs. This is the
- >> sneaky bit.
- >
- >It's a _pointer_ and all of this will break for a variety of reasons.
-
- Again, *sorry*... *meant* "pointer"! Sheesh; like someone doing this would
- not have to look at the /usr/include/sys/vnode.h or
- /usr/include/sys/fs/ufs_inode.h files and see it for themselves!
-
- Not because it's a pointer. As a matter of fact, the pointer is a reference
- to a kernel space address, which, as we all know is invariant for all user
- processes. This is beacause vnodes aren't mapped out of the processes
- address space, they are mapped from the inode cache (since vnodes are
- declared as objects rather than pointers to objects). Since we are
- referencing from /dev/kmem (and possibly /dev/swap, depending on the box),
- the addresses can be looked up *without kernel to user page translation*
- or vice versa. Thus the pointer is a simple lseek() offset, which we
- don't care about, since we want to swap the pointer *values*, not
- *contents* (ie: we never need to dereference the things).
-
- The one thing that might bite you is accessing things as other than longs,
- since a lot of processors hate unaligned data access (which is why you
- can crash some boxes by cat'ing /dev/kmem). Fortuantely, these values will
- be aligned in the kernel on such architectures.
-
- Using the kstuff package (Ftp from wuarchive.wustl.edu), I wrote something
- that does this in less than 20 minutes on a Sun SPARCStation IPX (so it
- didn't break, as predicted)... but the idea itself, and the concept of
- having to have write access to /dev/kmem for it s so radioactive (many,
- many bogons!) in the first place, I doubt if I would ever use it anywhere
- for any reason, or even if there is any potential legitimate use for it at
- all.
-
- A better (but more expensive in terms of having to really remap pages) is
- to write a system call to do it. This is fairly easy on the Sun, as well,
- as the u struct is permanently mapped to different kernel addresses for
- each process (unlike SysV, that likes to map the struct into the same
- (and in many cases on the 386, user writable) area for all users, and it's
- relatively easy to assume the parents credentials and make the chdir() call
- on the parent's behalf. The nifty thing about this is that you just need
- to declare 3 int's as parameters to the "chpdir()" call (my parental chdir())
- and then call the real chdir() from within the system call on the parent's
- behalf. When you are done, zap everything back, and return to the caller.
-
- Sequence of events:
-
- 1) Find the parent u struct offset for cwd for the parent.
- 2) Swap child, parent cwd's
- 3) Save child credentials
- 4) Copy parent credentials to user
- 5) Call chdir to change "childs" dir
- 6) Restore childs credentials
- 7) Swap child, parent cwd's (paren has new cwd, child has same
- cwd as started with)
- 8) Return to caller (child).
-
- By virtue of kernel serialization, we don't even have a problem if the
- child is executing and the parent is running in the background.
-
- Note: This is not recommended for processes which are children of init. 8-).
-
- The system call implementation (I decided to make it hard on myself and
- reverse engineer loadable system calls from the SPARCPrinter drivers rather
- than just modding /sys/os/init_sysent.c) took about 30 minutes, most of
- that dedicated to the loading of the calls.
-
- Note that the first method has the advantage of potentially working under
- AIX, since the u struct is not directly available to loaded system calls in
- AIX. The second has the advantage of not being really dangerous to let normal
- users use, since you can check if the parent is init before allowing it to
- proceed. If you disallow differences in parent and child credentials, then
- you don't even have to do the credentials swap.
-
- In any case, both implementations work... I'd have to posit that it's
- possible to do.
-
- Terry Lambert
- terry_lambert@gateway.novell.com
- terry@icarus.weber.edu
-
- ---
- Disclaimer: Any opinions in this posting are my own and not those of
- my present or previous employers.
-