~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/kernel/exec_domain.c

Version: ~ [ 2.4.0 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 #include <linux/mm.h>
  2 #include <linux/smp_lock.h>
  3 #include <linux/module.h>
  4 
  5 static asmlinkage void no_lcall7(int segment, struct pt_regs * regs);
  6 
  7 
  8 static unsigned long ident_map[32] = {
  9         0,      1,      2,      3,      4,      5,      6,      7,
 10         8,      9,      10,     11,     12,     13,     14,     15,
 11         16,     17,     18,     19,     20,     21,     22,     23,
 12         24,     25,     26,     27,     28,     29,     30,     31
 13 };
 14 
 15 struct exec_domain default_exec_domain = {
 16         "Linux",        /* name */
 17         no_lcall7,      /* lcall7 causes a seg fault. */
 18         0, 0xff,        /* All personalities. */
 19         ident_map,      /* Identity map signals. */
 20         ident_map,      /*  - both ways. */
 21         NULL,           /* No usage counter. */
 22         NULL            /* Nothing after this in the list. */
 23 };
 24 
 25 static struct exec_domain *exec_domains = &default_exec_domain;
 26 static rwlock_t exec_domains_lock = RW_LOCK_UNLOCKED;
 27 
 28 static asmlinkage void no_lcall7(int segment, struct pt_regs * regs)
 29 {
 30   /*
 31    * This may have been a static linked SVr4 binary, so we would have the
 32    * personality set incorrectly.  Check to see whether SVr4 is available,
 33    * and use it, otherwise give the user a SEGV.
 34    */
 35         set_personality(PER_SVR4);
 36 
 37         if (current->exec_domain && current->exec_domain->handler
 38         && current->exec_domain->handler != no_lcall7) {
 39                 current->exec_domain->handler(segment, regs);
 40                 return;
 41         }
 42 
 43         send_sig(SIGSEGV, current, 1);
 44 }
 45 
 46 static struct exec_domain *lookup_exec_domain(unsigned long personality)
 47 {
 48         unsigned long pers = personality & PER_MASK;
 49         struct exec_domain *it;
 50 
 51         read_lock(&exec_domains_lock);
 52         for (it=exec_domains; it; it=it->next)
 53                 if (pers >= it->pers_low && pers <= it->pers_high) {
 54                         if (!try_inc_mod_count(it->module))
 55                                 continue;
 56                         read_unlock(&exec_domains_lock);
 57                         return it;
 58                 }
 59         read_unlock(&exec_domains_lock);
 60 
 61         /* Should never get this far. */
 62         printk(KERN_ERR "No execution domain for personality 0x%02lx\n", pers);
 63         return NULL;
 64 }
 65 
 66 int register_exec_domain(struct exec_domain *it)
 67 {
 68         struct exec_domain *tmp;
 69 
 70         if (!it)
 71                 return -EINVAL;
 72         if (it->next)
 73                 return -EBUSY;
 74         write_lock(&exec_domains_lock);
 75         for (tmp=exec_domains; tmp; tmp=tmp->next)
 76                 if (tmp == it) {
 77                         write_unlock(&exec_domains_lock);
 78                         return -EBUSY;
 79                 }
 80         it->next = exec_domains;
 81         exec_domains = it;
 82         write_unlock(&exec_domains_lock);
 83         return 0;
 84 }
 85 
 86 int unregister_exec_domain(struct exec_domain *it)
 87 {
 88         struct exec_domain ** tmp;
 89 
 90         tmp = &exec_domains;
 91         write_lock(&exec_domains_lock);
 92         while (*tmp) {
 93                 if (it == *tmp) {
 94                         *tmp = it->next;
 95                         it->next = NULL;
 96                         write_unlock(&exec_domains_lock);
 97                         return 0;
 98                 }
 99                 tmp = &(*tmp)->next;
100         }
101         write_unlock(&exec_domains_lock);
102         return -EINVAL;
103 }
104 
105 void __set_personality(unsigned long personality)
106 {
107         struct exec_domain *it, *prev;
108 
109         it = lookup_exec_domain(personality);
110         if (it == current->exec_domain) {
111                 current->personality = personality;
112                 return;
113         }
114         if (!it)
115                 return;
116         if (atomic_read(&current->fs->count) != 1) {
117                 struct fs_struct *new = copy_fs_struct(current->fs);
118                 struct fs_struct *old;
119                 if (!new) {
120                         put_exec_domain(it);
121                         return;
122                 }
123                 task_lock(current);
124                 old = current->fs;
125                 current->fs = new;
126                 task_unlock(current);
127                 put_fs_struct(old);
128         }
129         /*
130          * At that point we are guaranteed to be the sole owner of
131          * current->fs.
132          */
133         current->personality = personality;
134         prev = current->exec_domain;
135         current->exec_domain = it;
136         set_fs_altroot();
137         put_exec_domain(prev);
138 }
139 
140 asmlinkage long sys_personality(unsigned long personality)
141 {
142         int ret = current->personality;
143         if (personality != 0xffffffff) {
144                 set_personality(personality);
145                 if (current->personality != personality)
146                         ret = -EINVAL;
147         }
148         return ret;
149 }
150 
151 int get_exec_domain_list(char * page)
152 {
153         int len = 0;
154         struct exec_domain * e;
155 
156         read_lock(&exec_domains_lock);
157         for (e=exec_domains; e && len < PAGE_SIZE - 80; e=e->next)
158                 len += sprintf(page+len, "%d-%d\t%-16s\t[%s]\n",
159                         e->pers_low, e->pers_high, e->name,
160                         e->module ? e->module->name : "kernel");
161         read_unlock(&exec_domains_lock);
162         return len;
163 }
164 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.