diff --git a/libclamav/Makefile.am b/libclamav/Makefile.am index 6252c2537..99f2375de 100644 --- a/libclamav/Makefile.am +++ b/libclamav/Makefile.am @@ -357,7 +357,8 @@ libclamav_la_SOURCES = \ cache.c \ cache.h \ bytecode_detect.c \ - bytecode_detect.h + bytecode_detect.h\ + builtin_bytecodes.h if !LINK_TOMMATH libclamav_la_SOURCES += bignum.c \ diff --git a/libclamav/Makefile.in b/libclamav/Makefile.in index 4fc964074..7e105da52 100644 --- a/libclamav/Makefile.in +++ b/libclamav/Makefile.in @@ -157,8 +157,8 @@ am__libclamav_la_SOURCES_DIST = clamav.h matcher-ac.c matcher-ac.h \ clambc.h cpio.c cpio.h macho.c macho.h ishield.c ishield.h \ type_desc.h bcfeatures.h bytecode_api.c bytecode_api_decl.c \ bytecode_api.h bytecode_api_impl.h bytecode_hooks.h cache.c \ - cache.h bytecode_detect.c bytecode_detect.h bignum.c \ - bignum_class.h sha1.c sha1.h + cache.h bytecode_detect.c bytecode_detect.h \ + builtin_bytecodes.h bignum.c bignum_class.h sha1.c sha1.h @LINK_TOMMATH_FALSE@am__objects_1 = libclamav_la-bignum.lo @BUILD_SHA1_TRUE@am__objects_2 = libclamav_la-sha1.lo am_libclamav_la_OBJECTS = libclamav_la-matcher-ac.lo \ @@ -661,8 +661,8 @@ libclamav_la_SOURCES = clamav.h matcher-ac.c matcher-ac.h matcher-bm.c \ clambc.h cpio.c cpio.h macho.c macho.h ishield.c ishield.h \ type_desc.h bcfeatures.h bytecode_api.c bytecode_api_decl.c \ bytecode_api.h bytecode_api_impl.h bytecode_hooks.h cache.c \ - cache.h bytecode_detect.c bytecode_detect.h $(am__append_7) \ - $(am__append_8) + cache.h bytecode_detect.c bytecode_detect.h \ + builtin_bytecodes.h $(am__append_7) $(am__append_8) noinst_LTLIBRARIES = libclamav_internal_utils.la libclamav_internal_utils_nothreads.la libclamav_nocxx.la COMMON_CLEANFILES = version.h version.h.tmp *.gcda *.gcno @MAINTAINER_MODE_TRUE@BUILT_SOURCES = jsparse/generated/operators.h jsparse/generated/keywords.h jsparse-keywords.gperf diff --git a/libclamav/builtin_bytecodes.h b/libclamav/builtin_bytecodes.h new file mode 100644 index 000000000..44e75e658 --- /dev/null +++ b/libclamav/builtin_bytecodes.h @@ -0,0 +1,133 @@ +/* + * Builtin ClamAV bytecodes. + * + * Copyright (C) 2010 Sourcefire, Inc. + * + * Authors: Török Edvin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#ifndef BUILTIN_BYTECODES_H +#define BUILTIN_BYTECODES_H + +/* bytecode run on startup with interpreter to determine if JIT/bytecode should + * be disabled. + * There can only be one such bytecode, if there is none this is used as + * fallback. + * Usually bytecode.cvd will contain this bytecode */ + +static const char* builtin_bc_startup = "ClamBCafhgjmdaeld|afefdfggifnf```aa```|biacflfafmfbfcfmb`cnbacacmbacdcdcmbgfcchc`cdf`cafgc``bgbaap`clamcoincidencejb:1378\n" +"\n" +"Teddaaahdabahdacahdadahdaeahdafahdagahebffebidebefebdfebcfebbfebedebafeb`feboeebadcbgab`bb`bb`bb`bb`bb`bb`bbnebnebnebnebnebnebneahahahahahahahahahebgeebneaacb`bbadb`baacb`bbheb`baadb`bbadb`bb`baadb`bbadbadb`bdbadahdbkaahdbbcahdbibahdb`eahdbddahdbodahdbdaahdbnbah\n" +"Ebjdadafbje|b`adfefbfeggfoe`gbgifnfdgoecgdgbg``bhdbke|b`agfefdgoeefnffgifbgofnfmfefnfdg``bidble|bdadfifcgafbflfefoebfigdgefcfofdfefoeifff``bjdble|aodfifcgafbflfefoejfifdgoeifff``\n" +"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" +"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" +"Bb`bababbbhdaaClnadbadacdbbheaaBdadahadgbacaaaeeaahad@aTaaaeb`aaa\n" +"BbadafdbbheaaB`adahaggbafaaaheaahagAaaTaaahabae\n" +"BbieaidbbheaaAidbadajdbbieai@db`bakkbajAn`Addaaaleab`bak@db`b`bbAad`Taaaladac\n" +"Bb`bamkbajAo`Addaaaneab`bam@db`b``aanb`b`bb``Tbaad\n" +"Bb`baobb`aob`bb`aabcbjdAm`@daoTbaae\n" +"BbadbaadbbheaaBeadahbbagbbaab`bbca`abbab`bbdak`bcaAadaabeaeab`bbda@dTaabeaafal\n" +"Bb`bbfaabcbjdB`a`@dAadbadbgadbbheaaBbadahbhagbbgaaabiaeaahbhaAjaTaabiaagb`a\n" +"Bahbjagbbaab`bbka`abjab`bblak`bkaAbdaabmaeab`bbla@dTaabmaaiah\n" +"Bb`bbnaabcbjdBaa`@dAadTbab`a\n" +"Bb`bboak`bkaAhdaab`beab`bboa@dTaab`bakaj\n" +"Bb`bbababcbjdBba`@dAadTbab`a\n" +"Bb`bbbbabcbjdBca`@dAadTbab`a\n" +"BbadbcbdbbheaaBbadahbdbgbbcbaabebeaahbdbAjaTaabebanam\n" +"BbadbfbdbbheaaBaadahbgbgbbfbaabhbeaahbgbAfaTaabhbanb`a\n" +"Bb`bbibk`bcaB`adaabjbeab`bbib@dTaabjbb`aao\n" +"Bb`bbkbabcbjdBba`@dAadTbab`a\n" +"Bb`bblbabcbidBda`@d@daabmbnab`bblbAadTaabmbbdabaa\n" +"Baabnbnab`bblbAbdTaabnbbcabba\n" +"Baabobeab`bblbAbdTaabobbgabha\n" +"Baab`ceab`bblbAadTaab`cbfabha\n" +"Baabaceab`bblb@dTaabacbeabha\n" +"Bb`bbbcabbafBea`@dTcab`b@d\n" +"Bb`bbccabbafBfa`@dTcab`b@d\n" +"Bb`bbdcabbafBga`@dTcab`b@d\n" +"BTcab`b@dE\n" +; +/* source-code for builtin_bc_startup: */ +#if 0 +const uint16_t __clambc_kind = BC_STARTUP; +int entrypoint() +{ + // Whole platform specific bugs can be disabled with check_platform, + // see clamscan --debug for meaning of bits. + // For example: + //disable_jit_if("Pax mprotect on, with RWX", 0, + // check_platform(0x0affffff, 0xffffffff, 0x19)); + + struct cli_environment env; + get_environment(&env, sizeof(env)); + if (env.has_jit_compiled) { + /* CPU checks */ + switch (env.arch) { + case arch_i386: + disable_jit_if("i[34]86 detected, JIT needs pentium or better",0, + !memcmp(env.cpu,"i386",4) || + !memcmp(env.cpu,"i486",4)); + break; + default: + break; + } + + /* RWX checks */ + if (!(env.os_features & (1 << feature_map_rwx))) { + disable_jit_if("RWX mapping denied.", 0, 1); + if (env.os == os_linux) { + if (env.os_features & (1 << feature_selinux)) + /* all SELinux versions deny RWX mapping when policy says so */ + disable_jit_if("^SELinux is preventing 'execmem' access.\n" + "Run 'setsebool -P clamd_use_jit on'.", 0, 1); + else if (env.os_features & (1 << feature_pax)) + /* recent versions of PaX deny RWX mapping */ + disable_jit_if("^PaX is preventing 'mprotect' access.\n" + "Run 'paxctl -cm '", 0, 1); + else + /* RWX mapping got denied but apparently not due to SELinux/PaX */ + disable_jit_if("^RWX mapping denied for unknown reason." + "Please report to http://bugs.clamav.net\n", 0, 1); + } + } else { + if ((env.os == os_linux || env.os_category == llvm_os_Linux) && + (env.os_features & (1 << feature_pax_mprotect))) { + /* older versions of PaX allow RWX mapping but silently degrade it to RW + * mapping and kill the program if it tries to execute. */ + disable_jit_if("^PaX is preventing 'mprotect' access.\n" + "Run 'paxctl -cm '", 0, 1); + } + } + } + int s = disable_bytecode_if("",0,0); + switch (s) { + case 0: + debug("startup: bytecode execution in auto mode"); + break; + case 1: + debug("startup: bytecode execution with interpreter only"); + break; + case 2: + debug("startup: bytecode disabled"); + break; + } + return 0; +} + + +#endif +#endif diff --git a/libclamav/bytecode.c b/libclamav/bytecode.c index 9e9c9570c..d77480bcb 100644 --- a/libclamav/bytecode.c +++ b/libclamav/bytecode.c @@ -36,6 +36,7 @@ #include "scanners.h" #include "bytecode_api.h" #include "bytecode_api_impl.h" +#include "builtin_bytecodes.h" #include /* dummy values */ @@ -2230,7 +2231,7 @@ int cli_bytecode_prepare(struct cl_engine *engine, struct cli_all_bc *bcs, unsig cli_errmsg("Bytecode: failed to allocate bytecode context\n"); return CL_EMEM; } - rc = run_builtin_or_loaded(bcs, BC_STARTUP, "", ctx, "BC_STARTUP"); + rc = run_builtin_or_loaded(bcs, BC_STARTUP, builtin_bc_startup, ctx, "BC_STARTUP"); if (rc != CL_SUCCESS) { cli_warnmsg("Bytecode: BC_STARTUP failed to run, disabling ALL bytecodes! Please report to http://bugs.clamav.net\n"); ctx->bytecode_disable_status = 2;