Browse code

Make BC_STARTUP run a minimal self-test.

Also change return value to something else than 0.
It is too easy for buggy bytecode to return 0.

Török Edvin authored on 2010/07/30 01:34:54
Showing 2 changed files
... ...
@@ -24,45 +24,83 @@
24 24
 #define BUILTIN_BYTECODES_H
25 25
 
26 26
 /* bytecode run on startup with interpreter to determine if JIT/bytecode should
27
- * be disabled.
27
+ * be disabled. It also runs a minimal self-check.
28 28
  * There can only be one such bytecode, if there is none this is used as
29 29
  * fallback.
30 30
  * Usually bytecode.cvd will contain this bytecode */
31 31
 
32
-static const char* builtin_bc_startup = "ClamBCafhgjmdaeld|afefdfggifnf```aa```|biacflfafmfbfcfmb`cnbacacmbacdcdcmbgfcchc`cdf`cafgc``bgbaap`clamcoincidencejb:1378\n"
32
+static const char* builtin_bc_startup = "ClamBCafhcgmjaeld|afefdfggifnf```aa```|biacflfafmfbfcfmb`cnbacacmbacdcdcmbgfcchc`cdf`cafgc``bkbaap`clamcoincidencejb:1378\n"
33 33
 "\n"
34
-"Teddaaahdabahdacahdadahdaeahdafahdagahebffebidebefebdfebcfebbfebedebafeb`feboeebadcbgab`bb`bb`bb`bb`bb`bb`bbnebnebnebnebnebnebneahahahahahahahahahebgeebneaacb`bbadb`baacb`bbheb`baadb`bbadb`bb`baadb`bbadbadb`bdbadahdbkaahdbbcahdbibahdb`eahdbddahdbodahdbdaahdbnbah\n"
35
-"Ebjdadafbje|b`adfefbfeggfoe`gbgifnfdgoecgdgbg``bhdbke|b`agfefdgoeefnffgifbgofnfmfefnfdg``bidble|bdadfifcgafbflfefoebfigdgefcfofdfefoeifff``bjdble|aodfifcgafbflfefoejfifdgoeifff``\n"
36
-"G`bha`@`b`aAa`bffBifBkeBccBdcBmeBhcBfcB`bBdfBefBdgBefBcfBdgBefBdfBlbB`bBjdBidBdeB`bBnfBefBefBdfBcgB`bB`gBefBnfBdgBifBegBmfB`bBofBbgB`bBbfBefBdgBdgBefBbg@`bidBifBccBhcBfc@`bidBifBdcBhcBfc@`befBbeBgeBheB`bBmfBafB`gB`gBifBnfBgfB`bBdfBefBnfBifBefBdfBnb@`bdfBneBceBedBldBifBnfBegBhgB`bBifBcgB`bB`gBbgBefBfgBefBnfBdgBifBnfBgfB`bBgbBefBhgBefBcfBmfBefBmfBgbB`bBafBcfBcfBefBcgBcgBnbAjBbeBegBnfB`bB`bBgbBcgBefBdgBcgBefBbfBofBofBlfB`bBmbB`eB`bBcfBlfBafBmfBdfBoeBegBcgBefBoeBjfBifBdgB`bBofBnfBgbBnb@`bcfBneB`eBafBheB`bBifBcgB`bB`gBbgBefBfgBefBnfBdgBifBnfBgfB`bBgbBmfB`gBbgBofBdgBefBcfBdgBgbB`bBafBcfBcfBefBcgBcgBnbAjBbeBegBnfB`bBgbB`gBafBhgBcfBdgBlfB`bBmbBcfBmfB`bBlcBefBhgBefBcfBegBdgBafBbfBlfBefBncBgb@`bbfBneBbeBgeBheB`bBmfBafB`gB`gBifBnfBgfB`bBdfBefBnfBifBefBdfB`bBffBofBbgB`bBegBnfBkfBnfBofBggBnfB`bBbgBefBafBcgBofBnfBnbB`eBlfBefBafBcgBefB`bBbgBefB`gBofBbgBdgB`bBdgBofB`bBhfBdgBdgB`gBjcBobBobBbfBegBgfBcgBnbBcfBlfBafBmfBafBfgBnbBnfBefBdgAj@`bed@`bafBcgBdgBafBbgBdgBegB`gBjcB`bBbfBigBdgBefBcfBofBdfBefB`bBefBhgBefBcfBegBdgBifBofBnfB`bBifBnfB`bBafBegBdgBofB`bBmfBofBdfBef@`b`fBcgBdgBafBbgBdgBegB`gBjcB`bBbfBigBdgBefBcfBofBdfBefB`bBefBhgBefBcfBegBdgBifBofBnfB`bBggBifBdgBhfB`bBifBnfBdgBefBbgB`gBbgBefBdgBefBbgB`bBofBnfBlfBig@`boeBcgBdgBafBbgBdgBegB`gBjcB`bBbfBigBdgBefBcfBofBdfBefB`bBdfBifBcgBafBbfBlfBefBdf@`bad@Ab`bad@Ac`bad@Ad`bad@Ae`bad@Af`bad@Ag`bad@Ah`bad@Ai`bad@Aj`bad@Ak`bad@Al`\n"
37
-"A`b`bLbecb`b`bgeab`b`bad`ah`aa`bad`ah`aa`bie`bad`b`b`aa`b`b`aa`b`b`b`b`bad`ah`b`b`b`b`aa`b`b`bad`ah`aa`ah`b`b`b`b`aa`b`b`b`b`aa`b`b`b`b`bad`ah`aa`bad`ah`aa`b`b`aa`b`b`b`b`aa`aa`aa`aa`aa`b`b`b`b`b`b`Fbodbia\n"
38
-"Bb`bababbbhdaaClnadbadacdbbheaaBdadahadgbacaaaeeaahad@aTaaaeb`aaa\n"
39
-"BbadafdbbheaaB`adahaggbafaaaheaahagAaaTaaahabae\n"
40
-"BbieaidbbheaaAidbadajdbbieai@db`bakkbajAn`Addaaaleab`bak@db`b`bbAad`Taaaladac\n"
41
-"Bb`bamkbajAo`Addaaaneab`bam@db`b``aanb`b`bb``Tbaad\n"
42
-"Bb`baobb`aob`bb`aabcbjdAm`@daoTbaae\n"
43
-"BbadbaadbbheaaBeadahbbagbbaab`bbca`abbab`bbdak`bcaAadaabeaeab`bbda@dTaabeaafal\n"
44
-"Bb`bbfaabcbjdB`a`@dAadbadbgadbbheaaBbadahbhagbbgaaabiaeaahbhaAjaTaabiaagb`a\n"
45
-"Bahbjagbbaab`bbka`abjab`bblak`bkaAbdaabmaeab`bbla@dTaabmaaiah\n"
46
-"Bb`bbnaabcbjdBaa`@dAadTbab`a\n"
47
-"Bb`bboak`bkaAhdaab`beab`bboa@dTaab`bakaj\n"
48
-"Bb`bbababcbjdBba`@dAadTbab`a\n"
49
-"Bb`bbbbabcbjdBca`@dAadTbab`a\n"
50
-"BbadbcbdbbheaaBbadahbdbgbbcbaabebeaahbdbAjaTaabebanam\n"
51
-"BbadbfbdbbheaaBaadahbgbgbbfbaabhbeaahbgbAfaTaabhbanb`a\n"
52
-"Bb`bbibk`bcaB`adaabjbeab`bbib@dTaabjbb`aao\n"
53
-"Bb`bbkbabcbjdBba`@dAadTbab`a\n"
54
-"Bb`bblbabcbidBda`@d@daabmbnab`bblbAadTaabmbbdabaa\n"
55
-"Baabnbnab`bblbAbdTaabnbbcabba\n"
56
-"Baabobeab`bblbAbdTaabobbgabha\n"
57
-"Baab`ceab`bblbAadTaab`cbfabha\n"
58
-"Baabaceab`bblb@dTaabacbeabha\n"
59
-"Bb`bbbcabbafBea`@dTcab`b@d\n"
60
-"Bb`bbccabbafBfa`@dTcab`b@d\n"
61
-"Bb`bbdcabbafBga`@dTcab`b@d\n"
62
-"BTcab`b@dE\n"
34
+"Teddaaahdabahdacahdadahdaeahdafahdagahebjfebidebifebhfebgfebffebedebefebdfebcfebadcbgab`bb`bb`bb`bb`bb`bb`bbbfbbfbbfbbfbbfbbfbbfahahahahahahahahahebgeebbfaaaaaaaab`baabb`bb`baacb`bbadb`baacb`bbheb`baacb`bb`bb`baadb`bbadb`bb`baadb`bbadbadb`bdbadahdbkaahdbbcahdbibahdb`eahdbddahdbodahdbdaahdbnbah\n"
35
+"Ebjdaibcdbke|bcaefnfgfifnfefoedfcfofnfffoelfeffgeflf``bbdbke|bkaefnfgfifnfefoeffegnfcfdgifofnfaflfifdgigoelfeffgeflf``agble|baadfefbfeggfoe`gbgifnfdgoeegifnfdg``bcable|afdgefcgdgbc``afbme|b`adfefbfeggfoe`gbgifnfdgoecgdgbg``bhdbne|b`agfefdgoeefnffgifbgofnfmfefnfdg``aaboe|afdgefcgdgac``bidb`f|bdadfifcgafbflfefoebfigdgefcfofdfefoeifff``bjdb`f|aodfifcgafbflfefoejfifdgoeifff``\n"
36
+"G`bha`@`b`aAa`bjfBifBkeBccBdcBmeBhcBfcB`bBdfBefBdgBefBcfBdgBefBdfBlbB`bBjdBidBdeB`bBnfBefBefBdfBcgB`bB`gBefBnfBdgBifBegBmfB`bBofBbgB`bBbfBefBdgBdgBefBbg@`bidBifBccBhcBfc@`bidBifBdcBhcBfc@`bifBbeBgeBheB`bBmfBafB`gB`gBifBnfBgfB`bBdfBefBnfBifBefBdfBnb@`bhfBneBceBedBldBifBnfBegBhgB`bBifBcgB`bB`gBbgBefBfgBefBnfBdgBifBnfBgfB`bBgbBefBhgBefBcfBmfBefBmfBgbB`bBafBcfBcfBefBcgBcgBnbAjBbeBegBnfB`bB`bBgbBcgBefBdgBcgBefBbfBofBofBlfB`bBmbB`eB`bBcfBlfBafBmfBdfBoeBegBcgBefBoeBjfBifBdgB`bBofBnfBgbBnb@`bgfBneB`eBafBheB`bBifBcgB`bB`gBbgBefBfgBefBnfBdgBifBnfBgfB`bBgbBmfB`gBbgBofBdgBefBcfBdgBgbB`bBafBcfBcfBefBcgBcgBnbAjBbeBegBnfB`bBgbB`gBafBhgBcfBdgBlfB`bBmbBcfBmfB`bBlcBefBhgBefBcfBegBdgBafBbfBlfBefBncBgb@`bffBneBbeBgeBheB`bBmfBafB`gB`gBifBnfBgfB`bBdfBefBnfBifBefBdfB`bBffBofBbgB`bBegBnfBkfBnfBofBggBnfB`bBbgBefBafBcgBofBnfBnbB`eBlfBefBafBcgBefB`bBbgBefB`gBofBbgBdgB`bBdgBofB`bBhfBdgBdgB`gBjcBobBobBbfBegBgfBcgBnbBcfBlfBafBmfBafBfgBnbBnfBefBdgAj@`bed@`befBcgBdgBafBbgBdgBegB`gBjcB`bBbfBigBdgBefBcfBofBdfBefB`bBefBhgBefBcfBegBdgBifBofBnfB`bBifBnfB`bBafBegBdgBofB`bBmfBofBdfBef@`bdfBcgBdgBafBbgBdgBegB`gBjcB`bBbfBigBdgBefBcfBofBdfBefB`bBefBhgBefBcfBegBdgBifBofBnfB`bBggBifBdgBhfB`bBifBnfBdgBefBbgB`gBbgBefBdgBefBbgB`bBofBnfBlfBig@`bcfBcgBdgBafBbgBdgBegB`gBjcB`bBbfBigBdgBefBcfBofBdfBefB`bBdfBifBcgBafBbfBlfBefBdf@`bad@Ab`bad@Ac`bad@Ad`bad@Ae`bad@Af`bad@Ag`bad@Ah`bad@Ai`bad@Aj`bad@Ak`bad@Al`\n"
37
+"A`b`bLbbhb`bab`babgeab`b`bad`ah`aa`bad`ah`aa`bie`bad`b`b`aa`b`b`aa`b`b`b`b`bad`ah`b`b`b`b`aa`b`b`bad`ah`aa`ah`b`b`b`b`aa`b`b`b`b`aa`b`b`b`b`bad`ah`aa`bad`ah`aa`b`b`aa`b`b`b`b`aa`aa`aa`aa`aa`b`b`b`b`b`b`ah`aa`bcd`b`b`aa`bcd`b`b`bcd`b`b`aa`b`b`aa`b`b`b`b`aa`bad`ah`b`b`aa`b`b`aa`bad`ah`b`b`b`b`bad`ah`b`b`b`b`bad`ah`b`b`b`b`b`b`b`b`b`b`b`b`b`b`b`b`b`b`b`b`bad`ah`b`b`b`b`bcd`b`b`b`b`b`b`bad`ah`b`b`b`b`bcd`b`b`b`b`bcd`b`b`aa`b`b`bcd`b`b`aa`b`b`bcd`b`b`aa`b`b`b`b`aa`b`b`b`b`aa`b`b`b`b`b`b`Fbakbjb\n"
38
+"Bb`bacabbbhdabClnadbadaddbbheabBdadahaegbadaaafeaahae@aTaaafb`aaa\n"
39
+"BbadagdbbheabB`adahahgbagaaaieaahahAaaTaaaiabae\n"
40
+"BbieajdbbheabAidbadakdbbieaj@db`balkbakAn`Addaaameab`bal@db`b`bbAadaaTaaamadac\n"
41
+"Bb`bankbakAo`Addaaaoeab`ban@db`baa`aaob`b`bbaaaaTbaad\n"
42
+"Bb`bb`abbaab`ab`bbaaabcbjdAm`@db`aTbaae\n"
43
+"BbadbbadbbheabBeadahbcagbbbab`bbda`abcab`bbeak`bdaAadaabfaeab`bbea@dTaabfaafal\n"
44
+"Bb`bbgaabcbjdB`a`@dAadbadbhadbbheabBbadahbiagbbhaaabjaeaahbiaAjaTaabjaagb`a\n"
45
+"Bahbkagbbbab`bbla`abkab`bbmak`blaAbdaabnaeab`bbma@dTaabnaaiah\n"
46
+"Bb`bboaabcbjdBaa`@dAadTbab`a\n"
47
+"Bb`bb`bk`blaAhdaababeab`bb`b@dTaababakaj\n"
48
+"Bb`bbbbabcbjdBba`@dAadTbab`a\n"
49
+"Bb`bbcbabcbjdBca`@dAadTbab`a\n"
50
+"BbadbdbdbbheabBbadahbebgbbdbaabfbeaahbebAjaTaabfbanam\n"
51
+"BbadbgbdbbheabBaadahbhbgbbgbaabibeaahbhbAfaTaabibanb`a\n"
52
+"Bb`bbjbk`bdaB`adaabkbeab`bbjb@dTaabkbb`aao\n"
53
+"Bb`bblbabcbjdBba`@dAadTbab`a\n"
54
+"Bb`bbmbabcbidBda`@d@daabnbnab`bbmbAadTaabnbbdabaa\n"
55
+"Baabobnab`bbmbAbdTaabobbcabba\n"
56
+"Baab`ceab`bbmbAbdTaab`cbgabha\n"
57
+"Baabaceab`bbmbAadTaabacbfabha\n"
58
+"Baabbceab`bbmb@dTaabbcbeabha\n"
59
+"Bb`bbccabbafBea`@dTbabha\n"
60
+"Bb`bbdcabbafBfa`@dTbabha\n"
61
+"Bb`bbecabbafBga`@dTbabha\n"
62
+"Bahbfcgbadaabgceaahbfc@aTaabgcbjabia\n"
63
+"BbcdbhcdbbheabAddb`bbicgbbhcaabjceab`bbic@db`b`bbEamjnmd`Taabjcbibbja\n"
64
+"BbcdbkcdbbheabAfdb`bblcgbbkcbcdbmcdbbheabAedb`bbncgbbmcaabociab`bblcbncb`b`bbEbmjnmd`Taabocbibbka\n"
65
+"Bb`bb`dab`bbdaabadeab`bbncb`db`b`bbEcmjnmd`Taabadblabib\n"
66
+"Bb`bbbdgbbkcb`bbcdab`bcdaabddeab`bbbdbcdb`b`bbEdmjnmd`Taabddbmabib\n"
67
+"BbadbeddbbheabAndahbfdgbbedb`bbgd`abfdaabhdlbb`bbid`abhdaabjdeab`bbgdbidb`b`bbEemjnmd`Taabjdbnabib\n"
68
+"BbadbkddbbheabBaadahbldgbbkdb`bbmd`abldb`bbndh`bmdBhadbadboddbbheabB`adahb`egbbodb`bbae`ab`eb`bbbeh`baeBdadbadbcedbbheabBcadahbdegbbceb`bbee`abdeb`bbfeh`beeB`adb`bbgegbbmcb`bbheh`bgeAhdb`bbiegbbkcb`bbjel`bbebndb`bbkel`bjebheb`bblel`bkebieb`bbmel`blebfeb`bbneh`bgdBladbadboedbbheabAodahb`fgbboeb`bbaf`ab`fb`bbbfh`bafBhadbcdbcfdbbheabAddb`bbdfgbbcfb`bbefl`bdfbneb`bbffl`befbbfbadbgfdbbheabBeadahbhfgbbgfb`bbif`abhfb`bbjfh`bifBhadbcdbkfdbbheabAcdb`bblfgbbkfb`bbmfl`bjfblfbcdbnfdbbheab@db`bbofgbbnfaab`geab`bbmebofTaab`gb`bboa\n"
69
+"Bb`bbagabaagbmeTcab`bEfmjnmd\n"
70
+"BbcdbbgdbbheabAadb`bbcggbbbgaabdgeab`bbffbcgTaabdgbbbbab\n"
71
+"Bb`bbegabaagbffTcab`bEgmjnmd\n"
72
+"BbcdbfgdbbheabAbdb`bbgggbbfgaabhgeab`bbmfbggTaabhgbdbbcb\n"
73
+"Bb`bbigabaagbmfTcab`bEhmjnmd\n"
74
+"Bb`bbjgabbaaHonnkm``odHm``oonnkdaabkgeab`bbjgHhgfedcbadTaabkgbfbbeb\n"
75
+"Bb`bblgabaagbjgTcab`bEimjnmd\n"
76
+"Bb`bbmgababcaDm``odaabngeab`bbmgDo``mdTaabngbhbbgb\n"
77
+"Bb`bbogabaagbmgTcab`bF`amjnmd\n"
78
+"Bb`bb`hoabhdFaamjnmdHnejkjgjmdTcab`bb`h\n"
79
+"Bb`bbahbb`bahTcab`bbahE\n"
63 80
 ;
64 81
 /* source-code for builtin_bc_startup: */
65 82
 #if 0
83
+/*
84
+ *  ClamAV bytecode startup checks and self-check.
85
+ *
86
+ *  Copyright (C) 2010 Sourcefire, Inc.
87
+ *
88
+ *  Authors: Török Edvin
89
+ *
90
+ *  This program is free software; you can redistribute it and/or modify
91
+ *  it under the terms of the GNU General Public License version 2 as
92
+ *  published by the Free Software Foundation.
93
+ *
94
+ *  This program is distributed in the hope that it will be useful,
95
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
96
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
97
+ *  GNU General Public License for more details.
98
+ *
99
+ *  You should have received a copy of the GNU General Public License
100
+ *  along with this program; if not, write to the Free Software
101
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
102
+ *  MA 02110-1301, USA.
103
+ */
66 104
 const uint16_t __clambc_kind = BC_STARTUP;
67 105
 int entrypoint()
68 106
 {
... ...
@@ -125,7 +163,77 @@ int entrypoint()
125 125
     debug("startup: bytecode disabled");
126 126
     break;
127 127
   }
128
-  return 0;
128
+
129
+  /* check that the OS information is consistent */
130
+  /* JIT == C++ code compiled */
131
+  if (env.has_jit_compiled && !env.cpp_version) {
132
+    return 0xdead1;
133
+  }
134
+  if (env.dconf_level < env.functionality_level) {
135
+    return 0xdead2;
136
+  }
137
+  if (env.functionality_level != engine_functionality_level()) {
138
+    return 0xdead3;
139
+  }
140
+  if (env.dconf_level != engine_dconf_level()) {
141
+    return 0xdead4;
142
+  }
143
+  if (env.big_endian != __is_bigendian()) {
144
+    return 0xdead5;
145
+  }
146
+
147
+  uint32_t a = (env.os_category << 24) | (env.arch << 20) |
148
+    (env.compiler <<  16) | (env.functionality_level << 8) |
149
+    (env.dconf_level);
150
+  uint32_t b = (env.big_endian << 28) | (env.sizeof_ptr << 24) |
151
+    env.cpp_version;
152
+  uint32_t c = (env.os_features << 24) | env.c_version;
153
+  if (a != env.platform_id_a) {
154
+    debug_print_uint(a);
155
+    return 0xdead6;
156
+  }
157
+  if (b != env.platform_id_b) {
158
+    debug_print_uint(b);
159
+    return 0xdead7;
160
+  }
161
+  if (c != env.platform_id_c) {
162
+    debug_print_uint(c);
163
+    return 0xdead8;
164
+  }
165
+  c = test1(0xf00dbeef, 0xbeeff00d);
166
+  if (c != 0x12345678) {
167
+    debug_print_uint(c);
168
+    return 0xdead9;
169
+  }
170
+  c = test2(0xf00d);
171
+  if (c != 0xd00f) {
172
+    debug_print_uint(c);
173
+    return 0xdead10;
174
+  }
175
+
176
+  /* check endianness and bswap */
177
+  char buf[16] = {
178
+    0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
179
+  };
180
+  char buf2[16];
181
+  uint32_t x;
182
+  memset(&buf2, 0, sizeof(buf2));
183
+  if (cli_readint16(&buf) != 0x100)
184
+    return 0xdead11;
185
+  x = cli_readint32(&buf);
186
+  if (x != 0x03020100)
187
+    return 0xdead12;
188
+  x = __builtin_bswap32(x);
189
+  if (x != 0x00010203)
190
+    return 0xdead13;
191
+  cli_writeint32(&buf2, 0x12345678);
192
+  if (cli_readint32(&buf2) != 0x12345678)
193
+    return 0xdead14;
194
+  if (buf2[0] != 0x78)
195
+    return 0xdead15;
196
+
197
+  /* magic number to tell libclamav that selftest succeeded */
198
+  return 0xda7aba5e;
129 199
 }
130 200
 
131 201
 
... ...
@@ -2297,8 +2297,10 @@ int cli_bytecode_prepare(struct cl_engine *engine, struct cli_all_bc *bcs, unsig
2297 2297
     } else {
2298 2298
 	cli_dbgmsg("Bytecode: disable status is %d\n", ctx->bytecode_disable_status);
2299 2299
 	rc = cli_bytecode_context_getresult_int(ctx);
2300
-	if (rc) {
2301
-	    cli_warnmsg("Bytecode: selftest failed with code %d. Please report to http://bugs.clamav.net\n",
2300
+	/* check magic number, don't use 0 here because it is too easy for a
2301
+	 * buggy bytecode to return 0 */
2302
+	if (rc != 0xda7aba5e) {
2303
+	    cli_warnmsg("Bytecode: selftest failed with code %08x. Please report to http://bugs.clamav.net\n",
2302 2304
 			rc);
2303 2305
 	    if (engine->bytecode_mode == CL_BYTECODE_MODE_TEST)
2304 2306
 		return CL_EBYTECODE_TESTFAIL;