[PATCH openbmc v6 17/18] initfs: update: Sanitze whitelist directory entries

Andrew Jeffery andrew at aj.id.au
Mon Jun 27 14:35:49 AEST 2016


On Sun, 2016-06-26 at 00:12 +0000, Milton Miller II wrote:
> 
> On 06/23/2016 about 01:26AM in some time zone, Andrew Jeffery wrote:
> >On Wed, 2016-06-22 at 19:30 -0500, OpenBMC Patches wrote:
> >> From: Milton Miller <miltonm at us.ibm.com>
> >> 
> >> Repeatedly strip trailing / and /. from whitelist entries and
> >> fail if an entry includes /../ or ends with /.. or doesn't start
> >> with a /.  Also use the entries quoted to avoid any glob.
> >
> >Right. Ending this particular sentence with a '/' is a bit subtle. I
> >think you should quote your path bits: "/", "/.", "/../", "/.."; this
> >way the sentence would end '... or doesn't start with a "/".'.
> 
> Ok done.
> 
> >> 
> >> It was noticed the save code was saving directories that ended in /
> >> into a subdirectory of the last component name.  This was traced
> >> the the code creating the directory just stripping the last /
> >> and then copying to the directory.
> >> 
> >> Choose to sanitize the entry where possible for ease of use verses
> >> a small performance penality.
> >> 
> >> Signed-off-by: Milton Miller <miltonm at us.ibm.com>
> >> ---
> >>  .../obmc-phosphor-initfs/files/obmc-update.sh             | 15
> >+++++++++++++--
> >>  1 file changed, 13 insertions(+), 2 deletions(-)
> >> 
> >> diff --git
> >a/meta-phosphor/common/recipes-phosphor/obmc-phosphor-initfs/files/ob
> >mc-update.sh
> >b/meta-phosphor/common/recipes-phosphor/obmc-phosphor-initfs/files/ob
> >mc-update.sh
> >> index 7120a18..bfacd00 100755
> >> ---
> >a/meta-phosphor/common/recipes-phosphor/obmc-phosphor-initfs/files/ob
> >mc-update.sh
> >> +++
> >b/meta-phosphor/common/recipes-phosphor/obmc-phosphor-initfs/files/ob
> >mc-update.sh
> >> @@ -170,13 +170,24 @@ then
> >>  
> >>   while read f
> >>   do
> >> - if ! test -e $upper/$f
> >> + # Entries shall start with /, no trailing /.. or embedded /../
> >> + if test "/${f#/}" != "$f" -o "${f%/..}" != "${f#*/../}"
> >
> >Can we do this with `readlink -f` or `realpath` instead? Do we have
> >them available in this environment? As in, test that the result
> >before
> >and after realpath are the same. You can tell realpath to not expand
> >symlinks.
> >
> 
> ENODOC
> 
> There does not appear to be a man page available for realpath(1)
> in either Debian wheezy or RHEL 6.4.

Okay, as suggested in your link[1] it looks like debian ship their own
realpath and RHEL 6.4 is probably too old for GNU realpath. GNU
realpath has:

       -s, --strip, --no-symlinks
              don't expand symlinks

So:

    $ realpath -s /etc/../etc/alternatives/cc
    /etc/alternatives/cc
    $ ls -l !$
    ls -l /etc/../etc/alternatives/cc
    lrwxrwxrwx 1 root root 12 Dec  7  2015 /etc/../etc/alternatives/cc -> /usr/bin/gcc

>   The man page for readlink
> is talking about expanding symlinks with -f saying it follows symlinks
> recursively, no where does it talk about cleaning up the path, nor
> returning the path of something not a symlink.

Yes, readlink -f was probably a poor suggestion if we don't want to
resolve symlinks.

> 
> A qucik search turned up [1] which shows some of the history.  
> Also note it says busybox (which is the version we are using) 
> does not take options in its realpath command.

Right, this is the killer bit, that busybox realpath can't do -s.

> 
> Also this is already peaking under the covers at the read-write 
> COW directory which is a sparse copy and not looking though 
> the combined file system.  And this file subtree is not mounted 
> at / meaning any attempt to follow an absolute symlink will likely 
> find the wrong content and not necessarily fail.
> 
> So I am rejecting this suggestion.

Given the above, I'm okay with that.

> 
> [1] http://unix.stackexchange.com/questions/136494/whats-the-difference-between-realpath-and-readlink-f
> 
> >> + then
> >> + echo 1>&2 "WARNING: Skipping bad whitelist entry $f."
> >> + continue
> >> + fi
> >> + if ! test -e "$upper/$f"
> >>   then
> >>   continue
> >>   fi
> >>   d="$save/$f"
> >> + while test "${d%/}" != "${d%/.}"
> >> + do
> >> + d="${d%/.}"
> >> + d="${d%/}"
> >> + done
> >>   mkdir -p "${d%/*}"
> >> - cp -rp $upper/$f "${d%/*}/"
> >> + cp -rp "$upper/$f" "${d%/*}/"
> >
> >Again the while loop and other bits can hopefully be replaced by
> >`readlink -f` or `realpath`. The whole trailing-slash thing with `cp`
> >always throws me.
> 
> While the test here for $d is absolute I'd rather not do it.  And 
> right now this has at least two / (one in the string and one leading 
> the $f) meaning a simple equality check of $d and $(realpath $d) 
> will always fail.

If we know everything in the whitelist is absolute could we take a
different approach to the path construction?

>   I could remove the slash but that implies the 
> first check,

Isn't it instead that because of the first check we now know that the
whitelist path is absolute, so we can validly removing the leading '/'
to construct the necessary path?

>  and again we are copying from a sparse directory and 
> want to copy a symlink not resolve it. 

Sure; as above, realpath -s would have avoided the resolution but as
you point out we can't use it (busybox).

>   I'd love to use rsync here 
> but that is not currently available.

right.

> 
> If you object to the while loop I can reject the path if the conditions 
> on $f with similar substitutions are not equal (reordering the fix
> commit). I don't anticipate the loop executing more than once
> unless someone is testing corner cases and thought the convenience 
> of making the entry sane was better than the debug why the entry
> didn't work.
> 

What you've got sounds preferable. The path string hackery is
unfortunate but sounds unavoidable.

Andrew
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: This is a digitally signed message part
URL: <http://lists.ozlabs.org/pipermail/openbmc/attachments/20160627/a908885d/attachment.sig>


More information about the openbmc mailing list