]> sourceware.org Git - annobin.git/commitdiff
Annocheck: Extend section size tool to allow for searching for sections or segments...
authorNick Clifton <nickc@redhat.com>
Fri, 1 Feb 2019 15:12:25 +0000 (15:12 +0000)
committerNick Clifton <nickc@redhat.com>
Fri, 1 Feb 2019 15:12:25 +0000 (15:12 +0000)
annocheck/annocheck.c
annocheck/size.c
doc/annobin.info
doc/annobin.texi
doc/annocheck.1
plugin/annobin.cc

index 20a6de14202bb5bc8cb5e89d88f9040551cee1cd..f4186fd8f5527f6aeec44d8f8baabe7737bd8123 100644 (file)
@@ -32,7 +32,7 @@ ulong         verbosity = 0;
    version_string definitions in annobin.cc.
    FIXME: This value should be defined in only one place...  */
 const uint              major_version = 8;
-const uint              minor_version = 69;
+const uint              minor_version = 70;
 
 static ulong           num_files = 0;
 static const char *     files[MAX_NUM_FILES];
index 1ec55f9720c27716c66298ef34b29d2a8928a66a..f8cdc97386923f4208f844134a05c34cd67e7652 100644 (file)
 static bool disabled = true;
 static bool human = false;
 
+static Elf64_Word sec_need_flags = 0;
+static Elf64_Word sec_not_flags = 0;
+static Elf64_Word sec_flag_size = 0;
+static uint       sec_flag_match = 0;
+
+static Elf64_Word seg_need_flags = 0;
+static Elf64_Word seg_not_flags = 0;
+static Elf64_Word seg_flag_size = 0;
+static uint       seg_flag_match = 0;
+
+
 typedef struct sec_size
 {
   const char *        name;
@@ -82,11 +93,58 @@ size_interesting_sec (annocheck_data *     data,
        }
     }
 
+  if (sec_need_flags || sec_not_flags)
+    {
+      if ((sec->shdr.sh_flags & sec_need_flags) == sec_need_flags
+         && (sec->shdr.sh_flags & sec_not_flags) == 0)
+       {
+         if (BE_VERBOSE)
+           {
+             einfo (VERBOSE, "%s: flag match for section %s, size: ",
+                    data->filename, sec->secname);
+             print_size (sec->shdr.sh_size);
+             einfo (PARTIAL, "\n");
+           }
+         sec_flag_match ++;
+         sec_flag_size += sec->shdr.sh_size;
+       }
+    }
+
   /* We do not need any more information from the section, so there is no
      need to run the checker.  */
   return false;
 }
 
+static bool
+size_interesting_seg (annocheck_data *     data,
+                     annocheck_segment *  seg)
+{
+  if (disabled)
+    return false;
+
+  if (seg_need_flags || seg_not_flags)
+    {
+      if ((seg->phdr->p_flags & seg_need_flags) == seg_need_flags
+         && (seg->phdr->p_flags & seg_not_flags) == 0)
+       {
+         if (BE_VERBOSE)
+           {
+             einfo (VERBOSE, "%s: flag match for segment %d, size: ",
+                    data->filename, seg->number);
+             print_size (seg->phdr->p_memsz);
+             einfo (PARTIAL, "\n");
+           }
+
+         seg_flag_match ++;
+         seg_flag_size += seg->phdr->p_memsz;
+       }
+    }
+
+  /* We do not need any more information from the segment,
+     so there is no need to run the checker.  */
+  return false;
+}
+
 /* This function is needed so that a data transfer file will be created.  */
 
 static void
@@ -133,6 +191,21 @@ size_end_scan (uint level, const char * datafile)
            }
        }
 
+      uint sec_count, seg_count;
+      unsigned long long sec_size, seg_size;
+
+      if (fscanf (f, "%u %llx %u %llx\n", & sec_count, & sec_size, & seg_count, & seg_size) != 4)
+       {
+         einfo (WARN, "Unable to locate section/segment flag size & counts");
+       }
+      else
+       {
+         sec_flag_match += sec_count;
+         sec_flag_size += sec_size;
+         seg_flag_match += seg_count;
+         seg_flag_size += seg_size;
+       }
+
       fclose (f);
     }
 
@@ -145,6 +218,20 @@ size_end_scan (uint level, const char * datafile)
          einfo (PARTIAL, "\n");
        }
 
+      if (sec_need_flags || sec_not_flags)
+       {
+         einfo (INFO, "%u sections match flag requirements, total size: ", sec_flag_match);
+         print_size (sec_flag_size);
+         einfo (PARTIAL, "\n");
+       }
+       
+      if (seg_need_flags || seg_not_flags)
+       {
+         einfo (INFO, "%u segments match flag requirements, total size: ", seg_flag_match);
+         print_size (seg_flag_size);
+         einfo (PARTIAL, "\n");
+       }
+       
       einfo (VERBOSE2, "Deleting data file %s", datafile);
       unlink (datafile);
     }
@@ -157,13 +244,16 @@ size_end_scan (uint level, const char * datafile)
 
       if (f == NULL)
        {
-         einfo (WARN, "unable to open datafile %s", datafile);
+         einfo (WARN, "Unable to open datafile %s", datafile);
          return;
        }
 
       for (sec = sec_list; sec != NULL; sec = sec->next)
        fprintf (f, "%s %llx %x\n", sec->name, sec->size, sec->num_found);
 
+      fprintf (f, "%u %llx %u %llx\n",
+              sec_flag_match, (unsigned long long) sec_flag_size,
+              seg_flag_match, (unsigned long long) seg_flag_size);
       fclose (f);
     }
 }
@@ -171,7 +261,46 @@ size_end_scan (uint level, const char * datafile)
 static bool
 size_process_arg (const char * arg, const char ** argv, const uint argc, uint * next)
 {
-  if (const_strneq (arg, "--section-size"))
+  if (const_strneq (arg, "--size-sec-flags="))
+    {
+      const char * flag = arg + strlen ("--size-sec-flags=");
+      Elf64_Word * addto = & sec_need_flags;
+      
+      disabled = false;
+
+      while (*flag)
+       {
+         switch (*flag)
+           {
+           case '!':
+             /* Inverts the meaning of the following flags.  */
+             addto = & sec_not_flags;
+             break;
+           case 'w':
+           case 'W':
+             * addto |= SHF_WRITE;
+             break;
+           case 'a':
+           case 'A':
+             * addto |= SHF_ALLOC;
+             break;
+           case 'x':
+           case 'X':
+             * addto |= SHF_EXECINSTR;
+             break;
+           default:
+             /* FIXME: Add more section flags.  */
+             einfo (WARN, "Unrecognised section flag '%c'", *flag);
+             break;
+           }
+         ++ flag;
+       }
+
+      return true;
+    }
+  
+  if (const_strneq (arg, "--section-size") /* Deprecated.  */
+      || const_strneq (arg, "--size-sec"))
     {
       const char * parameter;
       const char * sought;
@@ -193,12 +322,51 @@ size_process_arg (const char * arg, const char ** argv, const uint argc, uint *
       return true;
     }
 
-  if (streq (arg, "--human"))
+  if (streq (arg, "--human") /* Deprecated.  */
+      || streq (arg, "--size-human"))
     {
       human = true;
       return true;
     }
 
+  if (const_strneq (arg, "--size-seg-flags="))
+    {
+      const char * flag = arg + strlen ("--size-seg-flags=");
+      Elf64_Word * addto = & seg_need_flags;
+      
+      disabled = false;
+
+      while (*flag)
+       {
+         switch (*flag)
+           {
+           case '!':
+             /* Inverts the meaning of the following flags.  */
+             addto = & seg_not_flags;
+             break;
+           case 'w':
+           case 'W':
+             * addto |= PF_W;
+             break;
+           case 'r':
+           case 'R':
+             * addto |= PF_R;
+             break;
+           case 'x':
+           case 'X':
+             * addto |= PF_X;
+             break;
+           default:
+             /* FIXME: Add more segment flags.  */
+             einfo (WARN, "Unrecognised segment flag '%c'", *flag);
+             break;
+           }
+         ++ flag;
+       }
+
+      return true;
+    }
+  
   return false;
 }
 
@@ -207,15 +375,17 @@ size_usage (void)
 {
   einfo (INFO, "Computes the cumulative size of the specified section(s) in the input files");
   einfo (INFO, " NOTE: This tool is disabled by default.  To enable it use: --section-size=<NAME>");
-  einfo (INFO, " --section-size=<NAME>   Records the size of section NAME.  Can be used more than once");
+  einfo (INFO, " --size-sec=<NAME>   Records the size of section NAME.  Can be used more than once");
   einfo (INFO, " If --verbose has been enabled then the size of every encountered NAME section will be displayed");
-  einfo (INFO, " Use --human to display the sizes in human readable amounts");
+  einfo (INFO, " Use --size-human to display the sizes in human readable amounts");
+  einfo (INFO, " Use --size-sec-flags=[!WAX] to count the size of any section with/without the specified flags");
+  einfo (INFO, " Use --size-seg-flags=[!WRX] to count the size of any segment with/without the specified flags");
 }
 
 static void
 size_version (void)
 {
-  einfo (INFO, "Version 1.0");
+  einfo (INFO, "Version 1.1");
 }
 
 struct checker size_checker = 
@@ -224,7 +394,7 @@ struct checker size_checker =
   NULL, /* file_start */
   size_interesting_sec,
   NULL, /* check_sec */
-  NULL, /* interesting_seg */
+  size_interesting_seg,
   NULL, /* check_seg */
   NULL, /* end_file */
   size_process_arg,
index adad5fe2c3371e8860da4f22b48aa7f11dfa2e5a..8cb09d4e7510f9cbb30a0fb1edea7e5d5dcf486c 100644 (file)
@@ -582,7 +582,8 @@ code to support the test.
 
 'BIND_NOW'
      Lazy binding must not have been enabled via the linker option '-z
-     now'.  Disabled by '--skip-bind-now'.
+     lazy'.  Instead the '-z now' option must have been used.  Disabled
+     by '--skip-bind-now'.
 
 'Non executable stack'
      The program must not have a stack in an executable region of
@@ -597,8 +598,8 @@ code to support the test.
      execute permission bits set.  Disabled by '--skip-rwx-seg'.
 
 'No text relocations'
-     The should be no relocations against executable code.  Disabled by
-     '--skip-textrel'.
+     There should be no relocations against executable code.  Disabled
+     by '--skip-textrel'.
 
 'Correct runpaths'
      The runpath information used to locate shared libraries at runtime
@@ -706,8 +707,10 @@ File: annobin.info,  Node: Section-Size,  Next: Timing,  Prev: Notes,  Up: Annoc
 
      annocheck
        [-disable-hardened]
-       -section-size=NAME
-       [-human]
+       [-size-sec=NAME]
+       [-size-sec-flags=!WAX]
+       [-size-seg-flags=!WRX]
+       [-size-human]
        FILE...
 
    The SECTION-SIZE tool records the size of named sections within a
@@ -715,15 +718,32 @@ list of files and then reports the accumulated size at the end.  Since
 it is part of the 'annocheck' framework, it is able to handle
 directories and rpms files as well as ordinary binary files.
 
-   The '--section-size=NAME' option enables the tool and tells it to
-record the size of section NAME.  The option can be repeated multiple
-times to record the sizes of multiple sections.  It may also be useful
-to add the '--disable-hardened' option to the command line as otherwise
-the security hardening will be run at the same time.
+   The '--size-sec=NAME' option enables the tool and tells it to record
+the size of section NAME.  The option can be repeated multiple times to
+record the sizes of multiple sections.  It may also be useful to add the
+'--disable-hardened' option to the command line as otherwise the
+security hardening will be run at the same time.
+
+   Instead of searching for named sections, it is also possible to
+search for sections with specific flags.  The '--size-sec-flags=<flags>'
+option will search for any section that has all of the specified <FLAGS>
+set.  Currently only W, A and X are recognised as flags, indicating that
+the section must have the WRITE, ALLOC or EXECUTE flags set
+respectively.  If the ! exclamation mark character is present then it
+negates the meaning of the following flags.  Thus
+'--section-sec-flags=W' option will search for any writeable section
+whereas the '--size-sec-flags=W!A' option will search only for sections
+that are writeable but not allocated.
+
+   Instead of searching for sections by flags it is also possible to
+search for segments by flags using the '--size-seg-flags=<flags>'
+option.  The flags recognised for segments are W for writeable, R for
+readable and X for executable.  Again the ! character can be used to
+invert the meaning of the flags that follow it.
 
    If the '--verbose' option is enabled, then the tool will also report
 the size of the named section(s) in each file it encounters.  If the
-'--human' option is enabled then sizes will be rounded down to the
+'--size-human' option is enabled then sizes will be rounded down to the
 nearest byte, kibibyte, mebibyte or gibibyte, as appropriate.
 
 \1f
@@ -1692,14 +1712,14 @@ Node: The ENUM Encoding\7f16192
 Node: Annocheck\7f16549
 Node: Built-By\7f19075
 Node: Hardened\7f20605
-Node: Notes\7f25402
-Node: Section-Size\7f26046
-Node: Timing\7f27167
-Node: Legacy Scripts\7f27814
-Node: Who Built Me\7f28581
-Node: ABI Checking\7f31341
-Node: Hardening Checks\7f33455
-Node: Checking Archives\7f37541
-Node: GNU FDL\7f39963
+Node: Notes\7f25460
+Node: Section-Size\7f26104
+Node: Timing\7f28258
+Node: Legacy Scripts\7f28905
+Node: Who Built Me\7f29672
+Node: ABI Checking\7f32432
+Node: Hardening Checks\7f34546
+Node: Checking Archives\7f38632
+Node: GNU FDL\7f41054
 \1f
 End Tag Table
index 16adebd17ce59cb999fc7c0cc23ea417230b8866..d9784d19819bb55208c9d55ee737c1e270a9766f 100644 (file)
@@ -679,7 +679,8 @@ creating the necessary code to support the test.
 
 @item BIND_NOW
 Lazy binding must not have been enabled via the linker option
-@option{-z now}.
+@option{-z lazy}.  Instead the @option{-z now} option must have been
+used.
 Disabled by @option{--skip-bind-now}.
 
 @item Non executable stack
@@ -696,7 +697,7 @@ execute permission bits set.
 Disabled by @option{--skip-rwx-seg}.
 
 @item No text relocations
-The should be no relocations against executable code.
+There should be no relocations against executable code.
 Disabled by @option{--skip-textrel}.
 
 @item Correct runpaths
@@ -827,8 +828,10 @@ the @option{--disable-hardened} option to the command line.
 
 annocheck
   [@b{--disable-hardened}]
-  @b{--section-size=@var{name}}
-  [@b{--human}]
+  [@b{--size-sec=@var{name}}]
+  [@b{--size-sec-flags=@var{!WAX}}]
+  [@b{--size-seg-flags=@var{!WRX}}]
+  [@b{--size-human}]
   @var{file}@dots{}
 @c man end
 @end smallexample
@@ -839,17 +842,36 @@ a list of files and then reports the accumulated size at the end.
 Since it is part of the @command{annocheck} framework, it is able to
 handle directories and rpms files as well as ordinary binary files.
 
-The @option{--section-size=@var{name}} option enables the tool and
+The @option{--size-sec=@var{name}} option enables the tool and
 tells it to record the size of section @var{name}.  The option can be
 repeated multiple times to record the sizes of multiple sections.  It
 may also be useful to add the @option{--disable-hardened} option to
 the command line as otherwise the security hardening will be run at
 the same time.
 
+Instead of searching for named sections, it is also possible to search
+for sections with specific flags.  The @option{--size-sec-flags=<flags>}
+option will search for any section that has all of the specified
+@var{<flags>} set.  Currently only @var{W}, @var{A} and @var{X} are
+recognised as flags, indicating that the section must have the
+@var{Write}, @var{Alloc} or @var{Execute} flags set respectively.  If
+the @var{!} exclamation mark character is present then it negates the
+meaning of the following flags.  Thus @option{--section-sec-flags=W}
+option will search for any writeable section whereas the
+@option{--size-sec-flags=W!A} option will search only for sections
+that are writeable but not allocated.
+
+Instead of searching for sections by flags it is also possible to
+search for segments by flags using the
+@option{--size-seg-flags=<flags>} option.  The flags recognised for
+segments are @var{W} for writeable, @var{R} for readable and @var{X}
+for executable.  Again the @var{!} character can be used to invert the
+meaning of the flags that follow it.
+
 If the @option{--verbose} option is enabled, then the tool will also
 report the size of the named section(s) in each file it encounters.
-If the @option{--human} option is enabled then sizes will be rounded
-down to the nearest byte, kibibyte, mebibyte or gibibyte, as
+If the @option{--size-human} option is enabled then sizes will be
+rounded down to the nearest byte, kibibyte, mebibyte or gibibyte, as
 appropriate.
 
 @c man end
index df0e704b438be13b398e42d5cb15c4ec464ff3a7..b0ddbc7840d471246f59a681f0ae3065ba0ebdba 100644 (file)
 .\" ========================================================================
 .\"
 .IX Title "ANNOCHECK 1"
-.TH ANNOCHECK 1 "2019-01-24" "annobin-1" "RPM Development Tools"
+.TH ANNOCHECK 1 "2019-02-01" "annobin-1" "RPM Development Tools"
 .\" For nroff, turn off justification.  Always turn off hyphenation; it makes
 .\" way too many mistakes in technical documents.
 .if n .ad l
@@ -195,8 +195,10 @@ annocheck
 .PP
 annocheck
   [\fB\-\-disable\-hardened\fR]
-  \fB\-\-section\-size=\fR\fIname\fR
-  [\fB\-\-human\fR]
+  [\fB\-\-size\-sec=\fR\fIname\fR]
+  [\fB\-\-size\-sec\-flags=\fR\fI!WAX\fR]
+  [\fB\-\-size\-seg\-flags=\fR\fI!WRX\fR]
+  [\fB\-\-size\-human\fR]
   \fIfile\fR...
 .PP
 annocheck
@@ -318,7 +320,8 @@ creating the necessary code to support the test.
 .el .IP "\f(CWBIND_NOW\fR" 4
 .IX Item "BIND_NOW"
 Lazy binding must not have been enabled via the linker option
-\&\fB\-z now\fR.
+\&\fB\-z lazy\fR.  Instead the \fB\-z now\fR option must have been
+used.
 Disabled by \fB\-\-skip\-bind\-now\fR.
 .ie n .IP """Non executable stack""" 4
 .el .IP "\f(CWNon executable stack\fR" 4
@@ -339,7 +342,7 @@ Disabled by \fB\-\-skip\-rwx\-seg\fR.
 .ie n .IP """No text relocations""" 4
 .el .IP "\f(CWNo text relocations\fR" 4
 .IX Item "No text relocations"
-The should be no relocations against executable code.
+There should be no relocations against executable code.
 Disabled by \fB\-\-skip\-textrel\fR.
 .ie n .IP """Correct runpaths""" 4
 .el .IP "\f(CWCorrect runpaths\fR" 4
@@ -457,17 +460,36 @@ a list of files and then reports the accumulated size at the end.
 Since it is part of the \fBannocheck\fR framework, it is able to
 handle directories and rpms files as well as ordinary binary files.
 .PP
-The \fB\-\-section\-size=\fR\fIname\fR option enables the tool and
+The \fB\-\-size\-sec=\fR\fIname\fR option enables the tool and
 tells it to record the size of section \fIname\fR.  The option can be
 repeated multiple times to record the sizes of multiple sections.  It
 may also be useful to add the \fB\-\-disable\-hardened\fR option to
 the command line as otherwise the security hardening will be run at
 the same time.
 .PP
+Instead of searching for named sections, it is also possible to search
+for sections with specific flags.  The \fB\-\-size\-sec\-flags=<flags>\fR
+option will search for any section that has all of the specified
+\&\fI<flags>\fR set.  Currently only \fIW\fR, \fIA\fR and \fIX\fR are
+recognised as flags, indicating that the section must have the
+\&\fIWrite\fR, \fIAlloc\fR or \fIExecute\fR flags set respectively.  If
+the \fI!\fR exclamation mark character is present then it negates the
+meaning of the following flags.  Thus \fB\-\-section\-sec\-flags=W\fR
+option will search for any writeable section whereas the
+\&\fB\-\-size\-sec\-flags=W!A\fR option will search only for sections
+that are writeable but not allocated.
+.PP
+Instead of searching for sections by flags it is also possible to
+search for segments by flags using the
+\&\fB\-\-size\-seg\-flags=<flags>\fR option.  The flags recognised for
+segments are \fIW\fR for writeable, \fIR\fR for readable and \fIX\fR
+for executable.  Again the \fI!\fR character can be used to invert the
+meaning of the flags that follow it.
+.PP
 If the \fB\-\-verbose\fR option is enabled, then the tool will also
 report the size of the named section(s) in each file it encounters.
-If the \fB\-\-human\fR option is enabled then sizes will be rounded
-down to the nearest byte, kibibyte, mebibyte or gibibyte, as
+If the \fB\-\-size\-human\fR option is enabled then sizes will be
+rounded down to the nearest byte, kibibyte, mebibyte or gibibyte, as
 appropriate.
 .PP
 The \fItiming\fR tool reports on the time taken by other tools to
index 5f7f80d8d2ec8654c02207af38790866830f6c83..43b8309e2d3f0cd6c3e645d48c0189d7c0705202 100644 (file)
@@ -31,8 +31,8 @@
    Also, keep in sync with the major_version and minor_version definitions
    in annocheck.c.
    FIXME: This value should be defined in only one place...  */
-static unsigned int   annobin_version = 869;
-static const char *   version_string = N_("Version 869");
+static unsigned int   annobin_version = 870;
+static const char *   version_string = N_("Version 870");
 
 /* Prefix used to isolate annobin symbols from program symbols.  */
 #define ANNOBIN_SYMBOL_PREFIX ".annobin_"
This page took 0.043333 seconds and 5 git commands to generate.