bug-hurd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] libdiskfs: fix reference counting of peropen objects


From: Justus Winter
Subject: [PATCH] libdiskfs: fix reference counting of peropen objects
Date: Fri, 29 Aug 2014 11:33:44 +0200

Previously, peropen objects were created with a reference count of
zero.  Therefore, if diskfs_create_protid fails, passing such an
object to diskfs_release_peropen would lead to a reference count
underflow.

* libdiskfs/peropen-make.c (diskfs_peropen_make): Initialize reference
count to one.
* libdiskfs/protid-make.c (diskfs_start_protid): And consume this
reference on success.  Update comment.
(diskfs_create_protid): Update comment.
* libdiskfs/diskfs.h: Update comments.
* libdiskfs/io-duplicate.c (diskfs_S_io_duplicate): Adjust reference
counting accordingly.
* libdiskfs/io-reauthenticate.c (diskfs_S_io_reauthenticate): Likewise.
* libdiskfs/io-restrict-auth.c (diskfs_S_io_restrict_auth): Likewise.
---
 libdiskfs/diskfs.h            | 4 ++--
 libdiskfs/io-duplicate.c      | 3 +++
 libdiskfs/io-reauthenticate.c | 2 ++
 libdiskfs/io-restrict-auth.c  | 3 +++
 libdiskfs/peropen-make.c      | 2 +-
 libdiskfs/protid-make.c       | 6 +++---
 6 files changed, 14 insertions(+), 6 deletions(-)

diff --git a/libdiskfs/diskfs.h b/libdiskfs/diskfs.h
index e328527..e59ba99 100644
--- a/libdiskfs/diskfs.h
+++ b/libdiskfs/diskfs.h
@@ -820,12 +820,12 @@ diskfs_create_node (struct node *dir, const char *name, 
mode_t mode,
                    struct dirstat *ds);
 
 /* Create and return a protid for an existing peropen PO in CRED,
-   referring to user USER.  */
+   referring to user USER.  On success, consume a reference to PO.  */
 error_t diskfs_create_protid (struct peropen *po, struct iouser *user,
                              struct protid **cred);
 
 /* Build and return in CRED a protid which has no user identification, for
-   peropen PO.  */
+   peropen PO.  On success, consume a reference to PO.  */
 error_t diskfs_start_protid (struct peropen *po, struct protid **cred);
 
 /* Finish building protid CRED started with diskfs_start_protid;
diff --git a/libdiskfs/io-duplicate.c b/libdiskfs/io-duplicate.c
index 45c4df5..a2e568b 100644
--- a/libdiskfs/io-duplicate.c
+++ b/libdiskfs/io-duplicate.c
@@ -32,6 +32,7 @@ diskfs_S_io_duplicate (struct protid *cred,
   
   pthread_mutex_lock (&cred->po->np->lock);
 
+  refcount_ref (&cred->po->refcnt);
   err = diskfs_create_protid (cred->po, cred->user, &newpi);
   if (! err)
     {
@@ -39,6 +40,8 @@ diskfs_S_io_duplicate (struct protid *cred,
       *portpoly = MACH_MSG_TYPE_MAKE_SEND;
       ports_port_deref (newpi);
     }
+  else
+    refcount_deref (&cred->po->refcnt);
 
   pthread_mutex_unlock (&cred->po->np->lock);
 
diff --git a/libdiskfs/io-reauthenticate.c b/libdiskfs/io-reauthenticate.c
index 69d78bc..649315f 100644
--- a/libdiskfs/io-reauthenticate.c
+++ b/libdiskfs/io-reauthenticate.c
@@ -35,11 +35,13 @@ diskfs_S_io_reauthenticate (struct protid *cred,
      are a simpleroutine, so callers won't know to restart. */
 
   pthread_mutex_lock (&cred->po->np->lock);
+  refcount_ref (&cred->po->refcnt);
   do
     err = diskfs_start_protid (cred->po, &newcred);
   while (err == EINTR);
   if (err)
     {
+      refcount_deref (&cred->po->refcnt);
       pthread_mutex_unlock (&cred->po->np->lock);
       return err;
     }
diff --git a/libdiskfs/io-restrict-auth.c b/libdiskfs/io-restrict-auth.c
index 011aa19..80c0b20 100644
--- a/libdiskfs/io-restrict-auth.c
+++ b/libdiskfs/io-restrict-auth.c
@@ -41,6 +41,7 @@ diskfs_S_io_restrict_auth (struct protid *cred,
     return err;
 
   pthread_mutex_lock (&cred->po->np->lock);
+  refcount_ref (&cred->po->refcnt);
   err = diskfs_create_protid (cred->po, user, &newpi);
   if (! err)
     {
@@ -48,6 +49,8 @@ diskfs_S_io_restrict_auth (struct protid *cred,
       *newportpoly = MACH_MSG_TYPE_MAKE_SEND;
       ports_port_deref (newpi);
     }
+  else
+    refcount_deref (&cred->po->refcnt);
   pthread_mutex_unlock (&cred->po->np->lock);
 
   iohelp_free_iouser (user);
diff --git a/libdiskfs/peropen-make.c b/libdiskfs/peropen-make.c
index 6d5ca01..788b9a7 100644
--- a/libdiskfs/peropen-make.c
+++ b/libdiskfs/peropen-make.c
@@ -31,7 +31,7 @@ diskfs_make_peropen (struct node *np, int flags, struct 
peropen *context,
 
   po->filepointer = 0;
   po->lock_status = LOCK_UN;
-  refcount_init (&po->refcnt, 0);
+  refcount_init (&po->refcnt, 1);
   po->openstat = flags;
   po->np = np;
   po->path = NULL;
diff --git a/libdiskfs/protid-make.c b/libdiskfs/protid-make.c
index 22aaa2e..0b09299 100644
--- a/libdiskfs/protid-make.c
+++ b/libdiskfs/protid-make.c
@@ -20,7 +20,7 @@
 #include <assert.h>
 
 /* Build and return in CRED a protid which has no user identification, for
-   peropen PO.  */
+   peropen PO.  On success, consume a reference to PO.  */
 error_t
 diskfs_start_protid (struct peropen *po, struct protid **cred)
 {
@@ -29,7 +29,7 @@ diskfs_start_protid (struct peropen *po, struct protid **cred)
                                 sizeof (struct protid), cred);
   if (! err)
     {
-      refcount_ref (&po->refcnt);
+      /* Consume a reference to po.  */
       (*cred)->po = po;
       (*cred)->shared_object = MACH_PORT_NULL;
       (*cred)->mapped = 0;
@@ -56,7 +56,7 @@ diskfs_finish_protid (struct protid *cred, struct iouser 
*user)
 }
 
 /* Create and return a protid for an existing peropen PO in CRED for
-   USER.  */
+   USER.  On success, consume a reference to PO.  */
 error_t
 diskfs_create_protid (struct peropen *po, struct iouser *user,
                      struct protid **cred)
-- 
2.1.0




reply via email to

[Prev in Thread] Current Thread [Next in Thread]