[systemd-devel] [PATCH 7/9] nspawn: escape paths in overlay mount options

Richard Maw richard.maw at codethink.co.uk
Fri Jun 19 03:17:53 PDT 2015


On Thu, Jun 18, 2015 at 08:39:10PM +0200, Lennart Poettering wrote:
> On Thu, 28.05.15 13:02, Richard Maw (richard.maw at codethink.co.uk) wrote:
> 
> > Overlayfs uses , as an option separator and : as a list separator. These
> > characters are both valid in file paths, so overlayfs allows file paths
> > which contain these characters to backslash escape these values.
> > ---
> >  src/nspawn/nspawn.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++------
> >  1 file changed, 56 insertions(+), 7 deletions(-)
> > 
> > diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
> > index c40d50f..f7580f9 100644
> > --- a/src/nspawn/nspawn.c
> > +++ b/src/nspawn/nspawn.c
> > @@ -1237,6 +1237,42 @@ static int mount_tmpfs(const char *dest, CustomMount *m) {
> >          return 0;
> >  }
> >  
> > +static char *escaped_overlay_path(const char *path) {
> > +        _cleanup_free_ char *colon_escaped = NULL;
> > +        char *comma_escaped = NULL;
> > +
> > +        colon_escaped = strreplace(path, ":", "\\:");
> > +        if (!colon_escaped)
> > +                return NULL;
> > +
> > +        comma_escaped = strreplace(colon_escaped, ",", "\\,");
> > +
> > +        return comma_escaped;
> 
> This looks incomplete. What happens with "\\" itself?

Ah, yes. --overlay='\\a' would become '\a' after command-line parsing,
and overlayfs' unescaping would turn that into 'a'. I'll sort it out.

> Also, it's really inefficient, since strreplace() goes through the
> string each time from the beginning.

I was looking to do something simple rather than fast, as this isn't a
particularly latency sensitive bit of code, and I wasn't confident in
the need of a generic solution, but if you think it'll have wider use,
that's fine by me.

> I think it would make sense to add a generic 
> 
>   char *shell_escape(const char *s, const char *bad);
> 
> that works like xescape() but applies shell-style escaping instead of
> C-style escaping.

This isn't exactly shell escaping as I understand it, as that would also
require putting quotation marks aroud the string in certain circumstances,
and shell_maybe_quote() handles that already.

I'd call it backslash_escape() and possibly use it inside
shell_maybe_quote().

> > +}
> > +
> > +static char *joined_and_escaped_lower_dirs(char * const *lower) {
> > +        _cleanup_free_ char *s = NULL;
> > +        char *ret = NULL;
> > +        char * const *path;
> > +        bool first = true;
> > +
> > +        STRV_FOREACH_BACKWARDS(path, lower) {
> > +                _cleanup_free_ char *escaped_path = NULL;
> > +                escaped_path = escaped_overlay_path(*path);
> > +                if (first) {
> > +                        if (!strextend(&s, escaped_path, NULL))
> > +                                return NULL;
> > +                        first = false;
> > +                } else
> > +                        if (!strextend(&s, ":", escaped_path, NULL))
> > +                                return NULL;
> > +        }
> > +
> > +        ret = s;
> > +        s = NULL;
> > +        return ret;
> > +}
> 
> I'd prefer if we could have a routine:
> 
>     char **shell_escape_strv(char **l, const char *bad);
> 
> that goes through the strv list "l", and replaces all items in-place
> with shell_escape() and returns that.
> 
> If we have that, then we can nicely invoke strv_join() after
> shell_escape_strv(), and all would be good and simple.

Ok.


More information about the systemd-devel mailing list