summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJustus Winter <justus@gnupg.org>2016-05-22 14:05:25 +0200
committerJustus Winter <justus@gnupg.org>2016-05-22 14:05:25 +0200
commit06e9e359b950201fad5347f90854ecfdbb4caab4 (patch)
tree59711f3c9ba750b26044e8ffaccaac667f3414d7
parent6dc11de010ad9a1ef4921a8c6dc8900941e914d1 (diff)
add patch series
-rw-r--r--debian/patches/fix-refcount-assertion0001-libdiskfs-fix-error-handling.patch26
-rw-r--r--debian/patches/fix-refcount-assertion0002-ext2fs-fix-pager-use-after-free.patch87
-rw-r--r--debian/patches/series2
3 files changed, 115 insertions, 0 deletions
diff --git a/debian/patches/fix-refcount-assertion0001-libdiskfs-fix-error-handling.patch b/debian/patches/fix-refcount-assertion0001-libdiskfs-fix-error-handling.patch
new file mode 100644
index 00000000..8bed4a0e
--- /dev/null
+++ b/debian/patches/fix-refcount-assertion0001-libdiskfs-fix-error-handling.patch
@@ -0,0 +1,26 @@
+From 0ab3825f250486453892e3e18a702a44538bff6d Mon Sep 17 00:00:00 2001
+From: Justus Winter <justus@gnupg.org>
+Date: Sun, 22 May 2016 00:43:19 +0200
+Subject: [PATCH hurd 1/2] libdiskfs: fix error handling
+
+* libdiskfs/dir-rmdir.c (diskfs_S_dir_rmdir): Initialize 'np'.
+---
+ libdiskfs/dir-rmdir.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/libdiskfs/dir-rmdir.c b/libdiskfs/dir-rmdir.c
+index 83ec37b..8a29979 100644
+--- a/libdiskfs/dir-rmdir.c
++++ b/libdiskfs/dir-rmdir.c
+@@ -25,7 +25,7 @@ diskfs_S_dir_rmdir (struct protid *dircred,
+ char *name)
+ {
+ struct node *dnp;
+- struct node *np;
++ struct node *np = NULL;
+ struct dirstat *ds = alloca (diskfs_dirstat_size);
+ error_t error;
+
+--
+2.1.4
+
diff --git a/debian/patches/fix-refcount-assertion0002-ext2fs-fix-pager-use-after-free.patch b/debian/patches/fix-refcount-assertion0002-ext2fs-fix-pager-use-after-free.patch
new file mode 100644
index 00000000..8809a309
--- /dev/null
+++ b/debian/patches/fix-refcount-assertion0002-ext2fs-fix-pager-use-after-free.patch
@@ -0,0 +1,87 @@
+From 60d14f5b3c4ea27af6f4220a15947c328bc888ee Mon Sep 17 00:00:00 2001
+From: Justus Winter <justus@gnupg.org>
+Date: Sun, 22 May 2016 00:52:29 +0200
+Subject: [PATCH hurd 2/2] ext2fs: fix pager use-after-free
+
+Previously, pagers had no reference for being part of a node, only for
+having a send right made for them. Hence we sometimes saw
+use-after-free errors if the kernel did give up that send right,
+typically while deleting files. Keep a weak reference as long as the
+pager is referenced by a node.
+
+* ext2fs/pager.c (pager_clear_user_data): Assert that 'pager' has been
+NULLed.
+(pager_dropweak): Drop the weak reference and NULL 'pager'.
+(diskfs_get_filemap): Simplify. Acquire a weak reference.
+---
+ ext2fs/pager.c | 31 ++++++++++++++++++++-----------
+ 1 file changed, 20 insertions(+), 11 deletions(-)
+
+diff --git a/ext2fs/pager.c b/ext2fs/pager.c
+index 7d3a8f3..485f69c 100644
+--- a/ext2fs/pager.c
++++ b/ext2fs/pager.c
+@@ -817,8 +817,7 @@ pager_clear_user_data (struct user_pager_info *upi)
+
+ pthread_spin_lock (&node_to_page_lock);
+ pager = diskfs_node_disknode (upi->node)->pager;
+- if (pager && pager_get_upi (pager) == upi)
+- diskfs_node_disknode (upi->node)->pager = 0;
++ assert (!pager || pager_get_upi (pager) != upi);
+ pthread_spin_unlock (&node_to_page_lock);
+
+ diskfs_nrele_light (upi->node);
+@@ -831,8 +830,21 @@ pager_clear_user_data (struct user_pager_info *upi)
+ The pager library creates no weak references itself. If the user doesn't
+ either, then it's OK for this function to do nothing. */
+ void
+-pager_dropweak (struct user_pager_info *p __attribute__ ((unused)))
++pager_dropweak (struct user_pager_info *upi)
+ {
++ if (upi->type == FILE_DATA)
++ {
++ struct pager *pager;
++
++ pthread_spin_lock (&node_to_page_lock);
++ pager = diskfs_node_disknode (upi->node)->pager;
++ if (pager && pager_get_upi (pager) == upi)
++ {
++ diskfs_node_disknode (upi->node)->pager = NULL;
++ ports_port_deref_weak (pager);
++ }
++ pthread_spin_unlock (&node_to_page_lock);
++ }
+ }
+
+ /* Cached blocks from disk. */
+@@ -1298,15 +1310,9 @@ diskfs_get_filemap (struct node *node, vm_prot_t prot)
+ struct pager *pager = diskfs_node_disknode (node)->pager;
+ if (pager)
+ {
+- /* Because PAGER is not a real reference,
+- this might be nearly deallocated. If that's so, then
+- the port right will be null. In that case, clear here
+- and loop. The deallocation will complete separately. */
+ right = pager_get_port (pager);
+- if (right == MACH_PORT_NULL)
+- diskfs_node_disknode (node)->pager = 0;
+- else
+- pager_get_upi (pager)->max_prot |= prot;
++ assert (MACH_PORT_VALID (right));
++ pager_get_upi (pager)->max_prot |= prot;
+ }
+ else
+ {
+@@ -1327,6 +1333,9 @@ diskfs_get_filemap (struct node *node, vm_prot_t prot)
+ return MACH_PORT_NULL;
+ }
+
++ /* A weak reference for being part of the node. */
++ ports_port_ref_weak (diskfs_node_disknode (node)->pager);
++
+ right = pager_get_port (diskfs_node_disknode (node)->pager);
+ ports_port_deref (diskfs_node_disknode (node)->pager);
+ }
+--
+2.1.4
+
diff --git a/debian/patches/series b/debian/patches/series
index 0a3bced4..520c8cbc 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -37,3 +37,5 @@ exec_filename0003-Use-the-new-_hurd_exec_file_name-function.patch
exec_filename0004-This-patch-is-an-amendment-of-exec_filename_exec.pat.patch
crash0001-xxx-crash-logging-works.patch
+fix-refcount-assertion0001-libdiskfs-fix-error-handling.patch
+fix-refcount-assertion0002-ext2fs-fix-pager-use-after-free.patch