"Fossies" - the Fresh Open Source Software Archive

Member "snort-2.9.17/src/reload.c" (16 Oct 2020, 34124 Bytes) of package /linux/misc/snort-2.9.17.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "reload.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 2.9.16.1_vs_2.9.17.

    1 /*
    2  **
    3  **  reload.c
    4  **
    5  **  Copyright (C) 2014-2020 Cisco and/or its affiliates. All rights reserved.
    6  **
    7  **  This program is free software; you can redistribute it and/or modify
    8  **  it under the terms of the GNU General Public License Version 2 as
    9  **  published by the Free Software Foundation.  You may not use, modify or
   10  **  distribute this program under any other version of the GNU General
   11  **  Public License.
   12  **
   13  **  This program is distributed in the hope that it will be useful,
   14  **  but WITHOUT ANY WARRANTY; without even the implied warranty of
   15  **  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   16  **  GNU General Public License for more details.
   17  **
   18  **  You should have received a copy of the GNU General Public License
   19  **  along with this program; if not, write to the Free Software
   20  **  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
   21  **
   22  */
   23 
   24 #ifdef HAVE_CONFIG_H
   25 #include "config.h"
   26 #endif
   27 
   28 #ifdef HAVE_GETTID
   29 #define _GNU_SOURCE
   30 #endif
   31 
   32 #include <stdio.h>
   33 #include <ctype.h>
   34 #include <sys/stat.h>
   35 
   36 #include "reload.h"
   37 #include "snort.h"
   38 #include "parser.h"
   39 #include "sfcontrol_funcs.h"
   40 #include "sfcontrol.h"
   41 #include "mpse.h"
   42 #include "sp_flowbits.h"
   43 #include "sp_dynamic.h"
   44 #include "rate_filter.h"
   45 #include "file_service_config.h"
   46 #include "so_rule_mem_adjust.h"
   47 #include "file_service.h"
   48 #ifdef INTEL_SOFT_CPM
   49 #include "intel-soft-cpm.h"
   50 #endif
   51 #ifdef HAVE_MALLOC_TRIM
   52 #include <malloc.h>
   53 #endif
   54 #ifdef SIDE_CHANNEL
   55 # include "sidechannel.h"
   56 #endif
   57 #ifdef SNORT_RELOAD
   58 #include "sftarget_reader.h"
   59 #endif
   60 #ifdef REG_TEST
   61 #include "reg_test.h"
   62 #endif
   63 
   64 extern volatile int attribute_reload_thread_running;
   65 extern int reload_attribute_table_flags;
   66 
   67 #if defined(SNORT_RELOAD)
   68 
   69 void ReloadFreeAdjusters(SnortConfig* sc)
   70 {
   71     ReloadAdjustEntry* rae;
   72 
   73     while ((rae = sc->raEntry))
   74     {
   75         sc->raEntry = rae->raNext;
   76         if (rae->raUserFreeFunc && rae->raUserData) 
   77             rae->raUserFreeFunc(rae->raUserData);
   78         free(rae);
   79     }
   80     if ((rae = sc->raSessionEntry))
   81     {
   82         if (rae->raUserFreeFunc && rae->raUserData)
   83             rae->raUserFreeFunc(rae->raUserData);
   84         free(rae);
   85         sc->raSessionEntry = NULL;
   86     }
   87 }
   88 
   89 static ReloadAdjustEntry* ReloadAdjustRegisterAlloc(const char* raName, tSfPolicyId raPolicyId,
   90                                                     ReloadAdjustFunc raFunc, void* raUserData,
   91                                                     ReloadAdjustUserFreeFunc raUserFreeFunc)
   92 {
   93     static const char* raUnspecified = "Unspecified";
   94     ReloadAdjustEntry* rae;
   95 
   96     if ((rae = (ReloadAdjustEntry*)calloc(1, sizeof*rae)))
   97     {
   98         rae->raName = raName ? raName : raUnspecified;
   99         rae->raPolicyId = raPolicyId; 
  100         rae->raFunc = raFunc;
  101         rae->raUserData = raUserData;
  102         rae->raUserFreeFunc = raUserFreeFunc;
  103         LogMessage("Registered %s to adjust for reload.\n", rae->raName); 
  104     }
  105     return rae;
  106 }
  107 
  108 int ReloadAdjustRegister(SnortConfig* sc, const char* raName, tSfPolicyId raPolicyId,
  109                          ReloadAdjustFunc raFunc, void* raUserData,
  110                          ReloadAdjustUserFreeFunc raUserFreeFunc)
  111 {
  112     ReloadAdjustEntry* rae;
  113 
  114     rae = ReloadAdjustRegisterAlloc(raName, raPolicyId, raFunc, raUserData, raUserFreeFunc);
  115     if (!rae)
  116         return -1;
  117     rae->raNext = sc->raEntry;
  118     sc->raEntry = rae;
  119     return 0;
  120 }
  121 
  122 int ReloadAdjustSessionRegister(SnortConfig* sc, const char* raName, tSfPolicyId raPolicyId,
  123                                 ReloadAdjustFunc raFunc, void* raUserData,
  124                                 ReloadAdjustUserFreeFunc raUserFreeFunc)
  125 {
  126     ReloadAdjustEntry* rae;
  127 
  128     rae = ReloadAdjustRegisterAlloc(raName, raPolicyId, raFunc, raUserData, raUserFreeFunc);
  129     if (!rae)
  130         return -1;
  131     sc->raSessionEntry = rae; 
  132     return 0;
  133 }
  134 
  135 #endif
  136 
  137 #if defined(SNORT_RELOAD) && !defined(WIN32) 
  138 volatile bool reloadInProgress = false;
  139 static pthread_mutex_t reload_mutex = PTHREAD_MUTEX_INITIALIZER;
  140 #endif
  141 
  142 #if defined(SNORT_RELOAD) && !defined(WIN32)
  143 static volatile int snort_swapped = 0;
  144 SnortConfig *snort_conf_new = NULL;
  145 static SnortConfig *snort_conf_old = NULL;
  146 #endif
  147 
  148 bool SnortDynamicLibsChanged(void)
  149 {
  150 #ifdef SNORT_RELOAD
  151     if (detection_lib_changed)
  152         return true;
  153 #endif
  154     return false;
  155 }
  156 
  157 void CheckForReload(void)
  158 {
  159 #if defined(SNORT_RELOAD) && !defined(WIN32)
  160 
  161     /* Check for a new configuration */
  162     if (snort_reload)
  163     {
  164         PostConfigFuncNode *idxPlugin;
  165         snort_reload = 0;
  166 
  167         /* There was an error reloading.  A non-reloadable configuration
  168          * option changed */
  169         if (snort_conf_new == NULL)
  170         {
  171 #ifdef RELOAD_ERROR_FATAL
  172             CleanExit(1);
  173 #else
  174             Restart();
  175 #endif
  176         }
  177 
  178         snort_conf_old = snort_conf;
  179         snort_conf = snort_conf_new;
  180         snort_conf_new = NULL;
  181 
  182         FileServiceInstall();
  183 
  184         ScRestoreInternalLogLevel();
  185 
  186         SwapPreprocConfigurations(snort_conf);
  187 
  188         /* Need to do this here because there is potentially outstanding
  189          * state data pointing to the previous configuration.  A race
  190          * condition is created if these are free'd in the reload thread
  191          * where a double free could occur. */
  192         FreeSwappedPreprocConfigurations(snort_conf);
  193 
  194 #ifdef INTEL_SOFT_CPM
  195         if (snort_conf->fast_pattern_config->search_method == MPSE_INTEL_CPM)
  196             IntelPmActivate(snort_conf);
  197 #endif
  198 
  199         snort_swapped = 1;
  200          setNapRuntimePolicy( getParserPolicy(snort_conf) );
  201          setIpsRuntimePolicy( getParserPolicy(snort_conf) );
  202 
  203         /* Do any reload for plugin data */
  204         idxPlugin = plugin_reload_funcs;
  205         while(idxPlugin)
  206         {
  207             idxPlugin->func(snort_conf, SIGHUP, idxPlugin->arg);
  208             idxPlugin = idxPlugin->next;
  209         }
  210 
  211     }
  212 #endif
  213 }
  214 
  215 #if defined(SNORT_RELOAD) && !defined(WIN32)
  216 static int VerifyLibInfos(DynamicLibInfo *old_info, DynamicLibInfo *new_info)
  217 {
  218     if ((old_info != NULL) && (new_info != NULL))
  219     {
  220         unsigned i;
  221 
  222         if (old_info->type != new_info->type)
  223         {
  224             FatalError("%s(%d) Incompatible library types.\n",
  225                        __FILE__, __LINE__);
  226         }
  227 
  228         if (old_info->count != new_info->count)
  229             return -1;
  230 
  231         for (i = 0; i < old_info->count; i++)
  232         {
  233             unsigned j;
  234             DynamicLibPath *old_path = old_info->lib_paths[i];
  235 
  236             for (j = 0; j < new_info->count; j++)
  237             {
  238                 DynamicLibPath *new_path = new_info->lib_paths[j];
  239 
  240                 if ((strcmp(old_path->path, new_path->path) == 0) &&
  241                     (old_path->ptype == new_path->ptype))
  242                 {
  243 #if defined (SFLINUX) || defined(WRLINUX)
  244                     if (old_info->type != DYNAMIC_TYPE__DETECTION)
  245 #endif
  246                         if (old_path->last_mod_time != new_path->last_mod_time)
  247                             return -1;
  248 
  249                     break;
  250                 }
  251             }
  252 
  253             if (j == new_info->count)
  254                 return -1;
  255         }
  256     }
  257     else if (old_info != new_info)
  258     {
  259         return -1;
  260     }
  261 
  262     return 0;
  263 }
  264 
  265 static int VerifyOutputs(SnortConfig *old_config, SnortConfig *new_config)
  266 {
  267     OutputConfig *old_output_config, *new_output_config;
  268     int old_outputs = 0, new_outputs = 0;
  269 
  270     /* Get from output_configs to see if output has changed */
  271     for (old_output_config = old_config->output_configs;
  272          old_output_config != NULL;
  273          old_output_config = old_output_config->next)
  274     {
  275         old_outputs++;
  276     }
  277 
  278     for (new_output_config = new_config->output_configs;
  279          new_output_config != NULL;
  280          new_output_config = new_output_config->next)
  281     {
  282         new_outputs++;
  283     }
  284 
  285     if (new_outputs != old_outputs)
  286     {
  287         ErrorMessage("Snort Reload: Any change to any output "
  288                      "configurations requires a restart.\n");
  289         return -1;
  290     }
  291 
  292     for (old_output_config = old_config->output_configs;
  293          old_output_config != NULL;
  294          old_output_config = old_output_config->next)
  295     {
  296 
  297         for (new_output_config = new_config->output_configs;
  298                 new_output_config != NULL;
  299                 new_output_config = new_output_config->next)
  300         {
  301             if (strcasecmp(old_output_config->keyword, new_output_config->keyword) == 0)
  302             {
  303                 if ((old_output_config->opts != NULL) &&
  304                         (new_output_config->opts != NULL) &&
  305                         (strcasecmp(old_output_config->opts, new_output_config->opts) == 0))
  306                 {
  307                     new_outputs++;
  308                     break;
  309                 }
  310                 else if (old_output_config->opts == NULL &&
  311                         new_output_config->opts == NULL)
  312                 {
  313                     new_outputs++;
  314                     break;
  315                 }
  316             }
  317 
  318         }
  319 
  320         old_outputs++;
  321     }
  322 
  323     if (new_outputs != old_outputs)
  324     {
  325         ErrorMessage("Snort Reload: Any change to any output "
  326                      "configurations requires a restart.\n");
  327         return -1;
  328     }
  329 
  330     /* Check user defined rule type outputs */
  331     for (old_output_config = old_config->rule_type_output_configs;
  332          old_output_config != NULL;
  333          old_output_config = old_output_config->next)
  334     {
  335         old_outputs++;
  336     }
  337 
  338     for (new_output_config = new_config->rule_type_output_configs;
  339          new_output_config != NULL;
  340          new_output_config = new_output_config->next)
  341     {
  342         new_outputs++;
  343     }
  344 
  345     if (new_outputs != old_outputs)
  346     {
  347         ErrorMessage("Snort Reload: Any change to any output "
  348                      "configurations requires a restart.\n");
  349         return -1;
  350     }
  351 
  352     /* Do user defined rule type outputs as well */
  353     for (old_output_config = old_config->rule_type_output_configs;
  354          old_output_config != NULL;
  355          old_output_config = old_output_config->next)
  356     {
  357         for (new_output_config = new_config->rule_type_output_configs;
  358              new_output_config != NULL;
  359              new_output_config = new_output_config->next)
  360         {
  361             if (strcasecmp(old_output_config->keyword,
  362                            new_output_config->keyword) == 0)
  363             {
  364                 if (old_output_config->opts && new_output_config->opts)
  365                 {
  366                     if (strcasecmp(old_output_config->opts,
  367                                    new_output_config->opts) == 0)
  368                     {
  369                         new_outputs++;
  370                         break;
  371                     }
  372                 }
  373                 if (!old_output_config->opts && !new_output_config->opts)
  374                 {
  375                     new_outputs++;
  376                     break;
  377                 }
  378             }
  379         }
  380 
  381         old_outputs++;
  382     }
  383 
  384     if (new_outputs != old_outputs)
  385     {
  386         ErrorMessage("Snort Reload: Any change to any output "
  387                      "configurations requires a restart.\n");
  388         return -1;
  389     }
  390 
  391     return 0;
  392 }
  393 
  394 static int VerifyReload(SnortConfig *sc)
  395 {
  396     if (sc == NULL)
  397         return -1;
  398 
  399 #ifdef TARGET_BASED
  400     {
  401         SnortPolicy *p1 = sc->targeted_policies[getDefaultPolicy()];
  402         SnortPolicy *p2 = snort_conf->targeted_policies[getDefaultPolicy()];
  403 
  404         if ((p1->target_based_config.args != NULL) &&
  405             (p2->target_based_config.args != NULL))
  406         {
  407             if (strcasecmp(p1->target_based_config.args,
  408                            p2->target_based_config.args) != 0)
  409             {
  410                 ErrorMessage("Snort Reload: Changing the attribute table "
  411                              "configuration requires a restart.\n");
  412                 return -1;
  413             }
  414         }
  415     }
  416 #endif
  417 
  418     if ((snort_conf->alert_file != NULL) && (sc->alert_file != NULL))
  419     {
  420         if (strcasecmp(snort_conf->alert_file, sc->alert_file) != 0)
  421         {
  422             ErrorMessage("Snort Reload: Changing the alert file "
  423                          "configuration requires a restart.\n");
  424             return -1;
  425         }
  426     }
  427     else if (snort_conf->alert_file != sc->alert_file)
  428     {
  429         ErrorMessage("Snort Reload: Changing the alert file "
  430                      "configuration requires a restart.\n");
  431         return -1;
  432     }
  433 
  434     if (snort_conf->asn1_mem != sc->asn1_mem)
  435     {
  436         ErrorMessage("Snort Reload: Changing the asn1 memory configuration "
  437                      "requires a restart.\n");
  438         return -1;
  439     }
  440 
  441     if ((sc->bpf_filter == NULL) && (sc->bpf_file != NULL))
  442         sc->bpf_filter = read_infile(sc->bpf_file);
  443 
  444     if ((sc->bpf_filter != NULL) && (snort_conf->bpf_filter != NULL))
  445     {
  446         if (strcasecmp(snort_conf->bpf_filter, sc->bpf_filter) != 0)
  447         {
  448             ErrorMessage("Snort Reload: Changing the bpf filter configuration "
  449                          "requires a restart.\n");
  450             return -1;
  451         }
  452     }
  453     else if (sc->bpf_filter != snort_conf->bpf_filter)
  454     {
  455         ErrorMessage("Snort Reload: Changing the bpf filter configuration "
  456                      "requires a restart.\n");
  457         return -1;
  458     }
  459 
  460 #ifdef ACTIVE_RESPONSE
  461     if ( sc->respond_attempts != snort_conf->respond_attempts ||
  462          sc->respond_device != snort_conf->respond_device )
  463     {
  464         ErrorMessage("Snort Reload: Changing config response "
  465                      "requires a restart.\n");
  466         return -1;
  467     }
  468 #endif
  469 
  470     if ((snort_conf->chroot_dir != NULL) &&
  471         (sc->chroot_dir != NULL))
  472     {
  473         if (strcasecmp(snort_conf->chroot_dir, sc->chroot_dir) != 0)
  474         {
  475             ErrorMessage("Snort Reload: Changing the chroot directory "
  476                          "configuration requires a restart.\n");
  477             return -1;
  478         }
  479     }
  480     else if (snort_conf->chroot_dir != sc->chroot_dir)
  481     {
  482         ErrorMessage("Snort Reload: Changing the chroot directory "
  483                      "configuration requires a restart.\n");
  484         return -1;
  485     }
  486 
  487     if ((snort_conf->run_flags & RUN_FLAG__DAEMON) !=
  488         (sc->run_flags & RUN_FLAG__DAEMON))
  489     {
  490         ErrorMessage("Snort Reload: Changing to or from daemon mode "
  491                      "requires a restart.\n");
  492         return -1;
  493     }
  494 
  495     if ((snort_conf->interface != NULL) && (sc->interface != NULL))
  496     {
  497         if (strcasecmp(snort_conf->interface, sc->interface) != 0)
  498         {
  499             ErrorMessage("Snort Reload: Changing the interface "
  500                          "configuration requires a restart.\n");
  501             return -1;
  502         }
  503     }
  504     else if (snort_conf->interface != sc->interface)
  505     {
  506         ErrorMessage("Snort Reload: Changing the interface "
  507                      "configuration requires a restart.\n");
  508         return -1;
  509     }
  510 
  511     /* Orig log dir because a chroot might have changed it */
  512     if ((snort_conf->orig_log_dir != NULL) &&
  513         (sc->orig_log_dir != NULL))
  514     {
  515         if (strcasecmp(snort_conf->orig_log_dir, sc->orig_log_dir) != 0)
  516         {
  517             ErrorMessage("Snort Reload: Changing the log directory "
  518                          "configuration requires a restart.\n");
  519             return -1;
  520         }
  521     }
  522     else if (snort_conf->orig_log_dir != sc->orig_log_dir)
  523     {
  524         ErrorMessage("Snort Reload: Changing the log directory "
  525                      "configuration requires a restart.\n");
  526         return -1;
  527     }
  528 
  529     if (snort_conf->no_log != sc->no_log)
  530     {
  531         ErrorMessage("Snort Reload: Changing from log to no log or vice "
  532                      "versa requires a restart.\n");
  533         return -1;
  534     }
  535 
  536     if ((snort_conf->run_flags & RUN_FLAG__NO_PROMISCUOUS) !=
  537         (sc->run_flags & RUN_FLAG__NO_PROMISCUOUS))
  538     {
  539         ErrorMessage("Snort Reload: Changing to or from promiscuous mode "
  540                      "requires a restart.\n");
  541         return -1;
  542     }
  543 
  544 
  545 #ifdef PERF_PROFILING
  546     if ((snort_conf->profile_rules.num != sc->profile_rules.num) ||
  547         (snort_conf->profile_rules.sort != sc->profile_rules.sort) ||
  548         (snort_conf->profile_rules.append != sc->profile_rules.append))
  549     {
  550         ErrorMessage("Snort Reload: Changing rule profiling number, sort "
  551                      "or append configuration requires a restart.\n");
  552         return -1;
  553     }
  554 
  555     if ((snort_conf->profile_rules.filename != NULL) &&
  556         (sc->profile_rules.filename != NULL))
  557     {
  558         if (strcasecmp(snort_conf->profile_rules.filename,
  559                        sc->profile_rules.filename) != 0)
  560         {
  561             ErrorMessage("Snort Reload: Changing the rule profiling filename "
  562                          "configuration requires a restart.\n");
  563             return -1;
  564         }
  565     }
  566     else if (snort_conf->profile_rules.filename !=
  567              sc->profile_rules.filename)
  568     {
  569         ErrorMessage("Snort Reload: Changing the rule profiling filename "
  570                      "configuration requires a restart.\n");
  571         return -1;
  572     }
  573 
  574     if ((snort_conf->profile_preprocs.num !=  sc->profile_preprocs.num) ||
  575         (snort_conf->profile_preprocs.sort != sc->profile_preprocs.sort) ||
  576         (snort_conf->profile_preprocs.append != sc->profile_preprocs.append))
  577     {
  578         ErrorMessage("Snort Reload: Changing preprocessor profiling number, "
  579                      "sort or append configuration requires a restart.\n");
  580         return -1;
  581     }
  582 
  583     if ((snort_conf->profile_preprocs.filename != NULL) &&
  584         (sc->profile_preprocs.filename != NULL))
  585     {
  586         if (strcasecmp(snort_conf->profile_preprocs.filename,
  587                        sc->profile_preprocs.filename) != 0)
  588         {
  589             ErrorMessage("Snort Reload: Changing the preprocessor profiling "
  590                          "filename configuration requires a restart.\n");
  591             return -1;
  592         }
  593     }
  594     else if (snort_conf->profile_preprocs.filename !=
  595              sc->profile_preprocs.filename)
  596     {
  597         ErrorMessage("Snort Reload: Changing the preprocessor profiling "
  598                      "filename configuration requires a restart.\n");
  599         return -1;
  600     }
  601 #endif
  602 
  603     if (snort_conf->group_id != sc->group_id)
  604     {
  605         ErrorMessage("Snort Reload: Changing the group id "
  606                      "configuration requires a restart.\n");
  607         return -1;
  608     }
  609 
  610     if (snort_conf->user_id != sc->user_id)
  611     {
  612         ErrorMessage("Snort Reload: Changing the user id "
  613                      "configuration requires a restart.\n");
  614         return -1;
  615     }
  616 
  617     if (snort_conf->pkt_snaplen != sc->pkt_snaplen)
  618     {
  619         ErrorMessage("Snort Reload: Changing the packet snaplen "
  620                      "configuration requires a restart.\n");
  621         return -1;
  622     }
  623 
  624     if (snort_conf->threshold_config->memcap !=
  625         sc->threshold_config->memcap)
  626     {
  627         ErrorMessage("Snort Reload: Changing the threshold memcap "
  628                      "configuration requires a restart.\n");
  629         return -1;
  630     }
  631 
  632     if (snort_conf->rate_filter_config->memcap !=
  633         sc->rate_filter_config->memcap)
  634     {
  635         ErrorMessage("Snort Reload: Changing the rate filter memcap "
  636                      "configuration requires a restart.\n");
  637         return -1;
  638     }
  639 
  640     if (snort_conf->detection_filter_config->memcap !=
  641         sc->detection_filter_config->memcap)
  642     {
  643         ErrorMessage("Snort Reload: Changing the detection filter memcap "
  644                      "configuration requires a restart.\n");
  645         return -1;
  646     }
  647 
  648     if (VerifyLibInfos(snort_conf->dyn_engines, sc->dyn_engines) == -1)
  649     {
  650         ErrorMessage("Snort Reload: Any change to the dynamic engine "
  651                      "configuration requires a restart.\n");
  652         return -1;
  653     }
  654 
  655     if (VerifyLibInfos(snort_conf->dyn_rules, sc->dyn_rules) == -1)
  656     {
  657         LogMessage("Snort Reload: Dynamic detection libs have changed.\n");
  658         detection_lib_changed = 1;
  659     }
  660 
  661     if (VerifyLibInfos(snort_conf->dyn_preprocs, sc->dyn_preprocs) == -1)
  662     {
  663         ErrorMessage("Snort Reload: Any change to the dynamic preprocessor "
  664                      "configuration requires a restart.\n");
  665         return -1;
  666     }
  667 
  668     if (snort_conf->so_rule_memcap != sc->so_rule_memcap)
  669     {
  670         AdjustSoRuleMemory(sc, snort_conf);
  671     }
  672 
  673     if (VerifyOutputs(snort_conf, sc) == -1)
  674         return -1;
  675 
  676 #ifdef SIDE_CHANNEL
  677     if (SideChannelVerifyConfig(sc) != 0)
  678     {
  679         ErrorMessage("Snort Reload: Changing the side channel configuration requires a restart.\n");
  680         return -1;
  681     }
  682 #endif
  683 
  684     if (ScMaxIP6Extensions() != sc->max_ip6_extensions)
  685     {
  686     ErrorMessage("Snort Reload: Changing Max IP6 extensions "
  687              "configuration requires a restart.\n");
  688     return -1;
  689     }
  690 
  691     return 0;
  692 }
  693 
  694 static SnortConfig * ReloadConfig(void)
  695 {
  696     SnortConfig *sc;
  697 
  698     if (ScSuppressConfigLog())
  699         ScSetInternalLogLevel(INTERNAL_LOG_LEVEL__ERROR);
  700 
  701 #ifdef HAVE_MALLOC_TRIM
  702     malloc_trim(0);
  703 #endif
  704 
  705     sc = ParseSnortConf();
  706 
  707     sc = MergeSnortConfs(snort_cmd_line_conf, sc);
  708 
  709     sc->reloadPolicyFlag = 1;
  710 
  711 #ifdef PERF_PROFILING
  712     /* Parse profiling here because of file option and potential
  713      * dependence on log directory */
  714     {
  715         char *opts = NULL;
  716         int in_table;
  717 
  718         in_table = sfghash_find2(sc->config_table,
  719                                  CONFIG_OPT__PROFILE_PREPROCS, (void *)&opts);
  720         if (in_table)
  721             ConfigProfilePreprocs(sc, opts);
  722 
  723         in_table = sfghash_find2(sc->config_table,
  724                                  CONFIG_OPT__PROFILE_RULES, (void *)&opts);
  725         if (in_table)
  726             ConfigProfileRules(sc, opts);
  727     }
  728 #endif
  729 
  730     if (VerifyReload(sc) == -1)
  731     {
  732         SnortConfFree(sc);
  733         return NULL;
  734     }
  735 
  736     DAQ_UpdateTunnelBypass(sc);
  737 
  738     if (sc->output_flags & OUTPUT_FLAG__USE_UTC)
  739         sc->thiszone = 0;
  740     else
  741         sc->thiszone = gmt2local(0);
  742 
  743 #ifdef TARGET_BASED
  744     SFAT_ReloadCheck(sc);
  745 #endif
  746 
  747     /* Preprocessors will have a reload callback */
  748     ConfigurePreprocessors(sc, 1);
  749 
  750     FlowbitResetCounts();
  751     ParseRules(sc);
  752     RuleOptParseCleanup();
  753 
  754     /* Check if Dynamic detection libs have changed */
  755     if (!detection_lib_changed) 
  756     {
  757         pthread_mutex_lock(&dynamic_rules_lock);
  758         ReloadDynamicRules(sc);
  759         pthread_mutex_unlock(&dynamic_rules_lock);
  760     } 
  761     else 
  762     {
  763         ReloadDynamicDetectionLibs(sc);
  764         InitDynamicDetectionPlugins(sc);
  765     }
  766 
  767     /* Handles Fatal Errors itself. */
  768     SnortEventqNew(sc->event_queue_config, sc->event_queue);
  769 
  770     detection_filter_print_config(sc->detection_filter_config);
  771     RateFilter_PrintConfig(sc->rate_filter_config);
  772     print_thresholding(sc->threshold_config, 0);
  773     PrintRuleOrder(sc->rule_lists);
  774 
  775     SetRuleStates(sc);
  776 
  777     if (file_sevice_config_verify(snort_conf, sc) == -1)
  778     {
  779         SnortConfFree(sc);
  780         return NULL;
  781     }
  782 
  783     if (VerifyReloadedPreprocessors(sc))
  784     {
  785         SnortConfFree(sc);
  786         return NULL;
  787     }
  788 
  789     if (CheckPreprocessorsConfig(sc))
  790     {
  791         SnortConfFree(sc);
  792         return NULL;
  793     }
  794 
  795     FilterConfigPreprocessors(sc);
  796     PostConfigPreprocessors(sc);
  797     
  798     sc->udp_ips_port_filter_list = ParseIpsPortList(sc, IPPROTO_UDP);
  799 
  800     /* Need to do this after dynamic detection stuff is initialized, too */
  801     FlowBitsVerify();
  802 
  803     if ((sc->file_mask != 0) && (sc->file_mask != snort_conf->file_mask))
  804         umask(sc->file_mask);
  805 
  806     /* Transfer any user defined rule type outputs to the new rule list */
  807     {
  808         RuleListNode *cur = snort_conf->rule_lists;
  809 
  810         for (; cur != NULL; cur = cur->next)
  811         {
  812             RuleListNode *new = sc->rule_lists;
  813 
  814             for (; new != NULL; new = new->next)
  815             {
  816                 if (strcasecmp(cur->name, new->name) == 0)
  817                 {
  818                     OutputFuncNode *alert_list = cur->RuleList->AlertList;
  819                     OutputFuncNode *log_list = cur->RuleList->LogList;
  820 
  821                     sc->head_tmp = new->RuleList;
  822 
  823                     for (; alert_list != NULL; alert_list = alert_list->next)
  824                     {
  825                         AddFuncToOutputList(sc, alert_list->func,
  826                                             OUTPUT_TYPE__ALERT, alert_list->arg);
  827                     }
  828 
  829                     for (; log_list != NULL; log_list = log_list->next)
  830                     {
  831                         AddFuncToOutputList(sc, log_list->func,
  832                                             OUTPUT_TYPE__LOG, log_list->arg);
  833                     }
  834 
  835                     sc->head_tmp = NULL;
  836                     break;
  837                 }
  838             }
  839         }
  840     }
  841 
  842     /* XXX XXX Can't do any output plugins */
  843     //PostConfigInitPlugins(sc->plugin_post_config_funcs);
  844 
  845     fpCreateFastPacketDetection(sc);
  846 
  847 #ifdef PPM_MGR
  848     PPM_PRINT_CFG(&sc->ppm_cfg);
  849 #endif
  850 
  851 #if defined(DAQ_VERSION) && DAQ_VERSION > 9
  852     // This is needed when PPM is disabled and enabling snort-engine debugs
  853     if (!ppm_tpu)
  854        ppm_tpu = (PPM_TICKS)get_ticks_per_usec();
  855 #endif
  856 
  857     // Restores the configured logging level, if it was suppressed earlier
  858     ScRestoreInternalLogLevel();
  859 
  860     return sc;
  861 }
  862 
  863 static void updatePeriodicCheck(void)
  864 {
  865     PeriodicCheckFuncNode *checkFunc;
  866 
  867     /* reset preprocessors */
  868     checkFunc = periodic_check_funcs;
  869     while (checkFunc != NULL)
  870     {
  871         if ( 0 == checkFunc->time_left )
  872         {
  873             checkFunc->func(-1, checkFunc->arg);
  874             checkFunc->time_left = checkFunc->period;
  875             //LogMessage("        --== Share Memory! ==--\n");
  876         }
  877         else
  878             checkFunc->time_left--;
  879 
  880         checkFunc = checkFunc->next;
  881     }
  882 
  883 }
  884 
  885 void * ReloadConfigThread(void *data)
  886 {
  887     sigset_t mtmask;
  888 
  889     /* Don't handle any signals here */
  890     sigfillset(&mtmask);
  891     pthread_sigmask(SIG_BLOCK, &mtmask, NULL);
  892 
  893     snort_reload_thread_pid = gettid();
  894     snort_reload_thread_created = 1;
  895 
  896     while (snort_initializing)
  897         nanosleep(&thread_sleep, NULL);
  898 
  899     while (!snort_exiting)
  900     {
  901         if (reload_signal != reload_total)
  902         {
  903             int reload_failed = 0;
  904 
  905 #ifdef CONTROL_SOCKET
  906             pthread_mutex_lock(&reload_mutex);
  907             if (!reloadInProgress)
  908             {
  909                 reloadInProgress = true;
  910                 pthread_mutex_unlock(&reload_mutex);
  911 #endif
  912                 reload_total++;
  913 
  914                 LogMessage("\n");
  915                 LogMessage("        --== Reloading Snort ==--\n");
  916                 LogMessage("\n");
  917 
  918                 snort_conf_new = ReloadConfig();
  919 
  920                 // Restore Log level if we suppressed it earlier
  921 
  922                 if (snort_conf_new == NULL)
  923                     reload_failed = 1;
  924                 snort_reload = 1;
  925 
  926                 while (!snort_swapped && !snort_exiting)
  927                     nanosleep(&thread_sleep, NULL);
  928 
  929                 snort_swapped = 0;
  930 
  931                 SnortConfFree(snort_conf_old);
  932                 snort_conf_old = NULL;
  933 
  934 #ifdef INTEL_SOFT_CPM
  935                 if (snort_conf->fast_pattern_config->search_method != MPSE_INTEL_CPM)
  936                     IntelPmStopInstance();
  937 #endif
  938 
  939                 if (snort_exiting && !reload_failed)
  940                 {
  941                     /* This will load the new preprocessor configurations and
  942                      * free the old ones, so any preprocessor cleanup that
  943                      * requires a configuration will be using the new one
  944                      * unless it relies on old configurations that are still
  945                      * attached to existing sessions. */
  946                     SwapPreprocConfigurations(snort_conf);
  947                     FreeSwappedPreprocConfigurations(snort_conf);
  948 #if defined (SIDE_CHANNEL) && defined (REG_TEST)
  949                     if (snort_conf && snort_conf->file_config)
  950                       FileSSConfigFree(snort_conf->file_config);
  951 #endif
  952 
  953 #ifdef CONTROL_SOCKET
  954                     reloadInProgress = false;
  955 #endif
  956                     /* Get out of the loop and exit */
  957                     break;
  958                 }
  959 
  960                 if (!reload_failed)
  961                 {
  962 #if defined(TARGET_BASED) && !defined(WIN32)
  963             if(!IsAdaptiveConfigured())
  964             {
  965             if(attribute_reload_thread_running)
  966             {
  967                 ReloadAttributeThreadStop();
  968                 reload_attribute_table_flags = 0;
  969 #ifdef REG_TEST
  970                 if(REG_TEST_FLAG_RELOAD & getRegTestFlags())
  971                 {
  972                 printf("Adaptive profile disabled, attribute table cleared\n");
  973                 }
  974 #endif
  975             }
  976             SFAT_Cleanup();
  977             SnortAddSignal(SIGNAL_SNORT_READ_ATTR_TBL, SigNoAttributeTableHandler, 1);
  978             }
  979             else if(IsAdaptiveConfigured() && ScDisableAttrReload(snort_conf))
  980             {
  981             if(attribute_reload_thread_running)
  982             {
  983                 ReloadAttributeThreadStop();
  984                 SFAT_CleanPrevConfig();
  985                 }
  986             SnortAddSignal(SIGNAL_SNORT_READ_ATTR_TBL, SigNoAttributeTableHandler, 1);
  987             }
  988             else if(IsAdaptiveConfigured() && !ScDisableAttrReload(snort_conf))
  989             {
  990             SnortAddSignal(SIGNAL_SNORT_READ_ATTR_TBL,SigAttributeTableReloadHandler,0);
  991             }
  992 #endif
  993             while (snort_conf->raEntry)
  994             {
  995                 sleep(1);
  996             }
  997 
  998                     LogMessage("\n");
  999                     LogMessage("        --== Reload Complete ==--\n");
 1000                     LogMessage("\n");
 1001                 }
 1002 #ifdef CONTROL_SOCKET
 1003                 reloadInProgress = false;
 1004             }
 1005             else
 1006                 pthread_mutex_unlock(&reload_mutex);
 1007 #endif
 1008         }
 1009         /* Use the maintenance thread for periodic check*/
 1010         updatePeriodicCheck();
 1011 
 1012         sleep(1);
 1013     }
 1014 
 1015     pthread_exit((void *)0);
 1016 }
 1017 #endif
 1018 
 1019 #if defined(SNORT_RELOAD) && !defined(WIN32) && defined(CONTROL_SOCKET)
 1020 
 1021 static int ControlSocketReloadConfig(uint16_t type, const uint8_t *data, uint32_t length, void **new_config,
 1022                                      char *statusBuf, int statusBuf_len)
 1023 {
 1024     SnortConfig *new_sc;
 1025 
 1026     pthread_mutex_lock(&reload_mutex);
 1027     while (reloadInProgress || SnortIsInitializing())
 1028     {
 1029         sleep(1);
 1030     }
 1031     reloadInProgress = true;
 1032     pthread_mutex_unlock(&reload_mutex);
 1033 
 1034     LogMessage("\n");
 1035     LogMessage("        --== Reloading Snort ==--\n");
 1036     LogMessage("\n");
 1037 
 1038     new_sc = ReloadConfig();
 1039     if (new_sc == NULL)
 1040     {
 1041         reloadInProgress = false;
 1042         return -1;
 1043     }
 1044     *new_config = (void *)new_sc;
 1045     return 0;
 1046 }
 1047 
 1048 static int ControlSocketReloadSwap(uint16_t type, void *new_config, void **old_config)
 1049 {
 1050     PostConfigFuncNode *idxPlugin = NULL;
 1051 
 1052     *old_config = (void *)snort_conf;
 1053     snort_conf = (SnortConfig *)new_config;
 1054     FileServiceInstall();
 1055     SwapPreprocConfigurations(snort_conf);
 1056 
 1057 #ifdef INTEL_SOFT_CPM
 1058     if (snort_conf->fast_pattern_config->search_method == MPSE_INTEL_CPM)
 1059         IntelPmActivate(snort_conf);
 1060 #endif
 1061 
 1062     /* Do any reload for plugin data */
 1063     idxPlugin = plugin_reload_funcs;
 1064     while(idxPlugin)
 1065     {
 1066         idxPlugin->func(snort_conf, SIGHUP, idxPlugin->arg);
 1067         idxPlugin = idxPlugin->next;
 1068     }
 1069     if (snort_conf->raSessionEntry) 
 1070     {
 1071         /* Session is always the first to adjust */
 1072         snort_conf->raSessionEntry->raNext = snort_conf->raEntry; 
 1073         snort_conf->raEntry = snort_conf->raSessionEntry;
 1074         snort_conf->raSessionEntry = NULL;
 1075     }
 1076     setNapRuntimePolicy( getParserPolicy(snort_conf) );
 1077     setIpsRuntimePolicy( getParserPolicy(snort_conf) );
 1078 #if defined(REG_TEST)  && defined(PPM_MGR)
 1079     if (REG_TEST_FLAG_RELOAD & getRegTestFlags())
 1080     {
 1081        static char prev_ppm_cfg ;
 1082        if (snort_conf->ppm_cfg.rule_log & PPM_LOG_MESSAGE)
 1083        {
 1084            if (! ( prev_ppm_cfg & PPM_LOG_MESSAGE) )
 1085             {
 1086                printf("ppm rule-log set to PPM_LOG_MESSAGE\n");
 1087                prev_ppm_cfg |= PPM_LOG_MESSAGE;
 1088             }
 1089        }
 1090 
 1091        if( snort_conf->ppm_cfg.rule_log & PPM_LOG_ALERT )
 1092        {
 1093           if ( ! ( prev_ppm_cfg & PPM_LOG_ALERT) )
 1094           {
 1095              printf("ppm rule-log set to PPM_LOG_ALERT\n");
 1096              prev_ppm_cfg |= PPM_LOG_ALERT;
 1097           }
 1098        }
 1099     }
 1100 #endif
 1101     return 0;
 1102 }
 1103 
 1104 static void ControlSocketReloadFree(uint16_t type, void *old_config, struct _THREAD_ELEMENT *te, ControlDataSendFunc f)
 1105 {
 1106     SnortConfig *old_sc = (SnortConfig *)old_config;
 1107 
 1108     FreeSwappedPreprocConfigurations(snort_conf);
 1109 
 1110     SnortConfFree(old_sc);
 1111 
 1112 #ifdef INTEL_SOFT_CPM
 1113     if (snort_conf->fast_pattern_config->search_method != MPSE_INTEL_CPM)
 1114         IntelPmStopInstance();
 1115 #endif
 1116 
 1117 #if defined(TARGET_BASED) && !defined(WIN32)
 1118     if(!IsAdaptiveConfigured())
 1119     {
 1120     if(attribute_reload_thread_running)
 1121     {
 1122         ReloadAttributeThreadStop();
 1123         reload_attribute_table_flags = 0;
 1124 #ifdef REG_TEST
 1125         if(REG_TEST_FLAG_RELOAD & getRegTestFlags())
 1126         {
 1127         printf("Adaptive profile disabled, attribute table cleared\n");
 1128         }
 1129 #endif
 1130     }
 1131     SFAT_Cleanup();
 1132     SnortAddSignal(SIGNAL_SNORT_READ_ATTR_TBL, SigNoAttributeTableHandler, 1);
 1133     }
 1134     else if(IsAdaptiveConfigured() && ScDisableAttrReload(snort_conf))
 1135     {
 1136     if(attribute_reload_thread_running)
 1137     {
 1138         ReloadAttributeThreadStop();
 1139         SFAT_CleanPrevConfig();
 1140     }
 1141     SnortAddSignal(SIGNAL_SNORT_READ_ATTR_TBL, SigNoAttributeTableHandler, 1);
 1142     }
 1143     else if(IsAdaptiveConfigured() && !ScDisableAttrReload(snort_conf))
 1144     {
 1145     SnortAddSignal(SIGNAL_SNORT_READ_ATTR_TBL,SigAttributeTableReloadHandler,0);
 1146     }
 1147 #endif
 1148 
 1149     while (snort_conf->raEntry && !snort_exiting )
 1150         sleep(1);
 1151 
 1152     if( !snort_conf->raEntry )
 1153     {
 1154         LogMessage("\n");
 1155         LogMessage("        --== Reload Complete ==--\n");
 1156         LogMessage("\n");
 1157     }
 1158     else
 1159     {
 1160         LogMessage("            Reloading Aborted \n");
 1161     }
 1162 
 1163     reloadInProgress = false;
 1164 }
 1165 
 1166 #endif
 1167 
 1168 void ReloadControlSocketRegister(void)
 1169 {
 1170 #if defined(SNORT_RELOAD) && !defined(WIN32) && defined(CONTROL_SOCKET)
 1171     if (ControlSocketRegisterHandler(CS_TYPE_RELOAD, &ControlSocketReloadConfig, &ControlSocketReloadSwap, &ControlSocketReloadFree))
 1172     {
 1173         LogMessage("Failed to register the reload control handler.\n");
 1174     }
 1175 #endif
 1176 }
 1177 
 1178