fs-backend: do not expose file descriptors to frontend
authorKeir Fraser <keir.fraser@citrix.com>
Wed, 16 Jul 2008 10:13:21 +0000 (11:13 +0100)
committerKeir Fraser <keir.fraser@citrix.com>
Wed, 16 Jul 2008 10:13:21 +0000 (11:13 +0100)
Signed-off-by: Samuel Thibault <samuel.thibault@eu.citrix.com>
tools/fs-back/fs-backend.c
tools/fs-back/fs-backend.h
tools/fs-back/fs-ops.c

index 71518f0aa2251a7e1a7716655fb97591d4600af9..22686b82b202e914e2dd606e8d55db2f98593a42 100644 (file)
@@ -198,6 +198,7 @@ static void handle_connection(int frontend_dom_id, int export_id, char *frontend
     int evt_port;
     pthread_t handling_thread;
     struct fsif_sring *sring;
+    int i;
 
     printf("Handling connection from dom=%d, for export=%d\n", 
             frontend_dom_id, export_id);
@@ -240,6 +241,8 @@ static void handle_connection(int frontend_dom_id, int export_id, char *frontend
                                     PROT_READ | PROT_WRITE);
     BACK_RING_INIT(&mount->ring, sring, PAGE_SIZE);
     mount->nr_entries = mount->ring.nr_ents; 
+    for (i = 0; i < MAX_FDS; i++)
+        mount->fds[i] = -1;
     xenbus_write_backend_ready(mount);
 
     pthread_create(&handling_thread, NULL, &handle_mount, mount);
index bf54dae531557a02c6f35aefcdb57a942a908e15..2ad96f88d4d6b24a2cd71975b40586ee15868c3a 100644 (file)
@@ -12,6 +12,7 @@
 #define EXPORTS_SUBNODE     "exports"
 #define EXPORTS_NODE        ROOT_NODE"/"EXPORTS_SUBNODE
 #define WATCH_NODE          EXPORTS_NODE"/requests"
+#define MAX_FDS             16
 
 struct fs_export
 {
@@ -45,6 +46,7 @@ struct mount
     int nr_entries;
     struct fs_request *requests;
     unsigned short *freelist;
+    int fds[MAX_FDS];
 };
 
 
index 4246759f5a931464772c2cc7cc68b416b6abbd2c..d55e9565246f542862926d710f60a29ef7e76483 100644 (file)
@@ -34,6 +34,16 @@ unsigned short get_request(struct mount *mount, struct fsif_request *req)
     return id;
 }
 
+int get_fd(struct mount *mount)
+{
+    int i;
+
+    for (i = 0; i < MAX_FDS; i++)
+        if (mount->fds[i] == -1)
+            return i;
+    return -1;
+}
+
 
 void dispatch_file_open(struct mount *mount, struct fsif_request *req)
 {
@@ -59,8 +69,17 @@ void dispatch_file_open(struct mount *mount, struct fsif_request *req)
            mount->export->export_path, file_name);
     assert(xc_gnttab_munmap(mount->gnth, file_name, 1) == 0);
     printf("Issuing open for %s\n", full_path);
-    fd = open(full_path, O_RDWR);
-    printf("Got FD: %d\n", fd);
+    fd = get_fd(mount);
+    if (fd >= 0) {
+        int real_fd = open(full_path, O_RDWR);
+        if (real_fd < 0)
+            fd = -1;
+        else
+        {
+            mount->fds[fd] = real_fd;
+            printf("Got FD: %d for real %d\n", fd, real_fd);
+        }
+    }
     /* We can advance the request consumer index, from here on, the request
      * should not be used (it may be overrinden by a response) */
     mount->ring.req_cons++;
@@ -84,7 +103,12 @@ void dispatch_file_close(struct mount *mount, struct fsif_request *req)
     printf("Dispatching file close operation (fd=%d).\n", req->u.fclose.fd);
    
     req_id = req->id;
-    ret = close(req->u.fclose.fd);
+    if (req->u.fclose.fd < MAX_FDS) {
+        int fd = mount->fds[req->u.fclose.fd];
+        ret = close(fd);
+        mount->fds[req->u.fclose.fd] = -1;
+    } else
+        ret = -1;
     printf("Got ret: %d\n", ret);
     /* We can advance the request consumer index, from here on, the request
      * should not be used (it may be overrinden by a response) */
@@ -115,7 +139,12 @@ void dispatch_file_read(struct mount *mount, struct fsif_request *req)
     req_id = req->id;
     printf("File read issued for FD=%d (len=%"PRIu64", offest=%"PRIu64")\n", 
             req->u.fread.fd, req->u.fread.len, req->u.fread.offset); 
-   
+
+    if (req->u.fread.fd < MAX_FDS)
+        fd = mount->fds[req->u.fread.fd];
+    else
+        fd = -1;
+
     priv_id = get_request(mount, req);
     printf("Private id is: %d\n", priv_id);
     priv_req = &mount->requests[priv_id];
@@ -123,13 +152,13 @@ void dispatch_file_read(struct mount *mount, struct fsif_request *req)
 
     /* Dispatch AIO read request */
     bzero(&priv_req->aiocb, sizeof(struct aiocb));
-    priv_req->aiocb.aio_fildes = req->u.fread.fd;
+    priv_req->aiocb.aio_fildes = fd;
     priv_req->aiocb.aio_nbytes = req->u.fread.len;
     priv_req->aiocb.aio_offset = req->u.fread.offset;
     priv_req->aiocb.aio_buf = buf;
     assert(aio_read(&priv_req->aiocb) >= 0);
 
-     
+out: 
     /* We can advance the request consumer index, from here on, the request
      * should not be used (it may be overrinden by a response) */
     mount->ring.req_cons++;
@@ -171,6 +200,11 @@ void dispatch_file_write(struct mount *mount, struct fsif_request *req)
     printf("File write issued for FD=%d (len=%"PRIu64", offest=%"PRIu64")\n", 
             req->u.fwrite.fd, req->u.fwrite.len, req->u.fwrite.offset); 
    
+    if (req->u.fwrite.fd < MAX_FDS)
+        fd = mount->fds[req->u.fwrite.fd];
+    else
+        fd = -1;
+
     priv_id = get_request(mount, req);
     printf("Private id is: %d\n", priv_id);
     priv_req = &mount->requests[priv_id];
@@ -178,7 +212,7 @@ void dispatch_file_write(struct mount *mount, struct fsif_request *req)
 
     /* Dispatch AIO write request */
     bzero(&priv_req->aiocb, sizeof(struct aiocb));
-    priv_req->aiocb.aio_fildes = req->u.fwrite.fd;
+    priv_req->aiocb.aio_fildes = fd;
     priv_req->aiocb.aio_nbytes = req->u.fwrite.len;
     priv_req->aiocb.aio_offset = req->u.fwrite.offset;
     priv_req->aiocb.aio_buf = buf;
@@ -224,8 +258,12 @@ void dispatch_stat(struct mount *mount, struct fsif_request *req)
                                   PROT_WRITE);
    
     req_id = req->id;
-    fd = req->u.fstat.fd;
-    printf("File stat issued for FD=%d\n", fd); 
+    if (req->u.fstat.fd < MAX_FDS)
+        fd = mount->fds[req->u.fstat.fd];
+    else
+        fd = -1;
+
+    printf("File stat issued for FD=%d\n", req->u.fstat.fd); 
    
     /* We can advance the request consumer index, from here on, the request
      * should not be used (it may be overrinden by a response) */
@@ -274,10 +312,14 @@ void dispatch_truncate(struct mount *mount, struct fsif_request *req)
     int64_t length;
 
     req_id = req->id;
-    fd = req->u.ftruncate.fd;
     length = req->u.ftruncate.length;
-    printf("File truncate issued for FD=%d, length=%"PRId64"\n", fd, length); 
+    printf("File truncate issued for FD=%d, length=%"PRId64"\n", req->u.ftruncate.fd, length); 
    
+    if (req->u.ftruncate.fd < MAX_FDS)
+        fd = mount->fds[req->u.ftruncate.fd];
+    else
+        fd = -1;
+
     /* We can advance the request consumer index, from here on, the request
      * should not be used (it may be overrinden by a response) */
     mount->ring.req_cons++;
@@ -510,7 +552,11 @@ void dispatch_chmod(struct mount *mount, struct fsif_request *req)
     printf("Dispatching file chmod operation (fd=%d, mode=%o).\n", 
             req->u.fchmod.fd, req->u.fchmod.mode);
     req_id = req->id;
-    fd = req->u.fchmod.fd;
+    if (req->u.fchmod.fd < MAX_FDS)
+        fd = mount->fds[req->u.fchmod.fd];
+    else
+        fd = -1;
+
     mode = req->u.fchmod.mode;
     /* We can advance the request consumer index, from here on, the request
      * should not be used (it may be overrinden by a response) */
@@ -575,8 +621,12 @@ void dispatch_file_sync(struct mount *mount, struct fsif_request *req)
     struct fs_request *priv_req;
 
     req_id = req->id;
-    fd = req->u.fsync.fd;
-    printf("File sync issued for FD=%d\n", fd); 
+    if (req->u.fsync.fd < MAX_FDS)
+        fd = mount->fds[req->u.fsync.fd];
+    else
+        fd = -1;
+
+    printf("File sync issued for FD=%d\n", req->u.fsync.fd); 
    
     priv_id = get_request(mount, req);
     printf("Private id is: %d\n", priv_id);