Mercurial > pkg
view previous-work/more_control_helpers/bin/list_package @ 20:c75924bd38e3
fix security hole relating to path for package user.
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Thu, 10 Jan 2013 04:25:17 +0000 |
parents | d6bef198ae71 |
children |
line wrap: on
line source
1 #!/bin/bash2 # Copyright (c) 2004 Matthias S. Benkmann <article AT winterdrache DOT de>3 # You may do everything with this code except misrepresent its origin.4 # PROVIDED `AS IS' WITH ABSOLUTELY NO WARRANTY OF ANY KIND!6 if [ $# -lt 1 -o \( $# -gt 1 -a "z$1" != "z:man" -a "z$1" != "z:mani" -a "z$1" != "z:lib" \) -o "$1" = "--help" ]; then7 echo 1>&28 echo 1>&2 'USAGE: '"${0##*/}"' <user_or_group_name>'9 echo 1>&210 echo 1>&2 ' Entries will be matched if group and/or user equals <user_or_group_name>'11 echo 1>&2 ' (numeric UID/GID allowed).'12 echo 1>&2 ' This script uses `forall_direntries_from'"'"' and `list_suspicious_files_from'"'."13 echo 1>&214 echo 1>&2 ' NOTE: Several minutes may pass before you see the first output.'15 echo 1>&2 ' You should probably redirect output to a file for later reference.'16 echo 1>&217 echo 1>&2 ' WARNING! This program is for listing files from package users only!'18 echo 1>&2 ' Do NOT use it to list files from untrusted users!'19 echo 1>&2 ' An untrusted user could set up a manipulated manpage to exploit'20 echo 1>&2 ' a bug in man when it is used to extract the summary!'21 exit 122 fi24 # KNOWN BUGS:25 # - when extracting summaries from manpages, candidate manpages are considered26 # in alphabetic order rather than the order used by the man command.27 # The problem with this is that section 8, which contains manpages for28 # admin commands, will be considered after lower-numbered sections.29 # In the rare case that an admin command has the same name as a topic from30 # a lower-numbered manpage installed by the same package, the summary will31 # be taken from the wrong manpage.32 # An example for such a clash are the faillog.5 and faillog.8 manpages from33 # the shadow package.34 # Because this problem is difficult to fix, rare and easily spotted (since35 # the manpage that should have provided the summary will be listed under36 # EXTRA MANPAGES) I won't fix it.38 ugname="$1"40 #suppress ugly debug output from shell41 trap ':' SIGPIPE43 if [ $# -gt 1 ]; then44 name="${2##*/}"45 case "$1" in46 :man)47 name=${name%.gz}48 name=${name%.bz2}49 name=${name%.*}50 echo $'command\2'"$name"$'\2man\2'"$2" ;;51 :mani)52 name=${name%.gz}53 name=${name%.bz2}54 name=${name%.*}55 echo $'command\2'"$name"$'\2mani\2'"$2" ;;56 :lib)57 name=${name%.a}58 name=${name%%.so*}59 echo "lib $name"60 ;;61 esac62 exit 063 fi65 sanitize() { tr -c '[:print:]' '?' ; }67 # $1: <commandname>68 # $2: command\2<commandname>\2cmd\2(-><linktarget>)69 # $3: command\2<commandname>\2man[i]\2<manpage_path> or <empty>70 expand_command()71 {72 sep=$'\2'73 cmdname="$1"74 cmdline="$2"75 manline="$3"76 linktarget="${cmdline##*${sep}}"78 if [ -z "$manline" ]; then79 description='No manpage'80 #the "l" at the beginning is just to make it sort after "lib"81 echo -n "lmanlessbin $cmdname" | sanitize82 echo84 else # if [ ! -z "$manline" ]; then85 manpage=${manline##*${sep}}86 manpagedir=${manpage%/*}87 wsc='[[:space:],]\+'88 # The cd $manpagedir is a workaround for a bug in man-db that causes it89 # to attempt to resolve paths relative to cwd.90 # The `t l;d;:l;n;b l' in the sed command is voodoo magic to make sed91 # output only the first match but to keep eating up all input. I use this92 # instead of `| head -n 1', because head breaks the pipe after doing93 # its 1 line output, which (if it happens before sed has processed the94 # complete input) freaks out man and causes it to emit a totally95 # silly error message including "No such file or directory", which is96 # annoying when you do testing without suppressing man's errors.97 # The $'s/.\b\\(.\\)/\\1/g;s/\x1b[^m]\\+m//g' removes the backspace-based98 # as well as ESC-based formatting from man's output.99 description="$( { cd "$manpagedir/.." 2>/dev/null ;100 COLUMNS=300 man "$manpage" 2>/dev/null ||101 echo " $name - Broken manpage" ; } |102 sed $'s/.\b\\(.\\)/\\1/g;s/\x1b[^m]\\+m//g' |103 sed -n "/^NAME/,/^[A-Z]/s/^.*${wsc}${cmdname}${wsc}.*-\+${wsc}\(.*\)/\1/p;t l;d;:l;n;b l" )"104 if [ -z "$description" ]; then105 description="$( cd "$manpagedir/.." 2>/dev/null ;106 COLUMNS=300 man "$manpage" 2>/dev/null |107 sed $'s/.\b\\(.\\)/\\1/g;s/\x1b[^m]\\+m//g' |108 sed -n "s/^.*${wsc}..*${wsc}.*-\+${wsc}\(.*\)/\1/p;t l;d;:l;n;b l" )"109 fi110 test -z "$description" && description="Weird manpage"111 fi113 echo -n "binexe $cmdname" | sanitize114 test "$linktarget" != '(->)' && echo -n "$linktarget" | sanitize115 echo116 #the "lx" in "lxdescription" is just to make sure it sorts after "lmanlessbin"117 echo -n "lxdescription $cmdname: $description" | sanitize118 echo119 }121 # NOTE: The -path and -lname stuff at the beginning of the following is122 # there to make sure that none of the lines output by find contains123 # a) \n or \r, because that would mess up post-processing the output124 # line-by-line.125 # b) \x7f, because this character triggers one of the nastier bash-bugs126 # wrt string handling127 # c) \2, because I use this as separator within the lines128 # (Why \2 and not \0 or \1 ? Because bash can't cope with \0 at all and has129 # bugs related to \1.)130 #131 # Because of this, having the final section called "ALL FILES" is technically132 # a lie, because files with a path containing one of the abovementioned133 # characters will not appear in output.134 # However, a) no sane package contains such files135 # b) they will be listed in the output from list_suspicious_files136 cmd=(\( -path $'*\n*' -or -path $'*\r*' -or -path $'*\x7f*'137 -or -path $'*\2*'138 -or -lname $'*\n*' -or -lname $'*\r*' -or -lname $'*\x7f*'139 -or -lname $'*\2*'140 \)141 -or142 \(143 \( -printf "zall %p\n" \) ,144 \(145 \( -type f -or -xtype f \) -and146 \(147 \( -perm -u+x \( -path "*/bin/*" -or -path "*/sbin/*" \) -printf 'command\2%f\2cmd\2(->%l)\n' \)148 -or \( -path "*/man/man*/*" -exec "$0" ":man" {} \; \)149 -or \( -path "*/man/*/man*/*" -exec "$0" ":mani" {} \; \)150 -or \( \( -name "lib*.so" -or -name "lib*.a" -or -name "lib*.so.*" \) -path "*/lib/*" -exec "$0" ":lib" {} \; \)151 -or \( -type f -perm -u+x -not \( \( -name "lib*.so" -or -name "lib*.a" -or -name "lib*.so.*" \) -path "*/lib/*" \) -printf "nobinexe %p\n" \)152 \)153 \)154 \)155 )157 forall_direntries_from "$ugname" "${cmd[@]}" | sort -u |158 {159 sep=$'\2'160 hold=''161 for((;;))162 do163 if [ -z "$hold" ]; then164 read -r line || break165 else166 line="$hold"167 hold=''168 fi170 case "z$line" in171 zcommand${sep}*${sep}cmd${sep}*)172 cmdname=${line#command${sep}}173 cmdname=${cmdname%%${sep}*}174 read -r hold175 case "z$hold" in176 zcommand${sep}${cmdname}${sep}man${sep}*|zcommand${sep}${cmdname}${sep}mani${sep}*)177 expand_command "$cmdname" "$line" "$hold"178 hold=''179 ;;181 z*)182 expand_command "$cmdname" "$line" ""183 ;;184 esac185 ;;187 zcommand${sep}*${sep}man${sep}*|command${sep}*${sep}mani${sep}*)189 echo -n "manextra ${line##*${sep}}" | sanitize190 echo191 ;;193 z*)194 echo -n "$line" | sanitize195 echo196 ;;197 esac199 done200 } | sort | #no -u here, bc. the above processing may equalize different files201 {202 # (1) binexe: Executables (in *bin/)203 # (2) lib: Libraries (in *lib/*)204 # (3) lmanlessbin: Executables (in *bin/) without manpages205 # (4) lxdescription: Summaries for executables (in *bin/)206 # (5) manextra: Extra manpages207 # full paths, no perms208 # (6) nobinexe: Executables not in *bin/ (excluding *lib/*.so and *lib/*.so.*)209 # full paths, no perms210 # (7) zall: All files211 # full paths, no perms213 curstate=''214 while read -r line215 do216 newstate="${line%% *}"217 if [ "$newstate" != "$curstate" ]; then218 curstate="$newstate"219 case "$curstate" in220 binexe)221 echo 'EXECUTABLES (in */bin or */sbin)'222 echo -n " ${line#binexe }"223 ;;224 lib)225 echo226 echo227 echo 'LIBRARIES (lib*.a or lib*.so)'228 echo -n " ${line#lib }"229 ;;230 lmanlessbin)231 echo232 echo233 echo 'EXECUTABLES WITH NO MANPAGE (in */bin or */sbin)'234 echo -n " ${line#lmanlessbin }"235 ;;236 lxdescription)237 echo238 echo239 echo 'MANPAGE SUMMARIES OF EXECUTABLES (in */bin or */sbin)'240 echo " ${line#lxdescription }"241 ;;242 manextra)243 echo244 echo 'EXTRA MANPAGES'245 echo " ${line#manextra }"246 ;;247 nobinexe)248 echo249 echo 'EXTRA EXECUTABLES (not in */bin or */sbin)'250 echo " ${line#nobinexe }"251 ;;252 zall)253 echo254 echo 'ALL FILES'255 echo " ${line#zall }"256 ;;257 *)258 echo259 echo260 echo 'UNEXPECTED LINE'261 echo " $line"262 ;;264 esac265 else266 case "$curstate" in267 binexe) echo -n ", ${line#binexe }"268 ;;269 lib) echo -n ", ${line#lib }"270 ;;271 lmanlessbin) echo -n ", ${line#lmanlessbin }"272 ;;273 lxdescription) echo " ${line#lxdescription }"274 ;;275 manextra) echo " ${line#manextra }"276 ;;277 nobinexe) echo " ${line#nobinexe }"278 ;;279 zall) echo " ${line#zall }"280 ;;281 *)282 echo283 echo 'UNEXPECTED LINE'284 echo " $line"285 ;;286 esac287 fi288 done289 }291 list_suspicious_files_from "$ugname"