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-changelog

[Xen-changelog] Implement watching of nodes which don't exist.

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] Implement watching of nodes which don't exist.
From: Xen patchbot -unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Tue, 02 Aug 2005 14:04:12 -0400
Delivery-date: Tue, 02 Aug 2005 18:04:47 +0000
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User cl349@xxxxxxxxxxxxxxxxxxxx
# Node ID 5eead9930294f699f8feb9f7f5b157cb9c607b69
# Parent  a05338d886d9e43996c4061d912a15cc93ef145c
Implement watching of nodes which don't exist.
Requires permission check every time event is generated.
Requires generalization of permissions: ask arbitrary number of
parents whether it's OK to tell about node (eg. watching
/dir/subdir/x when /dir is deleted: root permissions will now
determine whether we fire event).
Add test that we don't leak information on whether a file exists
or not.
Signed-off-by: Rusty Russel <rusty@xxxxxxxxxxxxxxx>
Signed-off-by: Christian Limpach <Christian.Limpach@xxxxxxxxxxxx>

diff -r a05338d886d9 -r 5eead9930294 tools/xenstore/testsuite/07watch.sh
--- a/tools/xenstore/testsuite/07watch.sh       Tue Aug  2 18:04:00 2005
+++ b/tools/xenstore/testsuite/07watch.sh       Tue Aug  2 18:04:28 2005
@@ -160,3 +160,22 @@
 1 waitwatch' | ./xs_test 2>&1`" = "1:/test2/foo:token
 1:contents2
 1:waitwatch timeout" ]
+
+# We can watch something which doesn't exist.
+[ "`echo '1 watch /dir/subdir token
+2 mkdir /dir/subdir
+1 waitwatch' | ./xs_test 2>&1`" = "1:/dir/subdir:token" ]
+
+# If we don't have permission, we won't see event (rm).
+[ "`echo '1 setid 1
+1 watch /dir/subdir token
+setperm /dir 0 NONE
+rm /dir/subdir
+1 waitwatch' | ./xs_test 2>&1`" = "1:waitwatch timeout" ]
+
+# If we don't have permission, we won't see event (create).
+[ "`echo '1 setid 1
+1 watch /dir/subdir token
+mkdir /dir/subdir
+write /dir/subdir/entry create contents
+1 waitwatch' | ./xs_test 2>&1`" = "1:waitwatch timeout" ]
diff -r a05338d886d9 -r 5eead9930294 tools/xenstore/xenstored_core.c
--- a/tools/xenstore/xenstored_core.c   Tue Aug  2 18:04:00 2005
+++ b/tools/xenstore/xenstored_core.c   Tue Aug  2 18:04:28 2005
@@ -707,7 +707,7 @@
 
        /* Owners and tools get it all... */
        if (!id || perms[0].id == id)
-               return XS_PERM_READ|XS_PERM_WRITE|XS_PERM_CREATE|XS_PERM_OWNER;
+               return XS_PERM_READ|XS_PERM_WRITE|XS_PERM_OWNER;
 
        for (i = 1; i < num; i++)
                if (perms[i].id == id)
@@ -716,19 +716,12 @@
        return perms[0].perms;
 }
 
-/* We have a weird permissions system.  You can allow someone into a
- * specific node without allowing it in the parents.  If it's going to
- * fail, however, we don't want the errno to indicate any information
- * about the node. */
-static int check_with_parents(struct connection *conn, const char *node,
-                             int errnum)
+/* What do parents say? */
+static enum xs_perm_type ask_parents(struct connection *conn,
+                                    const char *node)
 {
        struct xs_permissions *perms;
        unsigned int num;
-
-       /* We always tell them about memory failures. */
-       if (errnum == ENOMEM)
-               return errnum;
 
        do {
                node = get_parent(node);
@@ -741,10 +734,23 @@
        if (!perms)
                corrupt(conn, "No permissions file at root");
 
-       if (!(perm_for_id(conn->id, perms, num) & XS_PERM_READ))
-               return EACCES;
-
-       return errnum;
+       return perm_for_id(conn->id, perms, num);
+}
+
+/* We have a weird permissions system.  You can allow someone into a
+ * specific node without allowing it in the parents.  If it's going to
+ * fail, however, we don't want the errno to indicate any information
+ * about the node. */
+static int errno_from_parents(struct connection *conn, const char *node,
+                             int errnum)
+{
+       /* We always tell them about memory failures. */
+       if (errnum == ENOMEM)
+               return errnum;
+
+       if (ask_parents(conn, node) & XS_PERM_READ)
+               return errnum;
+       return EACCES;
 }
 
 char *canonicalize(struct connection *conn, const char *node)
@@ -776,24 +782,26 @@
        }
 
        perms = get_perms(conn->transaction, node, &num);
-       /* No permissions.  If we want to create it and
-        * it doesn't exist, check parent directory. */
-       if (!perms && errno == ENOENT && (perm & XS_PERM_CREATE)) {
-               char *parent = get_parent(node);
-               if (!parent)
-                       return false;
-
-               perms = get_perms(conn->transaction, parent, &num);
-       }
-       if (!perms) {
-               errno = check_with_parents(conn, node, errno);
+
+       if (perms) {
+               if (perm_for_id(conn->id, perms, num) & perm)
+                       return true;
+               errno = EACCES;
                return false;
        }
 
-       if (perm_for_id(conn->id, perms, num) & perm)
-               return true;
-
-       errno = check_with_parents(conn, node, EACCES);
+       /* If it's OK not to exist, we consult parents. */
+       if (errno == ENOENT && (perm & XS_PERM_ENOENT_OK)) {
+               if (ask_parents(conn, node) & perm)
+                       return true;
+               /* Parents say they should not know. */
+               errno = EACCES;
+               return false;
+       }
+
+       /* They might not have permission to even *see* this node, in
+        * which case we return EACCES even if it's ENOENT or EIO. */
+       errno = errno_from_parents(conn, node, errno);
        return false;
 }
 
@@ -930,9 +938,9 @@
        if (streq(vec[1], XS_WRITE_NONE))
                mode = XS_PERM_WRITE;
        else if (streq(vec[1], XS_WRITE_CREATE))
-               mode = XS_PERM_WRITE|XS_PERM_CREATE;
+               mode = XS_PERM_WRITE|XS_PERM_ENOENT_OK;
        else if (streq(vec[1], XS_WRITE_CREATE_EXCL))
-               mode = XS_PERM_WRITE|XS_PERM_CREATE;
+               mode = XS_PERM_WRITE|XS_PERM_ENOENT_OK;
        else {
                send_error(conn, EINVAL);
                return;
@@ -951,7 +959,7 @@
                }
 
                /* Not going to create it? */
-               if (!(mode & XS_PERM_CREATE)) {
+               if (streq(vec[1], XS_WRITE_NONE)) {
                        send_error(conn, ENOENT);
                        return;
                }
@@ -985,7 +993,7 @@
 static void do_mkdir(struct connection *conn, const char *node)
 {
        node = canonicalize(conn, node);
-       if (!check_node_perms(conn, node, XS_PERM_WRITE|XS_PERM_CREATE)) {
+       if (!check_node_perms(conn, node, XS_PERM_WRITE|XS_PERM_ENOENT_OK)) {
                send_error(conn, errno);
                return;
        }
diff -r a05338d886d9 -r 5eead9930294 tools/xenstore/xenstored_watch.c
--- a/tools/xenstore/xenstored_watch.c  Tue Aug  2 18:04:00 2005
+++ b/tools/xenstore/xenstored_watch.c  Tue Aug  2 18:04:28 2005
@@ -95,9 +95,18 @@
        return 0;
 }
 
-static void add_event(struct watch *watch, const char *node)
+static void add_event(struct connection *conn,
+                     struct watch *watch, const char *node)
 {
        struct watch_event *event;
+
+       /* Check read permission: no permission, no watch event.
+        * If it doesn't exist, we need permission to read parent.
+        */
+       if (!check_node_perms(conn, node, XS_PERM_READ|XS_PERM_ENOENT_OK)) {
+               fprintf(stderr, "No permission for %s\n", node);
+               return;
+       }
 
        if (watch->relative_path) {
                node += strlen(watch->relative_path);
@@ -132,9 +141,9 @@
 
                list_for_each_entry(watch, &i->watches, list) {
                        if (is_child(node, watch->node))
-                               add_event(watch, node);
+                               add_event(i, watch, node);
                        else if (recurse && is_child(watch->node, node))
-                               add_event(watch, watch->node);
+                               add_event(i, watch, watch->node);
                        else
                                continue;
                        /* If connection not doing anything, queue this. */
@@ -206,7 +215,7 @@
 
        relative = !strstarts(vec[0], "/");
        vec[0] = canonicalize(conn, vec[0]);
-       if (!check_node_perms(conn, vec[0], XS_PERM_READ)) {
+       if (!is_valid_nodename(vec[0])) {
                send_error(conn, errno);
                return;
        }
diff -r a05338d886d9 -r 5eead9930294 tools/xenstore/xs_lib.h
--- a/tools/xenstore/xs_lib.h   Tue Aug  2 18:04:00 2005
+++ b/tools/xenstore/xs_lib.h   Tue Aug  2 18:04:28 2005
@@ -30,7 +30,7 @@
        XS_PERM_READ = 1,
        XS_PERM_WRITE = 2,
        /* Internal use. */
-       XS_PERM_CREATE = 4,
+       XS_PERM_ENOENT_OK = 4,
        XS_PERM_OWNER = 8,
 };
 

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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] Implement watching of nodes which don't exist., Xen patchbot -unstable <=