On 10/09/2013 02:45 PM, Thomas Preud'homme wrote:
>> I've deleted "/var/spool/dspam/data" and let dspam deliver a mail, that
>> produces this backtrace:
>>
>> #0  0xb6f118ec in raise () from /lib/arm-linux-gnueabi/libpthread.so.0
>> No symbol table info available.
>> #1  0xb6a5acf4 in __aeabi_ldiv0 () from
>> /usr/lib/arm-linux-gnueabi/dspam/libhash_drv.so No symbol table info
>> available.
>> #2  0xb6a59b9c in _hash_drv_seek (map=map@entry=0xb57073d8,
>> offset=offset@entry=16147856, hashcode=<optimized out>,
>> flags=flags@entry=1) at hash_drv.c:1194 header = <optimized out>
>>         rec = <optimized out>
>>         fpos = <optimized out>
>>         iterations = 0
> 
> Ok, this bug was very likely introduced with the patch I made to handle 
> corrupted css file. Unfortunetely I don't have the time to fix the patch now. 

Yes the bug was introduced between 3.10.2+dfsg-9 and 3.10.2+dfsg-10. As
I'm running -9 without problems.

Although the incremental diff from -9 to -10 doesn't look suspicious at
the first glance:

> diff --git a/src/hash_drv.c b/src/hash_drv.c
> index 349b491..daae2e7 100644
> --- a/src/hash_drv.c
> +++ b/src/hash_drv.c
> @@ -1187,32 +1187,36 @@ unsigned long _hash_drv_seek(
>    unsigned long fpos;
>    unsigned long iterations = 0;
> 
>    if (offset >= map->file_len)
>      return 0;
> 
>    fpos = sizeof(struct _hash_drv_header) +
>      ((hashcode % header->hash_rec_max) * sizeof(struct 
> _hash_drv_spam_record));
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

According to the backtrace's line number the diff-by-zero should happen
here. But the modulo, which is IIRC implemented on ARM as
divide/multiply/difference, was here all the time.

Was there a compiler change? Maybe some new optimisations brakes the code.

>    rec = (void *)((unsigned long) map->addr + offset + fpos);
> -  while(rec->hashcode != hashcode  &&   /* Match token     */
> -        rec->hashcode != 0         &&   /* Insert on empty */
> -        iterations < map->max_seek)     /* Max Iterations  */
> +  while(rec + sizeof(*rec) <= map->file_len &&  /* not end of file */
> +        rec->hashcode != hashcode  &&           /* Match token     */
> +        rec->hashcode != 0         &&           /* Insert on empty */
> +        iterations < map->max_seek)             /* Max Iterations  */
>    {
>      iterations++;
>      fpos += sizeof(struct _hash_drv_spam_record);
> 
>      if (fpos >= (header->hash_rec_max * sizeof(struct 
> _hash_drv_spam_record)))
>        fpos = sizeof(struct _hash_drv_header);
>      rec = (void *)((unsigned long) map->addr + offset + fpos);
>    }
> 
> +  if (rec + sizeof(*rec) > map->file_len)
> +    return 0;
> +
>    if (rec->hashcode == hashcode)
>      return fpos;
> 
>    if (rec->hashcode == 0 && (flags & HSEEK_INSERT))
>      return fpos;
> 
>    return 0;
>  }

> I'm very busy for a few weeks but I'll try to take a look at it as soon as 
> possible.

Thanks,
Marc

Attachment: signature.asc
Description: OpenPGP digital signature

Reply via email to