Hello, everyone.

Sorry for digging up this old bug, but I was it by it in the current
stable.
I confirm Jaroslav's finding - this SEGV reproduces with an empty "spam"
list with the following backtrace:

#0  word_cmp (w1=0x55e6bad0b050, w2=0x0) at ../../src/word.c:40
#1  0x000055e6b8ac24e5 in listsort (list=0x55e6bace5900, 
compare=compare@entry=0x55e6b8abc690 <compare_rstats_t>)
    at ../../src/listsort.c:114
#2  0x000055e6b8abc853 in rstats_print (unsure=<optimized out>) at 
../../src/rstats.c:142
#3  0x000055e6b8abd0dd in msg_print_stats (fp=<optimized out>) at 
../../src/score.c:104
#4  0x000055e6b8ab0575 in print_stats (fp=<optimized out>) at 
../../src/bogofilter.c:67
#5  0x000055e6b8abae76 in write_spam_info () at ../../src/passthrough.c:99
#6  0x000055e6b8abb384 in write_header (rf=<optimized out>, rfarg=<synthetic 
pointer>, status=RC_UNSURE)
    at ../../src/passthrough.c:179
#7  write_message (status=status@entry=RC_UNSURE) at ../../src/passthrough.c:239
#8  0x000055e6b8ab0789 in bogofilter (argc=argc@entry=0, argv=<optimized out>) 
at ../../src/bogofilter.c:132
#9  0x000055e6b8ab28b9 in bogomain (argc=<optimized out>, argv=0x7ffcebb92f88) 
at ../../src/bogomain.c:67
#10 0x000055e6b8ab0436 in main (argc=5, argv=0x7ffcebb92f88) at
../../src/main.c:31

Which can be explained by a classic NULL pointer dereference at word_cmp
here:

 int word_cmp(const word_t *w1, const word_t *w2)
 {
     uint l = min(w1->leng, w2->leng);
     int r = memcmp((const char *)w1->u.text, (const char *)w2->u.text, l);


Either w1 or w2 can be NULL with empty "spam"/"ham" list, and this kind
of problem should never reproduce if both lists contain something.

Attached patch solves the issue for me.

Sincerely yours, Reco
--- a/src/word.c	2018-10-05 07:12:10.281153971 +0000
+++ b/src/word.c	2018-10-05 07:12:03.937217631 +0000
@@ -37,6 +37,10 @@
 
 int word_cmp(const word_t *w1, const word_t *w2)
 {
+    if (! w1 && ! w2) return 0;
+    if (! w1 && w2) return -1;
+    if (w1 && ! w2) return 1;
+
     uint l = min(w1->leng, w2->leng);
     int r = memcmp((const char *)w1->u.text, (const char *)w2->u.text, l);
     if (r) return r;

Reply via email to