bogoutil and realpath
David Relson
relson at osagesoftware.com
Fri Apr 22 00:52:50 CEST 2005
On Fri, 22 Apr 2005 00:45:04 +0200
Matthias Andree wrote:
> Matthias Andree <matthias.andree at gmx.de> writes:
>
> >> By the way, have you read the manpage of realpath? It says "do not
> >> use" :0
> >
> > The GNU libc manual pages in their usual vituperating politcal agenda. I
> > don't care, realpath() isn't going away anywhen soon, it's in POSIX 2004
> > and is not marked "legacy".
>
> Well, it seems GNU has a reason to bitch - their HURD has no PATH_MAX
> since that value is dynamic.
>
> So we'll stat and compare st_dev and st_ino - these are unique on a
> machine and specific for a directory entry.
>
> How about this patch?
> (I'm not committing this now to avoid conflicting changes.)
>
> BTW, this has an implicit TOCTOU race as it checks earlier than it's
> used but if someone feels like hacking symlinks for BOGOHOME underneath
> a running bogofilter, their business if they suffer holes in their feet.
>
> Really bedtime now.
>
> Index: src/datastore_db.c
> ===================================================================
> RCS file: /cvsroot/bogofilter/bogofilter/src/datastore_db.c,v
> retrieving revision 1.202
> diff -u -p -r1.202 datastore_db.c
> --- a/src/datastore_db.c 11 Apr 2005 19:06:33 -0000 1.202
> +++ b/src/datastore_db.c 21 Apr 2005 22:42:17 -0000
> @@ -276,18 +276,6 @@ static void handle_free(/*@only@*/ dbh_t
> return;
> }
>
> -static bool checkpath(const char *path, char *norm)
> -{
> - if (realpath(path, norm) != NULL)
> - return true;
> - else {
> - print_error(__FILE__, __LINE__,
> - "error: cannot normalize path \"%s\": %s",
> - path, strerror(errno));
> - return false;
> - }
> -}
> -
> /** Initialize data base, configure some lock table sizes
> * (which can be overridden in the DB_CONFIG file)
> * and lock the file to tell other parts we're initialized and
> @@ -295,16 +283,23 @@ static bool checkpath(const char *path,
> */
> void *dbe_init(bfpath *bfp)
> {
> - char norm_dir[PATH_MAX+1]; /* check normalized directory names */
> - char norm_home[PATH_MAX+1];/* see man realpath(3) for details */
> -
> + struct stat std, sth;
> dbe_t *env;
>
> - if ( !checkpath(bfp->dirname, norm_dir) ||
> - !checkpath(bogohome, norm_home))
> + if (stat(bfp->dirname, &std)) {
> + fprintf(stderr, "ERROR: cannot stat \"%s\": %s, aborting.\n",
> + bfp->dirname, strerror(errno));
> + exit(EX_ERROR);
> + }
> +
> + if (stat(bogohome, &sth)) {
> + fprintf(stderr, "ERROR: cannot stat \"%s\": %s, aborting.\n",
> + bfp->dirname, strerror(errno));
> exit(EX_ERROR);
> + }
>
> - if (strcmp(norm_dir, norm_home) != 0)
> + if (std.st_dev != sth.st_dev
> + || sth.st_ino != sth.st_ino)
> {
> fprintf(stderr,
> "ERROR: only one database _environment_ (directory) can be used at a time.\n"
> @@ -312,8 +307,7 @@ void *dbe_init(bfpath *bfp)
> fprintf(stderr,
> "If you need multiple wordlists in different directories,\n"
> "you cannot use the transactional interface, but you must configure\n"
> - "the non-transactional interface, i. e. ./configure --disable-transactions\n"
> - "then type make clean, after that rebuild and install as usual.\n"
> + "the non-transactional interface.\n"
> "Note that the data base will no longer be crash-proof in that case.\n"
> "Please accept our apologies for the inconvenience.\n");
> fprintf(stderr,
> @@ -322,7 +316,7 @@ void *dbe_init(bfpath *bfp)
> }
>
> dsm_init(bfp);
> -
> +
> env = dsm->dsm_env_init(bfp);
>
> return env;
Let's keep dbe_init() short and simple and put all the path checking
stuff into check_path(). I'm done with the changes I have. Feel free
to test to add yours in now (or in the morning). If things go well, I
can do a release Saturday.
Cheers!
More information about the bogofilter-dev
mailing list