]> git.ipfire.org Git - ipfire-3.x.git/commitdiff
QA: Update quality-agent.
authorMichael Tremer <michael.tremer@ipfire.org>
Mon, 5 Apr 2010 13:10:13 +0000 (15:10 +0200)
committerMichael Tremer <michael.tremer@ipfire.org>
Mon, 5 Apr 2010 13:11:22 +0000 (15:11 +0200)
Added some new checks and replaced scanelf by readelf.

18 files changed:
tools/common-functions
tools/quality-agent
tools/quality-agent.d/001-include-files
tools/quality-agent.d/001-remove-info-files
tools/quality-agent.d/001-remove-static-libs
tools/quality-agent.d/001-unsafe-files
tools/quality-agent.d/002-bad-symlinks
tools/quality-agent.d/003-libs-location
tools/quality-agent.d/050-canary [new file with mode: 0755]
tools/quality-agent.d/050-execstacks
tools/quality-agent.d/050-libs-needed
tools/quality-agent.d/050-libs-soname [changed mode: 0644->0755]
tools/quality-agent.d/050-nx [new file with mode: 0755]
tools/quality-agent.d/050-relro [new file with mode: 0755]
tools/quality-agent.d/050-rpaths
tools/quality-agent.d/050-textrels [deleted file]
tools/quality-agent.d/095-directory-layout
tools/quality-agent.d/qa-include

index d887a5c08d177159a610dfa0269bc064fa481bb8..e3c8928d0deae9d8ec11218961a8f48a33c61759 100644 (file)
@@ -4,6 +4,53 @@ LIBARY_PATHS="${BUILDROOT}/lib ${BUILDROOT}/usr/lib"
 BINARY_PATHS="${LIBARY_PATHS} ${BUILDROOT}/bin ${BUILDROOT}/sbin"
 BINARY_PATHS="${BINARY_PATHS} ${BUILDROOT}/usr/bin ${BUILDROOT}/usr/sbin"
 
+has_canary() {
+       local file=${1}
+
+       readelf -s ${file} | grep -q "__stack_chk_fail"
+}
+
+has_execstack() {
+       local file=${1}
+
+       readelf -h ${file} | grep -qE "Type:[[:space:]]*EXEC"
+}
+
+has_interpreter() {
+       local file=${1}
+
+       [ -n "$(get_interpreter ${file})" ]
+}
+
+has_nx() {
+       local file=${1}
+
+       readelf -l ${file} | grep "GNU_STACK" | grep -q "RWE"
+       [ $? != 0 ]
+}
+
+is_relro_partly() {
+       local file=${1}
+
+       readelf -l ${file} | grep -q "GNU_RELRO"
+}
+
+is_relro_full() {
+       local file=${1}
+
+       if is_relro_partly ${file}; then
+               readelf -d ${file} | grep -q "BIND_NOW"
+               return $?
+       fi
+       return 1
+}
+
+is_shared_object() {
+       local file=${1}
+
+       file ${file} | grep -q "shared object"
+}
+
 get_interpreter() {
        local file=${1}
 
@@ -18,6 +65,13 @@ get_needed() {
                tr -d "[]" | awk '{ print $NF }'
 }
 
+get_rpath() {
+       local file=${1}
+
+       readelf -d ${file} | grep RPATH | \
+               tr -d "[]" | awk '{ print $NF }'
+}
+
 get_soname() {
        local file=${1}
 
@@ -58,7 +112,7 @@ find_elf_files() {
 
        for dir in ${dirs}; do
                for file in $(find ${dir} -maxdepth 1 -type f 2>/dev/null); do
-                       if file ${file} | grep -q ELF; then
+                       if file ${file} | grep -q "ELF"; then
                                files="${files} ${file}"
                        fi
                done
index 45e2560497135f6dd10348fdb7e09c87d2e038c9..57d06680ff319d0b780a20723d75e199129479f5 100755 (executable)
@@ -2,10 +2,11 @@
 
 DIR_QA=${0}.d
 
+failed=0
 for file in ${DIR_QA}/*; do
        [ -x "${file}" ] || continue
 
-       ${file} || exit $?
+       ${file} || failed=1
 done
 
-exit 0
+exit ${failed}
index abf683cec69e4fbdda94c6eb97548bd74ecfd4c7..34257e6903a9ac79bba6c359717dcd95d15350c0 100755 (executable)
@@ -2,11 +2,15 @@
 
 . $(dirname ${0})/qa-include
 
-# Fix include files
-log "Fix include files"
+DESC="Include files have to belong to the root user. \
+       This script will fix this automatically."
 
-if [ ! -d "${BUILDROOT}/usr/include" ]; then
-       exit 0
-fi
+check() {
+       if [ ! -d "${BUILDROOT}/usr/include" ]; then
+               return 0
+       fi
+       
+       chown -R root:root ${BUILDROOT}/usr/include
+}
 
-chown -R root:root ${BUILDROOT}/usr/include
+run
index 9b8db23d63f29bbb227dfd8f5f1bc2712ec07760..6e2ff0f291da1df1a1b07f93fcfc87e8d8531a49 100755 (executable)
@@ -3,10 +3,10 @@
 . $(dirname ${0})/qa-include
 
 # Remove documentation files
-log "Removing documentation files..."
+log_debug "Removing documentation files..."
 for dir in ${BUILDROOT}/usr/{,share}/{doc,info}; do
        if [ -d "${dir}" ]; then
-               log "  Removing: ${dir}"
+               log_debug "  Removing: ${dir}"
                rm -rf ${dir} || exit $?
        fi
 done
index 331a0f271aabad09ef410e7b4723b4308fa0640f..cbeabf21ecc402771cc30641765f431958e0a784 100755 (executable)
@@ -3,7 +3,7 @@
 . $(dirname ${0})/qa-include
 
 # Remove unwanted files
-log "Removing unwanted files: *.a *.la"
+log_debug "Removing unwanted files: *.a *.la"
 for file in $(find ${BUILDROOT} -name "*.a" -or -name "*.la"); do
        
        # Don't remove libc_nonshared.a. It is used by gcc/ld.
@@ -14,7 +14,7 @@ for file in $(find ${BUILDROOT} -name "*.a" -or -name "*.la"); do
        [ "${file##*/}" = "libfl_pic.a" ] && continue
        [ "${file##*/}" = "libpython2.6.a" ] && continue
        
-       log "  Removing: ${file}"
+       log_debug "  Removing: ${file}"
        rm -f ${file} || exit $?
 done
 
index 34e94832485fa2e7050b7cfa9c9253e53d3039e8..547a1b1ce5f558642f0c4ca8de9acfc6ae63b224 100755 (executable)
@@ -2,24 +2,24 @@
 
 . $(dirname ${0})/qa-include
 
-log "Searching for world-writeable files..."
+log_debug "Searching for world-writeable files..."
 
 files=$(find ${BUILDROOT} -type f -perm -2 2>/dev/null)
 if [ -n "${files}" ]; then
-       log "  QA Security Notice:"
-       log "   - The folloing files will be world writable."
-       log "   - This may or may not be a security problem, most of the time it is one."
-       log "   - Please double check that these files really need a world writeable bit and file bugs accordingly."
-       log
-       log "${files}"
+       log_error "  QA Security Notice:"
+       log_error "   - The folloing files will be world writable."
+       log_error "   - This may or may not be a security problem, most of the time it is one."
+       log_error "   - Please double check that these files really need a world writeable bit and file bugs accordingly."
+       log_error
+       log_error "${files}"
        exit 1
 fi
 
 files=$(find ${BUILDROOT} -type f '(' -perm -2002 -o -perm -4002 ')')
 if [ -n "${files}" ]; then
-       log "  QA Notice: Unsafe files detected (set*id and world writable)"
-       log
-       log "${files}"
+       log_error "  QA Notice: Unsafe files detected (set*id and world writable)"
+       log_error
+       log_error "${files}"
        exit 1
 fi
 
index f3217fd7bdfbae80980304fc2d6603101ebc03fd..e05fc82397598ad7f6fff33a8f83aab3751d1a37 100755 (executable)
@@ -5,17 +5,17 @@
 # Check for absolute symlinks.
 # We do not allow them because they may point to any bad location.
 
-log "Search for absolute symlinks"
+log_debug "Search for absolute symlinks"
 
 failed=0
 for link in $(find ${BUILDROOT} -type l); do
        destination=$(readlink ${link})
        if [ "${destination:0:1}" = "/" ]; then
-               log "  absolute symlink: ${link}"
+               log_error "  absolute symlink: ${link}"
                failed=1
        fi
        if [ ! -e "${link%/*}/${destination}" ]; then
-               log "  not existant destination: ${link} -> ${destination}"
+               log_error "  not existant destination: ${link} -> ${destination}"
                failed=1
        fi
 done
index 09a4280b1e4729124b5e5feba7ce19657aa5a723..3d29bea7aa5a60d0886a69ce8e1cf7f46cddbfd1 100755 (executable)
@@ -4,7 +4,7 @@
 
 # Check for libs that are missing in /usr/lib.
 
-log "Checking correct installation of libraries"
+log_debug "Checking correct installation of libraries"
 
 failed=0
 for lib in $(find ${BUILDROOT}/lib -type f -name "lib*.so.*" 2>/dev/null); do
@@ -13,7 +13,7 @@ for lib in $(find ${BUILDROOT}/lib -type f -name "lib*.so.*" 2>/dev/null); do
 
        if [ ! -e "${BUILDROOT}/usr/lib/${lib}.so" ]; then
                failed=1
-               log "  /usr/lib/${lib}.so is missing"
+               log_error "  /usr/lib/${lib}.so is missing"
        fi
 done
 
diff --git a/tools/quality-agent.d/050-canary b/tools/quality-agent.d/050-canary
new file mode 100755 (executable)
index 0000000..9841d5a
--- /dev/null
@@ -0,0 +1,21 @@
+#!/bin/bash
+
+. $(dirname ${0})/qa-include
+
+DESC="Every binary file has to provide a canary."
+
+function check() {
+       local failed=0
+
+       local file
+       for file in $(find_elf_files ${BINARY_PATHS}); do
+               if ! has_canary ${file}; then
+                       log_error "  Has no canary: ${file}"
+                       failed=1
+               fi
+       done
+
+       return ${failed}
+}
+
+run
index ce384f1b968aee42256f9b277e340b1e44a78dac..d3aace659fae532afbc7f20fe0da057f60d7bccd 100755 (executable)
@@ -2,32 +2,21 @@
 
 . $(dirname ${0})/qa-include
 
-# Also, executable stacks only matter on linux...
-log "Searching for executeable stacks"
+DESC="Files with executable stacks will not work properly (or at all!) \
+       on some architectures/operating systems."
 
-command="scanelf -qyRF '%e %p' ${BUILDROOT} 2>/dev/null"
+check() {
+       local failed=0
 
-for i in $QUALITY_AGENT_WHITELIST_EXECSTACK; do
-       if [ -n "$FILTER" ]; then
-               FILTER="$FILTER|$i"
-       else
-               FILTER="$i"
-       fi
-done
+       local file
+       for file in $(find_elf_files ${BINARY_PATHS}); do
+               if has_execstack ${file}; then
+                       log_error "  File has execstack: ${file}"
+                       failed=1
+               fi
+       done
 
-if [ -n "$FILTER" ]; then
-       log "  Filter: $FILTER"
-       command="$command | grep -vE \"$FILTER\""
-fi
+       return ${failed}
+}
 
-files=$(${command})
-if [ -n "${files}" ]; then
-       log "  QA Notice: The following files contain executable stacks"
-       log "   Files with executable stacks will not work properly (or at all!)"
-       log "   on some architectures/operating systems."
-       log "${files}"
-
-       exit 1
-fi
-
-exit 0
+run
index 3fefe61e510780a64e38c0437999413fd1e588b2..dbc6196d417aeb8ff3345b04130ad24be4fe317f 100755 (executable)
@@ -2,17 +2,30 @@
 
 . $(dirname ${0})/qa-include
 
-check_files=$(find ${BUILDROOT} -name lib*.so)
+DESC="Every shared object has to provide the NEEDED entry."
 
-log "Searching bad libs that lack the NEEDED attribute"
+check() {
+       local failed=0
 
-if [ -n "$check_files" ]; then
-       f=$(scanelf -ByF '%n %p' $check_files | awk '$2 == "" { print }')
-       if [ -n "$f" ]; then
-               log "  QA Notice: The following shared libraries lack NEEDED entries"
-               log "${f}"
-               exit 1
-       fi
-fi
+       local file
+       local needed
+       for file in $(find_elf_files ${LIBARY_PATHS}); do
+               if ! is_shared_object ${file}; then
+                       continue
+               fi
 
-exit 0
+               if ! has_interpreter ${file}; then
+                       continue
+               fi
+
+               needed=$(get_needed ${file})
+               if [ -z "${needed}" ]; then
+                       log_error "  File lacks needed attribute: ${file}"
+                       failed=1
+               fi
+       done
+
+       return ${failed}
+}
+
+run
old mode 100644 (file)
new mode 100755 (executable)
index 8430e46..e4f514c
@@ -2,30 +2,30 @@
 
 . $(dirname ${0})/qa-include
 
-log "Searching bad libs that lack a SONAME"
+DESC="Every shared object has to provide the SONAME entry."
 
-check_files=$(find ${BUILDROOT} -name lib*.so)
+check() {
+       local failed=0
 
-command="scanelf -ByF '%S %p' $check_files | awk '$2 == "" { print }'"
+       local file
+       local soname
+       for file in $(find_elf_files ${LIBARY_PATHS}); do
+               if ! is_shared_object ${file}; then
+                       continue
+               fi
 
-for i in $QUALITY_AGENT_WHITELIST_SONAME; do
-       if [ -n "$FILTER" ]; then
-               FILTER="$FILTER|$i"
-       else
-               FILTER="$i"
-       fi
-done
+               if ! has_interpreter ${file}; then
+                       continue
+               fi
 
-if [ -n "$FILTER" ]; then
-       command="$command | grep -vE \"$FILTER\""
-fi
+               soname=$(get_soname ${file})
+               if [ -z "${soname}" ]; then
+                       log_error "  File lacks soname attribute: ${file}"
+                       failed=1
+               fi
+       done
 
-files=$(${command})
-if [ -n "${files}" ]; then
-       log "  QA Notice: The following shared libraries lack a SONAME"
-       log "${files}"
+       return ${failed}
+}
 
-       exit 1
-fi
-
-exit 0
+run
diff --git a/tools/quality-agent.d/050-nx b/tools/quality-agent.d/050-nx
new file mode 100755 (executable)
index 0000000..7a78a72
--- /dev/null
@@ -0,0 +1,19 @@
+#!/bin/bash
+
+. $(dirname ${0})/qa-include
+
+function check() {
+       local failed=0
+
+       local file
+       for file in $(find_elf_files ${BINARY_PATHS}); do
+               if ! has_nx ${file}; then
+                       log_error "  No NX: ${file}"
+                       failed=1
+               fi
+       done
+
+       return ${failed}
+}
+
+run
diff --git a/tools/quality-agent.d/050-relro b/tools/quality-agent.d/050-relro
new file mode 100755 (executable)
index 0000000..f11c07e
--- /dev/null
@@ -0,0 +1,24 @@
+#!/bin/bash
+
+. $(dirname ${0})/qa-include
+
+DESC="Text relocations force the dynamic linker to perform extra \
+       work at startup, waste system resources, and may pose a security \
+       risk. On some architectures, the code may not even function \
+       properly, if at all."
+
+function check() {
+       local failed=0
+
+       local file
+       for file in $(find_elf_files ${BINARY_PATHS}); do
+               if ! is_relro_full ${file}; then
+                       log_error "  Is not full relro: ${file}"
+                       failed=1
+               fi
+       done
+
+       return ${failed}
+}
+
+run
index f14607d49264d77495cbd06b955caf2822aa244b..a5da54085dbe640d189a885997a949582bdd5679 100755 (executable)
@@ -2,33 +2,41 @@
 
 . $(dirname ${0})/qa-include
 
-# Make sure we disallow insecure RUNPATH/RPATH's
-# Don't want paths that point to the tree where the package was built
-# (older, broken libtools would do this).  Also check for null paths
-# because the loader will search $PWD when it finds null paths.
-log "Searching for bad RPATH attributes"
-
-command="scanelf -qyRF '%r %p' ${BUILDROOT} 2>/dev/null"
-
-for i in $QUALITY_AGENT_WHITELIST_RPATH; do
+DESC="Searching for RPATHs. We don't want paths that point to the tree where \
+       the package was built (older, broken libtools would do this). \
+       Also check for null paths because the loader will search \$PWD when it \
+       finds null paths."
+
+check() {
+       for i in $QUALITY_AGENT_WHITELIST_RPATH; do
+               if [ -n "$FILTER" ]; then
+                       FILTER="$FILTER|$i"
+               else
+                       FILTER="$i"
+               fi
+       done
+       
        if [ -n "$FILTER" ]; then
-               FILTER="$FILTER|$i"
-       else
-               FILTER="$i"
+               log_debug "  Filter: $FILTER"
        fi
-done
 
-if [ -n "$FILTER" ]; then
-       log "  Filter: $FILTER"
-       command="$command | grep -vE \"$FILTER\""
-fi
+       local failed=0
+
+       local file
+       local rpath
+       for file in $(find_elf_files ${BINARY_PATHS}); do
+               if filtered ${file}; then
+                       continue
+               fi
 
-files=$(${command})
-if [ -n "${files}" ]; then
-       log "  QA Notice: The following files contain insecure RUNPATH's"
-       log "${files}"
+               rpath=$(get_rpath ${file})
+               if [ -n "${rpath}" ]; then
+                       log_error "  File has rpath: ${file} - ${rpath}"
+                       failed=1
+               fi
+       done
 
-       exit 1
-fi
+       return ${failed}
+}
 
-exit 0
+run
diff --git a/tools/quality-agent.d/050-textrels b/tools/quality-agent.d/050-textrels
deleted file mode 100755 (executable)
index a3c2f2e..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-#!/bin/bash
-
-. $(dirname ${0})/qa-include
-
-# TEXTREL's are baaaaaaaad
-log "Searching for bad TEXTRELs"
-
-files=$(scanelf -qyRF '%t %p' ${BUILDROOT} 2>/dev/null | awk '{ print $NF }')
-if [ -n "${files}" ]; then
-       log "  QA Notice: The following files contain runtime text relocations"
-       log "   Text relocations force the dynamic linker to perform extra"
-       log "   work at startup, waste system resources, and may pose a security"
-       log "   risk. On some architectures, the code may not even function"
-       log "   properly, if at all."
-       log "${files}"
-
-       exit 1
-fi
-
-exit 0
index cf1f0bd4aff76648df5689eb07196ddfcd9e82ba..c18fd444369051fc3f631db92c1ea631daad5f37 100755 (executable)
@@ -2,26 +2,22 @@
 
 . $(dirname ${0})/qa-include
 
-function check() {
-       local dir=${1}
+DESC="The filelayout should comply to the FHS."
 
-       log "    ...${dir}"
+DIRS="/etc/init.d /etc/rc.d /lib/pkgconfig /usr/etc /usr/local /usr/man /usr/var"
 
-       if [ -d "${BUILDROOT}/${dir}" ]; then
-               log "ERROR: This directory should not be there: ${dir}"
-               exit 1
-       fi
-}
+function check() {
+       local failed=0
 
-log "Check directory layout"
+       local dir
+       for dir in ${DIRS}; do
+               if [ -d "${dir}" ]; then
+                       log_error "Bad directory: ${dir}"
+                       failed=1
+               fi
+       done
 
-log "  Checking for directories that should not be there"
-check /etc/init.d
-check /etc/rc.d
-check /lib/pkgconfig
-check /usr/etc
-check /usr/local
-check /usr/man
-check /usr/var
+       return ${failed}
+}
 
-exit 0
+run
index c7197268fffd27d4c9baffae711bbfb65ab3f673..1644a91452954b2e9882498df8d547ad23bfdbfb 100644 (file)
@@ -1,7 +1,29 @@
 #!/bin/bash
 
+# Include additional functions
+. $(dirname ${0})/qa-functions
+
+function debug() {
+       [ "${NAOKI_DEBUG}" = "1" ]
+}
+
 function log() {
-       printf "%-22s: %s\n" "${0##*/}" "$@"
+       local facility=${1}
+       shift
+
+       printf " %-7s %s\n" "${facility}" "$@"
+}
+
+function log_debug() {
+       debug && log DEBUG "$@"
+}
+
+function log_error() {
+       log "ERROR" "$@"
+}
+
+function log_info() {
+       log "INFO" "$@"
 }
 
 if [ -z "${BUILDROOT}" ]; then
@@ -9,5 +31,55 @@ if [ -z "${BUILDROOT}" ]; then
        exit 1
 fi
 
-# Include additional functions
-. $(dirname ${0})/qa-functions
+function filtered() {
+       [ -z "${FILTER}" ] && return 1
+       grep -qE ${FILTER} <<<$@
+}
+
+function print_description() {
+       # Remove all whitespaces
+       local desc=$(echo ${DESC})
+
+       log_info "Check: $(basename ${0})"
+       IFS='
+'
+       for line in $(fold -s -w 60 <<<${desc}); do
+               log_info "  ${line}"
+       done
+       log_info # Empty line
+
+       unset IFS
+}
+
+function qa_find() {
+       local filetype=${1}
+       local command=${2}
+
+       log_debug "Running qa_find with command ${command} in ${filetype}"
+
+       local file
+       for file in $(find_elf_files ${!filetype}); do
+               ${command} ${file}
+       done
+}
+
+function check() {
+       log_error "REPLACE THIS FUNCTION BY A CUSTOM CHECK"
+       return 1
+}
+
+function run() {
+       local error_message
+       local ret
+
+       error_message=$(check)
+       ret=$?
+
+       [ "${ret}" = "0" ] && return 0
+
+       print_description
+
+       echo "${error_message}"
+       return ${ret}   
+}
+