OpenCores
URL https://opencores.org/ocsvn/c0or1k/c0or1k/trunk

Subversion Repositories c0or1k

[/] [c0or1k/] [trunk/] [conts/] [test_suite0/] [src/] [example.c] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 drasko
 
2
#if 0
3
 
4
int mutex_user_thread(void *arg)
5
{
6
        /* TODO: Create and access a mutex */
7
}
8
 
9
int independent_thread(void *arg)
10
{
11
        /* TODO: Do whatever syscall available */
12
}
13
 
14
 
15
/*
16
 * This example demonstrates how the capability-based
17
 * security model can be bypassed and taken out of the
18
 * way for the sake of implementing an application that
19
 * doesn't worry too much about security.
20
 *
21
 * The benefit is that the user does neither worry about
22
 * capabilities nor using its api to design correctly
23
 * secure systems. The downside is that the system is
24
 * less security-enforced, i.e. all parties must be
25
 * trusted.
26
 */
27
int multi_threaded_nocaps_example(void)
28
{
29
        /*
30
         * We are the first pager with capabilities to
31
         * create new tasks, spaces, in its own container.
32
         */
33
        pager_read_caps();
34
 
35
        /*
36
         * We have all our capabilities private to us.
37
         *
38
         * If we create a new task, it won't be able to
39
         * any kernel operations that we can do, because
40
         * we hold our capabilities privately.
41
         *
42
         * In order to settle all capability access issues
43
         * once and for all threads we will create and manage,
44
         * we share our capabilities with the most global
45
         * collection possible.
46
         */
47
 
48
        /*
49
         * Share all of our capabilities with all threads
50
         * in the same container.
51
         *
52
         * From this point onwards, any thread we create and
53
         * manage (i.e. whose container id is equal to our
54
         * container id) will have the ability to leverage
55
         * all of our capabilities as defined for us at
56
         * configuration time.
57
         */
58
        l4_cap_share(0, CAP_SHARE_CONTAINER | CAP_SHARE_ALL, self_tid());
59
 
60
 
61
        /*
62
         * Lets try it.
63
         *
64
         * Create new thread that we don't have any hieararchical
65
         * relationship, i.e. one that is a pager of itself, one
66
         * that runs in a new address space, and in a new thread
67
         * group. All we share is the container.
68
         */
69
        if ((err = thread_create(independent_thread, 0,
70
                                 TC_NO_SHARING, &ids)) < 0) {
71
                printf("mutex_user_thread creation failed.\n");
72
                goto out_err;
73
        }
74
 
75
        /*
76
         * We can inspect the new thread by doing an ipc to it.
77
         * NOTE:
78
         *
79
         * We are able to send to this thread from the start,
80
         * as we had a container-wide ipc capability defined at
81
         * config-time.
82
         *
83
         * But we would not be able to receive from it, if we
84
         * did not share this capability with the container. It
85
         * would have no rights to do a send to us. But because
86
         * we're in the same container, and we shared our
87
         * capability, it now can.
88
         */
89
        if ((err = l4_recv(ids->tid, ids->tid, 0)) < 0) {
90
                print_err("%s: L4 IPC Error: %d.\n", __FUNCTION__, fd);
91
                goto out_err;
92
        }
93
 
94
        /*
95
         * From this point onwards we can create more threads
96
         * without worrying about whether they have the caps
97
         * to do certain ops, and the caps api. because we shared
98
         * them all at the beginning.
99
         */
100
 
101
out_err:
102
        BUG();
103
}
104
 
105
/*
106
 * This example demonstrates how a pager would
107
 * share part of its capabilities on the system
108
 * with its children.
109
 *
110
 * The example includes sharing of a mutex
111
 * capability with a paged-child.
112
 */
113
int multi_threaded_capability_sharing_example(void)
114
{
115
        struct capability *mutex_cap;
116
        int thread_retval;
117
 
118
        /*
119
         * We are the first pager with capabilities to
120
         * create new tasks, spaces, in its own container.
121
         */
122
        pager_read_caps();
123
 
124
        /*
125
         * We have all our capabilities private to us.
126
         *
127
         * If we create a new task, it won't be able to
128
         * create and use userspace mutexes, because we
129
         * hold mutex capabilities privately.
130
         *
131
         * Lets try it.
132
         */
133
 
134
        /*
135
         * Create new thread that will attempt
136
         * a mutex operation, and die on us with a
137
         * negative return code if it fails.
138
         */
139
        if ((err = thread_create(mutex_user_thread, 0,
140
                                 TC_SHARE_SPACE |
141
                                 TC_AS_PAGER, &ids)) < 0) {
142
                printf("mutex_user_thread creation failed.\n");
143
                goto out_err;
144
        }
145
 
146
        /* Check on how the thread has done */
147
        if ((err = l4_thread_wait_on(ids, &thread_retval)) < 0) {
148
                print("Waiting on thread %d failed. err = %d\n",
149
                      ids->tid, err);
150
                goto out_err;
151
        }
152
 
153
        if (thread_retval == 0) {
154
                printf("Thread %d returned with success, where "
155
                       "we expected failure.\n", ids->tid);
156
                goto out_err;
157
        }
158
 
159
        /*
160
         * Therefore, we share our capabilities with a
161
         * collection so that our capabilities may be also
162
         * used by them.
163
         */
164
 
165
        /* Get our private mutex cap */
166
        mutex_cap = cap_get(CAP_TYPE_MUTEX);
167
 
168
        /* We have ability to create and use this many mutexes */
169
        printf("%s: We have ability to create/use %d mutexes\n",
170
               self_tid(), mutex_cap->size);
171
 
172
        /* Split it */
173
        cap_new = cap_split(mutex_cap, 10, CAP_SPLIT_SIZE);
174
 
175
        /*
176
         * Share the split part with paged-children.
177
         *
178
         * From this point onwards, any thread we create and
179
         * manage (i.e. whose pagerid == self_tid()) will have
180
         * the ability to use mutexes, as defined by cap_new
181
         * we created.
182
         */
183
        l4_cap_share(cap_new, CAP_SHARE_PGGROUP, self_tid());
184
 
185
        /*
186
         * Create new thread that will attempt
187
         * a mutex operation, and die on us with a
188
         * negative return code if it fails.
189
         */
190
        if ((err = thread_create(mutex_user_thread, 0,
191
                                 TC_SHARE_SPACE |
192
                                 TC_AS_PAGER, &ids)) < 0) {
193
                printf("mutex_user_thread creation failed.\n");
194
                goto out_err;
195
        }
196
 
197
        /* Check on how the thread has done */
198
        if ((err = l4_thread_wait_on(ids, &thread_retval)) < 0) {
199
                printf("Waiting on thread %d failed. err = %d\n",
200
                      ids->tid, err);
201
                goto out_err;
202
        }
203
 
204
        if (thread_retval < 0) {
205
                printf("Thread %d returned with failure, where "
206
                       "we expected success.\n", ids->tid);
207
                goto out_err;
208
        }
209
 
210
out_err:
211
        BUG();
212
}
213
 
214
 
215
 
216
 
217
 
218
 
219
#endif
220
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.