Date: Mon, 8 Jun 1998 13:10:18 -0700 (PDT) From: Craig Spannring <cts@internetcds.com> To: nate@mt.sri.com, phk@FreeBSD.ORG Cc: freebsd-bugs@FreeBSD.ORG Subject: Re: bin/6787: race condition in pw command Message-ID: <199806082010.NAA21530@bangkok.office.cdsnet.net> In-Reply-To: <199806011822.MAA10429@mt.sri.com> References: <199805291844.LAA07680@hub.freebsd.org> <199805300220.UAA28867@mt.sri.com> <199806011818.LAA28408@bangkok.office.cdsnet.net> <199806011822.MAA10429@mt.sri.com>
next in thread | previous in thread | raw e-mail | index | archive | help
Here are the patches for -current. I have compiled them, but I don't have a 3.0 machine available for testing so I haven't run them. Sorry. >---cut here---< diff -c -r pw-cur.original/edgroup.c pw-cur/edgroup.c *** pw-cur.original/edgroup.c Mon Jun 8 10:39:32 1998 --- pw-cur/edgroup.c Mon Jun 8 12:13:39 1998 *************** *** 64,70 **** int rc = 0; int infd; ! if ((infd = open(groupfile, O_RDWR | O_CREAT | O_EXLOCK, 0644)) != -1) { FILE *infp; if ((infp = fdopen(infd, "r+")) == NULL) --- 64,70 ---- int rc = 0; int infd; ! if ((infd = open(groupfile, O_RDWR | O_CREAT, 0644)) != -1) { FILE *infp; if ((infp = fdopen(infd, "r+")) == NULL) diff -c -r pw-cur.original/fileupd.c pw-cur/fileupd.c *** pw-cur.original/fileupd.c Mon Jun 8 10:39:32 1998 --- pw-cur/fileupd.c Mon Jun 8 12:32:27 1998 *************** *** 76,82 **** if (pfxlen <= 1) errno = EINVAL; else { ! int infd = open(filename, O_RDWR | O_CREAT | O_EXLOCK, fmode); if (infd != -1) { FILE *infp = fdopen(infd, "r+"); --- 76,82 ---- if (pfxlen <= 1) errno = EINVAL; else { ! int infd = open(filename, O_RDWR | O_CREAT, fmode); if (infd != -1) { FILE *infp = fdopen(infd, "r+"); *************** *** 168,176 **** fputs(line, infp); /* * This is a gross hack, but we may have * corrupted the original file ! * Unfortunately, it will lose the inode. */ if (fflush(infp) == EOF || ferror(infp)) rc = rename(file, filename) == 0; --- 168,187 ---- fputs(line, infp); /* + * If there was a problem with copying + * we will just rename 'file.new' + * to 'file'. * This is a gross hack, but we may have * corrupted the original file ! * Unfortunately, it will lose the inode ! * and hence the lock. ! * ! * The implications of this is that this invocation of pw ! * won't have the file locked and concurrent copies ! * of pw, vipw etc could clobber what this one is doing. ! * ! * It should probably just return an error instead ! * of going on like nothing is wrong. */ if (fflush(infp) == EOF || ferror(infp)) rc = rename(file, filename) == 0; diff -c -r pw-cur.original/pw.c pw-cur/pw.c *** pw-cur.original/pw.c Mon Jun 8 10:39:33 1998 --- pw-cur/pw.c Mon Jun 8 12:30:05 1998 *************** *** 31,36 **** --- 31,37 ---- #include "pw.h" #include <err.h> + #include <fcntl.h> #include <paths.h> #include <sys/wait.h> *************** *** 49,54 **** --- 50,56 ---- static int getindex(const char *words[], const char *word); static void cmdhelp(int mode, int which); + static int filelock(const char *filename); int *************** *** 147,153 **** * Now, let's do the common initialisation */ cnf = read_userconfig(getarg(&arglist, 'C') ? getarg(&arglist, 'C')->val : NULL); ! ch = funcs[which] (cnf, mode, &arglist); /* * If everything went ok, and we've been asked to update --- 149,168 ---- * Now, let's do the common initialisation */ cnf = read_userconfig(getarg(&arglist, 'C') ? getarg(&arglist, 'C')->val : NULL); ! ! ! /* ! * Be pessimistic and lock the master passowrd and group ! * files right away. Keep it locked for the duration. ! */ ! if (-1 == filelock(_PATH_GROUP) || -1 == filelock(_PATH_MASTERPASSWD)) ! { ! ch = EX_IOERR; ! } ! else ! { ! ch = funcs[which] (cnf, mode, &arglist); ! } /* * If everything went ok, and we've been asked to update *************** *** 175,180 **** --- 190,201 ---- } } return ch; + } + + static int + filelock(const char *filename) + { + return open(filename, O_RDONLY | O_EXLOCK, 0); } static int To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199806082010.NAA21530>