[comp.unix.wizards] Two identical filenames in one directory!

jc@minya.UUCP (John Chambers) (09/28/89)

Hi, folks.  Here I am again with another puzzle.  You might recognize
the following output:

|	foo: ls -ltr |tail -6
|	 1956 -rw-rw-rw-   1 news     news         797 Sep 27 13:13 errlog
|	 2241 -rw-rw-rw-   1 news     news       14751 Sep 27 14:10 oactive
|	  256 drwxrwxrwx   2 news     news         224 Sep 27 16:08 history.od
|	  128 drwxrwxrwx   2 news     news         224 Sep 27 16:08 history.d
|	 1777 -rw-rw-rw-   1 news     news       14751 Sep 27 16:40 active
|	 1898 -rw-rw-rw-   1 news     news       14751 Sep 27 16:40 active

Those two "active" files are a bit curious.  Perhaps one of them has
a nonprinting character in its name?  Next I tried:

|	foo: mv active active.save
|	foo: ls -ltr |tail -6
|	./active not found
|	 1922 -rw-rw-rw-   1 news     news           3 Sep 26 17:03 seq
|	 1956 -rw-rw-rw-   1 news     news         797 Sep 27 13:13 errlog
|	 2241 -rw-rw-rw-   1 news     news       14751 Sep 27 14:10 oactive
|	  256 drwxrwxrwx   2 news     news         224 Sep 27 16:08 history.od
|	  128 drwxrwxrwx   2 news     news         224 Sep 27 16:08 history.d
|	 1777 -rw-rw-rw-   1 news     news       14751 Sep 27 16:40 active.save

Curiouser and curiouser.  The "active" file didn't just disappear; ls
told me that it wasn't there.  If it had a funny nonprinting character
in its name, we'd expect to see it still.  I undid the change, and fed
the listing to a hexdump program.  I won't bore you with the results of
this; suffice it to say that there was no funny character at the end of 
the last two lines.  (No remarks about the funny character sitting at the 
keyboard, please!)  My next try was to feed the directory itself to the 
hexdumper, and edit out most of the lines so you don't have to wade thru 
them like I did.  The two active files nicely turned out to be neighbors:

|	foo: hd . 
|	...
|	   192:_qactive_________jactive_________$errlog__________active--______
|	    C0:0F6676760000000106667676000000000A677666000000000066767622000000
|	       611349650000000F7A1349650000000074522CF70000000000134965DD000000
|	...

This is the "vertical" hexdump format, where each character in a vertical
3-byte slice.  Thus byte 195 is 'c' which is 0x63.  You all realized that
this was Sys/V without needing to be told, of course, as soon as you saw
this dump.  If we chop it into 16-byte chunks, we have the entries:
|	   _qactive________
|	   0F66767600000001
|	   611349650000000F
and:
|	   _jactive________
|	   0666767600000000
|	   7A13496500000000
Now we see what happened.  Some gremlin (I almost said daemon ;-) has changed
the last byte of one entry from 0x00 to 0x1F.  When ls scans the directory, 
it sees a file called "active", properly null-terminated.  It then tries to
stat("active",&status), and this fails, because the kernel's namei() routine
fills it with 8 null bytes, compares all 14 bytes, and they don't match.  This
also explains why the duplicate active files have all the data but the inode
numbers the same; they are both listings for the second file.

On earlier versions of Unix, I'd know instantly what to do.  It's easy enough
to write a program that runs thru a directory and extends each null byte to 
the end of the entry.  But on Sys/V, this doesn't work, because nobody, not
even root, can write a directory.  

I might observe that this is a clear violation of the principle that sofware
should be conservative in what it produces and liberal in what it accepts.
Sys/V allows the creation of such a directory entry; the proof is above; it
should properly handle references to them.  I might also make nasty remarks 
about the folks who decided that this sort of thing couldn't happen, so they 
didn't have to allow root to open directories for writing.  I might even make 
comments about people who add code to kernels that does nothing productive; 
it just wastes cycles preventing me from doing something I want to do.  But 
I won't.  I'll just ask:  Does anyone know a solution to this problem, short 
of zeroing the directory, running fsck, and reinstalling from backup?  The 
best way would be to say "Yes, root can write a directory; here's how..."

Alternatively, I guess I could try to find a pirate copy of the source to
fsck, and add this to its repertoire.  It'd probably only take an hour or
two.  Ain't binary-only systems nice?

-- 
#echo 'Opinions Copyright 1989 by John Chambers; for licensing information contact:'
echo '	John Chambers <{adelie,ima,mit-eddie}!minya!{jc,root}> (617/484-6393)'
echo ''
saying

gwyn@smoke.BRL.MIL (Doug Gwyn) (09/28/89)

In article <22@minya.UUCP> jc@minya.UUCP (John Chambers) writes:
>On earlier versions of Unix, I'd know instantly what to do.  It's easy enough
>to write a program that runs thru a directory and extends each null byte to 
>the end of the entry.  But on Sys/V, this doesn't work, because nobody, not
>even root, can write a directory.  

For just this one entry, you should be able to patch the raw disk image.

>I might observe that this is a clear violation of the principle that sofware
>should be conservative in what it produces and liberal in what it accepts.

The root cause of the problem is that directory entries were designed
for all 14 allocated characters to be usable, so there may not be a
null-byte terminator.  That's why the kernel uses the funny strcmp
method that it does.  One hopes that this is fixed in the FSS-based
(or VFS-based) UNIX implementations.

There is a lesson there..

>Does anyone know a solution to this problem, ...

Other than patching the raw disk, you could move all the other files
to a new directory, unlink whatever you can from the broken directory,
then use fsck to discard what's left (here's hoping fsck doesn't
insist on reconstructing the links you removed).

cpcahil@virtech.UUCP (Conor P. Cahill) (09/29/89)

In article <22@minya.UUCP>, jc@minya.UUCP (John Chambers) writes:
> Does anyone know a solution to this problem, short 
> of zeroing the directory, running fsck, and reinstalling from backup?  The 
> best way would be to say "Yes, root can write a directory; here's how..."

Use fsdb to patch the directory using the following sequence:

		ls -li .  (to get inode number of directory
		cd /
		umount /dev/dsk/...   		(file system file is on)
		fsdb /dev/rdsk/...

		(assuming 454 is the inode number of the directory)
		454i.fd				(displays directory entries)
		
		(look for the culprit.  remember what entry it is in the dir)
		(this assumes it is in slot 14)

		d14.nm="now_14_char_nm"		(rename entry 14)

		<CTRL-D>

		remount the file system and now remove the file.

Note that the new name given to the file must be 14 chars in order to 
fill all byte positions.
-- 
+-----------------------------------------------------------------------+
| Conor P. Cahill     uunet!virtech!cpcahil      	703-430-9247	!
| Virtual Technologies Inc.,    P. O. Box 876,   Sterling, VA 22170     |
+-----------------------------------------------------------------------+

lehners@uniol.UUCP (Joerg Lehners) (09/29/89)

Hello !

jc@minya.UUCP (John Chambers) writes:
>Hi, folks.  Here I am again with another puzzle.  You might recognize
>the following output:
>[lots of problem describing text deleted]
Well, I would have done the same things to determine the problem.

>On earlier versions of Unix, I'd know instantly what to do.  It's easy enough
>to write a program that runs thru a directory and extends each null byte to 
>the end of the entry.  But on Sys/V, this doesn't work, because nobody, not
>even root, can write a directory.  
Hmmm .. I started working with Unix with System V.2, now I use
System V.3 and sometimes SunOS.
But it never was possible to write on directories, even not as root.
Suppose something like 'ls > blah' when 'blah' ist a directory !

>I might observe that this is a clear violation of the principle that sofware
>should be conservative in what it produces and liberal in what it accepts.
>Sys/V allows the creation of such a directory entry; the proof is above; it
>should properly handle references to them.  I might also make nasty remarks 
Hmmm .. I don't believe that this offending file was created due to
'normal' kernel operation. Maybe I'm wrong, but I can't imagine a program
that would create such file names.
I think, it was a software or hardware flaw that caused some disk-write
do malfunction.
I once rebootet one system here (System V.3) and discovered some
defective directories. These directories had garbage in the first
three directory slots ('.' and '..' were lost, even on '/etc').
But I discovered too, that this was due to wild disk writes of the
kernel just before the crash. It took some time to clear the things
up, but it worked.

>about the folks who decided that this sort of thing couldn't happen, so they 
>didn't have to allow root to open directories for writing.  I might even make 
>comments about people who add code to kernels that does nothing productive; 
>it just wastes cycles preventing me from doing something I want to do.  But 
>I won't.  I'll just ask:  Does anyone know a solution to this problem, short 
>of zeroing the directory, running fsck, and reinstalling from backup?  The 
>best way would be to say "Yes, root can write a directory; here's how..."

I can image 3 possiblitities:

a.) If you have fsdb (File System DeBugger, it's located in /etc here)
you can do formatted reads and writes on inodes, files and directories
thru the disk file (raw or block device). It's dangerous, but it works.
There should be a manual to lookup the details.

b.) Move all 'accessible' files out of the directory with the offending
file and do 'unlink <dir>/..', 'unlink <dir>/.' and 'unlink <dir>' above
that directory with '<dir>' replaced by the directory name.
This is just what rmdir does, but without all the checks. unlink resides
in /etc on the systems here. Do it as root of course.
The kernel should throw away the now not connected directory (because
the unlinks made to link count zero).
Next run fsck, it should reconnect the offending file to the lost+found
of the partition. The new file name is composed from the i-node number.
(it works at least here, I tried it).

c.) Back up all the files with tar or cpio and restore all except
the offending file (maybe the offfending file isn't backed up at all).

Well, and all 3 possibilities don't need writes on directories.

>Alternatively, I guess I could try to find a pirate copy of the source to
>fsck, and add this to its repertoire.  It'd probably only take an hour or
>two.  Ain't binary-only systems nice?
Yes .. It would be nice to have the source for fsck. At least the fsck
here has a flaw: it does not detect wrong or missing '.' and '..'
entries of directories.

  Joerg
--
/ Joerg Lehners                       | Fachbereich 10 Informatik ARBI   \
|                                     | Universitaet Oldenburg           |
| BITNET/EARN: 066065@DOLUNI1.BITNET  | Ammerlaender Heerstrasse 114-118 |
\ UUCP/Eunet:  lehners@uniol.uucp     | D-2900 Oldenburg                 /

karl@ddsw1.MCS.COM (Karl Denninger) (09/29/89)

In article <22@minya.UUCP> jc@minya.UUCP (John Chambers) writes:
>
>|	 1777 -rw-rw-rw-   1 news     news       14751 Sep 27 16:40 active
>|	 1898 -rw-rw-rw-   1 news     news       14751 Sep 27 16:40 active
>
>|	   _qactive________
>|	   0F66767600000001
>|	   611349650000000F
>and:
>|	   _jactive________
>|	   0666767600000000
>|	   7A13496500000000

>On earlier versions of Unix, I'd know instantly what to do.  It's easy enough
>to write a program that runs thru a directory and extends each null byte to 
>the end of the entry.  But on Sys/V, this doesn't work, because nobody, not
>even root, can write a directory.  
>
>I'll just ask:  Does anyone know a solution to this problem, short 
>of zeroing the directory, running fsck, and reinstalling from backup?  The 
>best way would be to say "Yes, root can write a directory; here's how..."

Try using "clri" on the offending inode, then "fsck" the filesystem.....

See, that was easy.

--
Karl Denninger (karl@ddsw1.MCS.COM, <well-connected>!ddsw1!karl)
Public Access Data Line: [+1 312 566-8911], Voice: [+1 312 566-8910]
Macro Computer Solutions, Inc.		"Quality Solutions at a Fair Price"

perry@ccssrv.UUCP (Perry Hutchison) (09/29/89)

In article <22@minya.UUCP> jc@minya.UUCP (John Chambers) writes:

+ |	   _qactive________
+ |	   0F66767600000001
+ |	   611349650000000F
+ and:
+ |	   _jactive________
+ |	   0666767600000000
+ |	   7A13496500000000
+ Now we see what happened.  Some gremlin (I almost said daemon ;-) has changed
+ the last byte of one entry from 0x00 to 0x1F.

+ Does anyone know a solution to this problem, short of zeroing the directory,
+ running fsck, and reinstalling from backup?

Sure.  You boot DOS, run Norton Utilities in maintenance mode, search for the
problem pattern, and patch it.  Change the 1F to 00 and the name to anything
that doesn't duplicate some other entry in that directory.

This isn't a 386?  Well you can always use adb on the raw special file.

dold@mitisft.Convergent.COM (Clarence Dold) (09/29/89)

in article <22@minya.UUCP>, jc@minya.UUCP (John Chambers) says:

> On earlier versions of Unix, I'd know instantly what to do.  It's easy enough
> to write a program that runs thru a directory and extends each null byte to 
> the end of the entry.  But on Sys/V, this doesn't work, because nobody, not
> even root, can write a directory.  

I don't know about that.
Certainly fsdb can write to a directory.
So can ld.
-- 
---
Clarence A Dold - dold@tsmiti.Convergent.COM		(408) 434-5293
		...pyramid!ctnews!tsmiti!dold
		P.O.Box 6685, San Jose, CA 95150-6685	MS#10-007

jfh@rpp386.Dallas.TX.US (John F. Haugh II) (09/29/89)

In article <22@minya.UUCP> jc@minya.UUCP (John Chambers) writes:
>Now we see what happened.  Some gremlin (I almost said daemon ;-) has changed
>the last byte of one entry from 0x00 to 0x1F.  When ls scans the directory, 
>it sees a file called "active", properly null-terminated.  It then tries to
>stat("active",&status), and this fails, because the kernel's namei() routine
>fills it with 8 null bytes, compares all 14 bytes, and they don't match.  This
>also explains why the duplicate active files have all the data but the inode
>numbers the same; they are both listings for the second file.

Crank up fsdb and go find the directory you're interested in.

Begin on the partition containing directory.  fsdb has commands to
print an inode and associated directory blocks in directory format
with inode first and directory name next.  List out the directory
to find the slot you are interested in.

Change the name of the funky "active" entry to something with a 14
character file name.

Exit fsdb and voila.  Instant fixed directory.
-- 
John F. Haugh II                        +-Things you didn't want to know:------
VoiceNet: (512) 832-8832   Data: -8835  | The real meaning of MACH is ...
InterNet: jfh@rpp386.cactus.org         |    ... Messages Are Crufty Hacks.
UUCPNet:  {texbell|bigtex}!rpp386!jfh   +--------------------------------------

scott@bbxsda.UUCP (Scott Amspoker) (09/30/89)

In article <11177@smoke.BRL.MIL> gwyn@brl.arpa (Doug Gwyn) writes:
>In article <22@minya.UUCP> jc@minya.UUCP (John Chambers) writes:
>>On earlier versions of Unix, I'd know instantly what to do.  It's easy enough
>>to write a program that runs thru a directory and extends each null byte to 
>>the end of the entry.  But on Sys/V, this doesn't work, because nobody, not
>>even root, can write a directory.  
>
>For just this one entry, you should be able to patch the raw disk image.

I missed the original posting of the problem but I assume that you
have to directory entries with the same name field.  (I won't ask
how you managed to do that.)

Assuming that the 'ln' and 'rm' commands will operate on the first
occurance of the duplicate file name it should be easy enough to
rename one of the files.  Am I missing something?  Are these files
sharing the same inode?  Are they different files?

Another approach is to copy the entire directory and do a 'clri' on
the inode for the *old directory*.  Then let 'fsck' pick up the pieces.

-- 
Scott Amspoker
Basis International, Albuquerque, NM
(505) 345-5232

dg@lakart.UUCP (David Goodenough) (09/30/89)

From article <22@minya.UUCP>, by jc@minya.UUCP (John Chambers):

Lots of stuff about funky duplicate directory entries deleted .....

What happens if you do the following:

tar cf - . | ( cd someplace_else ; tar xf - )

I.e. use tar to shift the whole directory structure someplace else.
However, I'm still not 100% sure how you'd set about removing both
entries in the original directory, rm might still do ugly things.

If I were a _REAL_ hacker, I'd suggest opening the raw disk device
(/dev/rsm0g or whatever) for UPDATE, seeking along it looking for
the string "active", and then just patching the disk itself. [1]
I do this on a fairly regular basis to my machine at home, but then
the file structure of CP/M is a bit simpler that UNIX :-)

[1] This is not meant to be taken totally seriously, I'd suggest
waiting to hear what flames people have for such a brutal idea
before trying it. Also sync the disk, and umount it before
attempting this.
-- 
	dg@lakart.UUCP - David Goodenough		+---+
						IHS	| +-+-+
	....... !harvard!xait!lakart!dg			+-+-+ |
AKA:	dg%lakart.uucp@xait.xerox.com			  +---+

guy@auspex.auspex.com (Guy Harris) (09/30/89)

>This is the "vertical" hexdump format, where each character in a vertical
>3-byte slice.  Thus byte 195 is 'c' which is 0x63.  You all realized that
>this was Sys/V without needing to be told, of course, as soon as you saw
>this dump.

Or, at least, some system with the V7 file system, such as S5....

>On earlier versions of Unix, I'd know instantly what to do.  It's easy enough
>to write a program that runs thru a directory and extends each null byte to 
>the end of the entry.  But on Sys/V, this doesn't work, because nobody, not
>even root, can write a directory.  

And on earlier versions, root *can* write a directory?  Wrong.  The only
way "root" can write a directory - on V6, V7, S3, S5, or 4.xBSD, or on
most if not all UNIXes derived therefrom - is to open the raw disk and
stomp on the file.  If you could do it on some system that purported to
be one of the above, somebody must have hacked it.

>I might observe that this is a clear violation of the principle that sofware
>should be conservative in what it produces and liberal in what it accepts.
>Sys/V allows the creation of such a directory entry; the proof is
>above;

More correctly, System V doesn't *dis*allow the creation of such
directory entries by all possible creators of such entries.  Since one
such potential creator is generally known by the name "disk controller",
it would be a bit hard for it to do so - ultimately, it has to trust the
controller either not to screw up, or to report I/O errors if it does. 
Other possiblities include bugs in the file system code, or bugs in
"fsck" (yes, there was a bug in "fsck" that could cause it to create
entries of that sort, although as I remember those entries were created
when orphaned files were reattached to "lost+found", so that's not the
problem here.

>it should properly handle references to them.

And how would you suggest that it do so?  Allow null bytes in the middle
of path names? :-)

>I might also make nasty remarks about the folks who decided that this
>sort of thing couldn't happen, so they didn't have to allow root to
>open directories for writing.  I might even make comments about people
>who add code to kernels that does nothing productive; it just wastes
>cycles preventing me from doing something I want to do.

I'm sure Ken and/or Dennis would be glad to hear them, although they
might point out that preventing even the super-user from writing to
directories reduces the chances that a user *would* create a screwed-up
directory.  It's unfortunate that a file system bug or disk controller
problem can cause damage that can't be repaired easily, but that's life.

>Does anyone know a solution to this problem, short of zeroing the
>directory, running fsck, and reinstalling from backup?  The best way
>would be to say "Yes, root can write a directory; here's how..."

No, root can't write a directory, which has, as noted, been the case
since time immemorial (if you remember otherwise, you might want to get
your memory adjusted for distortion).  However, there are a couple of
possibilities:

	1) Make a new directory to hold all the files in question, move
	   all there (except, obviously, the one with the trashed
	   directory entry), "clri" the inode for the directory
	   containing the trashed entry, and then "fsck" the file
	   system.  This will cause the blocks of the directory
	   containing the trashed entry to be returned to the free pool,
	   the directory entry for that directory to be reamed out, link
	   counts to be adjusted appropriately and should result in the
	   file with the trashed entry getting reconnected in "lost+found";
	   you can then move it somewhere else, if you want.

	   Then rename the new directory to have the same name as the
	   now-defunct directory.

	2) Dive in with "fsdb", if your system has it, and patch the
	   directory.

Me, I'd go for 1) if possible.  Patching raw file systems may be loads
of fun, but I'd rather get my fun elsewhere....

"fsck" should check for this, and fix it somehow; unfortunately, it
doesn't.

thomson@hub.toronto.edu (Brian Thomson) (09/30/89)

In article <2516@auspex.auspex.com> guy@auspex.auspex.com (Guy Harris) writes:
>And on earlier versions, root *can* write a directory?  Wrong.  The only
>way "root" can write a directory - on V6, V7, S3, S5, or 4.xBSD, or on
>most if not all UNIXes derived therefrom - is to open the raw disk and
>stomp on the file. 

Hmm.  In my ongoing effort to further the cause of picking nits,
I offer the following:

1) In both V6 and V7, root is able to write a newly creat()'ed directory.
   This is how mkdir used to make the . and .. entries.

2) In V6, if you were unlucky enough to have a directory named 'core'
   and ran a sickly setuid-root program too near to it, you would discover
   yet another way that root could write a directory.
-- 
		    Brian Thomson,	    CSRI Univ. of Toronto
		    utcsri!uthub!thomson, thomson@hub.toronto.edu

cpcahil@virtech.UUCP (Conor P. Cahill) (09/30/89)

In article <188@bbxsda.UUCP>, scott@bbxsda.UUCP (Scott Amspoker) writes:
> I missed the original posting of the problem but I assume that you
> have to directory entries with the same name field.  (I won't ask
> how you managed to do that.)

No.  The problem was that the original poster had gotten a file with a
name that looked like the following:
	
	access\0\0\0\0\0\0\0\102

since the name contains non-null bytes after a null, there is no way 
to access the file through the system call interface.

> Assuming that the 'ln' and 'rm' commands will operate on the first
> occurance of the duplicate file name it should be easy enough to
> rename one of the files.  Am I missing something?  Are these files
> sharing the same inode?  Are they different files?

See above.

> Another approach is to copy the entire directory and do a 'clri' on
> the inode for the *old directory*.  Then let 'fsck' pick up the pieces.

This would probably work.
-- 
+-----------------------------------------------------------------------+
| Conor P. Cahill     uunet!virtech!cpcahil      	703-430-9247	!
| Virtual Technologies Inc.,    P. O. Box 876,   Sterling, VA 22170     |
+-----------------------------------------------------------------------+

jfh@rpp386.Dallas.TX.US (John F. Haugh II) (09/30/89)

In article <8909300118.AA09366@beaches.hub.toronto.edu> thomson@hub.toronto.edu (Brian Thomson) writes:
>Hmm.  In my ongoing effort to further the cause of picking nits,
>I offer the following:
>
>1) In both V6 and V7, root is able to write a newly creat()'ed directory.
>   This is how mkdir used to make the . and .. entries.

mkdir creates those entries with mknod, not write.  In fact, mkdir
doesn't create() directories, it mknod()s all of the entries.  Only
the low 9 bits of the file mode are honored by create, to get the
other 7 bits you have to use mknod().
-- 
John F. Haugh II                        +-Things you didn't want to know:------
VoiceNet: (512) 832-8832   Data: -8835  | The real meaning of MACH is ...
InterNet: jfh@rpp386.cactus.org         |    ... Messages Are Crufty Hacks.
UUCPNet:  {texbell|bigtex}!rpp386!jfh   +--------------------------------------

guy@auspex.auspex.com (Guy Harris) (10/01/89)

>1) In both V6 and V7, root is able to write a newly creat()'ed directory.
>   This is how mkdir used to make the . and .. entries.

Wrongo.  "mkdir" made those entries with the "link" system call.

In any case, UNIX never let user-mode programs running as root open a
directory for writing, even if bugs caused it not to properly check
whether "core" was a directory. 

cpcahil@virtech.UUCP (Conor P. Cahill) (10/01/89)

In article <17076@rpp386.Dallas.TX.US>, jfh@rpp386.Dallas.TX.US (John F. Haugh II) writes:
> Only
> the low 9 bits of the file mode are honored by create, to get the
> other 7 bits you have to use mknod().

Nope. create (and open) will also set the set[u|g]id bits, so it will
set 11 of the 12 low order bits (plus the file type bits for the regular
file file type).  The sticky bit can only be set using the [f]chmod system
call.  The other bits (file type) are set by mknod.

Since I only have SV.3 handy, I can't verify that this is also true for 
BSD, but I am pretty sure it is.
-- 
+-----------------------------------------------------------------------+
| Conor P. Cahill     uunet!virtech!cpcahil      	703-430-9247	!
| Virtual Technologies Inc.,    P. O. Box 876,   Sterling, VA 22170     |
+-----------------------------------------------------------------------+

jfh@rpp386.cactus.org (John F. Haugh II) (10/01/89)

In article <17076@rpp386.Dallas.TX.US> jfh@rpp386.cactus.org I wrote -
>mkdir creates those entries with mknod, not write.  In fact, mkdir
>doesn't create() directories, it mknod()s all of the entries.  Only
>the low 9 bits of the file mode are honored by create, to get the
>other 7 bits you have to use mknod().

Yeh, yeh, yeh.  I screwed up.

mkdir creates the original directory entry with mknod().  The entries
for "." and ".." are both created with link().

Thanks to Guy Harris for pointing this out.
-- 
John F. Haugh II                        +-Things you didn't want to know:------
VoiceNet: (512) 832-8832   Data: -8835  | The real meaning of MACH is ...
InterNet: jfh@rpp386.cactus.org         |    ... Messages Are Crufty Hacks.
UUCPNet:  {texbell|bigtex}!rpp386!jfh   +--------------------------------------

chris@mimsy.UUCP (Chris Torek) (10/01/89)

In article <701@ccssrv.UUCP> perry@ccssrv.UUCP (Perry Hutchison) writes:
(regarding fixing a file name of the form `foo\0\0\0\0\0\0\0\0\0\0x')
>Sure.  You boot DOS, run Norton Utilities in maintenance mode, search for the
>problem pattern, and patch it.  Change the 1F to 00 and the name to anything
>that doesn't duplicate some other entry in that directory.
>
>This isn't a 386?  Well you can always use adb on the raw special file.

For one thing, adb only works on block special files, since it reads and
writes one `int' at a time.  More importantly, this sort of problem is
rare enough under reasonable versions of Unix (i.e., never happens, because
fsck fixes it) that one does not need Norton Utilities.

If fsck does *not* fix it, then that is a bug in fsck.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@cs.umd.edu	Path:	uunet!mimsy!chris

cpcahil@virtech.UUCP (Conor P. Cahill) (10/01/89)

In article <705@lakart.UUCP>, dg@lakart.UUCP (David Goodenough) writes:
> What happens if you do the following:
> 
> tar cf - . | ( cd someplace_else ; tar xf - )
> 
> I.e. use tar to shift the whole directory structure someplace else.
> However, I'm still not 100% sure how you'd set about removing both
> entries in the original directory, rm might still do ugly things.

The problem with this solution is that you can't remove the bad entry 
through the system call interface.  You must bypass the kernel and 
directly modify the file system.  Tools that allow you to do this 
include clri, fsdb, fsck, etc.

> If I were a _REAL_ hacker, I'd suggest opening the raw disk device
> (/dev/rsm0g or whatever) for UPDATE, seeking along it looking for
> the string "active", and then just patching the disk itself. [1]
> I do this on a fairly regular basis to my machine at home, but then
> the file structure of CP/M is a bit simpler that UNIX :-)

If you are going to use the raw device you have to remember to read/write
with the proper block sizes (usually 512 or 1024), or multiples thereof.
You can expect wierd results if you do not use the proper multiple.
Another big problem with this is that you have to ensure that the 
pattern you are searching for does not appear anywhere else on the disk.  

You might say to me that  "active\0\0\0\0\0\0\0\102" is not a pattern that
would duplicate very much but what if you had the following in a directory:

		\000 \002 .  \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0
		\000 \002 .  .  \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0
		\000 \010 s  a  c  t  i  v  e  \0 \0 \0 \0 \0 \0 \0
		\102 \003 d  u  m  m  y  \0 \0 \0 \0 \0 \0 \0 \0 \0
		\000 \011 s  2  a  c  t  i  v  e  \0 \0 \0 \0 \0 \0
		\000 \102 d  u  m  m  y  2  \0 \0 \0 \0 \0 \0 \0 \0
		\000 \012 a  c  t  i  v  e  \0 \0 \0 \0 \0 \0 \0 \102

Note that the string "active\0\0\0\0\0\0\0\102" can be found three times in
that directory.

The only way to properly do this is to use an existing tool, or write a new one
that understands the disk file system structure.


> [1] This is not meant to be taken totally seriously, I'd suggest
> waiting to hear what flames people have for such a brutal idea
> before trying it. Also sync the disk, and umount it before
> attempting this.

Since the file name is in the data portion of the disk, why not use the 
block interface.  This way you can leave the fs mounted and don't have to
worry about syncing.

However I prefer to use the fsdb tool which already understands the layout
of the disk file system.
-- 
+-----------------------------------------------------------------------+
| Conor P. Cahill     uunet!virtech!cpcahil      	703-430-9247	!
| Virtual Technologies Inc.,    P. O. Box 876,   Sterling, VA 22170     |
+-----------------------------------------------------------------------+

dvu@prism.gatech.EDU (Dinh Vu) (10/02/89)

Contrary to the popular believe, UNIX does NOT even allow 
superuser to write to a directory (only link, and unlink with
mknod).  Directory is just another file, but its inode indicates 
as a directory.

Dinh


-- 
Dinh Vu 
Georgia Institute of Technology, Atlanta Georgia, 30332
uucp: ...!{allegra,amd,hplabs,seismo,ut-ngp}!gatech!prism!dvu
ARPA: dvu@prism.gatech.edu

pcf@galadriel.bt.co.uk (Pete French) (10/03/89)

From article <705@lakart.UUCP>, by dg@lakart.UUCP (David Goodenough):
> From article <22@minya.UUCP>, by jc@minya.UUCP (John Chambers):
> 
> If I were a _REAL_ hacker, I'd suggest opening the raw disk device
> (/dev/rsm0g or whatever) for UPDATE, seeking along it looking for
> the string "active", and then just patching the disk itself. [1]
> I do this on a fairly regular basis to my machine at home, but then
> the file structure of CP/M is a bit simpler that UNIX :-)

Actually I have done this - but it is rather hamperred by not having a binary
editor in UNIX . I used vi and it didnt work very well, there is nothing
like rebooting and finding the whole of /usr/bin in lost+_found to
convince you that a biunary editor would be nice.

(No - I am _NOT_ joking)

-Pete.

-- 
       -Pete French.               | "Love is the corpse,
  British Telecom Research Labs.   |  That crawls on dreams,
 Martlesham Heath, East Anglia.    |  Rips them apart,
All my own thoughts (of course)    |  And tears them to shreds" - SOM

nagle@well.UUCP (John Nagle) (10/04/89)

      Does FSCK validate filename syntax?  If it doesn't, it's a bug in
FSCK; one should be guaranteed that once a file system passes FSCK, it is
in a valid state.

      I've been at this too long.  I fixed the comparable bug in 1975
in CATFR (Catalogued File Recovery) in the Exec 8 operating system for 
UNIVAC mainframes.

					John Nagle

terryl@tekcrl.LABS.TEK.COM (10/04/89)

In article <374@galadriel.bt.co.uk> pcf@galadriel.bt.co.uk (Pete French) writes:
+From article <705@lakart.UUCP>, by dg@lakart.UUCP (David Goodenough):
+> From article <22@minya.UUCP>, by jc@minya.UUCP (John Chambers):
+> 
+> If I were a _REAL_ hacker, I'd suggest opening the raw disk device
+> (/dev/rsm0g or whatever) for UPDATE, seeking along it looking for
+> the string "active", and then just patching the disk itself. [1]
+> I do this on a fairly regular basis to my machine at home, but then
+> the file structure of CP/M is a bit simpler that UNIX :-)
+
+Actually I have done this - but it is rather hamperred by not having a binary
+editor in UNIX . I used vi and it didnt work very well, there is nothing
+like rebooting and finding the whole of /usr/bin in lost+_found to
+convince you that a biunary editor would be nice.

     Any hacker worth his/her salary should be able to adb a cooked device
and fix a file system. Maybe this should be one of the questions someone was
recently asking to find out who/what a wizard is like....

+(No - I am _NOT_ joking)

      Neither am I. I have done this (adb'ed a V7 file system to fix exactly
the original problem that was described: non-NUL characters after a terminating
NUL in the file name part of a directory entry....).

pcf@galadriel.bt.co.uk (Pete French) (10/05/89)

From article <4778@tekcrl.LABS.TEK.COM>, by terryl@tekcrl.LABS.TEK.COM:
> In article <374@galadriel.bt.co.uk> pcf@galadriel.bt.co.uk (Pete French) writes:
> 
>      Any hacker worth his/her salary should be able to adb a cooked device
> and fix a file system. Maybe this should be one of the questions someone was
> recently asking to find out who/what a wizard is like....
> 

Thats all very well - but our UNIX comes with no debuggers. No adb, no sdb
no nothing. Dont ask me why. My salary was 100 quid per week. I think I was
well worth it.

-- 
       -Pete French.               | "Love is the corpse,
  British Telecom Research Labs.   |  That crawls on dreams,
 Martlesham Heath, East Anglia.    |  Rips them apart,
All my own thoughts (of course)    |  And tears them to shreds" - SOM

jfh@rpp386.cactus.org (John F. Haugh II) (10/05/89)

In article <374@galadriel.bt.co.uk> pcf@galadriel.bt.co.uk (Pete French) writes:
>Actually I have done this - but it is rather hamperred by not having a binary
>editor in UNIX . I used vi and it didnt work very well, there is nothing
>like rebooting and finding the whole of /usr/bin in lost+_found to
>convince you that a biunary editor would be nice.

vi won't edit a device file, and we already covered writing directories.
What exactly did you do???  vi tells me `Block special' when I say `vi
/dev/root'.

>(No - I am _NOT_ joking)

bpatch is in the UNIX archives.  I've been using it lately to locate
my shadow password file which was recently added to the free list ;-)

It is somewheres along the line of many ``SUPERZAP'' like programs.  I've
used it to patch just about everything I've need to patch.

I have the sources on this machine if anyone wants to fire up UUCP and
fetch them.  It is in /usr/archive/bpatch.shar.Z.  The phone number is
in the .sig, login as uucp [ or kermit ], no password, 2400 baud.
-- 
John F. Haugh II                        +-Things you didn't want to know:------
VoiceNet: (512) 832-8832   Data: -8835  | The real meaning of MACH is ...
InterNet: jfh@rpp386.cactus.org         |    ... Messages Are Crufty Hacks.
UUCPNet:  {texbell|bigtex}!rpp386!jfh   +--------------------------------------

dold@mitisft.Convergent.COM (Clarence Dold) (10/07/89)

in article <13921@well.UUCP>, nagle@well.UUCP (John Nagle) says:

>       Does FSCK validate filename syntax?  If it doesn't, it's a bug in
> FSCK; one should be guaranteed that once a file system passes FSCK, it is
> in a valid state.

fsck can check, but doesn't by default.  fsck -D causes a directory consistency
check, one of the inconsistencies being a file name not padded with nulls.
-- 
---
Clarence A Dold - dold@tsmiti.Convergent.COM		(408) 434-5293
		...pyramid!ctnews!tsmiti!dold
		P.O.Box 6685, San Jose, CA 95150-6685	MS#10-007

jc@minya.UUCP (John Chambers) (10/11/89)

Well, lots of followup on that one; time for a summary.  As was my
fear, nobody told me how to write to a directory in Sys/V.  I suspect
that it can't be done.

Lots of people suggested writing to the raw device, implying that this 
is the same thing as writing to a directory on the device.  I don't 
think I'm picking any nits when I object that it's not the same thing
at all.

On the other hand, it's exactly what I've done.  Shortly after posting
the article, I bit the bullet, put my shoulder to the grindstone, and
lots of other cliches, and the result was a little program that groveled
through the filesystem, showing me what's there.  A couple of hourse
later, I added a routine to scan directories for funny-looking entries,
and if a -c option (for "changes allowed) was on the command line, make
some judicious changes.  It was sorta fun working on a live filesystem
(with lots of syncs), and watching it all work the first time....

I saw quite a few suggestions like:

> What happens if you do the following:
> 
> tar cf - . | ( cd someplace_else ; tar xf - )
> 
> I.e. use tar to shift the whole directory structure someplace else.
> However, I'm still not 100% sure how you'd set about removing both
> entries in the original directory, rm might still do ugly things.

Good guess.  You get a "not found" message from the first tar, and the
copy works otherwise.  The offending directory entry is still there; 
commands like rm won't touch it (because it can't be opened).

The most curious aspect is that the common suggestion (clri/fsck) didn't
clear up the problem.  I could get the directory renamed as something in
the lost+found directory; I couldn't get fsck to rename the garbage entry.
I'm not too clear on just what fsck did with the zeroed inode that used
to be the file's data; the bad directory entry was still there, but with
size 0.  

I'm reminded of some advice a read years ago, to the effect that, when 
faced with alternatives, one should avoid choosing the worst.  In this
case, clri+fsck tossed out the data, but kept the garbage directory entry.

> If I were a _REAL_ hacker, I'd suggest opening the raw disk device
> (/dev/rsm0g or whatever) for UPDATE, seeking along it looking for
> the string "active", and then just patching the disk itself. [1]
> I do this on a fairly regular basis to my machine at home, but then
> the file structure of CP/M is a bit simpler that UNIX :-)

Well, I guess I'm a real hacker, because that's what I did, and it
wasn't all that hard.  It took a bit of paranoid coding, because there
were numerous ambiguities in the manuals, and a few real strangenesses.
(Who ever got the bright idea to make the inode table 1-based? ;-) 
But now I have a little program that zips around a Sys/V filesystem,
and I can hack it up to do interesting things...

> [1] This is not meant to be taken totally seriously, I'd suggest
> waiting to hear what flames people have for such a brutal idea
> before trying it. Also sync the disk, and umount it before
> attempting this.

Maybe you weren't serious, but lots of others seem to think this is
a reasonable way to solve problems.  Maybe I'm paranoid, but I don't
agree.  On the other hand, it gives me more "Unix internals" that I
can put on my resume, and that's worth a lot in today's market, so
perhaps I shouldn't complain.  I mean, if people will pay me more to
solve problems that way than they will to work at a higher level, who
am I to criticise or refuse the money?

-- 
#echo 'Opinions Copyright 1989 by John Chambers; for licensing information contact:'
echo '	John Chambers <{adelie,ima,mit-eddie}!minya!{jc,root}> (617/484-6393)'
echo ''
saying