[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH]: fix crash in various tools by permitting xs_*() with NULL path
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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |