diff options
Diffstat (limited to 'tools/xenstore')
-rw-r--r-- | tools/xenstore/Makefile | 3 | ||||
-rw-r--r-- | tools/xenstore/fake_libxc.c | 2 | ||||
-rw-r--r-- | tools/xenstore/xenstored_core.c | 34 | ||||
-rw-r--r-- | tools/xenstore/xenstored_core.h | 3 | ||||
-rw-r--r-- | tools/xenstore/xenstored_domain.c | 3 | ||||
-rw-r--r-- | tools/xenstore/xenstored_test.h | 2 | ||||
-rw-r--r-- | tools/xenstore/xs.c | 14 | ||||
-rw-r--r-- | tools/xenstore/xs_lib.c | 8 | ||||
-rw-r--r-- | tools/xenstore/xs_lib.h | 8 | ||||
-rw-r--r-- | tools/xenstore/xs_random.c | 8 | ||||
-rw-r--r-- | tools/xenstore/xs_test.c | 8 |
11 files changed, 55 insertions, 38 deletions
diff --git a/tools/xenstore/Makefile b/tools/xenstore/Makefile index b5511aea3c..408078efba 100644 --- a/tools/xenstore/Makefile +++ b/tools/xenstore/Makefile @@ -92,8 +92,11 @@ install: xenstored libxenstore.a $(INSTALL_DIR) -p $(DESTDIR)/var/run/xenstored $(INSTALL_DIR) -p $(DESTDIR)/var/lib/xenstored $(INSTALL_DIR) -p $(DESTDIR)/usr/sbin + $(INSTALL_DIR) -p $(DESTDIR)/usr/include $(INSTALL_PROG) xenstored $(DESTDIR)/usr/sbin $(INSTALL_DIR) -p $(DESTDIR)/usr/$(LIBDIR) $(INSTALL_DATA) libxenstore.a $(DESTDIR)/usr/$(LIBDIR) + $(INSTALL_DATA) xs.h $(DESTDIR)/usr/include + $(INSTALL_DATA) xs_lib.h $(DESTDIR)/usr/include -include $(PROG_DEP) diff --git a/tools/xenstore/fake_libxc.c b/tools/xenstore/fake_libxc.c index decfb4001d..50e1db717c 100644 --- a/tools/xenstore/fake_libxc.c +++ b/tools/xenstore/fake_libxc.c @@ -71,7 +71,7 @@ int xc_interface_open(void) return fd; memset(page, 0, sizeof(page)); - if (!write_all(fd, page, sizeof(page))) + if (!xs_write_all(fd, page, sizeof(page))) barf_perror("Failed to write /tmp/xcmap page"); return fd; diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c index 9d15848463..1df00f37b4 100644 --- a/tools/xenstore/xenstored_core.c +++ b/tools/xenstore/xenstored_core.c @@ -81,7 +81,7 @@ bool test_write_all(int fd, void *contents, unsigned int len) errno = ENOSPC; return false; } - return write_all(fd, contents, len); + return xs_write_all(fd, contents, len); } int test_mkdir(const char *dir, int perms); @@ -443,9 +443,9 @@ static struct xs_permissions *get_perms(struct transaction *transaction, if (!strings) return NULL; - *num = count_strings(strings, size); + *num = xs_count_strings(strings, size); ret = talloc_array(node, struct xs_permissions, *num); - if (!strings_to_perms(ret, *num, strings)) + if (!xs_strings_to_perms(ret, *num, strings)) corrupt(NULL, "Permissions corrupt for %s", node); return ret; @@ -460,7 +460,7 @@ static char *perms_to_strings(const char *node, char buffer[MAX_STRLEN(domid_t) + 1]; for (*len = 0, i = 0; i < num; i++) { - if (!perm_to_string(&perms[i], buffer)) + if (!xs_perm_to_string(&perms[i], buffer)) return NULL; strings = talloc_realloc(node, strings, char, @@ -506,7 +506,7 @@ static char *tempfile(const char *path, void *contents, unsigned int len) if (!fd) return NULL; talloc_set_destructor(tmppath, destroy_path); - if (!write_all(*fd, contents, len)) + if (!xs_write_all(*fd, contents, len)) return NULL; return tmppath; @@ -617,7 +617,7 @@ bool check_node_perms(struct connection *conn, const char *node, return false; } - if (!conn->write && (perm & XS_PERM_WRITE)) { + if (!conn->can_write && (perm & XS_PERM_WRITE)) { errno = EROFS; return false; } @@ -721,14 +721,14 @@ static bool new_directory(struct connection *conn, permstr = perms_to_strings(dir, &perms, 1, &len); fd = talloc_open(node_permfile(conn->transaction, node), O_WRONLY|O_CREAT|O_EXCL, 0640); - if (!fd || !write_all(*fd, permstr, len)) + if (!fd || !xs_write_all(*fd, permstr, len)) return false; if (data) { char *datapath = node_datafile(conn->transaction, node); fd = talloc_open(datapath, O_WRONLY|O_CREAT|O_EXCL, 0640); - if (!fd || !write_all(*fd, data, datalen)) + if (!fd || !xs_write_all(*fd, data, datalen)) return false; } @@ -878,7 +878,7 @@ static bool do_set_perms(struct connection *conn, struct buffered_data *in) char *node; struct xs_permissions *perms; - num = count_strings(in->buffer, in->used); + num = xs_count_strings(in->buffer, in->used); if (num < 2) return send_error(conn, EINVAL); @@ -898,7 +898,7 @@ static bool do_set_perms(struct connection *conn, struct buffered_data *in) return send_error(conn, errno); perms = talloc_array(node, struct xs_permissions, num); - if (!strings_to_perms(perms, num, in->buffer)) + if (!xs_strings_to_perms(perms, num, in->buffer)) return send_error(conn, errno); if (!set_perms(conn->transaction, node, perms, num)) @@ -938,6 +938,12 @@ static bool process_message(struct connection *conn, struct buffered_data *in) return do_set_perms(conn, in); case XS_SHUTDOWN: + /* FIXME: Implement gentle shutdown too. */ + /* Only tools can do this. */ + if (conn->id != 0) + return send_error(conn, EACCES); + if (!conn->can_write) + return send_error(conn, EROFS); send_ack(conn, XS_SHUTDOWN); /* Everything hangs off auto-free context, freed at exit. */ exit(0); @@ -1137,6 +1143,7 @@ struct connection *new_connection(connwritefn_t *write, connreadfn_t *read) new->transaction = NULL; new->write = write; new->read = read; + new->can_write = true; talloc_set_fail_handler(out_of_mem, &talloc_fail); if (setjmp(talloc_fail)) { @@ -1170,10 +1177,11 @@ static void accept_connection(int sock, bool canwrite) if (fd < 0) return; - conn = new_connection(canwrite ? writefd : NULL, readfd); - if (conn) + conn = new_connection(writefd, readfd); + if (conn) { conn->fd = fd; - else + conn->can_write = canwrite; + } else close(fd); } diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h index fe6eec8f72..0d0ebcaae0 100644 --- a/tools/xenstore/xenstored_core.h +++ b/tools/xenstore/xenstored_core.h @@ -56,6 +56,9 @@ struct connection /* Are we blocked waiting for a transaction to end? Contains node. */ char *blocked; + /* Is this a read-only connection? */ + bool can_write; + /* Our current event. If all used, we're waiting for ack. */ struct watch_event *event; diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c index bcc0a64967..a6f69ddf5b 100644 --- a/tools/xenstore/xenstored_domain.c +++ b/tools/xenstore/xenstored_domain.c @@ -268,6 +268,9 @@ bool do_introduce(struct connection *conn, struct buffered_data *in) if (get_strings(in, vec, ARRAY_SIZE(vec)) < ARRAY_SIZE(vec)) return send_error(conn, EINVAL); + if (!conn->can_write) + return send_error(conn, EROFS); + /* Hang domain off "in" until we're finished. */ domain = talloc(in, struct domain); domain->domid = atoi(vec[0]); diff --git a/tools/xenstore/xenstored_test.h b/tools/xenstore/xenstored_test.h index f173a5ca91..cf607cf2e0 100644 --- a/tools/xenstore/xenstored_test.h +++ b/tools/xenstore/xenstored_test.h @@ -21,7 +21,7 @@ #ifdef TESTING bool test_write_all(int fd, void *contents, unsigned int len); -#define write_all test_write_all +#define xs_write_all test_write_all int test_mkdir(const char *dir, int perms); #define mkdir test_mkdir diff --git a/tools/xenstore/xs.c b/tools/xenstore/xs.c index d5058abfb3..d6e41380f9 100644 --- a/tools/xenstore/xs.c +++ b/tools/xenstore/xs.c @@ -118,7 +118,7 @@ static bool read_all(int fd, void *data, unsigned int len) #ifdef XSTEST #define read_all read_all_choice -#define write_all write_all_choice +#define xs_write_all write_all_choice #endif static int get_error(const char *errorstring) @@ -179,11 +179,11 @@ static void *xs_talkv(struct xs_handle *h, enum xsd_sockmsg_type type, ignorepipe.sa_flags = 0; sigaction(SIGPIPE, &ignorepipe, &oldact); - if (!write_all(h->fd, &msg, sizeof(msg))) + if (!xs_write_all(h->fd, &msg, sizeof(msg))) goto fail; for (i = 0; i < num_vecs; i++) - if (!write_all(h->fd, iovec[i].iov_base, iovec[i].iov_len)) + if (!xs_write_all(h->fd, iovec[i].iov_base, iovec[i].iov_len)) goto fail; /* Watches can have fired before reply comes: daemon detects @@ -253,7 +253,7 @@ char **xs_directory(struct xs_handle *h, const char *path, unsigned int *num) return NULL; /* Count the strings. */ - *num = count_strings(strings, len); + *num = xs_count_strings(strings, len); /* Transfer to one big alloc for easy freeing. */ ret = malloc(*num * sizeof(char *) + len); @@ -342,7 +342,7 @@ struct xs_permissions *xs_get_permissions(struct xs_handle *h, return NULL; /* Count the strings: each one perms then domid. */ - *num = count_strings(strings, len); + *num = xs_count_strings(strings, len); /* Transfer to one big alloc for easy freeing. */ ret = malloc(*num * sizeof(struct xs_permissions)); @@ -351,7 +351,7 @@ struct xs_permissions *xs_get_permissions(struct xs_handle *h, return NULL; } - if (!strings_to_perms(ret, *num, strings)) { + if (!xs_strings_to_perms(ret, *num, strings)) { free_no_errno(ret); ret = NULL; } @@ -376,7 +376,7 @@ bool xs_set_permissions(struct xs_handle *h, const char *path, for (i = 0; i < num_perms; i++) { char buffer[MAX_STRLEN(domid_t)+1]; - if (!perm_to_string(&perms[i], buffer)) + if (!xs_perm_to_string(&perms[i], buffer)) goto unwind; iov[i+1].iov_base = strdup(buffer); diff --git a/tools/xenstore/xs_lib.c b/tools/xenstore/xs_lib.c index 8630eaffce..3f4f4b0899 100644 --- a/tools/xenstore/xs_lib.c +++ b/tools/xenstore/xs_lib.c @@ -48,7 +48,7 @@ const char *xs_daemon_transactions(void) } /* Simple routines for writing to sockets, etc. */ -bool write_all(int fd, const void *data, unsigned int len) +bool xs_write_all(int fd, const void *data, unsigned int len) { while (len) { int done; @@ -66,7 +66,7 @@ bool write_all(int fd, const void *data, unsigned int len) } /* Convert strings to permissions. False if a problem. */ -bool strings_to_perms(struct xs_permissions *perms, unsigned int num, +bool xs_strings_to_perms(struct xs_permissions *perms, unsigned int num, const char *strings) { const char *p; @@ -104,7 +104,7 @@ bool strings_to_perms(struct xs_permissions *perms, unsigned int num, } /* Convert permissions to a string (up to len MAX_STRLEN(domid_t)+1). */ -bool perm_to_string(const struct xs_permissions *perm, char *buffer) +bool xs_perm_to_string(const struct xs_permissions *perm, char *buffer) { switch (perm->perms) { case XS_PERM_WRITE: @@ -128,7 +128,7 @@ bool perm_to_string(const struct xs_permissions *perm, char *buffer) } /* Given a string and a length, count how many strings (nul terms). */ -unsigned int count_strings(const char *strings, unsigned int len) +unsigned int xs_count_strings(const char *strings, unsigned int len) { unsigned int num; const char *p; diff --git a/tools/xenstore/xs_lib.h b/tools/xenstore/xs_lib.h index a946ab0b19..76ea9b67fe 100644 --- a/tools/xenstore/xs_lib.h +++ b/tools/xenstore/xs_lib.h @@ -48,16 +48,16 @@ const char *xs_daemon_store(void); const char *xs_daemon_transactions(void); /* Simple write function: loops for you. */ -bool write_all(int fd, const void *data, unsigned int len); +bool xs_write_all(int fd, const void *data, unsigned int len); /* Convert strings to permissions. False if a problem. */ -bool strings_to_perms(struct xs_permissions *perms, unsigned int num, +bool xs_strings_to_perms(struct xs_permissions *perms, unsigned int num, const char *strings); /* Convert permissions to a string (up to len MAX_STRLEN(domid_t)+1). */ -bool perm_to_string(const struct xs_permissions *perm, char *buffer); +bool xs_perm_to_string(const struct xs_permissions *perm, char *buffer); /* Given a string and a length, count how many strings (nul terms). */ -unsigned int count_strings(const char *strings, unsigned int len); +unsigned int xs_count_strings(const char *strings, unsigned int len); #endif /* _XS_LIB_H */ diff --git a/tools/xenstore/xs_random.c b/tools/xenstore/xs_random.c index ef5d44d0b0..675cc89093 100644 --- a/tools/xenstore/xs_random.c +++ b/tools/xenstore/xs_random.c @@ -223,10 +223,10 @@ static struct xs_permissions *file_get_perms(struct file_ops_info *info, release_file(perms, size); return ret; } - *num = count_strings(perms, size); + *num = xs_count_strings(perms, size); ret = new_array(struct xs_permissions, *num); - if (!strings_to_perms(ret, *num, perms)) + if (!xs_strings_to_perms(ret, *num, perms)) barf("Reading permissions from %s", permfile); release_file(perms, size); return ret; @@ -267,7 +267,7 @@ static bool file_set_perms(struct file_ops_info *info, for (i = 0; i < num; i++) { char buffer[100]; - if (!perm_to_string(&perms[i], buffer)) { + if (!xs_perm_to_string(&perms[i], buffer)) { int saved_errno = errno; close(fd); errno = saved_errno; @@ -536,7 +536,7 @@ static char *dump_dir(struct ops *ops, ret = talloc_asprintf_append(ret, "%s%s: ", spacing, dir[i]); for (j = 0; j < numperms; j++) { char buffer[100]; - if (!perm_to_string(&perms[j], buffer)) + if (!xs_perm_to_string(&perms[j], buffer)) barf("perm to string"); ret = talloc_asprintf_append(ret, "%s ", buffer); } diff --git a/tools/xenstore/xs_test.c b/tools/xenstore/xs_test.c index f1e66cbe28..4d769e220d 100644 --- a/tools/xenstore/xs_test.c +++ b/tools/xenstore/xs_test.c @@ -153,7 +153,7 @@ static bool write_all_choice(int fd, const void *data, unsigned int len) { if (fd == -2) return write_all_shmem(fd, data, len); - return write_all(fd, data, len); + return xs_write_all(fd, data, len); } /* We want access to internal functions. */ @@ -176,11 +176,11 @@ static void __attribute__((noreturn)) usage(void) " watch <path> <prio>\n" " waitwatch\n" " ackwatch\n" - " unwatch <path>\n" + " unwatch <path> <token>\n" " close\n" " start <node>\n" " abort\n" - " introduce <domid> <mfn> <eventchn>\n" + " introduce <domid> <mfn> <eventchn> <path>\n" " commit\n" " sleep <seconds>\n" " dump\n"); @@ -491,7 +491,7 @@ static void dump_dir(unsigned int handle, printf("%s%s: ", spacing, dir[i]); for (j = 0; j < numperms; j++) { char buffer[100]; - if (!perm_to_string(&perms[j], buffer)) + if (!xs_perm_to_string(&perms[j], buffer)) barf("perm to string"); printf("%s ", buffer); } |