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

Subversion Repositories or1k_soc_on_altera_embedded_dev_kit

[/] [or1k_soc_on_altera_embedded_dev_kit/] [trunk/] [linux-2.6/] [linux-2.6.24/] [kernel/] [capability.c] - Blame information for rev 17

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 xianfeng
/*
2
 * linux/kernel/capability.c
3
 *
4
 * Copyright (C) 1997  Andrew Main <zefram@fysh.org>
5
 *
6
 * Integrated into 2.1.97+,  Andrew G. Morgan <morgan@kernel.org>
7
 * 30 May 2002: Cleanup, Robert M. Love <rml@tech9.net>
8
 */
9
 
10
#include <linux/capability.h>
11
#include <linux/mm.h>
12
#include <linux/module.h>
13
#include <linux/security.h>
14
#include <linux/syscalls.h>
15
#include <linux/pid_namespace.h>
16
#include <asm/uaccess.h>
17
 
18
/*
19
 * This lock protects task->cap_* for all tasks including current.
20
 * Locking rule: acquire this prior to tasklist_lock.
21
 */
22
static DEFINE_SPINLOCK(task_capability_lock);
23
 
24
/*
25
 * For sys_getproccap() and sys_setproccap(), any of the three
26
 * capability set pointers may be NULL -- indicating that that set is
27
 * uninteresting and/or not to be changed.
28
 */
29
 
30
/**
31
 * sys_capget - get the capabilities of a given process.
32
 * @header: pointer to struct that contains capability version and
33
 *      target pid data
34
 * @dataptr: pointer to struct that contains the effective, permitted,
35
 *      and inheritable capabilities that are returned
36
 *
37
 * Returns 0 on success and < 0 on error.
38
 */
39
asmlinkage long sys_capget(cap_user_header_t header, cap_user_data_t dataptr)
40
{
41
        int ret = 0;
42
        pid_t pid;
43
        __u32 version;
44
        struct task_struct *target;
45
        struct __user_cap_data_struct data;
46
 
47
        if (get_user(version, &header->version))
48
                return -EFAULT;
49
 
50
        if (version != _LINUX_CAPABILITY_VERSION) {
51
                if (put_user(_LINUX_CAPABILITY_VERSION, &header->version))
52
                        return -EFAULT;
53
                return -EINVAL;
54
        }
55
 
56
        if (get_user(pid, &header->pid))
57
                return -EFAULT;
58
 
59
        if (pid < 0)
60
                return -EINVAL;
61
 
62
        spin_lock(&task_capability_lock);
63
        read_lock(&tasklist_lock);
64
 
65
        if (pid && pid != task_pid_vnr(current)) {
66
                target = find_task_by_vpid(pid);
67
                if (!target) {
68
                        ret = -ESRCH;
69
                        goto out;
70
                }
71
        } else
72
                target = current;
73
 
74
        ret = security_capget(target, &data.effective, &data.inheritable, &data.permitted);
75
 
76
out:
77
        read_unlock(&tasklist_lock);
78
        spin_unlock(&task_capability_lock);
79
 
80
        if (!ret && copy_to_user(dataptr, &data, sizeof data))
81
                return -EFAULT;
82
 
83
        return ret;
84
}
85
 
86
/*
87
 * cap_set_pg - set capabilities for all processes in a given process
88
 * group.  We call this holding task_capability_lock and tasklist_lock.
89
 */
90
static inline int cap_set_pg(int pgrp_nr, kernel_cap_t *effective,
91
                              kernel_cap_t *inheritable,
92
                              kernel_cap_t *permitted)
93
{
94
        struct task_struct *g, *target;
95
        int ret = -EPERM;
96
        int found = 0;
97
        struct pid *pgrp;
98
 
99
        pgrp = find_vpid(pgrp_nr);
100
        do_each_pid_task(pgrp, PIDTYPE_PGID, g) {
101
                target = g;
102
                while_each_thread(g, target) {
103
                        if (!security_capset_check(target, effective,
104
                                                        inheritable,
105
                                                        permitted)) {
106
                                security_capset_set(target, effective,
107
                                                        inheritable,
108
                                                        permitted);
109
                                ret = 0;
110
                        }
111
                        found = 1;
112
                }
113
        } while_each_pid_task(pgrp, PIDTYPE_PGID, g);
114
 
115
        if (!found)
116
                ret = 0;
117
        return ret;
118
}
119
 
120
/*
121
 * cap_set_all - set capabilities for all processes other than init
122
 * and self.  We call this holding task_capability_lock and tasklist_lock.
123
 */
124
static inline int cap_set_all(kernel_cap_t *effective,
125
                               kernel_cap_t *inheritable,
126
                               kernel_cap_t *permitted)
127
{
128
     struct task_struct *g, *target;
129
     int ret = -EPERM;
130
     int found = 0;
131
 
132
     do_each_thread(g, target) {
133
             if (target == current || is_container_init(target->group_leader))
134
                     continue;
135
             found = 1;
136
             if (security_capset_check(target, effective, inheritable,
137
                                                permitted))
138
                     continue;
139
             ret = 0;
140
             security_capset_set(target, effective, inheritable, permitted);
141
     } while_each_thread(g, target);
142
 
143
     if (!found)
144
             ret = 0;
145
     return ret;
146
}
147
 
148
/**
149
 * sys_capset - set capabilities for a process or a group of processes
150
 * @header: pointer to struct that contains capability version and
151
 *      target pid data
152
 * @data: pointer to struct that contains the effective, permitted,
153
 *      and inheritable capabilities
154
 *
155
 * Set capabilities for a given process, all processes, or all
156
 * processes in a given process group.
157
 *
158
 * The restrictions on setting capabilities are specified as:
159
 *
160
 * [pid is for the 'target' task.  'current' is the calling task.]
161
 *
162
 * I: any raised capabilities must be a subset of the (old current) permitted
163
 * P: any raised capabilities must be a subset of the (old current) permitted
164
 * E: must be set to a subset of (new target) permitted
165
 *
166
 * Returns 0 on success and < 0 on error.
167
 */
168
asmlinkage long sys_capset(cap_user_header_t header, const cap_user_data_t data)
169
{
170
        kernel_cap_t inheritable, permitted, effective;
171
        __u32 version;
172
        struct task_struct *target;
173
        int ret;
174
        pid_t pid;
175
 
176
        if (get_user(version, &header->version))
177
                return -EFAULT;
178
 
179
        if (version != _LINUX_CAPABILITY_VERSION) {
180
                if (put_user(_LINUX_CAPABILITY_VERSION, &header->version))
181
                        return -EFAULT;
182
                return -EINVAL;
183
        }
184
 
185
        if (get_user(pid, &header->pid))
186
                return -EFAULT;
187
 
188
        if (pid && pid != task_pid_vnr(current) && !capable(CAP_SETPCAP))
189
                return -EPERM;
190
 
191
        if (copy_from_user(&effective, &data->effective, sizeof(effective)) ||
192
            copy_from_user(&inheritable, &data->inheritable, sizeof(inheritable)) ||
193
            copy_from_user(&permitted, &data->permitted, sizeof(permitted)))
194
                return -EFAULT;
195
 
196
        spin_lock(&task_capability_lock);
197
        read_lock(&tasklist_lock);
198
 
199
        if (pid > 0 && pid != task_pid_vnr(current)) {
200
                target = find_task_by_vpid(pid);
201
                if (!target) {
202
                        ret = -ESRCH;
203
                        goto out;
204
                }
205
        } else
206
                target = current;
207
 
208
        ret = 0;
209
 
210
        /* having verified that the proposed changes are legal,
211
           we now put them into effect. */
212
        if (pid < 0) {
213
                if (pid == -1)  /* all procs other than current and init */
214
                        ret = cap_set_all(&effective, &inheritable, &permitted);
215
 
216
                else            /* all procs in process group */
217
                        ret = cap_set_pg(-pid, &effective, &inheritable,
218
                                         &permitted);
219
        } else {
220
                ret = security_capset_check(target, &effective, &inheritable,
221
                                            &permitted);
222
                if (!ret)
223
                        security_capset_set(target, &effective, &inheritable,
224
                                            &permitted);
225
        }
226
 
227
out:
228
        read_unlock(&tasklist_lock);
229
        spin_unlock(&task_capability_lock);
230
 
231
        return ret;
232
}
233
 
234
int __capable(struct task_struct *t, int cap)
235
{
236
        if (security_capable(t, cap) == 0) {
237
                t->flags |= PF_SUPERPRIV;
238
                return 1;
239
        }
240
        return 0;
241
}
242
 
243
int capable(int cap)
244
{
245
        return __capable(current, cap);
246
}
247
EXPORT_SYMBOL(capable);

powered by: WebSVN 2.1.0

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