trt (05/15/82)
A patch such as chmod(f, 0600) does *not* make a file secure. fopen(f, "w"); /* f can be opened here */ chmod(f, 0600); The window is admittedly small, but it does exist. Umask(II) is usually the appropriate cure: oldmask = umask(077); os = fopen(f, "w"); umask(oldmask); ... But because /tmp is generally writable the above fails anyway! A villain can guess the name of the file that will be opened (usually an easy task) and pre-creat(II)e it. Generally writable files are especially hazardous for set-uid programs, as mentioned in an ancient James Ellis/Tom Truscott article. Here is a safer version of sort.c/newfile: newfile() { struct stat statbuf; register int oldmask; register char *f; f = setfil(nfiles); do { oldmask = umask(077); os = fopen(f, "w"); umask(oldmask); if (os == NULL) { diag("can't create ", f); term(); } if (fstat(fileno(os), &statbuf)) { diag("can't stat!! ", f); term(); } } while (statbuf.st_uid != geteuid()); nfiles++; } The fstat(II) ensures that no other uid pre-created the file. Unfortunately, sort(I) must later read f, which can be foiled by deleting f or replacing it with a bogus file. Generally writable files are almost always insecure. Don't use them. Tom Truscott (duke!trt)