Changeset 544


Ignore:
Timestamp:
Feb 17, 2019, 2:41:49 PM (2 months ago)
Author:
katerina
Message:

Fix for ticket #436 (new gcc compiler options, including LTO).

Location:
trunk
Files:
15 edited

Legend:

Unmodified
Added
Removed
  • trunk/Makefile.in

    r534 r544  
    16591659sh_gpg.o: $(srcsrc)/sh_gpg.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_utils.h $(srcinc)/sh_error.h $(srcinc)/sh_tiger.h $(srcinc)/sh_static.h $(srcinc)/sh_gpg.h  
    16601660sh_cat.o: $(srcsrc)/sh_cat.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_error.h $(srcinc)/sh_cat.h  
    1661 sh_calls.o: $(srcsrc)/sh_calls.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_error.h $(srcinc)/sh_calls.h $(srcinc)/sh_ipvx.h $(srcinc)/sh_sub.h $(srcinc)/sh_utils.h  
     1661sh_calls.o: $(srcsrc)/sh_calls.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_error.h $(srcinc)/sh_ipvx.h $(srcinc)/sh_sub.h $(srcinc)/sh_utils.h  
    16621662sh_extern.o: $(srcsrc)/sh_extern.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_utils.h $(srcinc)/sh_unix.h $(srcinc)/sh_tiger.h $(srcinc)/sh_extern.h $(srcinc)/sh_calls.h $(srcinc)/sh_filter.h $(srcinc)/sh_static.h  
    16631663sh_database.o: $(srcsrc)/sh_database.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_cat.h $(srcinc)/sh_error.h $(srcinc)/sh_utils.h  
     
    16721672encode.o: $(srcsrc)/encode.c Makefile  
    16731673sstrip.o: $(srcsrc)/sstrip.c Makefile config.h  
    1674 trustfile.o: $(srcsrc)/trustfile.c Makefile config_xor.h $(srcinc)/sh_calls.h $(srcinc)/slib.h $(srcinc)/sh_static.h $(srcinc)/sh_pthread.h  
     1674trustfile.o: $(srcsrc)/trustfile.c Makefile config_xor.h $(srcinc)/slib.h $(srcinc)/sh_static.h $(srcinc)/sh_pthread.h $(srcinc)/sh_calls.h  
    16751675exepack.o: $(srcsrc)/exepack.c Makefile config.h $(srcinc)/minilzo.h $(srcinc)/exepack.data  
    16761676exepack_fill.o: $(srcsrc)/exepack_fill.c Makefile config.h config.h $(srcinc)/minilzo.h  
  • trunk/aclocal.m4

    r499 r544  
    11251125  AC_LANG_ASSERT(C) 
    11261126  if test "X$CC" != "X"; then 
    1127     AC_CACHE_CHECK([whether ${CC} accepts -fstack-protector-all], 
     1127    AC_CACHE_CHECK([whether ${CC} accepts -fstack-protector-strong], 
    11281128      ssp_cv_cc, 
    11291129      [ssp_old_cflags="$CFLAGS" 
    1130        CFLAGS="$CFLAGS -fstack-protector-all" 
     1130       CFLAGS="$CFLAGS -fstack-protector-strong" 
    11311131       AC_TRY_COMPILE(,, ssp_cv_cc=yes, ssp_cv_cc=no) 
    11321132       CFLAGS="$ssp_old_cflags" 
    11331133      ]) 
    11341134    if test $ssp_cv_cc = no; then 
    1135       AC_CACHE_CHECK([whether ${CC} accepts -fstack-protector], 
     1135      AC_CACHE_CHECK([whether ${CC} accepts -fstack-protector-all], 
    11361136        ssp_cv_cc, 
    11371137        [ssp_old_cflags="$CFLAGS" 
    1138          CFLAGS="$CFLAGS -fstack-protector" 
     1138         CFLAGS="$CFLAGS -fstack-protector-all" 
    11391139         AC_TRY_COMPILE(,, ssp_cv_cc=yes, ssp_cv_cc=no) 
    11401140         CFLAGS="$ssp_old_cflags" 
    11411141        ]) 
    1142       if test $ssp_cv_cc = yes; then 
    1143         CFLAGS="$CFLAGS -D_FORTIFY_SOURCE=2 -fstack-protector" 
    1144         LDFLAGS="$LDFLAGS -fstack-protector" 
    1145         AC_DEFINE([ENABLE_SSP_CC], 1, [Define if SSP C support is enabled.]) 
     1142      if test $ssp_cv_cc = no; then 
     1143        AC_CACHE_CHECK([whether ${CC} accepts -fstack-protector], 
     1144          ssp_cv_cc, 
     1145          [ssp_old_cflags="$CFLAGS" 
     1146           CFLAGS="$CFLAGS -fstack-protector" 
     1147           AC_TRY_COMPILE(,, ssp_cv_cc=yes, ssp_cv_cc=no) 
     1148           CFLAGS="$ssp_old_cflags" 
     1149          ]) 
     1150        if test $ssp_cv_cc = yes; then 
     1151          CFLAGS="$CFLAGS -D_FORTIFY_SOURCE=2 -fstack-protector" 
     1152          LDFLAGS="$LDFLAGS -fstack-protector" 
     1153          AC_DEFINE([ENABLE_SSP_CC], 1, [Define if SSP C support is enabled.]) 
     1154        fi 
     1155      else 
     1156        if test $ssp_cv_cc = yes; then 
     1157          CFLAGS="$CFLAGS -D_FORTIFY_SOURCE=2 -fstack-protector-all" 
     1158          LDFLAGS="$LDFLAGS -fstack-protector-all" 
     1159          AC_DEFINE([ENABLE_SSP_CC], 1, [Define if SSP C support is enabled.]) 
     1160        fi 
    11461161      fi 
    11471162    else 
    11481163      if test $ssp_cv_cc = yes; then 
    1149         CFLAGS="$CFLAGS -D_FORTIFY_SOURCE=2 -fstack-protector-all" 
    1150         LDFLAGS="$LDFLAGS -fstack-protector-all" 
     1164        CFLAGS="$CFLAGS -D_FORTIFY_SOURCE=2 -fstack-protector-strong" 
     1165        LDFLAGS="$LDFLAGS -fstack-protector-strong" 
    11511166        AC_DEFINE([ENABLE_SSP_CC], 1, [Define if SSP C support is enabled.]) 
    11521167      fi 
     
    12111226  AC_LANG_ASSERT(C) 
    12121227  if test "X$CC" != "X"; then 
    1213     AC_CACHE_CHECK([whether ${CC} accepts -fstack-check], 
     1228    AC_CACHE_CHECK([whether ${CC} accepts -fstack-clash-protection], 
    12141229      stackcheck_cv_cc, 
    12151230      [stackcheck_old_cflags="$CFLAGS" 
    1216        CFLAGS="$CFLAGS -fstack-check" 
     1231       CFLAGS="$CFLAGS -fstack-clash-protection" 
    12171232       AC_TRY_COMPILE(,, stackcheck_cv_cc=yes, stackcheck_cv_cc=no) 
    12181233       CFLAGS="$stackcheck_old_cflags" 
    12191234      ]) 
    12201235    if test $stackcheck_cv_cc = yes; then 
    1221       CFLAGS="$CFLAGS -fstack-check" 
     1236      CFLAGS="$CFLAGS -fstack-clash-protection" 
    12221237    fi 
    12231238  fi 
  • trunk/config.h.in

    r534 r544  
    525525/* Define to 1 if you have the `endpwent' function. */ 
    526526#undef HAVE_ENDPWENT 
     527 
     528/* Define to 1 if you have the `explicit_bzero' function. */ 
     529#undef HAVE_EXPLICIT_BZERO 
     530 
     531/* Define to 1 if you have the `explicit_memset' function. */ 
     532#undef HAVE_EXPLICIT_MEMSET 
    527533 
    528534/* Define to 1 if you have the <ext2fs/ext2_fs.h> header file. */ 
  • trunk/configure.ac

    r539 r544  
    1212dnl start 
    1313dnl 
    14 AM_INIT_AUTOMAKE(samhain, 4.3.2) 
     14AM_INIT_AUTOMAKE(samhain, 4.3.3) 
    1515AC_DEFINE([SAMHAIN], 1, [Application is samhain]) 
    1616AC_CANONICAL_HOST 
     
    380380AC_FUNC_STRFTIME 
    381381AC_CHECK_FUNCS(memcmp memcpy memmove memset getpwent endpwent fpurge \ 
     382        explicit_memset explicit_bzero \ 
    382383        gettimeofday strlcat strlcpy strstr strchr strerror strsignal \ 
    383384        seteuid setreuid setresuid lstat getwd getcwd ptrace \ 
     
    706707        GCC_STACK_PROTECT_LIB 
    707708        GCC_STACK_PROTECT_CC 
    708 dnl   GCC_STACK_CHECK_CC 
    709       GCC_PIE_CC 
     709        GCC_STACK_CHECK_CC 
     710        GCC_PIE_CC 
     711        GCC_FLAG_CHECK([-fexceptions]) 
     712        GCC_FLAG_CHECK([-mcet -fcf-protection]) 
    710713   fi    
    711714 
     
    10381041                  tmp_LIBS=`echo $LIBS | sed 's%\-lauparse%%' ` 
    10391042                  LIBS="${tmp_LIBS}" 
     1043                  AC_MSG_WARN([--enable-static: no support for Linux Auditing System]) 
    10401044                fi 
    10411045 
    10421046                if test "x$GCC" = "xyes";  
    10431047                then 
     1048                   if test -n "`echo "$CFLAGS" | grep "\-flto" 2> /dev/null`" 
     1049                   then 
     1050                        AC_MSG_ERROR([--enable-static: not compatible with link-time optimisation]) 
     1051                   fi 
    10441052                   case "$host_os" in 
    10451053 
     
    12061214        [  --with-database=[[mysql|postgresql|oracle|odbc]]     database support [[no]]], 
    12071215        [ 
     1216        if test x"$enable_static" = xyes; then 
     1217                AC_MSG_WARN([With --enable-static,  --with-database may fail to compile.]) 
     1218        fi 
    12081219        if test x"$enable_xml_log" != xyes; then 
    12091220                AC_MSG_ERROR([With --with-database,  --enable-xml-log is required as well.]) 
     
    17911802           ;; 
    17921803        *) 
    1793            CFLAGS="$CFLAGS -Wall -W " 
     1804           CFLAGS="$CFLAGS -Wall -W -Werror=implicit-function-declaration " 
    17941805           ;; 
    17951806     esac 
  • trunk/depend.dep

    r534 r544  
    2828sh_gpg.o: $(srcsrc)/sh_gpg.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_utils.h $(srcinc)/sh_error.h $(srcinc)/sh_tiger.h $(srcinc)/sh_static.h $(srcinc)/sh_gpg.h  
    2929sh_cat.o: $(srcsrc)/sh_cat.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_error.h $(srcinc)/sh_cat.h  
    30 sh_calls.o: $(srcsrc)/sh_calls.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_error.h $(srcinc)/sh_calls.h $(srcinc)/sh_ipvx.h $(srcinc)/sh_sub.h $(srcinc)/sh_utils.h  
     30sh_calls.o: $(srcsrc)/sh_calls.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_error.h $(srcinc)/sh_ipvx.h $(srcinc)/sh_sub.h $(srcinc)/sh_utils.h  
    3131sh_extern.o: $(srcsrc)/sh_extern.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_utils.h $(srcinc)/sh_unix.h $(srcinc)/sh_tiger.h $(srcinc)/sh_extern.h $(srcinc)/sh_calls.h $(srcinc)/sh_filter.h $(srcinc)/sh_static.h  
    3232sh_database.o: $(srcsrc)/sh_database.c Makefile config_xor.h $(srcinc)/samhain.h $(srcinc)/sh_cat.h $(srcinc)/sh_error.h $(srcinc)/sh_utils.h  
     
    4141encode.o: $(srcsrc)/encode.c Makefile  
    4242sstrip.o: $(srcsrc)/sstrip.c Makefile config.h  
    43 trustfile.o: $(srcsrc)/trustfile.c Makefile config_xor.h $(srcinc)/sh_calls.h $(srcinc)/slib.h $(srcinc)/sh_static.h $(srcinc)/sh_pthread.h  
     43trustfile.o: $(srcsrc)/trustfile.c Makefile config_xor.h $(srcinc)/slib.h $(srcinc)/sh_static.h $(srcinc)/sh_pthread.h $(srcinc)/sh_calls.h  
    4444exepack.o: $(srcsrc)/exepack.c Makefile config.h $(srcinc)/minilzo.h $(srcinc)/exepack.data  
    4545exepack_fill.o: $(srcsrc)/exepack_fill.c Makefile config.h config.h $(srcinc)/minilzo.h  
  • trunk/depend.sum

    r534 r544  
    1 3903466696 
     13038455203 
  • trunk/docs/Changelog

    r539 r544  
     14.3.3: 
     2        * fix some issues with link-time optimisation (option -flto with 
     3        recent gcc versions) 
     4        * fix compiler warning in sh_prelude.c 
     5        * add patch (by Kamel H.) to init for alternative root fs) 
     6 
    174.3.2: 
    28        * fix compile failure on OpenBSD (reported by Mithrond) 
  • trunk/include/slib.h

    r525 r544  
    227227   */ 
    228228  int sl_strncmp(const char * a, const char * b, size_t n); 
     229  int sl_ts_strncmp(const char * a, const char * b, size_t n); 
    229230 
    230231  int sl_strncasecmp(const char * a, const char * b, size_t n); 
  • trunk/src/bignum.c

    r454 r544  
    425425{ 
    426426    DIGIT *a_ptr, *b_ptr; 
     427    int retval = 0; 
    427428 
    428429    if (a->dgs_used  == b->dgs_used) 
     
    437438        if (a_ptr < a->dp) 
    438439        { 
    439             return 0; 
     440            return retval; 
    440441        } 
    441442        else 
    442443        { 
    443             return (*a_ptr > *b_ptr) ? 1 : -1; 
    444         } 
     444            if (retval == 0) 
     445                retval = (*a_ptr > *b_ptr) ? 1 : -1; 
     446        } 
     447        return retval; 
    445448    } 
    446449    return (a->dgs_used > b->dgs_used) ? 1 : -1; 
  • trunk/src/cutest_slib.c

    r248 r544  
    5858} 
    5959 
     60void Test_sl_ts_strncmp (CuTest *tc) { 
     61  char one[64], two[64]; 
     62  int  res; 
     63 
     64  strcpy(one, "foo"); 
     65  strcpy(two, "foo"); 
     66  res = sl_ts_strncmp(one, two, 3); 
     67  CuAssertIntEquals(tc, 0, res); 
     68 
     69  strcpy(one, "fox"); 
     70  strcpy(two, "foo"); 
     71  res = sl_ts_strncmp(one, two, 2); 
     72  CuAssertIntEquals(tc, 0, res); 
     73   
     74  strcpy(one, "f9o"); 
     75  strcpy(two, "foo"); 
     76  res = sl_ts_strncmp(one, two, 3); 
     77  CuAssertTrue(tc, 0 != res); 
     78 
     79} 
     80 
    6081void Test_sl_strcasecmp (CuTest *tc) { 
    6182  char one[64], two[64]; 
  • trunk/src/sh_calls.c

    r509 r544  
    5151#include "samhain.h" 
    5252#include "sh_error.h" 
    53 #include "sh_calls.h" 
    5453#include "sh_ipvx.h" 
    5554#include "sh_sub.h" 
  • trunk/src/sh_srp.c

    r474 r544  
    4848#define bignum MP_INT 
    4949 
    50 inline 
     50static 
    5151int big_create (bignum * a) 
    5252{ 
     
    5555} 
    5656 
    57 inline 
     57static 
    5858int big_zerop (bignum * a) 
    5959{ 
     
    6969} 
    7070 
    71 inline 
     71static 
    7272int big_trunc (bignum * a, bignum * b, bignum * q, bignum *r) 
    7373{ 
     
    7676} 
    7777 
    78 inline 
     78static 
    7979int big_exptmod (bignum * a, bignum * b, bignum * c, bignum *d) 
    8080{ 
     
    136136} 
    137137 
    138 inline  
     138static  
    139139int big_add(bignum * a, bignum * b, bignum * c) 
    140140{ 
     
    143143} 
    144144 
    145 inline  
     145static  
    146146int big_sub(bignum * a, bignum * b, bignum * c) 
    147147{ 
     
    150150} 
    151151 
    152 inline  
     152static  
    153153int big_mul(bignum * a, bignum * b, bignum * c) 
    154154{ 
     
    157157} 
    158158 
    159 inline  
     159static  
    160160int big_greaterp(bignum * a, bignum * b) 
    161161{ 
     
    163163} 
    164164 
    165 inline  
     165static  
    166166int big_set_big(bignum * a, bignum * b) 
    167167{ 
     
    171171 
    172172 
    173 inline  
     173static  
    174174int big_set_string(const char * str, int base, bignum * a) 
    175175{ 
  • trunk/src/sh_xfer_client.c

    r541 r544  
    769769   */ 
    770770  sh_passwd (nounce, NULL, NULL, temp); 
    771   if ( 0 != sl_strncmp(temp, answer, KEY_LEN)) 
     771  if ( 0 != sl_ts_strncmp(temp, answer, KEY_LEN)) 
    772772    flag_err = (-1); 
    773773   
     
    10031003                                    ); 
    10041004                      if (M != NULL &&  
    1005                           0 == sl_strncmp (answer, M, KEY_LEN+1)) 
     1005                          0 == sl_ts_strncmp (answer, M, KEY_LEN+1)) 
    10061006                        { 
    10071007                          sl_strlcpy (skey->session,  
     
    10831083                        pos+1); 
    10841084      flag_err =  
    1085         sl_strncmp(&answer[KEY_LEN+pos], 
     1085        sl_ts_strncmp(&answer[KEY_LEN+pos], 
    10861086                   sh_util_siggen(skey->session,  
    10871087                                  buffer, 
     
    12021202      (void) sl_strlcpy(buffer, errmsg, len); 
    12031203      (void) sl_strlcat(buffer, nsrv,   len); 
    1204       flag_err = sl_strncmp(answer, 
    1205                             sh_util_siggen(skey->session,  
    1206                                            buffer, 
    1207                                            sl_strlen(buffer), 
    1208                                            sigbuf, sizeof(sigbuf)), 
    1209                             KEY_LEN); 
     1204      flag_err = sl_ts_strncmp(answer, 
     1205                               sh_util_siggen(skey->session,  
     1206                                              buffer, 
     1207                                              sl_strlen(buffer), 
     1208                                              sigbuf, sizeof(sigbuf)), 
     1209                               KEY_LEN); 
    12101210      TPT((0, FIL__, __LINE__, _("msg=<sign %s.>\n"), 
    12111211           sh_util_siggen(skey->session, buffer,  
  • trunk/src/sh_xfer_server.c

    r541 r544  
    11981198              KEY_LEN+1); 
    11991199   
    1200   if (0 != sl_strncmp(conn->K, conn->buf, KEY_LEN)) 
     1200  if (0 != sl_ts_strncmp(conn->K, conn->buf, KEY_LEN)) 
    12011201    { 
    12021202      TPT((0, FIL__, __LINE__, _("msg=<clt %s>\n"), conn->buf)); 
     
    16641664           */ 
    16651665          buffer = sh_util_strconcat(conn->buf, conn->challenge, NULL); 
    1666           i =  sl_strncmp(hash,  
    1667                           sh_util_siggen(conn->client_entry->session_key, 
    1668                                          buffer, 
    1669                                          sl_strlen(buffer), 
    1670                                          sigbuf, sizeof(sigbuf)), 
    1671                           KEY_LEN); 
     1666          i =  sl_ts_strncmp(hash,  
     1667                             sh_util_siggen(conn->client_entry->session_key, 
     1668                                            buffer, 
     1669                                            sl_strlen(buffer), 
     1670                                            sigbuf, sizeof(sigbuf)), 
     1671                             KEY_LEN); 
    16721672          TPT((0, FIL__, __LINE__, _("msg=<sign %s.>\n"), 
    16731673               sh_util_siggen(conn->client_entry->session_key, 
     
    20882088      TPT((0, FIL__, __LINE__, _("msg=<c/r: P = %s>\n"), conn->M1)); 
    20892089       
    2090       if ( 0 != sl_strncmp(conn->M1, conn->buf, KEY_LEN)) 
     2090      if ( 0 != sl_ts_strncmp(conn->M1, conn->buf, KEY_LEN)) 
    20912091        { 
    20922092          sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_BADCONN, 
     
    24142414       */ 
    24152415      if (conn->buf != NULL &&  
    2416           sl_strncmp(conn->buf, conn->M1, KEY_LEN) == 0) 
     2416          sl_ts_strncmp(conn->buf, conn->M1, KEY_LEN) == 0) 
    24172417        { 
    24182418          /* 
  • trunk/src/slib.c

    r539 r544  
    588588/* 
    589589 * Have memset in a different translation unit (i.e. this) to prevent  
    590  * it to get optimized away 
     590 * it to get optimized away ...not safe with link-time optimisation... 
    591591 */ 
    592 void *sl_memset(void *s, int c, size_t n) 
    593 { 
    594   return memset(s, c,n); 
     592void * sl_memset(void *s, int c, size_t n) 
     593{ 
     594  /* See: 
     595   * https://www.usenix.org/sites/default/files/conference/protected-files/usenixsecurity17_slides_zhaomo_yang.pdf 
     596   */ 
     597#if defined(HAVE_EXPLICIT_MEMSET) 
     598  return explicit_memset(s, c, n); 
     599#elif defined(HAVE_EXPLICIT_BZERO) 
     600  if (c == 0) { 
     601    explicit_bzero(s, n); 
     602    return s; 
     603  } else { 
     604    return memset(s, c, n); 
     605  } 
     606#elif defined(__GNUC__) 
     607  memset(s, c, n); 
     608  __asm__  __volatile__ ("" ::"r"(s): "memory"); /* compiler barrier */ 
     609  return s; 
     610#else 
     611  if (c == 0) { 
     612    size_t i; 
     613    volatile unsigned char * t_s = (volatile unsigned char *)s; 
     614    for (i=0; i<n; ++i) 
     615      t_s[i] = 0; 
     616    return s; 
     617  } else { 
     618    return memset(s, c, n); 
     619  } 
     620#endif   
    595621} 
    596622 
     
    10711097  if (a != NULL && b != NULL) 
    10721098    return (strcmp(a, b)); 
     1099  else if (a == NULL && b != NULL) 
     1100    return (-1); 
     1101  else if (a != NULL && b == NULL) 
     1102    return (1); 
     1103  else 
     1104    return (-7); /* default to not equal */ 
     1105} 
     1106 
     1107/* Does not report sign. */ 
     1108int sl_ts_strncmp(const char * a, const char * b, size_t n) 
     1109{ 
     1110#ifdef SL_FAIL_ON_ERROR 
     1111  SL_REQUIRE (a != NULL, _("a != NULL")); 
     1112  SL_REQUIRE (b != NULL, _("b != NULL")); 
     1113  SL_REQUIRE (n > 0, _("n > 0")); 
     1114#endif 
     1115 
     1116  if (a != NULL && b != NULL) 
     1117    { 
     1118      const unsigned char *a1 = (const unsigned char *)a; 
     1119      const unsigned char *b1 = (const unsigned char *)b; 
     1120      size_t i; 
     1121      int  retval=0; 
     1122      /* The simple index based access is optimized best by the 
     1123       * compiler (tested with gcc 7.3.0). */ 
     1124      for (i = 0; i < n; ++i) 
     1125        { 
     1126          if (a1[i] == '\0' || b1[i] == '\0') 
     1127            break; 
     1128          retval |= (a1[i] ^ b1[i]); 
     1129        } 
     1130      /* if (retval == 0) --> false (0) */  
     1131      return (retval != 0); 
     1132    } 
    10731133  else if (a == NULL && b != NULL) 
    10741134    return (-1); 
Note: See TracChangeset for help on using the changeset viewer.