> ==> The vast majority of users are not having the problem, so there
> must be some thing(s) unique about the installations that are having
> the problem. One difference between your installation and mine is
> that I am running Berkeley DB 3.29, and you are running 3.3.1.1.

Memory usage can vary wildly between different machines, but on a given
machine,
where most programs are always loaded and always loaded in a particular
order,
the usage pattern can be wierdly consistent from run to run. A similar
phenomenon
exists when people can't compile their kernel because of an "access
violation"
(error 11) during the compile process. This problem has been well
documented as
being due to faulty memory in the affected computers. I experienced this
myself
on an older Pentium I was trying to press into service as a Linux router.
The
kernel recompile always stopped at about the same place with the access
viola-
tion crash. Replacing the memory chips fixed the problem.

Similarly, in this case, the unallocated memory is being written on (most
likely)
by the squidGuard program itself. The particulars of how this happens will
vary
depending on the machine's software configuration, how much memory it has,
and
how the SG program was built. In all cases the unallocated memory is
written
on, but sometimes it doesn't effect the operation of the program visibly;
in
other cases, it does.

>> ==> Continuing with the fact that you are running Berkeley DB 3.3.1.1.
>> This user page <http://www.maynidea.com/squidguard/faq-plus.html> says
>> "In spite of what the documentation says, Squidguard 1.20 requires
>> version 3.29 of the Berkely db." and "With 3.3.x, it craps out every
>> time."

> Maybe you're right. But I still continue to think that's not a bug
> related to the database (because, it can't open the file xxx.diff). I
> think opening a file and doing things in the database are two different
> operations. In that case, it stops because it cannot find the file (the
> database shouldn't be open at this moment).

I completely agree.

> As both of us doesn't know C code, I hope someone could inspect that
> small part of squidGuard's source code and see what I've done good/wrong
> when modifying this.

> I really cannot explain more about this (and why it works when I change
> theses values). But, what I know is that it is working now (it wasn't
> before I modify the code).

> Hope someone will enlighten both of us about this very weird bug.

Here's an attempt at some enlightenment:

When a program needs a block of memory, it has to tell the system memory
manager how much memory it needs so it can find a block that big some-
where in the system. The details of what it may have to do to find such
a block are really yucchy. But the assumption is that once you get the
pointer to the block back, you will not use memory outside of the block.
Gilles found a place where the SquidGuard program violates that assump-
tion.
A pointer is really just another name for an address. The sgMalloc call
gets the address of a block of memory of the specified size. In this
case, the program wanted a block just big enough to store a particular
filename + extension in. But it did not ask for a big enough block, and
then it used a byte that didn't "belong" to it.
Part of the "power" of C/C++ is being able to do dangerous things. If the
programmer doesn't make mistakes, the result is the ultimate in power and
efficiency. If the programmer practices unsafe coding practices, then the
result is buggy code with mistakes like the one mentioned.

For instance, a better way to code the lines:
        update = (char *) sgMalloc(strlen(file) + 5);
        strcpy(update,file);
        strcat(update, DIFF_SUFFIX);
would be to say
        const char DIFF_SUFFIX[] = ".diff";
        #define lengthof(x) sizeof(x)/sizeof(x[0])
        .....
        update = (char *) sgMalloc(strlen(file) + lengthof(DIFF_SUFFIX));
        strcpy(update,file);
        strcat(update, DIFF_SUFFIX);
        ...
(I just tried this in sgDB.c and it worked).

One of the nice things about C++ is that it can hide a lot of the tedium
of making sure that these mistakes don't happen. For instance, in C++ the
same code could be:
        const char DIFF_SUFFIX[] = ".diff";
        string file = <blah blah blah>;
        file = file + DIFF_SUFFIX;
The "string" thingy is something called a "class"; the "string class"
knows how to do "<char string> + <char string>" in a safe way that's been
tested by hundreds of thousands of users, so you don't have to worry about
screwing up a malloc call.
---------------------------------------------------------------

Attachment: smime.p7s
Description: application/pkcs7-signature

Reply via email to