zsh-workers
 help / color / mirror / code / Atom feed
* PATCH: compaudit allows owner of executable
@ 2013-01-30 21:11 Peter Stephenson
  2013-01-30 21:40 ` Danek Duvall
  0 siblings, 1 reply; 3+ messages in thread
From: Peter Stephenson @ 2013-01-30 21:11 UTC (permalink / raw)
  To: Zsh Hackers' List

This prevents compaudit failing on the case where the whole of zsh,
executable and function library, has been installed by a non-root user.
If you are running the executable, you necessarily trust whoever owns
it, so there's no point complaining if they also own the completion
files.  We could print a warning message, but it seems way too late for
that.

I couldn't think of a reasonably safe, standard way of finding out who
owns the executable, however.  So I've done it using the /proc file
system.  I've also assumed zstat is available from zsh/stat.
Suggestions for improvements welcome.

Index: Completion/compaudit
===================================================================
RCS file: /cvsroot/zsh/zsh/Completion/compaudit,v
retrieving revision 1.11
diff -p -u -r1.11 compaudit
--- Completion/compaudit	10 Sep 2011 17:09:51 -0000	1.11
+++ Completion/compaudit	30 Jan 2013 21:10:33 -0000
@@ -82,18 +82,31 @@ fi
 
 [[ $_i_fail == use ]] && return 0
 
+# We will always allow files to be owned by root and the owner of the
+# present process.
+local owners="u0u${EUID}"
+
+# If we can find out who owns the executable, we will allow files to
+# be owned by that user, too.  The argument is that if you don't trust
+# the owner of the executable, it's way too late to worry about it now...
+if [[ -e /proc/$$/exe ]] && zmodload -F zsh/stat b:zstat 2>/dev/null; then
+  local -A stathash
+  if zstat -H stathash /proc/$$/exe && [[ $stathash[uid] -ne 0 ]]; then
+    owners+="u${stathash[uid]}"
+  fi
+fi
+
 # We search for:
-# - world/group-writable directories in fpath not owned by root and the user
+# - world/group-writable directories in fpath not owned by $owners
 # - parent-directories of directories in fpath that are world/group-writable
-#   and not owned by root and the user (that would allow someone to put a
+#   and not owned by $owners (that would allow someone to put a
 #   digest file for one of the directories into the parent directory)
-# - digest files for one of the directories in fpath not owned by root and
-#   the user
-# - and for files in directories from fpath not owned by root and the user
+# - digest files for one of the directories in fpath not owned by $owners
+# - and for files in directories from fpath not owned by $owners
 #   (including zwc files)
 
-_i_wdirs=( ${^fpath}(N-f:g+w:,-f:o+w:,-^u0u${EUID})
-           ${^fpath:h}(N-f:g+w:,-f:o+w:,-^u0u${EUID}) )
+_i_wdirs=( ${^fpath}(N-f:g+w:,-f:o+w:,-^${owners})
+           ${^fpath:h}(N-f:g+w:,-f:o+w:,-^${owners}) )
 
 # RedHat Linux "per-user groups" check.  This is tricky, because it's very
 # difficult to tell whether the sysadmin has put someone else into your
@@ -111,7 +124,7 @@ if (( $#_i_wdirs )); then
 
   if [[ $GROUP == $LOGNAME && ( -z $GROUPMEM || $GROUPMEM == $LOGNAME ) ]]
   then
-    _i_wdirs=( ${^_i_wdirs}(N-f:g+w:^g:${GROUP}:,-f:o+w:,-^u0u${EUID}) )
+    _i_wdirs=( ${^_i_wdirs}(N-f:g+w:^g:${GROUP}:,-f:o+w:,-^${owners}) )
   fi
 fi
 
@@ -122,8 +135,8 @@ then
   _i_wdirs=( ${_i_wdirs:#/usr/local/*} ${^_i_ulwdirs}(Nf:g+ws:^g:staff:,f:o+w:,^u0) )
 fi
 
-_i_wdirs=( $_i_wdirs ${^fpath}.zwc^([^_]*|*~)(N-^u0u${EUID}) )
-_i_wfiles=( ${^fpath}/^([^_]*|*~)(N-^u0u${EUID}) )
+_i_wdirs=( $_i_wdirs ${^fpath}.zwc^([^_]*|*~)(N-^${owners}) )
+_i_wfiles=( ${^fpath}/^([^_]*|*~)(N-^${owners}) )
 
 case "${#_i_wdirs}:${#_i_wfiles}" in
 (0:0) _i_q= ;;


-- 
Peter Stephenson <p.w.stephenson@ntlworld.com>
Web page now at http://homepage.ntlworld.com/p.w.stephenson/


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: PATCH: compaudit allows owner of executable
  2013-01-30 21:11 PATCH: compaudit allows owner of executable Peter Stephenson
@ 2013-01-30 21:40 ` Danek Duvall
  2013-01-31 19:45   ` Peter Stephenson
  0 siblings, 1 reply; 3+ messages in thread
From: Danek Duvall @ 2013-01-30 21:40 UTC (permalink / raw)
  To: Peter Stephenson; +Cc: Zsh Hackers' List

On Wed, Jan 30, 2013 at 09:11:48PM +0000, Peter Stephenson wrote:

> I couldn't think of a reasonably safe, standard way of finding out who
> owns the executable, however.  So I've done it using the /proc file
> system.  I've also assumed zstat is available from zsh/stat.
> Suggestions for improvements welcome.

On Solaris, the path would be /proc/$$/object/a.out.  From the code, I
think that'll work as far back as Solaris 2.6, but I don't have any old
machines to verify that on.

Solaris also has a "getexecname()" library call, also introduced in 2.6,
but that would require writing C code, and making it available from shell
code, which seems like it's more work (if slightly more stable an
interface).  There also are ways to get this information on Solaris with
dlinfo(), which may be more portable on other systems than getexecname().

http://stackoverflow.com/questions/1023306/finding-current-executables-path-without-proc-self-exe

has more, if you hadn't already gone looking.

Danek


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: PATCH: compaudit allows owner of executable
  2013-01-30 21:40 ` Danek Duvall
@ 2013-01-31 19:45   ` Peter Stephenson
  0 siblings, 0 replies; 3+ messages in thread
From: Peter Stephenson @ 2013-01-31 19:45 UTC (permalink / raw)
  To: Zsh Hackers' List

On Wed, 30 Jan 2013 13:40:24 -0800
Danek Duvall <duvall@comfychair.org> wrote:
> On Wed, Jan 30, 2013 at 09:11:48PM +0000, Peter Stephenson wrote:
> > I couldn't think of a reasonably safe, standard way of finding out who
> > owns the executable, however.  So I've done it using the /proc file
> > system.  I've also assumed zstat is available from zsh/stat.
> > Suggestions for improvements welcome.
> 
> On Solaris, the path would be /proc/$$/object/a.out.  From the code, I
> think that'll work as far back as Solaris 2.6, but I don't have any old
> machines to verify that on.

Thanks, I now have the following.
 
> Solaris also has a "getexecname()" library call, also introduced in 2.6,
> but that would require writing C code, and making it available from shell
> code, which seems like it's more work (if slightly more stable an
> interface).  There also are ways to get this information on Solaris with
> dlinfo(), which may be more portable on other systems than getexecname().

Unfortunately I can't find those elsewhere.  I'll stick with the /proc
link.

Index: Completion/compaudit
===================================================================
RCS file: /cvsroot/zsh/zsh/Completion/compaudit,v
retrieving revision 1.11
diff -p -u -r1.11 compaudit
--- Completion/compaudit	10 Sep 2011 17:09:51 -0000	1.11
+++ Completion/compaudit	31 Jan 2013 19:43:07 -0000
@@ -82,18 +82,45 @@ fi
 
 [[ $_i_fail == use ]] && return 0
 
+# We will always allow files to be owned by root and the owner of the
+# present process.
+local _i_owners="u0u${EUID}"
+
+# Places we will look for a link to the executable
+local -a _i_exes
+_i_exes=(
+    /proc/$$/exe
+    /proc/$$/object/a.out
+    )
+local _i_exe
+
+# If we can find out who owns the executable, we will allow files to
+# be owned by that user, too.  The argument is that if you don't trust
+# the owner of the executable, it's way too late to worry about it now...
+for _i_exe in _i_exes; do
+  if [[ -e $_i_exe ]] ;then
+    if zmodload -F zsh/stat b:zstat 2>/dev/null; then
+      local -A _i_stathash
+      if zstat -H _i_stathash /proc/$$/exe &&
+	[[ $_i_stathash[uid] -ne 0 ]]; then
+	_i_owners+="u${_i_stathash[uid]}"
+      fi
+    fi
+    break
+  fi
+done
+
 # We search for:
-# - world/group-writable directories in fpath not owned by root and the user
+# - world/group-writable directories in fpath not owned by $_i_owners
 # - parent-directories of directories in fpath that are world/group-writable
-#   and not owned by root and the user (that would allow someone to put a
+#   and not owned by $_i_owners (that would allow someone to put a
 #   digest file for one of the directories into the parent directory)
-# - digest files for one of the directories in fpath not owned by root and
-#   the user
-# - and for files in directories from fpath not owned by root and the user
+# - digest files for one of the directories in fpath not owned by $_i_owners
+# - and for files in directories from fpath not owned by $_i_owners
 #   (including zwc files)
 
-_i_wdirs=( ${^fpath}(N-f:g+w:,-f:o+w:,-^u0u${EUID})
-           ${^fpath:h}(N-f:g+w:,-f:o+w:,-^u0u${EUID}) )
+_i_wdirs=( ${^fpath}(N-f:g+w:,-f:o+w:,-^${_i_owners})
+           ${^fpath:h}(N-f:g+w:,-f:o+w:,-^${_i_owners}) )
 
 # RedHat Linux "per-user groups" check.  This is tricky, because it's very
 # difficult to tell whether the sysadmin has put someone else into your
@@ -111,7 +138,7 @@ if (( $#_i_wdirs )); then
 
   if [[ $GROUP == $LOGNAME && ( -z $GROUPMEM || $GROUPMEM == $LOGNAME ) ]]
   then
-    _i_wdirs=( ${^_i_wdirs}(N-f:g+w:^g:${GROUP}:,-f:o+w:,-^u0u${EUID}) )
+    _i_wdirs=( ${^_i_wdirs}(N-f:g+w:^g:${GROUP}:,-f:o+w:,-^${_i_owners}) )
   fi
 fi
 
@@ -122,8 +149,8 @@ then
   _i_wdirs=( ${_i_wdirs:#/usr/local/*} ${^_i_ulwdirs}(Nf:g+ws:^g:staff:,f:o+w:,^u0) )
 fi
 
-_i_wdirs=( $_i_wdirs ${^fpath}.zwc^([^_]*|*~)(N-^u0u${EUID}) )
-_i_wfiles=( ${^fpath}/^([^_]*|*~)(N-^u0u${EUID}) )
+_i_wdirs=( $_i_wdirs ${^fpath}.zwc^([^_]*|*~)(N-^${_i_owners}) )
+_i_wfiles=( ${^fpath}/^([^_]*|*~)(N-^${_i_owners}) )
 
 case "${#_i_wdirs}:${#_i_wfiles}" in
 (0:0) _i_q= ;;

-- 
Peter Stephenson <p.w.stephenson@ntlworld.com>
Web page now at http://homepage.ntlworld.com/p.w.stephenson/


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2013-01-31 20:16 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-01-30 21:11 PATCH: compaudit allows owner of executable Peter Stephenson
2013-01-30 21:40 ` Danek Duvall
2013-01-31 19:45   ` Peter Stephenson

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).