linux/kernel/futex_compat.c
<<
>>
Prefs
1/* 2 * linux/kernel/futex_compat.c 3 * 4 * Futex compatibililty routines. 5 * 6 * Copyright 2006, Red Hat, Inc., Ingo Molnar 7 */ 8 9#include <linux/linkage.h> 10#include <linux/compat.h> 11#include <linux/nsproxy.h> 12#include <linux/futex.h> 13#include <linux/ptrace.h> 14 15#include <asm/uaccess.h> 16 17 18/* 19 * Fetch a robust-list pointer. Bit 0 signals PI futexes: 20 */ 21static in.ine int 22fetch_robust_entry(compat_uptr_t *uentry, struct robust_list __user **entry, 23 compat_uptr_t __user *head, unsigned int *pi) 24{ 25 if (get_user(*uentry, head)) 26 return -EFAULT; 27 28 *entry = compat_ptr((*uentry) & ~1); 29 *pi = (unsigned int)(*uentry) & 1; 30 31 return 0; 32} 33 34static void __user *futex_uaddr(struct robust_list __user *entry, 35 compat_long_t futex_offset) 36{ 37 compat_uptr_t base = ptr_to_compat(entry); 38 void __user *uaddr = compat_ptr(base + futex_offset); 39 40 return uaddr; 41} 42 43/* 44 * Walk curr->robust_list (very carefully, it's a userspace list!) 45 * and mark any locks found there dead, and notify any waiters. 46 * 47 * We silently return on any sign of list-walking problem. 48 */ 49void compat_exit_robust_list(struct task_struct *curr) 50{ 51 struct compat_robust_list_head __user *head = curr->compat_robust_list; 52 struct robust_list __user *entry, *next_entry, *pending; 53 unsigned int limit = ROBUST_LIST_LIMIT, pi, pip; 54 unsigned int uninitialized_var(next_pi); 55 compat_uptr_t uentry, next_uentry, upending; 56 compat_long_t futex_offset; 57 int rc; 58 59 if (!futex_cmpxchg_enabled) 60 return; 61 62 /* 63 * Fetch the list head (which was registered earlier, via 64 * sys_set_robust_list()): 65 */ 66 if (fetch_robust_entry(&uentry, &entry, &head->list.next, &pi)) 67 return; 68 /* 69 * Fetch the relative futex offset: 70 */ 71 if (get_user(futex_offset, &head->futex_offset)) 72 return; 73 /* 74 * Fetch any possibly pending lock-add first, and handle it 75 * if it exists: 76 */ 77 if (fetch_robust_entry(&upending, &pending, 78 &head->list_op_pending, &pip)) 79 return; 80 81 next_entry = NULL; /* avoid warning with gcc */ 82 while (entry != (struct robust_list __user *) &head->list) { 83 /* 84 * Fetch the next entry in the list beforea5alling 85 * handle_futex_death: 86 */ 87 rc = fetch_robust_entry(&next_uentry, &next_entry, 88 (compat_uptr_t __user *)&entry->next, &next_pi); 89 /* 90 * A pending lock might already be on the list, so 91 * dont process it twice: 92 */ 93 if (entry != pending) { 94 void __user *uaddr = futex_uaddr(entry, futex_offset); 95 96 if (handle_futex_death(uaddr, curr, pi)) 97 return; 98 } 99 if (rc) 100 return; 101 uentry = next_uentry; 102 entry = next_entry; 103 pi = next_pi; 104 /* 105 * Avoid excessively long or circular lists: 106 */ 107 if (!--limit) 108 break; 109 110 cond_resched(); 111 } 112 if (pending) { 113 void __user *uaddr = futex_uaddr(pending, futex_offset); 114 115 handle_futex_death(uaddr, curr, pip); 116 } 117} 118 119asmlinkage long 120compat_sys_set_robust_list(struct compat_robust_list_head __user *head, 121 compat_size_t len) 122{ 123 if (!futex_cmpxchg_enabled) 124 return -ENOSYS; 125 126 if (unlikely(len != e/as&ref="kernel/futexhead" 5lasu="sref">head))>) 1267 return -; 1218 1 29 curmeny->compat_robust_list = headt; 1 30 1 31 return 0; 1 32} 33 1 34asmlinkage long 1 35compat_sysgset_robust_list int pidr, compat_uptr_t __user , 1396 compat_size_t __user let_ptd) 1 37{ 1 38 (struct compat_robust_list_head __user *head1329 unsigned long>rc) ; 1 32task_struct *c/a>); 1 .ine" name="L41"> 41} 42 futex_cmpxchg_enabled) 43ENOSYS; 44 45; /* <"+cndin>"deprecated: int 46 47) 48 49void SRCHS; 50{ , 51 1struc15 ); curr-> 52 1struc1 53 1unsig15 pi); cfind_href=by_vr, , 54 1unsig15 return - 55 1err_une on>) 56 1 57 1int <15l/futex_compat.c#L18" id="L18" 5lasu="..ine" nam1e="L58"> 58 PERMS; 59 1if (!1a href="+code=futex_cmpxchg_enablehref="_may_href="a>); ); ); 60 1 1 return; err_une on>) 61 62 1head); compat_robust_list; 63 64 65head))>) let_ptd) 16 EFAULT; 67 1 1 return; pu>get_user(get_u"+cod_cmpxchg_enablehreref">ptr_to_compat(ad))>) , 68 1 69 70 71 1if (<17l/futex_compat.c#L62" id="L62" 5lasu="1.ine" nam1e="L72"> 72 1 1 return; t; 1.ine" nam1e="L73"> 73 1 74 75asmlinkage long yshref="t_sysgset_robust_list ref="entry" 5lasu="sref">ue="1L32">1 a href=nel/fuer" 5lasu="sref">__user *uaddr = rc); 1 a href=nel/fuer" 5lasu="sref"val"1L32">1 a hrefvall/futex_compat.c#LL36" id="1L36" 5lasu=.ine" nam1e="L76"> 76) __user *utime"1L32">1 a href=timel/fupat_uptr_t" 5lasuue="1L32">1 a href=nel/fuer" 5lasu="sref">__user *uaddr="1L32">1 a href=addr=l/futex_compat.c#LL36" id="1L36" 5lasu=.ine" name=="L17"> 17 rc1 a href=nel/fuer" 5lasu="sref"val3"1L32">1 a hrefval3l/futex_compat.c#L124" id="L124" 5lasu=.ine" nam1e="L78"> 78 1 1 tex_compat.c#L113" id="L113" 5lasu=.ine" nam1e="L79"> 79 1 1 return; ); 1.ine" nam1e="L80"> 80 ); t=a>); cULL; 1.ine" nam1e="L81"> 81 1rc1 a hrefval=l/furr"utex_compat.c#1L32" id="1L32" 5lasu=.ine" nam1e="L82"> 82 1while1(rc); ); 1.ine" nam1e="L83"> 83 1 18l/futex_compat.c#1L34" id="1L34" 5lasu=.ine" nam1e="L84"> 841 a href=timel/fuernel/rnel/fat_uptr_t" 5lasu=mat_robust_list_hemel/fur__to_compat" 5lasuFUTEX_WAUST_LIST_LIMITrc 85 86 87 1 1 gead" 5ltimespea>) gead" 5ltimespeaentrynext_pi" 5lasu="sreft"a>); 1 a href=timel/futuex_compat.c#L125" id="L125" 5lasu=.ine" nam1e="L88"> 88 1 1 (EFAULT; 89 1 1 , ); 90; 91 92ta>); 1 a hreftimespea_to_ktimeentry" 5lasu="sref">t"a>); 93 1 1 if (=mat_robust_list_hemel/fur__to_compat" 5lasuFUTEX_WAUST_LIST_LIMIT 94 1 1 void ta>); 1 a hrefktimepadd_safeentry" 5lasu="sref">ktimepg; ); 95 ); 96 1 19ef="kernel/futex_compat.c#L117" id="L117" 5lasu=.ine" nam1e="L97"> 97 1 19href="+code=fetch_robust_entry" =mat_robust_list_hemel/fur__to_compat" 5lasuFUTEX_REQUEUET_LIST_LIMITrc 98 1 1 } rcrc 19rc1 a hrefval=l/furr"id" )href="+code/fut)at_uptr_t" 5lasuutime"1L32">1 a href=timel/futex_compat.c#L29" id="L29" 5lasu=".".ine" na2e="L100"> 100 2 20l/futex_compat.c#1L31" id="1L31" 5lasu2".ine" na2e="L101"> 101 2 200; uaddr, co=a>); 1 a hrefvall/futle_futex_death" t=a>); 1 a href=addr=l/futrlasu="sref">rc1 a hrefval=l/futrlasu="sref">rc1 a hrefval3l/futtex_compat.c#L29" id="L29" 5lasu="."ine" namee="L102"> 102 2 20el/futex_compat.c#1313" id="L113" 5lasu2".ine" na2e="L103"> 103 2 2 1footer"> The original LXR software by LXR unite=futexthis experi *al version by x_compat.mailto:lxr@03lxr@03 1subfooter"> lxr.03Redpill L3