1
2
3
4
5
6
7
8
9
10#include <linux/capability.h>
11#include <linux/module.h>
12#include <linux/init.h>
13#include <linux/kernel.h>
14#include <linux/security.h>
15#include <linux/file.h>
16#include <linux/mm.h>
17#include <linux/mman.h>
18#include <linux/pagemap.h>
19#include <linux/swap.h>
20#include <linux/smp_lock.h>
21#include <linux/skbuff.h>
22#include <linux/netlink.h>
23#include <linux/ptrace.h>
24#include <linux/xattr.h>
25#include <linux/hugetlb.h>
26
27int cap_netlink_send(struct sock *sk, struct sk_buff *skb)
28{
29 NETLINK_CB(skb).eff_cap = current->cap_effective;
30 return 0;
31}
32
33EXPORT_SYMBOL(cap_netlink_send);
34
35int cap_netlink_recv(struct sk_buff *skb, int cap)
36{
37 if (!cap_raised(NETLINK_CB(skb).eff_cap, cap))
38 return -EPERM;
39 return 0;
40}
41
42EXPORT_SYMBOL(cap_netlink_recv);
43
44int cap_capable (struct task_struct *tsk, int cap)
45{
46
47 if (cap_raised(tsk->cap_effective, cap))
48 return 0;
49 return -EPERM;
50}
51
52int cap_settime(struct timespec *ts, struct timezone *tz)
53{
54 if (!capable(CAP_SYS_TIME))
55 return -EPERM;
56 return 0;
57}
58
59int cap_ptrace (struct task_struct *parent, struct task_struct *child)
60{
61
62 if (!cap_issubset(child->cap_permitted, parent->cap_permitted) &&
63 !__capable(parent, CAP_SYS_PTRACE))
64 return -EPERM;
65 return 0;
66}
67
68int cap_capget (struct task_struct *target, kernel_cap_t *effective,
69 kernel_cap_t *inheritable, kernel_cap_t *permitted)
70{
71
72 *effective = cap_t (target->cap_effective);
73 *inheritable = cap_t (target->cap_inheritable);
74 *permitted = cap_t (target->cap_permitted);
75 return 0;
76}
77
78int cap_capset_check (struct task_struct *target, kernel_cap_t *effective,
79 kernel_cap_t *inheritable, kernel_cap_t *permitted)
80{
81
82
83 if (!cap_issubset (*inheritable,
84 cap_combine (target->cap_inheritable,
85 current->cap_permitted))) {
86 return -EPERM;
87 }
88
89
90 if (!cap_issubset (*permitted,
91 cap_combine (target->cap_permitted,
92 current->cap_permitted))) {
93 return -EPERM;
94 }
95
96
97 if (!cap_issubset (*effective, *permitted)) {
98 return -EPERM;
99 }
100
101 return 0;
102}
103
104void cap_capset_set (struct task_struct *target, kernel_cap_t *effective,
105 kernel_cap_t *inheritable, kernel_cap_t *permitted)
106{
107 target->cap_effective = *effective;
108 target->cap_inheritable = *inheritable;
109 target->cap_permitted = *permitted;
110}
111
112int cap_bprm_set_security (struct linux_binprm *bprm)
113{
114
115
116
117 cap_clear (bprm->cap_inheritable);
118 cap_clear (bprm->cap_permitted);
119 cap_clear (bprm->cap_effective);
120
121
122
123
124
125
126
127
128
129 if (!issecure (SECURE_NOROOT)) {
130 if (bprm->e_uid == 0 || current->uid == 0) {
131 cap_set_full (bprm->cap_inheritable);
132 cap_set_full (bprm->cap_permitted);
133 }
134 if (bprm->e_uid == 0)
135 cap_set_full (bprm->cap_effective);
136 }
137 return 0;
138}
139
140void cap_bprm_apply_creds (struct linux_binprm *bprm, int unsafe)
141{
142
143 kernel_cap_t new_permitted, working;
144
145 new_permitted = cap_intersect (bprm->cap_permitted, cap_bset);
146 working = cap_intersect (bprm->cap_inheritable,
147 current->cap_inheritable);
148 new_permitted = cap_combine (new_permitted, working);
149
150 if (bprm->e_uid != current->uid || bprm->e_gid != current->gid ||
151 !cap_issubset (new_permitted, current->cap_permitted)) {
152 current->mm->dumpable = suid_dumpable;
153
154 if (unsafe & ~LSM_UNSAFE_PTRACE_CAP) {
155 if (!capable(CAP_SETUID)) {
156 bprm->e_uid = current->uid;
157 bprm->e_gid = current->gid;
158 }
159 if (!capable (CAP_SETPCAP)) {
160 new_permitted = cap_intersect (new_permitted,
161 current->cap_permitted);
162 }
163 }
164 }
165
166 current->suid = current->euid = current->fsuid = bprm->e_uid;
167 current->sgid = current->egid = current->fsgid = bprm->e_gid;
168
169
170
171
172 if (current->pid != 1) {
173 current->cap_permitted = new_permitted;
174 current->cap_effective =
175 cap_intersect (new_permitted, bprm->cap_effective);
176 }
177
178
179
180 current->keep_capabilities = 0;
181}
182
183int cap_bprm_secureexec (struct linux_binprm *bprm)
184{
185
186
187
188
189
190 return (current->euid != current->uid ||
191 current->egid != current->gid);
192}
193
194int cap_inode_setxattr(struct dentry *dentry, char *name, void *value,
195 size_t size, int flags)
196{
197 if (!strncmp(name, XATTR_SECURITY_PREFIX,
198 sizeof(XATTR_SECURITY_PREFIX) - 1) &&
199 !capable(CAP_SYS_ADMIN))
200 return -EPERM;
201 return 0;
202}
203
204int cap_inode_removexattr(struct dentry *dentry, char *name)
205{
206 if (!strncmp(name, XATTR_SECURITY_PREFIX,
207 sizeof(XATTR_SECURITY_PREFIX) - 1) &&
208 !capable(CAP_SYS_ADMIN))
209 return -EPERM;
210 return 0;
211}
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243static inline void cap_emulate_setxuid (int old_ruid, int old_euid,
244 int old_suid)
245{
246 if ((old_ruid == 0 || old_euid == 0 || old_suid == 0) &&
247 (current->uid != 0 && current->euid != 0 && current->suid != 0) &&
248 !current->keep_capabilities) {
249 cap_clear (current->cap_permitted);
250 cap_clear (current->cap_effective);
251 }
252 if (old_euid == 0 && current->euid != 0) {
253 cap_clear (current->cap_effective);
254 }
255 if (old_euid != 0 && current->euid == 0) {
256 current->cap_effective = current->cap_permitted;
257 }
258}
259
260int cap_task_post_setuid (uid_t old_ruid, uid_t old_euid, uid_t old_suid,
261 int flags)
262{
263 switch (flags) {
264 case LSM_SETID_RE:
265 case LSM_SETID_ID:
266 case LSM_SETID_RES:
267
268 if (!issecure (SECURE_NO_SETUID_FIXUP)) {
269 cap_emulate_setxuid (old_ruid, old_euid, old_suid);
270 }
271 break;
272 case LSM_SETID_FS:
273 {
274 uid_t old_fsuid = old_ruid;
275
276
277
278
279
280
281
282
283 if (!issecure (SECURE_NO_SETUID_FIXUP)) {
284 if (old_fsuid == 0 && current->fsuid != 0) {
285 cap_t (current->cap_effective) &=
286 ~CAP_FS_MASK;
287 }
288 if (old_fsuid != 0 && current->fsuid == 0) {
289 cap_t (current->cap_effective) |=
290 (cap_t (current->cap_permitted) &
291 CAP_FS_MASK);
292 }
293 }
294 break;
295 }
296 default:
297 return -EINVAL;
298 }
299
300 return 0;
301}
302
303void cap_task_reparent_to_init (struct task_struct *p)
304{
305 p->cap_effective = CAP_INIT_EFF_SET;
306 p->cap_inheritable = CAP_INIT_INH_SET;
307 p->cap_permitted = CAP_FULL_SET;
308 p->keep_capabilities = 0;
309 return;
310}
311
312int cap_syslog (int type)
313{
314 if ((type != 3 && type != 10) && !capable(CAP_SYS_ADMIN))
315 return -EPERM;
316 return 0;
317}
318
319int cap_vm_enough_memory(long pages)
320{
321 int cap_sys_admin = 0;
322
323 if (cap_capable(current, CAP_SYS_ADMIN) == 0)
324 cap_sys_admin = 1;
325 return __vm_enough_memory(pages, cap_sys_admin);
326}
327
328EXPORT_SYMBOL(cap_capable);
329EXPORT_SYMBOL(cap_settime);
330EXPORT_SYMBOL(cap_ptrace);
331EXPORT_SYMBOL(cap_capget);
332EXPORT_SYMBOL(cap_capset_check);
333EXPORT_SYMBOL(cap_capset_set);
334EXPORT_SYMBOL(cap_bprm_set_security);
335EXPORT_SYMBOL(cap_bprm_apply_creds);
336EXPORT_SYMBOL(cap_bprm_secureexec);
337EXPORT_SYMBOL(cap_inode_setxattr);
338EXPORT_SYMBOL(cap_inode_removexattr);
339EXPORT_SYMBOL(cap_task_post_setuid);
340EXPORT_SYMBOL(cap_task_reparent_to_init);
341EXPORT_SYMBOL(cap_syslog);
342EXPORT_SYMBOL(cap_vm_enough_memory);
343
344MODULE_DESCRIPTION("Standard Linux Common Capabilities Security Module");
345MODULE_LICENSE("GPL");
346