mcooper@usc.edu (Michael A. Cooper) (04/29/89)
Description: 1 The "setmodes" command in interactive mode will not set modes if a directory already exists. If you are recovering from a bad dump image or restore blowing up, you sometimes need to override this feature. 2 When restoring from a dump image with missing directory inodes (such as when you have a dying disk), a non existent inode in the modes map will cause a panic. The user is prompted whether they want to abort the restore or not. If they continue on, a NULL deref occurs and restore dies on systems where this is illegal. Repeat-By: 1 Do an interactive restore, "add" a directory, and then quit. Start up another interactive restore, "add" the same directory", and run "setmodes". No modes are set. 2 Do a dump of a filesystem that you can't ready some blocks on that happen to have directory inodes on them. Run a restore and watch it blow up. Fix: Apply these patches: *** /tmp/,RCSt1a10337 Fri Apr 28 17:24:45 1989 --- /tmp/,RCSt2a10337 Fri Apr 28 17:24:46 1989 *************** *** 483,488 struct modeinfo node; struct entry *ep; char *cp; vprintf(stdout, "Set directory mode, owner, and times.\n"); (void) sprintf(modefile, "/tmp/rstmode%d", dumpdate); --- 502,508 ----- struct modeinfo node; struct entry *ep; char *cp; + int override = -1; vprintf(stdout, "Set directory mode, owner, and times.\n"); (void) sprintf(modefile, "/tmp/rstmode%d", dumpdate); *************** *** 503,510 if (ep == NIL) continue; if (ep->e_flags & EXISTED) { ! ep->e_flags &= ~NEW; ! continue; } if (node.ino == ROOTINO && reply("set owner/mode for '.'") == FAIL) --- 523,539 ----- if (ep == NIL) continue; if (ep->e_flags & EXISTED) { ! if (override < 0) { ! if (reply("Directories already exist, set modes anyway") == FAIL) { ! override = 0; ! } else { ! override = 1; ! } ! } ! if (override == 0) { ! ep->e_flags &= ~NEW; ! continue; ! } } if (node.ino == ROOTINO && reply("set owner/mode for '.'") == FAIL) *************** *** 510,516 reply("set owner/mode for '.'") == FAIL) continue; } ! if (ep == NIL) panic("cannot find directory inode %d\n", node.ino); cp = myname(ep); (void) chown(cp, node.uid, node.gid); --- 539,545 ----- reply("set owner/mode for '.'") == FAIL) continue; } ! if (ep == NIL) { panic("cannot find directory inode %d\n", node.ino); continue; } *************** *** 512,517 } if (ep == NIL) panic("cannot find directory inode %d\n", node.ino); cp = myname(ep); (void) chown(cp, node.uid, node.gid); (void) chmod(cp, node.mode); --- 541,548 ----- } if (ep == NIL) { panic("cannot find directory inode %d\n", node.ino); + continue; + } cp = myname(ep); (void) chown(cp, node.uid, node.gid); (void) chmod(cp, node.mode); -- Michael A. Cooper, University Computing Services, U of Southern California INTERNET: mcooper@usc.edu PHONE: (213) 743-2957 UUCP: ...!uunet!usc!mcooper BITNET: mcooper@gamera