Hi, there is a race condition in gzsig. It needs some fancy vector to step in, but better safe than sorry (especially if the fix is pretty cheap).
The race happens between opening the input file and applying the access rights to the temporary one. If an attacker is able to replace the input file between opening it and stat()ing it, he could manipulate the caller of gzsig to change the rights of the result file. Someone agrees? OK? ;) Tobias Index: sign.c =================================================================== RCS file: /cvs/src/usr.bin/gzsig/sign.c,v retrieving revision 1.9 diff -u -p -r1.9 sign.c --- sign.c 12 Oct 2007 19:52:06 -0000 1.9 +++ sign.c 9 Mar 2013 16:49:17 -0000 @@ -285,7 +285,7 @@ sign(int argc, char *argv[]) close(fd); continue; } - if (copy_permissions(gzipfile, tmppath) < 0) { + if (copy_permissions(fileno(fin), fd) < 0) { fprintf(stderr, "Error initializing %s: %s\n", tmppath, strerror(errno)); fclose(fin); Index: util.c =================================================================== RCS file: /cvs/src/usr.bin/gzsig/util.c,v retrieving revision 1.2 diff -u -p -r1.2 util.c --- util.c 28 May 2005 08:07:45 -0000 1.2 +++ util.c 9 Mar 2013 16:49:17 -0000 @@ -46,17 +46,17 @@ #include "util.h" int -copy_permissions(char *srcfile, char *dstfile) +copy_permissions(int srcfd, int dstfd) { struct stat st; - if (stat(srcfile, &st) < 0) + if (fstat(srcfd, &st) < 0) return (-1); - if (chmod(dstfile, st.st_mode) < 0) + if (fchmod(dstfd, st.st_mode) < 0) return (-1); - if (chown(dstfile, st.st_uid, st.st_gid) < 0) + if (fchown(dstfd, st.st_uid, st.st_gid) < 0) return (-1); return (0); Index: util.h =================================================================== RCS file: /cvs/src/usr.bin/gzsig/util.h,v retrieving revision 1.2 diff -u -p -r1.2 util.h --- util.h 28 May 2005 08:07:45 -0000 1.2 +++ util.h 9 Mar 2013 16:49:17 -0000 @@ -1,3 +1,4 @@ +/* $OpenBSD$ */ /* * util.h * @@ -33,7 +34,7 @@ #ifndef UTIL_H -int copy_permissions(char *srcfile, char *dstfile); +int copy_permissions(int srcfd, int dstfd); void fatal(int status, const char *fmt, ...); #endif /* UTIL_H */