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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [kernel/] [capability.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 * linux/kernel/capability.c
3
 *
4
 * Copyright (C) 1997  Andrew Main <zefram@fysh.org>
5
 * Integrated into 2.1.97+,  Andrew G. Morgan <morgan@transmeta.com>
6
 */
7
 
8
#include <linux/mm.h>
9
#include <asm/uaccess.h>
10
 
11
kernel_cap_t cap_bset = CAP_INIT_EFF_SET;
12
 
13
/* Note: never hold tasklist_lock while spinning for this one */
14
spinlock_t task_capability_lock = SPIN_LOCK_UNLOCKED;
15
 
16
/*
17
 * For sys_getproccap() and sys_setproccap(), any of the three
18
 * capability set pointers may be NULL -- indicating that that set is
19
 * uninteresting and/or not to be changed.
20
 */
21
 
22
asmlinkage long sys_capget(cap_user_header_t header, cap_user_data_t dataptr)
23
{
24
     int error, pid;
25
     __u32 version;
26
     struct task_struct *target;
27
     struct __user_cap_data_struct data;
28
 
29
     if (get_user(version, &header->version))
30
             return -EFAULT;
31
 
32
     error = -EINVAL;
33
     if (version != _LINUX_CAPABILITY_VERSION) {
34
             version = _LINUX_CAPABILITY_VERSION;
35
             if (put_user(version, &header->version))
36
                     error = -EFAULT;
37
             return error;
38
     }
39
 
40
     if (get_user(pid, &header->pid))
41
             return -EFAULT;
42
 
43
     if (pid < 0)
44
             return -EINVAL;
45
 
46
     error = 0;
47
 
48
     spin_lock(&task_capability_lock);
49
 
50
     if (pid && pid != current->pid) {
51
             read_lock(&tasklist_lock);
52
             target = find_task_by_pid(pid);  /* identify target of query */
53
             if (!target)
54
                     error = -ESRCH;
55
     } else {
56
             target = current;
57
     }
58
 
59
     if (!error) {
60
             data.permitted = cap_t(target->cap_permitted);
61
             data.inheritable = cap_t(target->cap_inheritable);
62
             data.effective = cap_t(target->cap_effective);
63
     }
64
 
65
     if (target != current)
66
             read_unlock(&tasklist_lock);
67
     spin_unlock(&task_capability_lock);
68
 
69
     if (!error) {
70
             if (copy_to_user(dataptr, &data, sizeof data))
71
                     return -EFAULT;
72
     }
73
 
74
     return error;
75
}
76
 
77
/* set capabilities for all processes in a given process group */
78
 
79
static void cap_set_pg(int pgrp,
80
                    kernel_cap_t *effective,
81
                    kernel_cap_t *inheritable,
82
                    kernel_cap_t *permitted)
83
{
84
     struct task_struct *target;
85
 
86
     /* FIXME: do we need to have a write lock here..? */
87
     read_lock(&tasklist_lock);
88
     for_each_task(target) {
89
             if (target->pgrp != pgrp)
90
                     continue;
91
             target->cap_effective   = *effective;
92
             target->cap_inheritable = *inheritable;
93
             target->cap_permitted   = *permitted;
94
     }
95
     read_unlock(&tasklist_lock);
96
}
97
 
98
/* set capabilities for all processes other than 1 and self */
99
 
100
static void cap_set_all(kernel_cap_t *effective,
101
                     kernel_cap_t *inheritable,
102
                     kernel_cap_t *permitted)
103
{
104
     struct task_struct *target;
105
 
106
     /* FIXME: do we need to have a write lock here..? */
107
     read_lock(&tasklist_lock);
108
     /* ALL means everyone other than self or 'init' */
109
     for_each_task(target) {
110
             if (target == current || target->pid == 1)
111
                     continue;
112
             target->cap_effective   = *effective;
113
             target->cap_inheritable = *inheritable;
114
             target->cap_permitted   = *permitted;
115
     }
116
     read_unlock(&tasklist_lock);
117
}
118
 
119
/*
120
 * The restrictions on setting capabilities are specified as:
121
 *
122
 * [pid is for the 'target' task.  'current' is the calling task.]
123
 *
124
 * I: any raised capabilities must be a subset of the (old current) Permitted
125
 * P: any raised capabilities must be a subset of the (old current) permitted
126
 * E: must be set to a subset of (new target) Permitted
127
 */
128
 
129
asmlinkage long sys_capset(cap_user_header_t header, const cap_user_data_t data)
130
{
131
     kernel_cap_t inheritable, permitted, effective;
132
     __u32 version;
133
     struct task_struct *target;
134
     int error, pid;
135
 
136
     if (get_user(version, &header->version))
137
             return -EFAULT;
138
 
139
     if (version != _LINUX_CAPABILITY_VERSION) {
140
             version = _LINUX_CAPABILITY_VERSION;
141
             if (put_user(version, &header->version))
142
                     return -EFAULT;
143
             return -EINVAL;
144
     }
145
 
146
     if (get_user(pid, &header->pid))
147
             return -EFAULT;
148
 
149
     if (pid && !capable(CAP_SETPCAP))
150
             return -EPERM;
151
 
152
     if (copy_from_user(&effective, &data->effective, sizeof(effective)) ||
153
         copy_from_user(&inheritable, &data->inheritable, sizeof(inheritable)) ||
154
         copy_from_user(&permitted, &data->permitted, sizeof(permitted)))
155
             return -EFAULT;
156
 
157
     error = -EPERM;
158
     spin_lock(&task_capability_lock);
159
 
160
     if (pid > 0 && pid != current->pid) {
161
             read_lock(&tasklist_lock);
162
             target = find_task_by_pid(pid);  /* identify target of query */
163
             if (!target) {
164
                     error = -ESRCH;
165
                     goto out;
166
             }
167
     } else {
168
             target = current;
169
     }
170
 
171
 
172
     /* verify restrictions on target's new Inheritable set */
173
     if (!cap_issubset(inheritable,
174
                       cap_combine(target->cap_inheritable,
175
                                   current->cap_permitted))) {
176
             goto out;
177
     }
178
 
179
     /* verify restrictions on target's new Permitted set */
180
     if (!cap_issubset(permitted,
181
                       cap_combine(target->cap_permitted,
182
                                   current->cap_permitted))) {
183
             goto out;
184
     }
185
 
186
     /* verify the _new_Effective_ is a subset of the _new_Permitted_ */
187
     if (!cap_issubset(effective, permitted)) {
188
             goto out;
189
     }
190
 
191
     /* having verified that the proposed changes are legal,
192
           we now put them into effect. */
193
     error = 0;
194
 
195
     if (pid < 0) {
196
             if (pid == -1)  /* all procs other than current and init */
197
                     cap_set_all(&effective, &inheritable, &permitted);
198
 
199
             else            /* all procs in process group */
200
                     cap_set_pg(-pid, &effective, &inheritable, &permitted);
201
             goto spin_out;
202
     } else {
203
             /* FIXME: do we need to have a write lock here..? */
204
             target->cap_effective   = effective;
205
             target->cap_inheritable = inheritable;
206
             target->cap_permitted   = permitted;
207
     }
208
 
209
out:
210
     if (target != current) {
211
             read_unlock(&tasklist_lock);
212
     }
213
spin_out:
214
     spin_unlock(&task_capability_lock);
215
     return error;
216
}

powered by: WebSVN 2.1.0

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