sed -i option TOCTTOU problem

Issue #255 resolved
Takehiko NOZAKI repo owner created an issue

here is FreeBSD HEAD usr.bin/sed/main.c:

406                 if (inplace != NULL) {
407                         if (lstat(fname, &sb) != 0)
408                                 err(1, "%s", fname);
409                         if (!S_ISREG(sb.st_mode))
410                                 errx(1, "%s: %s %s", fname,
411                                     "in-place editing only",
412                                     "works for regular files");
413                         if (*inplace != '\0') {
414                                 strlcpy(oldfname, fname,
415                                     sizeof(oldfname));
416                                 len = strlcat(oldfname, inplace,
417                                     sizeof(oldfname));
418                                 if (len > (ssize_t)sizeof(oldfname))
419                                         errx(1, "%s: name too long", fname);
420                         }
421                         if ((dirbuf = strdup(fname)) == NULL ||
422                             (basebuf = strdup(fname)) == NULL)
423                                 err(1, "strdup");
424                         len = snprintf(tmpfname, sizeof(tmpfname),
425                             "%s/.!%ld!%s", dirname(dirbuf), (long)getpid(),
426                             basename(basebuf));
427                         free(dirbuf);
428                         free(basebuf);
429                         if (len >= (ssize_t)sizeof(tmpfname))
430                                 errx(1, "%s: name too long", fname);
431                         unlink(tmpfname);
432                         if (outfile != NULL && outfile != stdout)
433                                 fclose(outfile);
434                         if ((outfile = fopen(tmpfname, "w")) == NULL)
435                                 err(1, "%s", fname);
436                         fchown(fileno(outfile), sb.st_uid, sb.st_gid);
437                         fchmod(fileno(outfile), sb.st_mode & ALLPERMS);
438                         outfname = tmpfname;
439                         if (!ispan) {
440                                 linenum = 0;
441                                 resetstate();
442                         }
443                 } else {
444                         outfile = stdout;
445                         outfname = "stdout";
446                 }

line from 431 to 434 is not atomic, use mkstemp(3) instead.

N**BSD has same problem, OpenBSD is OK

Comments (2)

  1. Log in to comment