WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

Re: [Xen-devel] [PATCH]: fix crash in various tools by permitting xs_*()

To: Ian Jackson <Ian.Jackson@xxxxxxxxxxxxx>
Subject: Re: [Xen-devel] [PATCH]: fix crash in various tools by permitting xs_*() with NULL path
From: Gianni Tedesco <gianni.tedesco@xxxxxxxxxx>
Date: Tue, 20 Jul 2010 18:02:57 +0100
Cc: Xen Devel <xen-devel@xxxxxxxxxxxxxxxxxxx>
Delivery-date: Tue, 20 Jul 2010 10:05:05 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
In-reply-to: <19525.52837.149559.660268@xxxxxxxxxxxxxxxxxxxxxxxx>
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
References: <1279641356.1723.1940.camel@xxxxxxxxxxxxxxxxxxxxxx> <19525.52837.149559.660268@xxxxxxxxxxxxxxxxxxxxxxxx>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
On Tue, 2010-07-20 at 17:27 +0100, Ian Jackson wrote:
> Gianni Tedesco writes ("[Xen-devel] [PATCH]: fix crash in various tools by 
> permitting xs_*() with NULL path"):
> > Many tools generate xenstore paths and then perform operations on those
> > paths without checking for NULL.
> 
> Do they ?  Those tools are buggy.

Yes, but for example libxl has around 300 calls to libxl_sprintf() which
are used un-checked as xenstore paths... We could either check every
result or check for ENOMEM in one place and abort() since NULL deref has
much the same effect.

> > While strictly this may be considered a bug in the tools it makes sense
> > to consider making these no-ops as a convenience measure.
> 
> I think this is fine for things like deletion but not otherwise.  So I
> think in the case of libxenstore only xs_rm should be modified like
> this.

I'm not so sure, I think NULL path should have some coherent meaning -
whether that's just to segfault or something else is another discussion.

> > @@ -503,6 +506,8 @@
> >  void *xs_read(struct xs_handle *h, xs_transaction_t t,
> >           const char *path, unsigned int *len)
> >  {
> > +    if ( NULL == path )
> > +        return NULL;
> >     return xs_single(h, t, XS_READ, path, len);
> >  }
> >  
> 
> This pattern is wrong.  Firstly, all functions in libxenstore set
> errno when returning errors and if you are going to return NULL you
> need to to do so as well.  Secondly, it is not appropriate to turn
> xs_read(,,NULL,) into an error.  It should crash.
> 
> Compare the C standard library.  If you call fprintf(NULL,...) it
> doesn't return EOF setting errno to EFAULT, it coredumps, and rightly
> so.

On the contrary open(NULL, O_RDONLY) will... The difference is FILE * is
a struct wheras the change I am proposing in this case is to treat NULL
as the empty string in the case of paths.

> Finally, to review this patch, it would be much more helpful if you
> used a diff tool which includes the function name in the diff output.
> Without that we have to apply the patch to a tree of our own and
> regenerate the diff.

good point

> > + *
> > + * path must be non-NULL
> 
> This should not be added here.  Competent C programmers will not
> expect to be able to pass NULL to things unless told they can.  So the
> assumption is the other way around.  You should add a note saying
> that NULL is permitted where it is.

OK

> Nacked-by: Ian Jackson <ian.jackson@xxxxxxxxxxxxx>
> 
> Sorry,
> Ian.

How about the following? If this is a total no-go then I'll fix the
callers.

Thanks for review

Signed-off-by: Gianni Tedesco <gianni.tedesco@xxxxxxxxxx>

diff -r 108ee7b37ac4 tools/xenstore/xs.h
--- a/tools/xenstore/xs.h       Tue Jul 20 15:01:15 2010 +0100
+++ b/tools/xenstore/xs.h       Tue Jul 20 17:56:34 2010 +0100
@@ -34,6 +34,11 @@ typedef uint32_t xs_transaction_t;
 
 /* On failure, these routines set errno. */
 
+/* In general path may be NULL and represents the empty string,
+ * write type operations will always succeed and read type operations
+ * will always fail. The watch/unwatch operations will segfault.
+ */
+
 /* Connect to the xs daemon.
  * Returns a handle or NULL.
  */
diff -r 108ee7b37ac4 tools/xenstore/xs.c
--- a/tools/xenstore/xs.c       Tue Jul 20 15:01:15 2010 +0100
+++ b/tools/xenstore/xs.c       Tue Jul 20 17:56:34 2010 +0100
@@ -474,6 +474,11 @@ char **xs_directory(struct xs_handle *h,
        char *strings, *p, **ret;
        unsigned int len;
 
+    if ( NULL == path ) {
+        errno = ENOENT;
+        return NULL;
+    }
+
        strings = xs_single(h, t, XS_DIRECTORY, path, &len);
        if (!strings)
                return NULL;
@@ -503,6 +508,10 @@ char **xs_directory(struct xs_handle *h,
 void *xs_read(struct xs_handle *h, xs_transaction_t t,
              const char *path, unsigned int *len)
 {
+    if ( NULL == path ) {
+        errno = ENOENT;
+        return NULL;
+    }
        return xs_single(h, t, XS_READ, path, len);
 }
 
@@ -514,6 +523,9 @@ bool xs_write(struct xs_handle *h, xs_tr
 {
        struct iovec iovec[2];
 
+    if ( NULL == path )
+        return true;
+
        iovec[0].iov_base = (void *)path;
        iovec[0].iov_len = strlen(path) + 1;
        iovec[1].iov_base = (void *)data;
@@ -529,6 +541,8 @@ bool xs_write(struct xs_handle *h, xs_tr
 bool xs_mkdir(struct xs_handle *h, xs_transaction_t t,
              const char *path)
 {
+    if ( NULL == path )
+        return true;
        return xs_bool(xs_single(h, t, XS_MKDIR, path, NULL));
 }
 
@@ -538,6 +552,8 @@ bool xs_mkdir(struct xs_handle *h, xs_tr
 bool xs_rm(struct xs_handle *h, xs_transaction_t t,
           const char *path)
 {
+    if ( NULL == path )
+        return true;
        return xs_bool(xs_single(h, t, XS_RM, path, NULL));
 }
 
@@ -552,6 +568,11 @@ struct xs_permissions *xs_get_permission
        unsigned int len;
        struct xs_permissions *ret;
 
+    if ( NULL == path ) {
+        errno = ENOENT;
+        return NULL;
+    }
+
        strings = xs_single(h, t, XS_GET_PERMS, path, &len);
        if (!strings)
                return NULL;
@@ -587,6 +608,9 @@ bool xs_set_permissions(struct xs_handle
        unsigned int i;
        struct iovec iov[1+num_perms];
 
+    if ( NULL == path )
+        return true;
+
        iov[0].iov_base = (void *)path;
        iov[0].iov_len = strlen(path) + 1;
        



_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel