Mon Mar 16 01:20:37 2009 UTC ()
Pull up following revision(s) (requested by adrianp in ticket #582):
	sys/compat/linux/common/linux_futex.c: revision 1.24 via patch
fix robust_list pointer mess!


(snj)
diff -r1.18.4.1 -r1.18.4.2 src/sys/compat/linux/common/linux_futex.c

cvs diff -r1.18.4.1 -r1.18.4.2 src/sys/compat/linux/common/Attic/linux_futex.c (expand / switch to unified diff)

--- src/sys/compat/linux/common/Attic/linux_futex.c 2009/02/26 20:40:52 1.18.4.1
+++ src/sys/compat/linux/common/Attic/linux_futex.c 2009/03/16 01:20:37 1.18.4.2
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: linux_futex.c,v 1.18.4.1 2009/02/26 20:40:52 snj Exp $ */ 1/* $NetBSD: linux_futex.c,v 1.18.4.2 2009/03/16 01:20:37 snj Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2005 Emmanuel Dreyfus, all rights reserved. 4 * Copyright (c) 2005 Emmanuel Dreyfus, all rights reserved.
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions 7 * modification, are permitted provided that the following conditions
8 * are met: 8 * are met:
9 * 1. Redistributions of source code must retain the above copyright 9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer. 10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright 11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the 12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution. 13 * documentation and/or other materials provided with the distribution.
14 * 3. All advertising materials mentioning features or use of this software 14 * 3. All advertising materials mentioning features or use of this software
@@ -22,27 +22,27 @@ @@ -22,27 +22,27 @@
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,  22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
23 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS  24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS
25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE. 31 * POSSIBILITY OF SUCH DAMAGE.
32 */ 32 */
33 33
34#include <sys/cdefs.h> 34#include <sys/cdefs.h>
35__KERNEL_RCSID(1, "$NetBSD: linux_futex.c,v 1.18.4.1 2009/02/26 20:40:52 snj Exp $"); 35__KERNEL_RCSID(1, "$NetBSD: linux_futex.c,v 1.18.4.2 2009/03/16 01:20:37 snj Exp $");
36 36
37#include <sys/param.h> 37#include <sys/param.h>
38#include <sys/time.h> 38#include <sys/time.h>
39#include <sys/systm.h> 39#include <sys/systm.h>
40#include <sys/proc.h> 40#include <sys/proc.h>
41#include <sys/lwp.h> 41#include <sys/lwp.h>
42#include <sys/queue.h> 42#include <sys/queue.h>
43#include <sys/condvar.h> 43#include <sys/condvar.h>
44#include <sys/mutex.h> 44#include <sys/mutex.h>
45#include <sys/once.h> 45#include <sys/once.h>
46#include <sys/kmem.h> 46#include <sys/kmem.h>
47#include <sys/kernel.h> 47#include <sys/kernel.h>
48#include <sys/atomic.h> 48#include <sys/atomic.h>
@@ -488,62 +488,63 @@ futex_atomic_op(lwp_t *l, int encoded_op @@ -488,62 +488,63 @@ futex_atomic_op(lwp_t *l, int encoded_op
488 return (oldval > cmparg); 488 return (oldval > cmparg);
489 default: 489 default:
490 return -ENOSYS; 490 return -ENOSYS;
491 } 491 }
492} 492}
493 493
494int 494int
495linux_sys_set_robust_list(struct lwp *l, 495linux_sys_set_robust_list(struct lwp *l,
496 const struct linux_sys_set_robust_list_args *uap, register_t *retval) 496 const struct linux_sys_set_robust_list_args *uap, register_t *retval)
497{ 497{
498 struct proc *p = l->l_proc; 498 struct proc *p = l->l_proc;
499 struct linux_emuldata *led = p->p_emuldata; 499 struct linux_emuldata *led = p->p_emuldata;
500 500
 501 if (SCARG(uap, len) != sizeof(*(led->robust_futexes)))
 502 return EINVAL;
501 led->robust_futexes = SCARG(uap, head); 503 led->robust_futexes = SCARG(uap, head);
502 *retval = 0; 504 *retval = 0;
503 return 0; 505 return 0;
504} 506}
505 507
506int 508int
507linux_sys_get_robust_list(struct lwp *l, 509linux_sys_get_robust_list(struct lwp *l,
508 const struct linux_sys_get_robust_list_args *uap, register_t *retval) 510 const struct linux_sys_get_robust_list_args *uap, register_t *retval)
509{ 511{
510 struct linux_emuldata *led; 512 struct linux_emuldata *led;
511 struct linux_robust_list_head *head; 513 struct linux_robust_list_head **head;
512 size_t len = sizeof(struct linux_robust_list_head); 514 size_t len = sizeof(*led->robust_futexes);
513 int error = 0; 515 int error = 0;
514 516
515 if (!SCARG(uap, pid)) { 517 if (!SCARG(uap, pid)) {
516 led = l->l_proc->p_emuldata; 518 led = l->l_proc->p_emuldata;
517 head = led->robust_futexes; 519 head = &led->robust_futexes;
518 } else { 520 } else {
519 struct proc *p; 521 struct proc *p;
520 522
521 mutex_enter(proc_lock);  523 mutex_enter(proc_lock);
522 if ((p = p_find(SCARG(uap, pid), PFIND_LOCKED)) == NULL || 524 if ((p = p_find(SCARG(uap, pid), PFIND_LOCKED)) == NULL ||
523 p->p_emul != &emul_linux) { 525 p->p_emul != &emul_linux) {
524 mutex_exit(proc_lock); 526 mutex_exit(proc_lock);
525 return ESRCH; 527 return ESRCH;
526 } 528 }
527 led = p->p_emuldata; 529 led = p->p_emuldata;
528 head = led->robust_futexes; 530 head = &led->robust_futexes;
529 mutex_exit(proc_lock); 531 mutex_exit(proc_lock);
530 } 532 }
531 533
532 error = copyout(&len, SCARG(uap, len), sizeof(size_t)); 534 error = copyout(&len, SCARG(uap, len), sizeof(len));
533 if (error) 535 if (error)
534 return error; 536 return error;
535 return copyout(head, SCARG(uap, head), 537 return copyout(head, SCARG(uap, head), sizeof(*head));
536 sizeof(struct linux_robust_list_head)); 
537} 538}
538 539
539static int 540static int
540handle_futex_death(void *uaddr, pid_t pid, int pi) 541handle_futex_death(void *uaddr, pid_t pid, int pi)
541{ 542{
542 int uval, nval, mval; 543 int uval, nval, mval;
543 struct futex *f; 544 struct futex *f;
544 545
545retry: 546retry:
546 if (copyin(uaddr, &uval, 4)) 547 if (copyin(uaddr, &uval, 4))
547 return EFAULT; 548 return EFAULT;
548 549
549 if ((uval & FUTEX_TID_MASK) == pid) { 550 if ((uval & FUTEX_TID_MASK) == pid) {
@@ -574,49 +575,50 @@ fetch_robust_entry(struct linux_robust_l @@ -574,49 +575,50 @@ fetch_robust_entry(struct linux_robust_l
574 if (copyin((const void *)head, &uentry, sizeof(unsigned long))) 575 if (copyin((const void *)head, &uentry, sizeof(unsigned long)))
575 return EFAULT; 576 return EFAULT;
576 577
577 *entry = (void *)(uentry & ~1UL); 578 *entry = (void *)(uentry & ~1UL);
578 *pi = uentry & 1; 579 *pi = uentry & 1;
579 580
580 return 0; 581 return 0;
581} 582}
582 583
583/* This walks the list of robust futexes, releasing them. */ 584/* This walks the list of robust futexes, releasing them. */
584void 585void
585release_futexes(struct proc *p) 586release_futexes(struct proc *p)
586{ 587{
587 struct linux_robust_list_head *head = NULL; 588 struct linux_robust_list_head head;
588 struct linux_robust_list *entry, *next_entry, *pending; 589 struct linux_robust_list *entry, *next_entry, *pending;
589 unsigned int limit = 2048, pi, next_pi, pip; 590 unsigned int limit = 2048, pi, next_pi, pip;
590 struct linux_emuldata *led; 591 struct linux_emuldata *led;
591 unsigned long futex_offset; 592 unsigned long futex_offset;
592 int rc; 593 int rc;
593 594
594 led = p->p_emuldata; 595 led = p->p_emuldata;
595 head = led->robust_futexes; 596 if (led->robust_futexes == NULL)
 597 return;
596 598
597 if (head == NULL) 599 if (copyin(led->robust_futexes, &head, sizeof(head)))
598 return; 600 return;
599 601
600 if (fetch_robust_entry(&entry, &head->list.next, &pi)) 602 if (fetch_robust_entry(&entry, &head.list.next, &pi))
601 return; 603 return;
602 604
603 if (copyin(&head->futex_offset, &futex_offset, sizeof(unsigned long))) 605 if (copyin(&head.futex_offset, &futex_offset, sizeof(unsigned long)))
604 return; 606 return;
605 607
606 if (fetch_robust_entry(&pending, &head->pending_list, &pip)) 608 if (fetch_robust_entry(&pending, &head.pending_list, &pip))
607 return; 609 return;
608 610
609 while (entry != &head->list) { 611 while (entry != &head.list) {
610 rc = fetch_robust_entry(&next_entry, &entry->next, &next_pi); 612 rc = fetch_robust_entry(&next_entry, &entry->next, &next_pi);
611 613
612 if (entry != pending) 614 if (entry != pending)
613 if (handle_futex_death((char *)entry + futex_offset, 615 if (handle_futex_death((char *)entry + futex_offset,
614 p->p_pid, pi)) 616 p->p_pid, pi))
615 return; 617 return;
616 618
617 if (rc) 619 if (rc)
618 return; 620 return;
619 621
620 entry = next_entry; 622 entry = next_entry;
621 pi = next_pi; 623 pi = next_pi;
622 624