[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[hurd] 01/01: Revert using protected payload in libdiskfs
From: |
Samuel Thibault |
Subject: |
[hurd] 01/01: Revert using protected payload in libdiskfs |
Date: |
Mon, 20 Apr 2015 02:45:52 +0000 |
This is an automated email from the git hooks/post-receive script.
sthibault pushed a commit to branch master
in repository hurd.
commit d21bfa210da9ad96d5bcd992fdee3f41e204fdfa
Author: Samuel Thibault <address@hidden>
Date: Mon Apr 20 02:45:20 2015 +0000
Revert using protected payload in libdiskfs
to fix a hang inside the Debian installer.
---
debian/changelog | 7 +
.../git-R-libdiskfs-protected-payload.patch | 669 +++++++++++++++++++++
debian/patches/series | 1 +
3 files changed, 677 insertions(+)
diff --git a/debian/changelog b/debian/changelog
index 3d3221d..361a782 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,10 @@
+hurd (1:0.6-2) unstable; urgency=medium
+
+ * patches/git-R-libdiskfs-protected-payload.patch: Revert using protected
+ payload in libdiskfs, to fix a hang inside the Debian installer.
+
+ -- Samuel Thibault <address@hidden> Mon, 20 Apr 2015 02:11:51 +0000
+
hurd (1:0.6-1) unstable; urgency=medium
* New upstream snapshot
diff --git a/debian/patches/git-R-libdiskfs-protected-payload.patch
b/debian/patches/git-R-libdiskfs-protected-payload.patch
new file mode 100644
index 0000000..8566b96
--- /dev/null
+++ b/debian/patches/git-R-libdiskfs-protected-payload.patch
@@ -0,0 +1,669 @@
+commit 4241dd5673566a61add85bd9eb52d4ae7db2750a
+Author: Justus Winter <address@hidden>
+Date: Sat Nov 23 16:12:55 2013 +0100
+
+ libports: use protected payloads to optimize the object lookup
+
+ * NEWS: Mention protected payloads.
+ * libports/Makefile (SRCS): Add `port-deref-deferred.c'.
+ * libports/create-internal.c (_ports_create_port_internal): Set the
+ protected payload to the objects address.
+ * libports/import-port.c (ports_import_port): Likewise.
+ * libports/reallocate-from-external.c (ports_reallocate_from_external):
+ Likewise.
+ * libports/reallocate-port.c (ports_reallocate_port): Likewise.
+ * libports/transfer-right.c (ports_transfer_right): Likewise.
+ * libports/manage-multithread.c (ports_manage_port_operations_multithread):
+ Use the protected payload for the object lookup if provided. Add
+ thread pool management calls.
+ * libports/manage-one-thread.c (ports_manage_port_operations_one_thread):
+ Likewise.
+ * libports/destroy-right.c (ports_destroy_right): Defer the
+ dereferencing of outstanding send rights to avoid a port_info
+ use-after-free.
+ * libports/port-deref-deferred.c: New file.
+ * libports/port-deref-deferred.h: Likewise.
+ * libports/ports.h (struct port_bucket): New field `threadpool'.
+ (ports_lookup_payload): Check `port_right'.
+
+diff --git b/NEWS a/NEWS
+index 18e1489..b047aed 100644
+--- b/NEWS
++++ a/NEWS
+@@ -6,8 +6,6 @@ problems have been identified using static analysis and
exercising
+ tools, and have subsequently been fixed.
+
+ The message dispatching code in the Hurd servers has been improved.
+-Among other things, we now make use of the protected payloads
+-introduced in GNU Mach 1.5.
+
+ The embedded gz and bz2 decompressor code has been removed, libz and
+ libbz2 is used instead.
+diff --git b/libports/Makefile a/libports/Makefile
+index b8b82ee..f49cb9f 100644
+--- b/libports/Makefile
++++ a/libports/Makefile
+@@ -36,7 +36,7 @@ SRCS = create-bucket.c create-class.c \
+ interrupt-operation.c interrupt-on-notify.c interrupt-notified-rpcs.c \
+ dead-name.c create-port.c import-port.c default-uninhibitable-rpcs.c \
+ claim-right.c transfer-right.c create-port-noinstall.c create-internal.c \
+- interrupted.c extern-inline.c port-deref-deferred.c
++ interrupted.c extern-inline.c
+
+ installhdrs = ports.h
+
+diff --git b/libports/complete-deallocate.c a/libports/complete-deallocate.c
+index e3123b2..0d852f5 100644
+--- b/libports/complete-deallocate.c
++++ a/libports/complete-deallocate.c
+@@ -27,7 +27,7 @@ _ports_complete_deallocate (struct port_info *pi)
+ {
+ assert ((pi->flags & PORT_HAS_SENDRIGHTS) == 0);
+
+- if (MACH_PORT_VALID (pi->port_right))
++ if (pi->port_right)
+ {
+ struct references result;
+
+@@ -37,9 +37,7 @@ _ports_complete_deallocate (struct port_info *pi)
+ {
+ /* A reference was reacquired through a hash table lookup.
+ It's fine, we didn't touch anything yet. */
+- /* XXX: This really shouldn't happen. */
+- assert (! "reacquired reference w/o send rights");
+- pthread_rwlock_unlock (&_ports_htable_lock);
++ pthread_mutex_unlock (&_ports_htable_lock);
+ return;
+ }
+
+diff --git b/libports/create-bucket.c a/libports/create-bucket.c
+index 82c00a4..2c5f1b6 100644
+--- b/libports/create-bucket.c
++++ a/libports/create-bucket.c
+@@ -48,6 +48,5 @@ ports_create_bucket ()
+
+ hurd_ihash_init (&ret->htable, offsetof (struct port_info, hentry));
+ ret->rpcs = ret->flags = ret->count = 0;
+- _ports_threadpool_init (&ret->threadpool);
+ return ret;
+ }
+diff --git b/libports/create-internal.c a/libports/create-internal.c
+index d79dc78..2d85931 100644
+--- b/libports/create-internal.c
++++ a/libports/create-internal.c
+@@ -99,11 +99,7 @@ _ports_create_port_internal (struct port_class *class,
+ bucket->count++;
+ class->count++;
+ pthread_mutex_unlock (&_ports_lock);
+-
+- /* This is an optimization. It may fail. */
+- mach_port_set_protected_payload (mach_task_self (), port,
+- (unsigned long) pi);
+-
++
+ if (install)
+ {
+ err = mach_port_move_member (mach_task_self (), pi->port_right,
+diff --git b/libports/destroy-right.c a/libports/destroy-right.c
+index 276255f..448b379 100644
+--- b/libports/destroy-right.c
++++ a/libports/destroy-right.c
+@@ -1,5 +1,5 @@
+ /*
+- Copyright (C) 1995, 1996, 1999, 2014 Free Software Foundation, Inc.
++ Copyright (C) 1995, 1996, 1999 Free Software Foundation, Inc.
+ Written by Michael I. Bushnell.
+
+ This file is part of the GNU Hurd.
+@@ -22,62 +22,30 @@
+ #include <hurd/ihash.h>
+ #include <assert.h>
+
+-#include <pthread.h>
+-#include <error.h>
+-#include <time.h>
+-#include <unistd.h>
+-
+ error_t
+ ports_destroy_right (void *portstruct)
+ {
+ struct port_info *pi = portstruct;
+- mach_port_t port_right;
+- int defer = 0;
+ error_t err;
+
+- pthread_mutex_lock (&_ports_lock);
+- port_right = pi->port_right;
+- pi->port_right = MACH_PORT_DEAD;
+-
+- if (pi->flags & PORT_HAS_SENDRIGHTS)
+- {
+- pi->flags &= ~PORT_HAS_SENDRIGHTS;
+-
+- /* There are outstanding send rights, so we might get more
+- messages. Attached to the messages is a reference to the
+- port_info object. Of course we destroyed the receive right
+- these were send to above, but the message could already have
+- been dequeued to userspace.
+-
+- Previously, those messages would have carried an stale name,
+- which would have caused a hash table lookup failure.
+- However, stale payloads results in port_info use-after-free.
+- Therefore, we cannot release the reference here, but defer
+- that instead until all currently running threads have gone
+- through a quiescent state. */
+- defer = 1;
+- }
+-
+- if (MACH_PORT_VALID (port_right))
++ if (pi->port_right != MACH_PORT_NULL)
+ {
+- mach_port_clear_protected_payload (mach_task_self (), port_right);
+-
+ pthread_rwlock_wrlock (&_ports_htable_lock);
+ hurd_ihash_locp_remove (&_ports_htable, pi->ports_htable_entry);
+ hurd_ihash_locp_remove (&pi->bucket->htable, pi->hentry);
+ pthread_rwlock_unlock (&_ports_htable_lock);
+- }
+- pthread_mutex_unlock (&_ports_lock);
+-
+- if (MACH_PORT_VALID (port_right))
+- {
+- err = mach_port_mod_refs (mach_task_self (), port_right,
+- MACH_PORT_RIGHT_RECEIVE, -1);
++ err = mach_port_mod_refs (mach_task_self (), pi->port_right,
++ MACH_PORT_RIGHT_RECEIVE, -1);
+ assert_perror (err);
+- }
+
+- if (defer)
+- _ports_port_deref_deferred (pi);
++ pi->port_right = MACH_PORT_NULL;
++
++ if (pi->flags & PORT_HAS_SENDRIGHTS)
++ {
++ pi->flags &= ~PORT_HAS_SENDRIGHTS;
++ ports_port_deref (pi);
++ }
++ }
+
+ return 0;
+ }
+diff --git b/libports/import-port.c a/libports/import-port.c
+index 2c638e1..c337c85 100644
+--- b/libports/import-port.c
++++ a/libports/import-port.c
+@@ -93,11 +93,7 @@ ports_import_port (struct port_class *class, struct
port_bucket *bucket,
+ bucket->count++;
+ class->count++;
+ pthread_mutex_unlock (&_ports_lock);
+-
+- /* This is an optimization. It may fail. */
+- mach_port_set_protected_payload (mach_task_self (), port,
+- (unsigned long) pi);
+-
++
+ mach_port_move_member (mach_task_self (), port, bucket->portset);
+
+ if (stat.mps_srights)
+diff --git b/libports/manage-multithread.c a/libports/manage-multithread.c
+index dcb6905..58814d2 100644
+--- b/libports/manage-multithread.c
++++ a/libports/manage-multithread.c
+@@ -167,21 +167,7 @@ ports_manage_port_operations_multithread (struct
port_bucket *bucket,
+ outp->RetCodeType = RetCodeType;
+ outp->RetCode = MIG_BAD_ID;
+
+- if (MACH_MSGH_BITS_LOCAL (inp->msgh_bits) ==
+- MACH_MSG_TYPE_PROTECTED_PAYLOAD)
+- pi = ports_lookup_payload (bucket, inp->msgh_protected_payload, NULL);
+- else
+- {
+- pi = ports_lookup_port (bucket, inp->msgh_local_port, 0);
+- if (pi)
+- {
+- inp->msgh_bits = MACH_MSGH_BITS (
+- MACH_MSGH_BITS_REMOTE (inp->msgh_bits),
+- MACH_MSG_TYPE_PROTECTED_PAYLOAD);
+- inp->msgh_protected_payload = (unsigned long) pi;
+- }
+- }
+-
++ pi = ports_lookup_port (bucket, inp->msgh_local_port, 0);
+ if (pi)
+ {
+ error_t err = ports_begin_rpc (pi, inp->msgh_id, &link);
+@@ -217,19 +203,10 @@ ports_manage_port_operations_multithread (struct
port_bucket *bucket,
+ void *
+ thread_function (void *arg)
+ {
+- struct ports_thread thread;
+ int master = (int) arg;
+ int timeout;
+ error_t err;
+
+- int synchronized_demuxer (mach_msg_header_t *inp,
+- mach_msg_header_t *outheadp)
+- {
+- int r = internal_demuxer (inp, outheadp);
+- _ports_thread_quiescent (&bucket->threadpool, &thread);
+- return r;
+- }
+-
+ adjust_priority (__atomic_load_n (&totalthreads, __ATOMIC_RELAXED));
+
+ if (hook)
+@@ -240,13 +217,10 @@ ports_manage_port_operations_multithread (struct
port_bucket *bucket,
+ else
+ timeout = thread_timeout;
+
+- _ports_thread_online (&bucket->threadpool, &thread);
+-
+ startover:
+
+ do
+- err = mach_msg_server_timeout (synchronized_demuxer,
+- 0, bucket->portset,
++ err = mach_msg_server_timeout (internal_demuxer, 0, bucket->portset,
+ timeout ? MACH_RCV_TIMEOUT : 0,
+ timeout);
+ while (err != MACH_RCV_TIMED_OUT);
+@@ -266,7 +240,6 @@ ports_manage_port_operations_multithread (struct
port_bucket *bucket,
+ }
+ __atomic_sub_fetch (&totalthreads, 1, __ATOMIC_RELAXED);
+ }
+- _ports_thread_offline (&bucket->threadpool, &thread);
+ return NULL;
+ }
+
+diff --git b/libports/manage-one-thread.c a/libports/manage-one-thread.c
+index 192907a..cbd2df7 100644
+--- b/libports/manage-one-thread.c
++++ a/libports/manage-one-thread.c
+@@ -25,7 +25,6 @@ ports_manage_port_operations_one_thread (struct port_bucket
*bucket,
+ ports_demuxer_type demuxer,
+ int timeout)
+ {
+- struct ports_thread thread;
+ error_t err;
+
+ int
+@@ -58,21 +57,7 @@ ports_manage_port_operations_one_thread (struct port_bucket
*bucket,
+ outp->RetCodeType = RetCodeType;
+ outp->RetCode = MIG_BAD_ID;
+
+- if (MACH_MSGH_BITS_LOCAL (inp->msgh_bits) ==
+- MACH_MSG_TYPE_PROTECTED_PAYLOAD)
+- pi = ports_lookup_payload (bucket, inp->msgh_protected_payload, NULL);
+- else
+- {
+- pi = ports_lookup_port (bucket, inp->msgh_local_port, 0);
+- if (pi)
+- {
+- inp->msgh_bits = MACH_MSGH_BITS (
+- MACH_MSGH_BITS_REMOTE (inp->msgh_bits),
+- MACH_MSG_TYPE_PROTECTED_PAYLOAD);
+- inp->msgh_protected_payload = (unsigned long) pi;
+- }
+- }
+-
++ pi = ports_lookup_port (bucket, inp->msgh_local_port, 0);
+ if (pi)
+ {
+ err = ports_begin_rpc (pi, inp->msgh_id, &link);
+@@ -98,7 +83,6 @@ ports_manage_port_operations_one_thread (struct port_bucket
*bucket,
+ status = 1;
+ }
+
+- _ports_thread_quiescent (&bucket->threadpool, &thread);
+ return status;
+ }
+
+@@ -109,10 +93,8 @@ ports_manage_port_operations_one_thread (struct
port_bucket *bucket,
+ zero. */
+ timeout = 0;
+
+- _ports_thread_online (&bucket->threadpool, &thread);
+ do
+ err = mach_msg_server_timeout (internal_demuxer, 0, bucket->portset,
+ timeout ? MACH_RCV_TIMEOUT : 0, timeout);
+ while (err != MACH_RCV_TIMED_OUT);
+- _ports_thread_offline (&bucket->threadpool, &thread);
+ }
+diff --git b/libports/port-deref-deferred.c a/libports/port-deref-deferred.c
+deleted file mode 100644
+index 2580e91..0000000
+--- b/libports/port-deref-deferred.c
++++ /dev/null
+@@ -1,161 +0,0 @@
+-/* Delayed deallocation of port_info objects.
+-
+- Copyright (C) 2015 Free Software Foundation, Inc.
+-
+- Written by Justus Winter <address@hidden>
+-
+- This file is part of the GNU Hurd.
+-
+- The GNU Hurd is free software; you can redistribute it and/or
+- modify it under the terms of the GNU General Public License as
+- published by the Free Software Foundation; either version 2, or (at
+- your option) any later version.
+-
+- The GNU Hurd is distributed in the hope that it will be useful, but
+- WITHOUT ANY WARRANTY; without even the implied warranty of
+- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+- General Public License for more details.
+-
+- You should have received a copy of the GNU General Public License
+- along with the GNU Hurd. If not, see <http://www.gnu.org/licenses/>. */
+-
+-#include <assert.h>
+-#include <pthread.h>
+-#include "ports.h"
+-
+-/*
+- * A threadpool has a color indicating which threads belong to the old
+- * generation.
+- */
+-#define COLOR_BLACK 0
+-#define COLOR_WHITE 1
+-#define COLOR_INVALID ~0U
+-
+-static inline int
+-valid_color (unsigned int c)
+-{
+- return c == COLOR_BLACK || c == COLOR_WHITE;
+-}
+-
+-static inline unsigned int
+-flip_color (unsigned int c)
+-{
+- assert (valid_color (c));
+- return ! c;
+-}
+-
+-/* Initialize the thread pool. */
+-void
+-_ports_threadpool_init (struct ports_threadpool *pool)
+-{
+- pthread_spin_init (&pool->lock, PTHREAD_PROCESS_PRIVATE);
+- pool->color = COLOR_BLACK;
+- pool->old_threads = 0;
+- pool->old_objects = NULL;
+- pool->young_threads = 0;
+- pool->young_objects = NULL;
+-}
+-
+-/* Turn all young objects and threads into old ones. */
+-static inline void
+-flip_generations (struct ports_threadpool *pool)
+-{
+- assert (pool->old_threads == 0);
+- pool->old_threads = pool->young_threads;
+- pool->old_objects = pool->young_objects;
+- pool->young_threads = 0;
+- pool->young_objects = NULL;
+- pool->color = flip_color (pool->color);
+-}
+-
+-/* Called by a thread to join a thread pool. */
+-void
+-_ports_thread_online (struct ports_threadpool *pool,
+- struct ports_thread *thread)
+-{
+- pthread_spin_lock (&pool->lock);
+- thread->color = flip_color (pool->color);
+- pool->young_threads += 1;
+- pthread_spin_unlock (&pool->lock);
+-}
+-
+-struct pi_list
+-{
+- struct pi_list *next;
+- struct port_info *pi;
+-};
+-
+-/* Called by a thread that enters its quiescent period. */
+-void
+-_ports_thread_quiescent (struct ports_threadpool *pool,
+- struct ports_thread *thread)
+-{
+- struct pi_list *free_list = NULL, *p;
+- assert (valid_color (thread->color));
+-
+- pthread_spin_lock (&pool->lock);
+- if (thread->color == pool->color)
+- {
+- pool->old_threads -= 1;
+- pool->young_threads += 1;
+- thread->color = flip_color (thread->color);
+-
+- if (pool->old_threads == 0)
+- {
+- free_list = pool->old_objects;
+- flip_generations (pool);
+- }
+- }
+- pthread_spin_unlock (&pool->lock);
+-
+- for (p = free_list; p;)
+- {
+- struct pi_list *old = p;
+- p = p->next;
+-
+- ports_port_deref (old->pi);
+- free (old);
+- }
+-}
+-
+-/* Called by a thread to leave a thread pool. */
+-void
+-_ports_thread_offline (struct ports_threadpool *pool,
+- struct ports_thread *thread)
+-{
+- assert (valid_color (thread->color));
+-
+- retry:
+- pthread_spin_lock (&pool->lock);
+- if (thread->color == pool->color)
+- {
+- pthread_spin_unlock (&pool->lock);
+- _ports_thread_quiescent (pool, thread);
+- goto retry;
+- }
+- thread->color = COLOR_INVALID;
+- pool->young_threads -= 1;
+- pthread_spin_unlock (&pool->lock);
+-}
+-
+-/* Schedule an object for deallocation. */
+-void
+-_ports_port_deref_deferred (struct port_info *pi)
+-{
+- struct ports_threadpool *pool = &pi->bucket->threadpool;
+-
+- struct pi_list *pl = malloc (sizeof *pl);
+- if (pl == NULL)
+- return;
+- pl->pi = pi;
+-
+- pthread_spin_lock (&pool->lock);
+- pl->next = pool->young_objects;
+- pool->young_objects = pl;
+- if (pool->old_threads == 0)
+- {
+- assert (pool->old_objects == NULL);
+- flip_generations (pool);
+- }
+- pthread_spin_unlock (&pool->lock);
+-}
+diff --git b/libports/port-deref-deferred.h a/libports/port-deref-deferred.h
+deleted file mode 100644
+index 1589cb2..0000000
+--- b/libports/port-deref-deferred.h
++++ /dev/null
+@@ -1,89 +0,0 @@
+-/* Delayed deallocation of port_info objects.
+-
+- Copyright (C) 2015 Free Software Foundation, Inc.
+-
+- Written by Justus Winter <address@hidden>
+-
+- This file is part of the GNU Hurd.
+-
+- The GNU Hurd is free software; you can redistribute it and/or
+- modify it under the terms of the GNU General Public License as
+- published by the Free Software Foundation; either version 2, or (at
+- your option) any later version.
+-
+- The GNU Hurd is distributed in the hope that it will be useful, but
+- WITHOUT ANY WARRANTY; without even the implied warranty of
+- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+- General Public License for more details.
+-
+- You should have received a copy of the GNU General Public License
+- along with the GNU Hurd. If not, see <http://www.gnu.org/licenses/>. */
+-
+-#ifndef _HURD_PORTS_DEREF_DEFERRED_
+-#define _HURD_PORTS_DEREF_DEFERRED_
+-
+-#include <pthread.h>
+-
+-/* A list of port_info objects. */
+-struct pi_list;
+-
+-/* We use protected payloads to look up objects without taking a lock.
+- A complication arises if we destroy an object using
+- ports_destroy_right. To avoid payloads from becoming stale (and
+- resulting in invalid memory accesses when being interpreted as
+- pointer), we delay the deallocation of those object until all
+- threads running at the time of the objects destruction are done
+- with whatever they were doing and entered a quiescent period. */
+-struct ports_threadpool
+-{
+- /* Access to the threadpool object is serialized by this lock. */
+- pthread_spinlock_t lock;
+-
+- /* We maintain two sets of objects and threads. Each thread and the
+- threadpool itself has a color. If a thread has the same color as
+- the thread pool, it belongs to the old generation. */
+- unsigned int color;
+-
+- /* The number of old threads. When an old thread enters its
+- quiescent period, it decrements OLD_THREADS and flips its color
+- (hence becoming a young thread). */
+- size_t old_threads;
+-
+- /* A list of old objects. Once OLD_THREADS drops to zero, they are
+- deallocated, and all young threads and objects become old threads
+- and objects. */
+- struct pi_list *old_objects;
+-
+- /* The number of young threads. Any thread joining or leaving the
+- thread group must be a young thread. */
+- size_t young_threads;
+-
+- /* The list of young objects. Any object being marked for delayed
+- deallocation is added to this list. */
+- struct pi_list *young_objects;
+-};
+-
+-/* Per-thread state. */
+-struct ports_thread
+-{
+- unsigned int color;
+-};
+-
+-/* Initialize the thread pool. */
+-void _ports_threadpool_init (struct ports_threadpool *);
+-
+-/* Called by a thread to join a thread pool. */
+-void _ports_thread_online (struct ports_threadpool *, struct ports_thread *);
+-
+-/* Called by a thread that enters its quiescent period. */
+-void _ports_thread_quiescent (struct ports_threadpool *, struct ports_thread
*);
+-
+-/* Called by a thread to leave a thread pool. */
+-void _ports_thread_offline (struct ports_threadpool *, struct ports_thread *);
+-
+-struct port_info;
+-
+-/* Schedule an object for deallocation. */
+-void _ports_port_deref_deferred (struct port_info *);
+-
+-#endif /* _HURD_PORTS_DEREF_DEFERRED_ */
+diff --git b/libports/ports.h a/libports/ports.h
+index 9299bc4..f02edb4 100644
+--- b/libports/ports.h
++++ a/libports/ports.h
+@@ -29,8 +29,6 @@
+ #include <pthread.h>
+ #include <refcount.h>
+
+-#include "port-deref-deferred.h"
+-
+ #ifdef PORTS_DEFINE_EI
+ #define PORTS_EI
+ #else
+@@ -75,7 +73,6 @@ struct port_bucket
+ int rpcs;
+ int flags;
+ int count;
+- struct ports_threadpool threadpool;
+ };
+ /* FLAGS above are the following: */
+ #define PORT_BUCKET_INHIBITED PORTS_INHIBITED
+@@ -265,9 +262,6 @@ ports_lookup_payload (struct port_bucket *bucket,
+ {
+ struct port_info *pi = (struct port_info *) payload;
+
+- if (pi && ! MACH_PORT_VALID (pi->port_right))
+- pi = NULL;
+-
+ if (pi && bucket && pi->bucket != bucket)
+ pi = NULL;
+
+diff --git b/libports/reallocate-from-external.c
a/libports/reallocate-from-external.c
+index d0fae1a..7205bd9 100644
+--- b/libports/reallocate-from-external.c
++++ a/libports/reallocate-from-external.c
+@@ -71,10 +71,6 @@ ports_reallocate_from_external (void *portstruct,
mach_port_t receive)
+ pthread_mutex_unlock (&_ports_lock);
+ assert_perror (err);
+
+- /* This is an optimization. It may fail. */
+- mach_port_set_protected_payload (mach_task_self (), pi->port_right,
+- (unsigned long) pi);
+-
+ mach_port_move_member (mach_task_self (), receive, pi->bucket->portset);
+
+ if (stat.mps_srights)
+diff --git b/libports/reallocate-port.c a/libports/reallocate-port.c
+index 4e859a1..cc534eb 100644
+--- b/libports/reallocate-port.c
++++ a/libports/reallocate-port.c
+@@ -59,10 +59,6 @@ ports_reallocate_port (void *portstruct)
+ pthread_mutex_unlock (&_ports_lock);
+ assert_perror (err);
+
+- /* This is an optimization. It may fail. */
+- mach_port_set_protected_payload (mach_task_self (), pi->port_right,
+- (unsigned long) pi);
+-
+ err = mach_port_move_member (mach_task_self (), pi->port_right,
+ pi->bucket->portset);
+ assert_perror (err);
+diff --git b/libports/transfer-right.c a/libports/transfer-right.c
+index 64de7f7..776a8d2 100644
+--- b/libports/transfer-right.c
++++ a/libports/transfer-right.c
+@@ -91,9 +91,6 @@ ports_transfer_right (void *tostruct,
+ err = hurd_ihash_add (&topi->bucket->htable, port, topi);
+ pthread_rwlock_unlock (&_ports_htable_lock);
+ assert_perror (err);
+- /* This is an optimization. It may fail. */
+- mach_port_set_protected_payload (mach_task_self (), port,
+- (unsigned long) topi);
+ if (topi->bucket != frompi->bucket)
+ {
+ err = mach_port_move_member (mach_task_self (), port,
diff --git a/debian/patches/series b/debian/patches/series
index 83b29e3..7327fb8 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -40,3 +40,4 @@ MAKEDEV-apm.patch
term-for-tcl.patch
disable_new_task_notification.diff
newRPC.patch
+git-R-libdiskfs-protected-payload.patch
--
Alioth's /usr/local/bin/git-commit-notice on
/srv/git.debian.org/git/pkg-hurd/hurd.git