tech-userlevel archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

alignement or compiler bug?



Hello

I tacked down a weird bug in libperfuse. Here is the offending code:

                struct fuse_write_in *fwi;
        (...)
                size_t max_write;
        (...)
        max_write = ps->ps_max_write - sizeof(*fwi);

                data_len = MIN(*resid, max_write);
                if (data_len > PAGE_SIZE)
                        data_len = data_len & ~(PAGE_SIZE - 1);
        (...)
        (void)memcpy(fwi + 1, buf + written, data_len);

This code wil rarely crash in memcpy(). gdb shows an unexpectely huge
data_len, bigger than max_write. My explanation this that memcpy overwrite
data_len becaue (fwi +1) did not hold the expected value.

Adding an intermediate variable and a test on it makes the problem vanish:

                char *data;
                (...)
                /*
                 * If (fwi + 1) is directly used as a memcpy argument,
                 * we get a rare strange sigsegv, with data_len corrupted
                 * by the memcpy() operation itself.
                 */
                data = (char *)(void *)(fwi + 1);
                if (data != ((char *)fwi) + sizeof(*fwi))
                        DERRX(EX_SOFTWARE, "%s:%d\n", __func__, __LINE__);

                (void)memcpy(data, buf + written, data_len);

Is there a subttle memory alignement problem I missed, or can we call that a
compiler bug?

-- 
Emmanuel Dreyfus
http://hcpnet.free.fr/pubz
manu%netbsd.org@localhost


Home | Main Index | Thread Index | Old Index