blob: 4d6f37644baa9977eb180f7d2c65b2788e425ac0 [file] [log] [blame]
Casey Schauflere114e472008-02-04 22:29:50 -08001/*
2 * Simplified MAC Kernel (smack) security module
3 *
4 * This file contains the smack hook function implementations.
5 *
Jarkko Sakkinen5c6d1122010-12-07 13:34:01 +02006 * Authors:
Casey Schauflere114e472008-02-04 22:29:50 -08007 * Casey Schaufler <casey@schaufler-ca.com>
Jarkko Sakkinen84088ba2011-10-07 09:27:53 +03008 * Jarkko Sakkinen <jarkko.sakkinen@intel.com>
Casey Schauflere114e472008-02-04 22:29:50 -08009 *
10 * Copyright (C) 2007 Casey Schaufler <casey@schaufler-ca.com>
Paul Moore07feee82009-03-27 17:10:54 -040011 * Copyright (C) 2009 Hewlett-Packard Development Company, L.P.
Paul Moore82c21bf2011-08-01 11:10:33 +000012 * Paul Moore <paul@paul-moore.com>
Jarkko Sakkinen5c6d1122010-12-07 13:34:01 +020013 * Copyright (C) 2010 Nokia Corporation
Jarkko Sakkinen84088ba2011-10-07 09:27:53 +030014 * Copyright (C) 2011 Intel Corporation.
Casey Schauflere114e472008-02-04 22:29:50 -080015 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License version 2,
18 * as published by the Free Software Foundation.
19 */
20
21#include <linux/xattr.h>
22#include <linux/pagemap.h>
23#include <linux/mount.h>
24#include <linux/stat.h>
Casey Schauflere114e472008-02-04 22:29:50 -080025#include <linux/kd.h>
26#include <asm/ioctls.h>
Paul Moore07feee82009-03-27 17:10:54 -040027#include <linux/ip.h>
Casey Schauflere114e472008-02-04 22:29:50 -080028#include <linux/tcp.h>
29#include <linux/udp.h>
Casey Schauflerc6739442013-05-22 18:42:56 -070030#include <linux/dccp.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090031#include <linux/slab.h>
Casey Schauflere114e472008-02-04 22:29:50 -080032#include <linux/mutex.h>
33#include <linux/pipe_fs_i.h>
Casey Schauflere114e472008-02-04 22:29:50 -080034#include <net/cipso_ipv4.h>
Casey Schauflerc6739442013-05-22 18:42:56 -070035#include <net/ip.h>
36#include <net/ipv6.h>
Ahmed S. Darwishd20bdda2008-04-30 08:34:10 +100037#include <linux/audit.h>
Nick Black1fd7317d2009-09-22 16:43:33 -070038#include <linux/magic.h>
Eric Paris2a7dba32011-02-01 11:05:39 -050039#include <linux/dcache.h>
Jarkko Sakkinen16014d82011-10-14 13:16:24 +030040#include <linux/personality.h>
Al Viro40401532012-02-13 03:58:52 +000041#include <linux/msg.h>
42#include <linux/shm.h>
43#include <linux/binfmts.h>
Casey Schauflere114e472008-02-04 22:29:50 -080044#include "smack.h"
45
David Howellsc69e8d92008-11-14 10:39:19 +110046#define task_security(task) (task_cred_xxx((task), security))
47
Jarkko Sakkinen5c6d1122010-12-07 13:34:01 +020048#define TRANS_TRUE "TRUE"
49#define TRANS_TRUE_SIZE 4
50
Casey Schauflerc6739442013-05-22 18:42:56 -070051#define SMK_CONNECTING 0
52#define SMK_RECEIVING 1
53#define SMK_SENDING 2
54
55LIST_HEAD(smk_ipv6_port_list);
56
Casey Schauflere114e472008-02-04 22:29:50 -080057/**
58 * smk_fetch - Fetch the smack label from a file.
59 * @ip: a pointer to the inode
60 * @dp: a pointer to the dentry
61 *
62 * Returns a pointer to the master list entry for the Smack label
63 * or NULL if there was no label to fetch.
64 */
Casey Schaufler2f823ff2013-05-22 18:43:03 -070065static struct smack_known *smk_fetch(const char *name, struct inode *ip,
66 struct dentry *dp)
Casey Schauflere114e472008-02-04 22:29:50 -080067{
68 int rc;
Casey Schauflerf7112e62012-05-06 15:22:02 -070069 char *buffer;
Casey Schaufler2f823ff2013-05-22 18:43:03 -070070 struct smack_known *skp = NULL;
Casey Schauflere114e472008-02-04 22:29:50 -080071
72 if (ip->i_op->getxattr == NULL)
73 return NULL;
74
Casey Schauflerf7112e62012-05-06 15:22:02 -070075 buffer = kzalloc(SMK_LONGLABEL, GFP_KERNEL);
76 if (buffer == NULL)
Casey Schauflere114e472008-02-04 22:29:50 -080077 return NULL;
78
Casey Schauflerf7112e62012-05-06 15:22:02 -070079 rc = ip->i_op->getxattr(dp, name, buffer, SMK_LONGLABEL);
80 if (rc > 0)
Casey Schaufler2f823ff2013-05-22 18:43:03 -070081 skp = smk_import_entry(buffer, rc);
Casey Schauflerf7112e62012-05-06 15:22:02 -070082
83 kfree(buffer);
84
Casey Schaufler2f823ff2013-05-22 18:43:03 -070085 return skp;
Casey Schauflere114e472008-02-04 22:29:50 -080086}
87
88/**
89 * new_inode_smack - allocate an inode security blob
90 * @smack: a pointer to the Smack label to use in the blob
91 *
92 * Returns the new blob or NULL if there's no memory available
93 */
94struct inode_smack *new_inode_smack(char *smack)
95{
96 struct inode_smack *isp;
97
Tetsuo Handaceffec552012-03-29 16:19:05 +090098 isp = kzalloc(sizeof(struct inode_smack), GFP_NOFS);
Casey Schauflere114e472008-02-04 22:29:50 -080099 if (isp == NULL)
100 return NULL;
101
102 isp->smk_inode = smack;
103 isp->smk_flags = 0;
104 mutex_init(&isp->smk_lock);
105
106 return isp;
107}
108
Casey Schaufler7898e1f2011-01-17 08:05:27 -0800109/**
110 * new_task_smack - allocate a task security blob
111 * @smack: a pointer to the Smack label to use in the blob
112 *
113 * Returns the new blob or NULL if there's no memory available
114 */
Casey Schaufler2f823ff2013-05-22 18:43:03 -0700115static struct task_smack *new_task_smack(struct smack_known *task,
116 struct smack_known *forked, gfp_t gfp)
Casey Schaufler7898e1f2011-01-17 08:05:27 -0800117{
118 struct task_smack *tsp;
119
120 tsp = kzalloc(sizeof(struct task_smack), gfp);
121 if (tsp == NULL)
122 return NULL;
123
124 tsp->smk_task = task;
125 tsp->smk_forked = forked;
126 INIT_LIST_HEAD(&tsp->smk_rules);
127 mutex_init(&tsp->smk_rules_lock);
128
129 return tsp;
130}
131
132/**
133 * smk_copy_rules - copy a rule set
134 * @nhead - new rules header pointer
135 * @ohead - old rules header pointer
136 *
137 * Returns 0 on success, -ENOMEM on error
138 */
139static int smk_copy_rules(struct list_head *nhead, struct list_head *ohead,
140 gfp_t gfp)
141{
142 struct smack_rule *nrp;
143 struct smack_rule *orp;
144 int rc = 0;
145
146 INIT_LIST_HEAD(nhead);
147
148 list_for_each_entry_rcu(orp, ohead, list) {
149 nrp = kzalloc(sizeof(struct smack_rule), gfp);
150 if (nrp == NULL) {
151 rc = -ENOMEM;
152 break;
153 }
154 *nrp = *orp;
155 list_add_rcu(&nrp->list, nhead);
156 }
157 return rc;
158}
159
Lukasz Pawelczyk56638842014-03-11 17:07:05 +0100160/**
161 * smk_ptrace_mode - helper function for converting PTRACE_MODE_* into MAY_*
162 * @mode - input mode in form of PTRACE_MODE_*
163 *
164 * Returns a converted MAY_* mode usable by smack rules
165 */
166static inline unsigned int smk_ptrace_mode(unsigned int mode)
167{
168 switch (mode) {
169 case PTRACE_MODE_READ:
170 return MAY_READ;
171 case PTRACE_MODE_ATTACH:
172 return MAY_READWRITE;
173 }
174
175 return 0;
176}
177
178/**
179 * smk_ptrace_rule_check - helper for ptrace access
180 * @tracer: tracer process
181 * @tracee_label: label of the process that's about to be traced
182 * @mode: ptrace attachment mode (PTRACE_MODE_*)
183 * @func: name of the function that called us, used for audit
184 *
185 * Returns 0 on access granted, -error on error
186 */
187static int smk_ptrace_rule_check(struct task_struct *tracer, char *tracee_label,
188 unsigned int mode, const char *func)
189{
190 int rc;
191 struct smk_audit_info ad, *saip = NULL;
192 struct task_smack *tsp;
193 struct smack_known *skp;
194
195 if ((mode & PTRACE_MODE_NOAUDIT) == 0) {
196 smk_ad_init(&ad, func, LSM_AUDIT_DATA_TASK);
197 smk_ad_setfield_u_tsk(&ad, tracer);
198 saip = &ad;
199 }
200
201 tsp = task_security(tracer);
202 skp = smk_of_task(tsp);
203
204 rc = smk_tskacc(tsp, tracee_label, smk_ptrace_mode(mode), saip);
205 return rc;
206}
207
Casey Schauflere114e472008-02-04 22:29:50 -0800208/*
209 * LSM hooks.
210 * We he, that is fun!
211 */
212
213/**
Ingo Molnar9e488582009-05-07 19:26:19 +1000214 * smack_ptrace_access_check - Smack approval on PTRACE_ATTACH
Casey Schauflere114e472008-02-04 22:29:50 -0800215 * @ctp: child task pointer
Lukasz Pawelczyk56638842014-03-11 17:07:05 +0100216 * @mode: ptrace attachment mode (PTRACE_MODE_*)
Casey Schauflere114e472008-02-04 22:29:50 -0800217 *
218 * Returns 0 if access is OK, an error code otherwise
219 *
Lukasz Pawelczyk56638842014-03-11 17:07:05 +0100220 * Do the capability checks.
Casey Schauflere114e472008-02-04 22:29:50 -0800221 */
Ingo Molnar9e488582009-05-07 19:26:19 +1000222static int smack_ptrace_access_check(struct task_struct *ctp, unsigned int mode)
Casey Schauflere114e472008-02-04 22:29:50 -0800223{
224 int rc;
Casey Schaufler2f823ff2013-05-22 18:43:03 -0700225 struct smack_known *skp;
Casey Schauflere114e472008-02-04 22:29:50 -0800226
Ingo Molnar9e488582009-05-07 19:26:19 +1000227 rc = cap_ptrace_access_check(ctp, mode);
Casey Schauflere114e472008-02-04 22:29:50 -0800228 if (rc != 0)
229 return rc;
230
Casey Schaufler2f823ff2013-05-22 18:43:03 -0700231 skp = smk_of_task(task_security(ctp));
Etienne Bassetecfcc532009-04-08 20:40:06 +0200232
Lukasz Pawelczyk56638842014-03-11 17:07:05 +0100233 rc = smk_ptrace_rule_check(current, skp->smk_known, mode, __func__);
David Howells5cd9c582008-08-14 11:37:28 +0100234 return rc;
235}
Casey Schauflere114e472008-02-04 22:29:50 -0800236
David Howells5cd9c582008-08-14 11:37:28 +0100237/**
238 * smack_ptrace_traceme - Smack approval on PTRACE_TRACEME
239 * @ptp: parent task pointer
240 *
241 * Returns 0 if access is OK, an error code otherwise
242 *
Lukasz Pawelczyk56638842014-03-11 17:07:05 +0100243 * Do the capability checks, and require PTRACE_MODE_ATTACH.
David Howells5cd9c582008-08-14 11:37:28 +0100244 */
245static int smack_ptrace_traceme(struct task_struct *ptp)
246{
247 int rc;
Casey Schaufler2f823ff2013-05-22 18:43:03 -0700248 struct smack_known *skp;
David Howells5cd9c582008-08-14 11:37:28 +0100249
250 rc = cap_ptrace_traceme(ptp);
251 if (rc != 0)
252 return rc;
253
Lukasz Pawelczyk959e6c72014-03-11 17:07:04 +0100254 skp = smk_of_task(current_security());
Etienne Bassetecfcc532009-04-08 20:40:06 +0200255
Lukasz Pawelczyk56638842014-03-11 17:07:05 +0100256 rc = smk_ptrace_rule_check(ptp, skp->smk_known,
257 PTRACE_MODE_ATTACH, __func__);
Casey Schauflere114e472008-02-04 22:29:50 -0800258 return rc;
259}
260
261/**
262 * smack_syslog - Smack approval on syslog
263 * @type: message type
264 *
Casey Schauflere114e472008-02-04 22:29:50 -0800265 * Returns 0 on success, error code otherwise.
266 */
Eric Paris12b30522010-11-15 18:36:29 -0500267static int smack_syslog(int typefrom_file)
Casey Schauflere114e472008-02-04 22:29:50 -0800268{
Eric Paris12b30522010-11-15 18:36:29 -0500269 int rc = 0;
Casey Schaufler2f823ff2013-05-22 18:43:03 -0700270 struct smack_known *skp = smk_of_current();
Casey Schauflere114e472008-02-04 22:29:50 -0800271
Casey Schaufler1880eff2012-06-05 15:28:30 -0700272 if (smack_privileged(CAP_MAC_OVERRIDE))
Casey Schauflere114e472008-02-04 22:29:50 -0800273 return 0;
274
Casey Schaufler24ea1b62013-12-30 09:38:00 -0800275 if (smack_syslog_label != NULL && smack_syslog_label != skp)
Casey Schauflere114e472008-02-04 22:29:50 -0800276 rc = -EACCES;
277
278 return rc;
279}
280
281
282/*
283 * Superblock Hooks.
284 */
285
286/**
287 * smack_sb_alloc_security - allocate a superblock blob
288 * @sb: the superblock getting the blob
289 *
290 * Returns 0 on success or -ENOMEM on error.
291 */
292static int smack_sb_alloc_security(struct super_block *sb)
293{
294 struct superblock_smack *sbsp;
295
296 sbsp = kzalloc(sizeof(struct superblock_smack), GFP_KERNEL);
297
298 if (sbsp == NULL)
299 return -ENOMEM;
300
301 sbsp->smk_root = smack_known_floor.smk_known;
302 sbsp->smk_default = smack_known_floor.smk_known;
303 sbsp->smk_floor = smack_known_floor.smk_known;
304 sbsp->smk_hat = smack_known_hat.smk_known;
Casey Schauflere830b392013-05-22 18:43:07 -0700305 /*
306 * smk_initialized will be zero from kzalloc.
307 */
Casey Schauflere114e472008-02-04 22:29:50 -0800308 sb->s_security = sbsp;
309
310 return 0;
311}
312
313/**
314 * smack_sb_free_security - free a superblock blob
315 * @sb: the superblock getting the blob
316 *
317 */
318static void smack_sb_free_security(struct super_block *sb)
319{
320 kfree(sb->s_security);
321 sb->s_security = NULL;
322}
323
324/**
325 * smack_sb_copy_data - copy mount options data for processing
Casey Schauflere114e472008-02-04 22:29:50 -0800326 * @orig: where to start
Randy Dunlap251a2a92009-02-18 11:42:33 -0800327 * @smackopts: mount options string
Casey Schauflere114e472008-02-04 22:29:50 -0800328 *
329 * Returns 0 on success or -ENOMEM on error.
330 *
331 * Copy the Smack specific mount options out of the mount
332 * options list.
333 */
Eric Parise0007522008-03-05 10:31:54 -0500334static int smack_sb_copy_data(char *orig, char *smackopts)
Casey Schauflere114e472008-02-04 22:29:50 -0800335{
336 char *cp, *commap, *otheropts, *dp;
337
Casey Schauflere114e472008-02-04 22:29:50 -0800338 otheropts = (char *)get_zeroed_page(GFP_KERNEL);
339 if (otheropts == NULL)
340 return -ENOMEM;
341
342 for (cp = orig, commap = orig; commap != NULL; cp = commap + 1) {
343 if (strstr(cp, SMK_FSDEFAULT) == cp)
344 dp = smackopts;
345 else if (strstr(cp, SMK_FSFLOOR) == cp)
346 dp = smackopts;
347 else if (strstr(cp, SMK_FSHAT) == cp)
348 dp = smackopts;
349 else if (strstr(cp, SMK_FSROOT) == cp)
350 dp = smackopts;
Casey Schauflere830b392013-05-22 18:43:07 -0700351 else if (strstr(cp, SMK_FSTRANS) == cp)
352 dp = smackopts;
Casey Schauflere114e472008-02-04 22:29:50 -0800353 else
354 dp = otheropts;
355
356 commap = strchr(cp, ',');
357 if (commap != NULL)
358 *commap = '\0';
359
360 if (*dp != '\0')
361 strcat(dp, ",");
362 strcat(dp, cp);
363 }
364
365 strcpy(orig, otheropts);
366 free_page((unsigned long)otheropts);
367
368 return 0;
369}
370
371/**
372 * smack_sb_kern_mount - Smack specific mount processing
373 * @sb: the file system superblock
James Morris12204e22008-12-19 10:44:42 +1100374 * @flags: the mount flags
Casey Schauflere114e472008-02-04 22:29:50 -0800375 * @data: the smack mount options
376 *
377 * Returns 0 on success, an error code on failure
378 */
James Morris12204e22008-12-19 10:44:42 +1100379static int smack_sb_kern_mount(struct super_block *sb, int flags, void *data)
Casey Schauflere114e472008-02-04 22:29:50 -0800380{
381 struct dentry *root = sb->s_root;
382 struct inode *inode = root->d_inode;
383 struct superblock_smack *sp = sb->s_security;
384 struct inode_smack *isp;
Casey Schaufler24ea1b62013-12-30 09:38:00 -0800385 struct smack_known *skp;
Casey Schauflere114e472008-02-04 22:29:50 -0800386 char *op;
387 char *commap;
388 char *nsp;
Casey Schauflere830b392013-05-22 18:43:07 -0700389 int transmute = 0;
Casey Schaufler24ea1b62013-12-30 09:38:00 -0800390 int specified = 0;
Casey Schauflere114e472008-02-04 22:29:50 -0800391
Casey Schauflere830b392013-05-22 18:43:07 -0700392 if (sp->smk_initialized)
Casey Schauflere114e472008-02-04 22:29:50 -0800393 return 0;
Casey Schauflereb982cb2012-05-23 17:46:58 -0700394
Casey Schauflere114e472008-02-04 22:29:50 -0800395 sp->smk_initialized = 1;
Casey Schauflere114e472008-02-04 22:29:50 -0800396
397 for (op = data; op != NULL; op = commap) {
398 commap = strchr(op, ',');
399 if (commap != NULL)
400 *commap++ = '\0';
401
402 if (strncmp(op, SMK_FSHAT, strlen(SMK_FSHAT)) == 0) {
403 op += strlen(SMK_FSHAT);
404 nsp = smk_import(op, 0);
Casey Schaufler24ea1b62013-12-30 09:38:00 -0800405 if (nsp != NULL) {
Casey Schauflere114e472008-02-04 22:29:50 -0800406 sp->smk_hat = nsp;
Casey Schaufler24ea1b62013-12-30 09:38:00 -0800407 specified = 1;
408 }
Casey Schauflere114e472008-02-04 22:29:50 -0800409 } else if (strncmp(op, SMK_FSFLOOR, strlen(SMK_FSFLOOR)) == 0) {
410 op += strlen(SMK_FSFLOOR);
411 nsp = smk_import(op, 0);
Casey Schaufler24ea1b62013-12-30 09:38:00 -0800412 if (nsp != NULL) {
Casey Schauflere114e472008-02-04 22:29:50 -0800413 sp->smk_floor = nsp;
Casey Schaufler24ea1b62013-12-30 09:38:00 -0800414 specified = 1;
415 }
Casey Schauflere114e472008-02-04 22:29:50 -0800416 } else if (strncmp(op, SMK_FSDEFAULT,
417 strlen(SMK_FSDEFAULT)) == 0) {
418 op += strlen(SMK_FSDEFAULT);
419 nsp = smk_import(op, 0);
Casey Schaufler24ea1b62013-12-30 09:38:00 -0800420 if (nsp != NULL) {
Casey Schauflere114e472008-02-04 22:29:50 -0800421 sp->smk_default = nsp;
Casey Schaufler24ea1b62013-12-30 09:38:00 -0800422 specified = 1;
423 }
Casey Schauflere114e472008-02-04 22:29:50 -0800424 } else if (strncmp(op, SMK_FSROOT, strlen(SMK_FSROOT)) == 0) {
425 op += strlen(SMK_FSROOT);
426 nsp = smk_import(op, 0);
Casey Schaufler24ea1b62013-12-30 09:38:00 -0800427 if (nsp != NULL) {
Casey Schauflere114e472008-02-04 22:29:50 -0800428 sp->smk_root = nsp;
Casey Schaufler24ea1b62013-12-30 09:38:00 -0800429 specified = 1;
430 }
Casey Schauflere830b392013-05-22 18:43:07 -0700431 } else if (strncmp(op, SMK_FSTRANS, strlen(SMK_FSTRANS)) == 0) {
432 op += strlen(SMK_FSTRANS);
433 nsp = smk_import(op, 0);
434 if (nsp != NULL) {
435 sp->smk_root = nsp;
436 transmute = 1;
Casey Schaufler24ea1b62013-12-30 09:38:00 -0800437 specified = 1;
Casey Schauflere830b392013-05-22 18:43:07 -0700438 }
Casey Schauflere114e472008-02-04 22:29:50 -0800439 }
440 }
441
Casey Schaufler24ea1b62013-12-30 09:38:00 -0800442 if (!smack_privileged(CAP_MAC_ADMIN)) {
443 /*
444 * Unprivileged mounts don't get to specify Smack values.
445 */
446 if (specified)
447 return -EPERM;
448 /*
449 * Unprivileged mounts get root and default from the caller.
450 */
451 skp = smk_of_current();
452 sp->smk_root = skp->smk_known;
453 sp->smk_default = skp->smk_known;
454 }
Casey Schauflere114e472008-02-04 22:29:50 -0800455 /*
456 * Initialize the root inode.
457 */
458 isp = inode->i_security;
José Bollo55dfc5d2014-01-08 15:53:05 +0100459 if (isp == NULL) {
460 isp = new_inode_smack(sp->smk_root);
461 if (isp == NULL)
462 return -ENOMEM;
463 inode->i_security = isp;
Casey Schauflere830b392013-05-22 18:43:07 -0700464 } else
Casey Schauflere114e472008-02-04 22:29:50 -0800465 isp->smk_inode = sp->smk_root;
466
Casey Schauflere830b392013-05-22 18:43:07 -0700467 if (transmute)
468 isp->smk_flags |= SMK_INODE_TRANSMUTE;
469
Casey Schauflere114e472008-02-04 22:29:50 -0800470 return 0;
471}
472
473/**
474 * smack_sb_statfs - Smack check on statfs
475 * @dentry: identifies the file system in question
476 *
477 * Returns 0 if current can read the floor of the filesystem,
478 * and error code otherwise
479 */
480static int smack_sb_statfs(struct dentry *dentry)
481{
482 struct superblock_smack *sbp = dentry->d_sb->s_security;
Etienne Bassetecfcc532009-04-08 20:40:06 +0200483 int rc;
484 struct smk_audit_info ad;
Casey Schauflere114e472008-02-04 22:29:50 -0800485
Eric Parisa2694342011-04-25 13:10:27 -0400486 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
Etienne Bassetecfcc532009-04-08 20:40:06 +0200487 smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
488
489 rc = smk_curacc(sbp->smk_floor, MAY_READ, &ad);
490 return rc;
Casey Schauflere114e472008-02-04 22:29:50 -0800491}
492
Casey Schauflere114e472008-02-04 22:29:50 -0800493/*
Casey Schaufler676dac42010-12-02 06:43:39 -0800494 * BPRM hooks
495 */
496
Casey Schauflerce8a4322011-09-29 18:21:01 -0700497/**
498 * smack_bprm_set_creds - set creds for exec
499 * @bprm: the exec information
500 *
Lukasz Pawelczyk56638842014-03-11 17:07:05 +0100501 * Returns 0 if it gets a blob, -EPERM if exec forbidden and -ENOMEM otherwise
Casey Schauflerce8a4322011-09-29 18:21:01 -0700502 */
Casey Schaufler676dac42010-12-02 06:43:39 -0800503static int smack_bprm_set_creds(struct linux_binprm *bprm)
504{
Al Viro496ad9a2013-01-23 17:07:38 -0500505 struct inode *inode = file_inode(bprm->file);
Jarkko Sakkinen84088ba2011-10-07 09:27:53 +0300506 struct task_smack *bsp = bprm->cred->security;
Casey Schaufler676dac42010-12-02 06:43:39 -0800507 struct inode_smack *isp;
Casey Schaufler676dac42010-12-02 06:43:39 -0800508 int rc;
509
510 rc = cap_bprm_set_creds(bprm);
511 if (rc != 0)
512 return rc;
513
514 if (bprm->cred_prepared)
515 return 0;
516
Jarkko Sakkinen84088ba2011-10-07 09:27:53 +0300517 isp = inode->i_security;
518 if (isp->smk_task == NULL || isp->smk_task == bsp->smk_task)
Casey Schaufler676dac42010-12-02 06:43:39 -0800519 return 0;
520
Lukasz Pawelczyk56638842014-03-11 17:07:05 +0100521 if (bprm->unsafe & (LSM_UNSAFE_PTRACE | LSM_UNSAFE_PTRACE_CAP)) {
522 struct task_struct *tracer;
523 rc = 0;
524
525 rcu_read_lock();
526 tracer = ptrace_parent(current);
527 if (likely(tracer != NULL))
528 rc = smk_ptrace_rule_check(tracer,
529 isp->smk_task->smk_known,
530 PTRACE_MODE_ATTACH,
531 __func__);
532 rcu_read_unlock();
533
534 if (rc != 0)
535 return rc;
536 } else if (bprm->unsafe)
Jarkko Sakkinen84088ba2011-10-07 09:27:53 +0300537 return -EPERM;
Casey Schaufler676dac42010-12-02 06:43:39 -0800538
Jarkko Sakkinen84088ba2011-10-07 09:27:53 +0300539 bsp->smk_task = isp->smk_task;
540 bprm->per_clear |= PER_CLEAR_ON_SETID;
Casey Schaufler676dac42010-12-02 06:43:39 -0800541
542 return 0;
543}
544
Jarkko Sakkinen84088ba2011-10-07 09:27:53 +0300545/**
546 * smack_bprm_committing_creds - Prepare to install the new credentials
547 * from bprm.
548 *
549 * @bprm: binprm for exec
550 */
551static void smack_bprm_committing_creds(struct linux_binprm *bprm)
552{
553 struct task_smack *bsp = bprm->cred->security;
554
555 if (bsp->smk_task != bsp->smk_forked)
556 current->pdeath_signal = 0;
557}
558
559/**
560 * smack_bprm_secureexec - Return the decision to use secureexec.
561 * @bprm: binprm for exec
562 *
563 * Returns 0 on success.
564 */
565static int smack_bprm_secureexec(struct linux_binprm *bprm)
566{
567 struct task_smack *tsp = current_security();
568 int ret = cap_bprm_secureexec(bprm);
569
570 if (!ret && (tsp->smk_task != tsp->smk_forked))
571 ret = 1;
572
573 return ret;
574}
575
Casey Schaufler676dac42010-12-02 06:43:39 -0800576/*
Casey Schauflere114e472008-02-04 22:29:50 -0800577 * Inode hooks
578 */
579
580/**
581 * smack_inode_alloc_security - allocate an inode blob
Randy Dunlap251a2a92009-02-18 11:42:33 -0800582 * @inode: the inode in need of a blob
Casey Schauflere114e472008-02-04 22:29:50 -0800583 *
584 * Returns 0 if it gets a blob, -ENOMEM otherwise
585 */
586static int smack_inode_alloc_security(struct inode *inode)
587{
Casey Schaufler2f823ff2013-05-22 18:43:03 -0700588 struct smack_known *skp = smk_of_current();
589
590 inode->i_security = new_inode_smack(skp->smk_known);
Casey Schauflere114e472008-02-04 22:29:50 -0800591 if (inode->i_security == NULL)
592 return -ENOMEM;
593 return 0;
594}
595
596/**
597 * smack_inode_free_security - free an inode blob
Randy Dunlap251a2a92009-02-18 11:42:33 -0800598 * @inode: the inode with a blob
Casey Schauflere114e472008-02-04 22:29:50 -0800599 *
600 * Clears the blob pointer in inode
601 */
602static void smack_inode_free_security(struct inode *inode)
603{
604 kfree(inode->i_security);
605 inode->i_security = NULL;
606}
607
608/**
609 * smack_inode_init_security - copy out the smack from an inode
610 * @inode: the inode
611 * @dir: unused
Eric Paris2a7dba32011-02-01 11:05:39 -0500612 * @qstr: unused
Casey Schauflere114e472008-02-04 22:29:50 -0800613 * @name: where to put the attribute name
614 * @value: where to put the attribute value
615 * @len: where to put the length of the attribute
616 *
617 * Returns 0 if it all works out, -ENOMEM if there's no memory
618 */
619static int smack_inode_init_security(struct inode *inode, struct inode *dir,
Tetsuo Handa95489062013-07-25 05:44:02 +0900620 const struct qstr *qstr, const char **name,
Eric Paris2a7dba32011-02-01 11:05:39 -0500621 void **value, size_t *len)
Casey Schauflere114e472008-02-04 22:29:50 -0800622{
Casey Schaufler2267b132012-03-13 19:14:19 -0700623 struct inode_smack *issp = inode->i_security;
Casey Schaufler2f823ff2013-05-22 18:43:03 -0700624 struct smack_known *skp = smk_of_current();
Casey Schauflere114e472008-02-04 22:29:50 -0800625 char *isp = smk_of_inode(inode);
Jarkko Sakkinen5c6d1122010-12-07 13:34:01 +0200626 char *dsp = smk_of_inode(dir);
Casey Schaufler7898e1f2011-01-17 08:05:27 -0800627 int may;
Casey Schauflere114e472008-02-04 22:29:50 -0800628
Tetsuo Handa95489062013-07-25 05:44:02 +0900629 if (name)
630 *name = XATTR_SMACK_SUFFIX;
Casey Schauflere114e472008-02-04 22:29:50 -0800631
632 if (value) {
Casey Schaufler7898e1f2011-01-17 08:05:27 -0800633 rcu_read_lock();
Casey Schaufler2f823ff2013-05-22 18:43:03 -0700634 may = smk_access_entry(skp->smk_known, dsp, &skp->smk_rules);
Casey Schaufler7898e1f2011-01-17 08:05:27 -0800635 rcu_read_unlock();
Jarkko Sakkinen5c6d1122010-12-07 13:34:01 +0200636
637 /*
638 * If the access rule allows transmutation and
639 * the directory requests transmutation then
640 * by all means transmute.
Casey Schaufler2267b132012-03-13 19:14:19 -0700641 * Mark the inode as changed.
Jarkko Sakkinen5c6d1122010-12-07 13:34:01 +0200642 */
Casey Schaufler7898e1f2011-01-17 08:05:27 -0800643 if (may > 0 && ((may & MAY_TRANSMUTE) != 0) &&
Casey Schaufler2267b132012-03-13 19:14:19 -0700644 smk_inode_transmutable(dir)) {
Jarkko Sakkinen5c6d1122010-12-07 13:34:01 +0200645 isp = dsp;
Casey Schaufler2267b132012-03-13 19:14:19 -0700646 issp->smk_flags |= SMK_INODE_CHANGED;
647 }
Jarkko Sakkinen5c6d1122010-12-07 13:34:01 +0200648
Tetsuo Handaceffec552012-03-29 16:19:05 +0900649 *value = kstrdup(isp, GFP_NOFS);
Casey Schauflere114e472008-02-04 22:29:50 -0800650 if (*value == NULL)
651 return -ENOMEM;
652 }
653
654 if (len)
655 *len = strlen(isp) + 1;
656
657 return 0;
658}
659
660/**
661 * smack_inode_link - Smack check on link
662 * @old_dentry: the existing object
663 * @dir: unused
664 * @new_dentry: the new object
665 *
666 * Returns 0 if access is permitted, an error code otherwise
667 */
668static int smack_inode_link(struct dentry *old_dentry, struct inode *dir,
669 struct dentry *new_dentry)
670{
Casey Schauflere114e472008-02-04 22:29:50 -0800671 char *isp;
Etienne Bassetecfcc532009-04-08 20:40:06 +0200672 struct smk_audit_info ad;
673 int rc;
674
Eric Parisa2694342011-04-25 13:10:27 -0400675 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
Etienne Bassetecfcc532009-04-08 20:40:06 +0200676 smk_ad_setfield_u_fs_path_dentry(&ad, old_dentry);
Casey Schauflere114e472008-02-04 22:29:50 -0800677
678 isp = smk_of_inode(old_dentry->d_inode);
Etienne Bassetecfcc532009-04-08 20:40:06 +0200679 rc = smk_curacc(isp, MAY_WRITE, &ad);
Casey Schauflere114e472008-02-04 22:29:50 -0800680
681 if (rc == 0 && new_dentry->d_inode != NULL) {
682 isp = smk_of_inode(new_dentry->d_inode);
Etienne Bassetecfcc532009-04-08 20:40:06 +0200683 smk_ad_setfield_u_fs_path_dentry(&ad, new_dentry);
684 rc = smk_curacc(isp, MAY_WRITE, &ad);
Casey Schauflere114e472008-02-04 22:29:50 -0800685 }
686
687 return rc;
688}
689
690/**
691 * smack_inode_unlink - Smack check on inode deletion
692 * @dir: containing directory object
693 * @dentry: file to unlink
694 *
695 * Returns 0 if current can write the containing directory
696 * and the object, error code otherwise
697 */
698static int smack_inode_unlink(struct inode *dir, struct dentry *dentry)
699{
700 struct inode *ip = dentry->d_inode;
Etienne Bassetecfcc532009-04-08 20:40:06 +0200701 struct smk_audit_info ad;
Casey Schauflere114e472008-02-04 22:29:50 -0800702 int rc;
703
Eric Parisa2694342011-04-25 13:10:27 -0400704 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
Etienne Bassetecfcc532009-04-08 20:40:06 +0200705 smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
706
Casey Schauflere114e472008-02-04 22:29:50 -0800707 /*
708 * You need write access to the thing you're unlinking
709 */
Etienne Bassetecfcc532009-04-08 20:40:06 +0200710 rc = smk_curacc(smk_of_inode(ip), MAY_WRITE, &ad);
711 if (rc == 0) {
Casey Schauflere114e472008-02-04 22:29:50 -0800712 /*
713 * You also need write access to the containing directory
714 */
Igor Zhbanovcdb56b62013-03-19 13:49:47 +0400715 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_INODE);
Etienne Bassetecfcc532009-04-08 20:40:06 +0200716 smk_ad_setfield_u_fs_inode(&ad, dir);
717 rc = smk_curacc(smk_of_inode(dir), MAY_WRITE, &ad);
718 }
Casey Schauflere114e472008-02-04 22:29:50 -0800719 return rc;
720}
721
722/**
723 * smack_inode_rmdir - Smack check on directory deletion
724 * @dir: containing directory object
725 * @dentry: directory to unlink
726 *
727 * Returns 0 if current can write the containing directory
728 * and the directory, error code otherwise
729 */
730static int smack_inode_rmdir(struct inode *dir, struct dentry *dentry)
731{
Etienne Bassetecfcc532009-04-08 20:40:06 +0200732 struct smk_audit_info ad;
Casey Schauflere114e472008-02-04 22:29:50 -0800733 int rc;
734
Eric Parisa2694342011-04-25 13:10:27 -0400735 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
Etienne Bassetecfcc532009-04-08 20:40:06 +0200736 smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
737
Casey Schauflere114e472008-02-04 22:29:50 -0800738 /*
739 * You need write access to the thing you're removing
740 */
Etienne Bassetecfcc532009-04-08 20:40:06 +0200741 rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE, &ad);
742 if (rc == 0) {
Casey Schauflere114e472008-02-04 22:29:50 -0800743 /*
744 * You also need write access to the containing directory
745 */
Igor Zhbanovcdb56b62013-03-19 13:49:47 +0400746 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_INODE);
Etienne Bassetecfcc532009-04-08 20:40:06 +0200747 smk_ad_setfield_u_fs_inode(&ad, dir);
748 rc = smk_curacc(smk_of_inode(dir), MAY_WRITE, &ad);
749 }
Casey Schauflere114e472008-02-04 22:29:50 -0800750
751 return rc;
752}
753
754/**
755 * smack_inode_rename - Smack check on rename
756 * @old_inode: the old directory
757 * @old_dentry: unused
758 * @new_inode: the new directory
759 * @new_dentry: unused
760 *
761 * Read and write access is required on both the old and
762 * new directories.
763 *
764 * Returns 0 if access is permitted, an error code otherwise
765 */
766static int smack_inode_rename(struct inode *old_inode,
767 struct dentry *old_dentry,
768 struct inode *new_inode,
769 struct dentry *new_dentry)
770{
771 int rc;
772 char *isp;
Etienne Bassetecfcc532009-04-08 20:40:06 +0200773 struct smk_audit_info ad;
774
Eric Parisa2694342011-04-25 13:10:27 -0400775 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
Etienne Bassetecfcc532009-04-08 20:40:06 +0200776 smk_ad_setfield_u_fs_path_dentry(&ad, old_dentry);
Casey Schauflere114e472008-02-04 22:29:50 -0800777
778 isp = smk_of_inode(old_dentry->d_inode);
Etienne Bassetecfcc532009-04-08 20:40:06 +0200779 rc = smk_curacc(isp, MAY_READWRITE, &ad);
Casey Schauflere114e472008-02-04 22:29:50 -0800780
781 if (rc == 0 && new_dentry->d_inode != NULL) {
782 isp = smk_of_inode(new_dentry->d_inode);
Etienne Bassetecfcc532009-04-08 20:40:06 +0200783 smk_ad_setfield_u_fs_path_dentry(&ad, new_dentry);
784 rc = smk_curacc(isp, MAY_READWRITE, &ad);
Casey Schauflere114e472008-02-04 22:29:50 -0800785 }
Casey Schauflere114e472008-02-04 22:29:50 -0800786 return rc;
787}
788
789/**
790 * smack_inode_permission - Smack version of permission()
791 * @inode: the inode in question
792 * @mask: the access requested
Casey Schauflere114e472008-02-04 22:29:50 -0800793 *
794 * This is the important Smack hook.
795 *
796 * Returns 0 if access is permitted, -EACCES otherwise
797 */
Al Viroe74f71e2011-06-20 19:38:15 -0400798static int smack_inode_permission(struct inode *inode, int mask)
Casey Schauflere114e472008-02-04 22:29:50 -0800799{
Etienne Bassetecfcc532009-04-08 20:40:06 +0200800 struct smk_audit_info ad;
Al Viroe74f71e2011-06-20 19:38:15 -0400801 int no_block = mask & MAY_NOT_BLOCK;
Eric Parisd09ca732010-07-23 11:43:57 -0400802
803 mask &= (MAY_READ|MAY_WRITE|MAY_EXEC|MAY_APPEND);
Casey Schauflere114e472008-02-04 22:29:50 -0800804 /*
805 * No permission to check. Existence test. Yup, it's there.
806 */
807 if (mask == 0)
808 return 0;
Andi Kleen8c9e80e2011-04-21 17:23:19 -0700809
810 /* May be droppable after audit */
Al Viroe74f71e2011-06-20 19:38:15 -0400811 if (no_block)
Andi Kleen8c9e80e2011-04-21 17:23:19 -0700812 return -ECHILD;
Eric Parisf48b7392011-04-25 12:54:27 -0400813 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_INODE);
Etienne Bassetecfcc532009-04-08 20:40:06 +0200814 smk_ad_setfield_u_fs_inode(&ad, inode);
815 return smk_curacc(smk_of_inode(inode), mask, &ad);
Casey Schauflere114e472008-02-04 22:29:50 -0800816}
817
818/**
819 * smack_inode_setattr - Smack check for setting attributes
820 * @dentry: the object
821 * @iattr: for the force flag
822 *
823 * Returns 0 if access is permitted, an error code otherwise
824 */
825static int smack_inode_setattr(struct dentry *dentry, struct iattr *iattr)
826{
Etienne Bassetecfcc532009-04-08 20:40:06 +0200827 struct smk_audit_info ad;
Casey Schauflere114e472008-02-04 22:29:50 -0800828 /*
829 * Need to allow for clearing the setuid bit.
830 */
831 if (iattr->ia_valid & ATTR_FORCE)
832 return 0;
Eric Parisa2694342011-04-25 13:10:27 -0400833 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
Etienne Bassetecfcc532009-04-08 20:40:06 +0200834 smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
Casey Schauflere114e472008-02-04 22:29:50 -0800835
Etienne Bassetecfcc532009-04-08 20:40:06 +0200836 return smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE, &ad);
Casey Schauflere114e472008-02-04 22:29:50 -0800837}
838
839/**
840 * smack_inode_getattr - Smack check for getting attributes
841 * @mnt: unused
842 * @dentry: the object
843 *
844 * Returns 0 if access is permitted, an error code otherwise
845 */
846static int smack_inode_getattr(struct vfsmount *mnt, struct dentry *dentry)
847{
Etienne Bassetecfcc532009-04-08 20:40:06 +0200848 struct smk_audit_info ad;
Eric Parisa2694342011-04-25 13:10:27 -0400849 struct path path;
Etienne Bassetecfcc532009-04-08 20:40:06 +0200850
Eric Parisa2694342011-04-25 13:10:27 -0400851 path.dentry = dentry;
852 path.mnt = mnt;
Etienne Bassetecfcc532009-04-08 20:40:06 +0200853
Eric Parisf48b7392011-04-25 12:54:27 -0400854 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
Eric Parisa2694342011-04-25 13:10:27 -0400855 smk_ad_setfield_u_fs_path(&ad, path);
Etienne Bassetecfcc532009-04-08 20:40:06 +0200856 return smk_curacc(smk_of_inode(dentry->d_inode), MAY_READ, &ad);
Casey Schauflere114e472008-02-04 22:29:50 -0800857}
858
859/**
860 * smack_inode_setxattr - Smack check for setting xattrs
861 * @dentry: the object
862 * @name: name of the attribute
863 * @value: unused
864 * @size: unused
865 * @flags: unused
866 *
867 * This protects the Smack attribute explicitly.
868 *
869 * Returns 0 if access is permitted, an error code otherwise
870 */
David Howells8f0cfa52008-04-29 00:59:41 -0700871static int smack_inode_setxattr(struct dentry *dentry, const char *name,
872 const void *value, size_t size, int flags)
Casey Schauflere114e472008-02-04 22:29:50 -0800873{
Etienne Bassetecfcc532009-04-08 20:40:06 +0200874 struct smk_audit_info ad;
Casey Schaufler19760ad2013-12-16 16:27:26 -0800875 struct smack_known *skp;
876 int check_priv = 0;
877 int check_import = 0;
878 int check_star = 0;
Casey Schauflerbcdca222008-02-23 15:24:04 -0800879 int rc = 0;
Casey Schauflere114e472008-02-04 22:29:50 -0800880
Casey Schaufler19760ad2013-12-16 16:27:26 -0800881 /*
882 * Check label validity here so import won't fail in post_setxattr
883 */
Casey Schauflerbcdca222008-02-23 15:24:04 -0800884 if (strcmp(name, XATTR_NAME_SMACK) == 0 ||
885 strcmp(name, XATTR_NAME_SMACKIPIN) == 0 ||
Casey Schaufler19760ad2013-12-16 16:27:26 -0800886 strcmp(name, XATTR_NAME_SMACKIPOUT) == 0) {
887 check_priv = 1;
888 check_import = 1;
889 } else if (strcmp(name, XATTR_NAME_SMACKEXEC) == 0 ||
890 strcmp(name, XATTR_NAME_SMACKMMAP) == 0) {
891 check_priv = 1;
892 check_import = 1;
893 check_star = 1;
Jarkko Sakkinen5c6d1122010-12-07 13:34:01 +0200894 } else if (strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0) {
Casey Schaufler19760ad2013-12-16 16:27:26 -0800895 check_priv = 1;
Jarkko Sakkinen5c6d1122010-12-07 13:34:01 +0200896 if (size != TRANS_TRUE_SIZE ||
897 strncmp(value, TRANS_TRUE, TRANS_TRUE_SIZE) != 0)
898 rc = -EINVAL;
Casey Schauflerbcdca222008-02-23 15:24:04 -0800899 } else
900 rc = cap_inode_setxattr(dentry, name, value, size, flags);
901
Casey Schaufler19760ad2013-12-16 16:27:26 -0800902 if (check_priv && !smack_privileged(CAP_MAC_ADMIN))
903 rc = -EPERM;
904
905 if (rc == 0 && check_import) {
906 skp = smk_import_entry(value, size);
907 if (skp == NULL || (check_star &&
908 (skp == &smack_known_star || skp == &smack_known_web)))
909 rc = -EINVAL;
910 }
911
Eric Parisa2694342011-04-25 13:10:27 -0400912 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
Etienne Bassetecfcc532009-04-08 20:40:06 +0200913 smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
914
Casey Schauflerbcdca222008-02-23 15:24:04 -0800915 if (rc == 0)
Etienne Bassetecfcc532009-04-08 20:40:06 +0200916 rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE, &ad);
Casey Schauflerbcdca222008-02-23 15:24:04 -0800917
918 return rc;
Casey Schauflere114e472008-02-04 22:29:50 -0800919}
920
921/**
922 * smack_inode_post_setxattr - Apply the Smack update approved above
923 * @dentry: object
924 * @name: attribute name
925 * @value: attribute value
926 * @size: attribute size
927 * @flags: unused
928 *
929 * Set the pointer in the inode blob to the entry found
930 * in the master label list.
931 */
David Howells8f0cfa52008-04-29 00:59:41 -0700932static void smack_inode_post_setxattr(struct dentry *dentry, const char *name,
933 const void *value, size_t size, int flags)
Casey Schauflere114e472008-02-04 22:29:50 -0800934{
Casey Schaufler2f823ff2013-05-22 18:43:03 -0700935 struct smack_known *skp;
Jarkko Sakkinen5c6d1122010-12-07 13:34:01 +0200936 struct inode_smack *isp = dentry->d_inode->i_security;
Casey Schaufler676dac42010-12-02 06:43:39 -0800937
Casey Schaufler2f823ff2013-05-22 18:43:03 -0700938 if (strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0) {
939 isp->smk_flags |= SMK_INODE_TRANSMUTE;
940 return;
941 }
942
943 skp = smk_import_entry(value, size);
Casey Schaufler676dac42010-12-02 06:43:39 -0800944 if (strcmp(name, XATTR_NAME_SMACK) == 0) {
Casey Schaufler2f823ff2013-05-22 18:43:03 -0700945 if (skp != NULL)
946 isp->smk_inode = skp->smk_known;
Casey Schaufler676dac42010-12-02 06:43:39 -0800947 else
948 isp->smk_inode = smack_known_invalid.smk_known;
Jarkko Sakkinen5c6d1122010-12-07 13:34:01 +0200949 } else if (strcmp(name, XATTR_NAME_SMACKEXEC) == 0) {
Casey Schaufler2f823ff2013-05-22 18:43:03 -0700950 if (skp != NULL)
951 isp->smk_task = skp;
Casey Schaufler676dac42010-12-02 06:43:39 -0800952 else
Casey Schaufler2f823ff2013-05-22 18:43:03 -0700953 isp->smk_task = &smack_known_invalid;
Casey Schaufler7898e1f2011-01-17 08:05:27 -0800954 } else if (strcmp(name, XATTR_NAME_SMACKMMAP) == 0) {
Casey Schaufler2f823ff2013-05-22 18:43:03 -0700955 if (skp != NULL)
956 isp->smk_mmap = skp;
Casey Schaufler7898e1f2011-01-17 08:05:27 -0800957 else
Casey Schaufler2f823ff2013-05-22 18:43:03 -0700958 isp->smk_mmap = &smack_known_invalid;
959 }
Casey Schauflere114e472008-02-04 22:29:50 -0800960
961 return;
962}
963
Casey Schauflerce8a4322011-09-29 18:21:01 -0700964/**
Casey Schauflere114e472008-02-04 22:29:50 -0800965 * smack_inode_getxattr - Smack check on getxattr
966 * @dentry: the object
967 * @name: unused
968 *
969 * Returns 0 if access is permitted, an error code otherwise
970 */
David Howells8f0cfa52008-04-29 00:59:41 -0700971static int smack_inode_getxattr(struct dentry *dentry, const char *name)
Casey Schauflere114e472008-02-04 22:29:50 -0800972{
Etienne Bassetecfcc532009-04-08 20:40:06 +0200973 struct smk_audit_info ad;
974
Eric Parisa2694342011-04-25 13:10:27 -0400975 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
Etienne Bassetecfcc532009-04-08 20:40:06 +0200976 smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
977
978 return smk_curacc(smk_of_inode(dentry->d_inode), MAY_READ, &ad);
Casey Schauflere114e472008-02-04 22:29:50 -0800979}
980
Casey Schauflerce8a4322011-09-29 18:21:01 -0700981/**
Casey Schauflere114e472008-02-04 22:29:50 -0800982 * smack_inode_removexattr - Smack check on removexattr
983 * @dentry: the object
984 * @name: name of the attribute
985 *
986 * Removing the Smack attribute requires CAP_MAC_ADMIN
987 *
988 * Returns 0 if access is permitted, an error code otherwise
989 */
David Howells8f0cfa52008-04-29 00:59:41 -0700990static int smack_inode_removexattr(struct dentry *dentry, const char *name)
Casey Schauflere114e472008-02-04 22:29:50 -0800991{
Casey Schaufler676dac42010-12-02 06:43:39 -0800992 struct inode_smack *isp;
Etienne Bassetecfcc532009-04-08 20:40:06 +0200993 struct smk_audit_info ad;
Casey Schauflerbcdca222008-02-23 15:24:04 -0800994 int rc = 0;
Casey Schauflere114e472008-02-04 22:29:50 -0800995
Casey Schauflerbcdca222008-02-23 15:24:04 -0800996 if (strcmp(name, XATTR_NAME_SMACK) == 0 ||
997 strcmp(name, XATTR_NAME_SMACKIPIN) == 0 ||
Casey Schaufler676dac42010-12-02 06:43:39 -0800998 strcmp(name, XATTR_NAME_SMACKIPOUT) == 0 ||
Jarkko Sakkinen5c6d1122010-12-07 13:34:01 +0200999 strcmp(name, XATTR_NAME_SMACKEXEC) == 0 ||
Casey Schaufler7898e1f2011-01-17 08:05:27 -08001000 strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0 ||
1001 strcmp(name, XATTR_NAME_SMACKMMAP)) {
Casey Schaufler1880eff2012-06-05 15:28:30 -07001002 if (!smack_privileged(CAP_MAC_ADMIN))
Casey Schauflerbcdca222008-02-23 15:24:04 -08001003 rc = -EPERM;
1004 } else
1005 rc = cap_inode_removexattr(dentry, name);
1006
Eric Parisa2694342011-04-25 13:10:27 -04001007 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
Etienne Bassetecfcc532009-04-08 20:40:06 +02001008 smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
Casey Schauflerbcdca222008-02-23 15:24:04 -08001009 if (rc == 0)
Etienne Bassetecfcc532009-04-08 20:40:06 +02001010 rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE, &ad);
Casey Schauflerbcdca222008-02-23 15:24:04 -08001011
Casey Schaufler676dac42010-12-02 06:43:39 -08001012 if (rc == 0) {
1013 isp = dentry->d_inode->i_security;
1014 isp->smk_task = NULL;
Casey Schaufler7898e1f2011-01-17 08:05:27 -08001015 isp->smk_mmap = NULL;
Casey Schaufler676dac42010-12-02 06:43:39 -08001016 }
1017
Casey Schauflerbcdca222008-02-23 15:24:04 -08001018 return rc;
Casey Schauflere114e472008-02-04 22:29:50 -08001019}
1020
1021/**
1022 * smack_inode_getsecurity - get smack xattrs
1023 * @inode: the object
1024 * @name: attribute name
1025 * @buffer: where to put the result
Randy Dunlap251a2a92009-02-18 11:42:33 -08001026 * @alloc: unused
Casey Schauflere114e472008-02-04 22:29:50 -08001027 *
1028 * Returns the size of the attribute or an error code
1029 */
1030static int smack_inode_getsecurity(const struct inode *inode,
1031 const char *name, void **buffer,
1032 bool alloc)
1033{
1034 struct socket_smack *ssp;
1035 struct socket *sock;
1036 struct super_block *sbp;
1037 struct inode *ip = (struct inode *)inode;
1038 char *isp;
1039 int ilen;
1040 int rc = 0;
1041
1042 if (strcmp(name, XATTR_SMACK_SUFFIX) == 0) {
1043 isp = smk_of_inode(inode);
1044 ilen = strlen(isp) + 1;
1045 *buffer = isp;
1046 return ilen;
1047 }
1048
1049 /*
1050 * The rest of the Smack xattrs are only on sockets.
1051 */
1052 sbp = ip->i_sb;
1053 if (sbp->s_magic != SOCKFS_MAGIC)
1054 return -EOPNOTSUPP;
1055
1056 sock = SOCKET_I(ip);
Ahmed S. Darwish2e1d1462008-02-13 15:03:34 -08001057 if (sock == NULL || sock->sk == NULL)
Casey Schauflere114e472008-02-04 22:29:50 -08001058 return -EOPNOTSUPP;
1059
1060 ssp = sock->sk->sk_security;
1061
1062 if (strcmp(name, XATTR_SMACK_IPIN) == 0)
1063 isp = ssp->smk_in;
1064 else if (strcmp(name, XATTR_SMACK_IPOUT) == 0)
Casey Schaufler2f823ff2013-05-22 18:43:03 -07001065 isp = ssp->smk_out->smk_known;
Casey Schauflere114e472008-02-04 22:29:50 -08001066 else
1067 return -EOPNOTSUPP;
1068
1069 ilen = strlen(isp) + 1;
1070 if (rc == 0) {
1071 *buffer = isp;
1072 rc = ilen;
1073 }
1074
1075 return rc;
1076}
1077
1078
1079/**
1080 * smack_inode_listsecurity - list the Smack attributes
1081 * @inode: the object
1082 * @buffer: where they go
1083 * @buffer_size: size of buffer
1084 *
1085 * Returns 0 on success, -EINVAL otherwise
1086 */
1087static int smack_inode_listsecurity(struct inode *inode, char *buffer,
1088 size_t buffer_size)
1089{
1090 int len = strlen(XATTR_NAME_SMACK);
1091
1092 if (buffer != NULL && len <= buffer_size) {
1093 memcpy(buffer, XATTR_NAME_SMACK, len);
1094 return len;
1095 }
1096 return -EINVAL;
1097}
1098
Ahmed S. Darwishd20bdda2008-04-30 08:34:10 +10001099/**
1100 * smack_inode_getsecid - Extract inode's security id
1101 * @inode: inode to extract the info from
1102 * @secid: where result will be saved
1103 */
1104static void smack_inode_getsecid(const struct inode *inode, u32 *secid)
1105{
1106 struct inode_smack *isp = inode->i_security;
1107
1108 *secid = smack_to_secid(isp->smk_inode);
1109}
1110
Casey Schauflere114e472008-02-04 22:29:50 -08001111/*
1112 * File Hooks
1113 */
1114
1115/**
1116 * smack_file_permission - Smack check on file operations
1117 * @file: unused
1118 * @mask: unused
1119 *
1120 * Returns 0
1121 *
1122 * Should access checks be done on each read or write?
1123 * UNICOS and SELinux say yes.
1124 * Trusted Solaris, Trusted Irix, and just about everyone else says no.
1125 *
1126 * I'll say no for now. Smack does not do the frequent
1127 * label changing that SELinux does.
1128 */
1129static int smack_file_permission(struct file *file, int mask)
1130{
1131 return 0;
1132}
1133
1134/**
1135 * smack_file_alloc_security - assign a file security blob
1136 * @file: the object
1137 *
1138 * The security blob for a file is a pointer to the master
1139 * label list, so no allocation is done.
1140 *
1141 * Returns 0
1142 */
1143static int smack_file_alloc_security(struct file *file)
1144{
Casey Schaufler2f823ff2013-05-22 18:43:03 -07001145 struct smack_known *skp = smk_of_current();
1146
1147 file->f_security = skp->smk_known;
Casey Schauflere114e472008-02-04 22:29:50 -08001148 return 0;
1149}
1150
1151/**
1152 * smack_file_free_security - clear a file security blob
1153 * @file: the object
1154 *
1155 * The security blob for a file is a pointer to the master
1156 * label list, so no memory is freed.
1157 */
1158static void smack_file_free_security(struct file *file)
1159{
1160 file->f_security = NULL;
1161}
1162
1163/**
1164 * smack_file_ioctl - Smack check on ioctls
1165 * @file: the object
1166 * @cmd: what to do
1167 * @arg: unused
1168 *
1169 * Relies heavily on the correct use of the ioctl command conventions.
1170 *
1171 * Returns 0 if allowed, error code otherwise
1172 */
1173static int smack_file_ioctl(struct file *file, unsigned int cmd,
1174 unsigned long arg)
1175{
1176 int rc = 0;
Etienne Bassetecfcc532009-04-08 20:40:06 +02001177 struct smk_audit_info ad;
1178
Eric Parisf48b7392011-04-25 12:54:27 -04001179 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
Etienne Bassetecfcc532009-04-08 20:40:06 +02001180 smk_ad_setfield_u_fs_path(&ad, file->f_path);
Casey Schauflere114e472008-02-04 22:29:50 -08001181
1182 if (_IOC_DIR(cmd) & _IOC_WRITE)
Etienne Bassetecfcc532009-04-08 20:40:06 +02001183 rc = smk_curacc(file->f_security, MAY_WRITE, &ad);
Casey Schauflere114e472008-02-04 22:29:50 -08001184
1185 if (rc == 0 && (_IOC_DIR(cmd) & _IOC_READ))
Etienne Bassetecfcc532009-04-08 20:40:06 +02001186 rc = smk_curacc(file->f_security, MAY_READ, &ad);
Casey Schauflere114e472008-02-04 22:29:50 -08001187
1188 return rc;
1189}
1190
1191/**
1192 * smack_file_lock - Smack check on file locking
1193 * @file: the object
Randy Dunlap251a2a92009-02-18 11:42:33 -08001194 * @cmd: unused
Casey Schauflere114e472008-02-04 22:29:50 -08001195 *
Casey Schauflerc0ab6e52013-10-11 18:06:39 -07001196 * Returns 0 if current has lock access, error code otherwise
Casey Schauflere114e472008-02-04 22:29:50 -08001197 */
1198static int smack_file_lock(struct file *file, unsigned int cmd)
1199{
Etienne Bassetecfcc532009-04-08 20:40:06 +02001200 struct smk_audit_info ad;
1201
Eric Paris92f42502011-04-25 13:15:55 -04001202 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
1203 smk_ad_setfield_u_fs_path(&ad, file->f_path);
Casey Schauflerc0ab6e52013-10-11 18:06:39 -07001204 return smk_curacc(file->f_security, MAY_LOCK, &ad);
Casey Schauflere114e472008-02-04 22:29:50 -08001205}
1206
1207/**
1208 * smack_file_fcntl - Smack check on fcntl
1209 * @file: the object
1210 * @cmd: what action to check
1211 * @arg: unused
1212 *
Casey Schaufler531f1d42011-09-19 12:41:42 -07001213 * Generally these operations are harmless.
1214 * File locking operations present an obvious mechanism
1215 * for passing information, so they require write access.
1216 *
Casey Schauflere114e472008-02-04 22:29:50 -08001217 * Returns 0 if current has access, error code otherwise
1218 */
1219static int smack_file_fcntl(struct file *file, unsigned int cmd,
1220 unsigned long arg)
1221{
Etienne Bassetecfcc532009-04-08 20:40:06 +02001222 struct smk_audit_info ad;
Casey Schaufler531f1d42011-09-19 12:41:42 -07001223 int rc = 0;
Casey Schauflere114e472008-02-04 22:29:50 -08001224
Etienne Bassetecfcc532009-04-08 20:40:06 +02001225
Casey Schauflere114e472008-02-04 22:29:50 -08001226 switch (cmd) {
Casey Schauflere114e472008-02-04 22:29:50 -08001227 case F_GETLK:
Casey Schauflerc0ab6e52013-10-11 18:06:39 -07001228 break;
Casey Schauflere114e472008-02-04 22:29:50 -08001229 case F_SETLK:
1230 case F_SETLKW:
Casey Schauflerc0ab6e52013-10-11 18:06:39 -07001231 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
1232 smk_ad_setfield_u_fs_path(&ad, file->f_path);
1233 rc = smk_curacc(file->f_security, MAY_LOCK, &ad);
1234 break;
Casey Schauflere114e472008-02-04 22:29:50 -08001235 case F_SETOWN:
1236 case F_SETSIG:
Casey Schaufler531f1d42011-09-19 12:41:42 -07001237 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
1238 smk_ad_setfield_u_fs_path(&ad, file->f_path);
Etienne Bassetecfcc532009-04-08 20:40:06 +02001239 rc = smk_curacc(file->f_security, MAY_WRITE, &ad);
Casey Schauflere114e472008-02-04 22:29:50 -08001240 break;
1241 default:
Casey Schaufler531f1d42011-09-19 12:41:42 -07001242 break;
Casey Schauflere114e472008-02-04 22:29:50 -08001243 }
1244
1245 return rc;
1246}
1247
1248/**
Al Viroe5467852012-05-30 13:30:51 -04001249 * smack_mmap_file :
Casey Schaufler7898e1f2011-01-17 08:05:27 -08001250 * Check permissions for a mmap operation. The @file may be NULL, e.g.
1251 * if mapping anonymous memory.
1252 * @file contains the file structure for file to map (may be NULL).
1253 * @reqprot contains the protection requested by the application.
1254 * @prot contains the protection that will be applied by the kernel.
1255 * @flags contains the operational flags.
1256 * Return 0 if permission is granted.
1257 */
Al Viroe5467852012-05-30 13:30:51 -04001258static int smack_mmap_file(struct file *file,
Casey Schaufler7898e1f2011-01-17 08:05:27 -08001259 unsigned long reqprot, unsigned long prot,
Al Viroe5467852012-05-30 13:30:51 -04001260 unsigned long flags)
Casey Schaufler7898e1f2011-01-17 08:05:27 -08001261{
Casey Schaufler272cd7a2011-09-20 12:24:36 -07001262 struct smack_known *skp;
Casey Schaufler2f823ff2013-05-22 18:43:03 -07001263 struct smack_known *mkp;
Casey Schaufler7898e1f2011-01-17 08:05:27 -08001264 struct smack_rule *srp;
1265 struct task_smack *tsp;
Casey Schaufler0e0a0702011-02-08 16:36:24 -08001266 char *osmack;
Casey Schaufler7898e1f2011-01-17 08:05:27 -08001267 struct inode_smack *isp;
Casey Schaufler0e0a0702011-02-08 16:36:24 -08001268 int may;
1269 int mmay;
1270 int tmay;
Casey Schaufler7898e1f2011-01-17 08:05:27 -08001271 int rc;
1272
Al Viro496ad9a2013-01-23 17:07:38 -05001273 if (file == NULL)
Casey Schaufler7898e1f2011-01-17 08:05:27 -08001274 return 0;
1275
Al Viro496ad9a2013-01-23 17:07:38 -05001276 isp = file_inode(file)->i_security;
Casey Schaufler7898e1f2011-01-17 08:05:27 -08001277 if (isp->smk_mmap == NULL)
1278 return 0;
Casey Schaufler2f823ff2013-05-22 18:43:03 -07001279 mkp = isp->smk_mmap;
Casey Schaufler7898e1f2011-01-17 08:05:27 -08001280
1281 tsp = current_security();
Casey Schaufler2f823ff2013-05-22 18:43:03 -07001282 skp = smk_of_current();
Casey Schaufler7898e1f2011-01-17 08:05:27 -08001283 rc = 0;
1284
1285 rcu_read_lock();
1286 /*
1287 * For each Smack rule associated with the subject
1288 * label verify that the SMACK64MMAP also has access
1289 * to that rule's object label.
Casey Schaufler7898e1f2011-01-17 08:05:27 -08001290 */
Casey Schaufler272cd7a2011-09-20 12:24:36 -07001291 list_for_each_entry_rcu(srp, &skp->smk_rules, list) {
Casey Schaufler0e0a0702011-02-08 16:36:24 -08001292 osmack = srp->smk_object;
Casey Schaufler7898e1f2011-01-17 08:05:27 -08001293 /*
1294 * Matching labels always allows access.
1295 */
Casey Schaufler2f823ff2013-05-22 18:43:03 -07001296 if (mkp->smk_known == osmack)
Casey Schaufler0e0a0702011-02-08 16:36:24 -08001297 continue;
1298 /*
1299 * If there is a matching local rule take
1300 * that into account as well.
1301 */
Casey Schaufler2f823ff2013-05-22 18:43:03 -07001302 may = smk_access_entry(srp->smk_subject->smk_known, osmack,
Casey Schaufler0e0a0702011-02-08 16:36:24 -08001303 &tsp->smk_rules);
1304 if (may == -ENOENT)
1305 may = srp->smk_access;
1306 else
1307 may &= srp->smk_access;
1308 /*
1309 * If may is zero the SMACK64MMAP subject can't
1310 * possibly have less access.
1311 */
1312 if (may == 0)
Casey Schaufler7898e1f2011-01-17 08:05:27 -08001313 continue;
1314
Casey Schaufler0e0a0702011-02-08 16:36:24 -08001315 /*
1316 * Fetch the global list entry.
1317 * If there isn't one a SMACK64MMAP subject
1318 * can't have as much access as current.
1319 */
Casey Schaufler2f823ff2013-05-22 18:43:03 -07001320 mmay = smk_access_entry(mkp->smk_known, osmack,
1321 &mkp->smk_rules);
Casey Schaufler0e0a0702011-02-08 16:36:24 -08001322 if (mmay == -ENOENT) {
1323 rc = -EACCES;
Casey Schaufler7898e1f2011-01-17 08:05:27 -08001324 break;
Casey Schaufler0e0a0702011-02-08 16:36:24 -08001325 }
1326 /*
1327 * If there is a local entry it modifies the
1328 * potential access, too.
1329 */
Casey Schaufler2f823ff2013-05-22 18:43:03 -07001330 tmay = smk_access_entry(mkp->smk_known, osmack,
1331 &tsp->smk_rules);
Casey Schaufler0e0a0702011-02-08 16:36:24 -08001332 if (tmay != -ENOENT)
1333 mmay &= tmay;
1334
1335 /*
1336 * If there is any access available to current that is
1337 * not available to a SMACK64MMAP subject
1338 * deny access.
1339 */
Casey Schaufler75a25632011-02-09 19:58:42 -08001340 if ((may | mmay) != mmay) {
Casey Schaufler0e0a0702011-02-08 16:36:24 -08001341 rc = -EACCES;
1342 break;
1343 }
Casey Schaufler7898e1f2011-01-17 08:05:27 -08001344 }
1345
1346 rcu_read_unlock();
1347
1348 return rc;
1349}
1350
1351/**
Casey Schauflere114e472008-02-04 22:29:50 -08001352 * smack_file_set_fowner - set the file security blob value
1353 * @file: object in question
1354 *
1355 * Returns 0
1356 * Further research may be required on this one.
1357 */
1358static int smack_file_set_fowner(struct file *file)
1359{
Casey Schaufler2f823ff2013-05-22 18:43:03 -07001360 struct smack_known *skp = smk_of_current();
1361
1362 file->f_security = skp->smk_known;
Casey Schauflere114e472008-02-04 22:29:50 -08001363 return 0;
1364}
1365
1366/**
1367 * smack_file_send_sigiotask - Smack on sigio
1368 * @tsk: The target task
1369 * @fown: the object the signal come from
1370 * @signum: unused
1371 *
1372 * Allow a privileged task to get signals even if it shouldn't
1373 *
1374 * Returns 0 if a subject with the object's smack could
1375 * write to the task, an error code otherwise.
1376 */
1377static int smack_file_send_sigiotask(struct task_struct *tsk,
1378 struct fown_struct *fown, int signum)
1379{
Casey Schaufler2f823ff2013-05-22 18:43:03 -07001380 struct smack_known *skp;
1381 struct smack_known *tkp = smk_of_task(tsk->cred->security);
Casey Schauflere114e472008-02-04 22:29:50 -08001382 struct file *file;
1383 int rc;
Etienne Bassetecfcc532009-04-08 20:40:06 +02001384 struct smk_audit_info ad;
Casey Schauflere114e472008-02-04 22:29:50 -08001385
1386 /*
1387 * struct fown_struct is never outside the context of a struct file
1388 */
1389 file = container_of(fown, struct file, f_owner);
Casey Schaufler7898e1f2011-01-17 08:05:27 -08001390
Etienne Bassetecfcc532009-04-08 20:40:06 +02001391 /* we don't log here as rc can be overriden */
Casey Schaufler2f823ff2013-05-22 18:43:03 -07001392 skp = smk_find_entry(file->f_security);
1393 rc = smk_access(skp, tkp->smk_known, MAY_WRITE, NULL);
David Howells5cd9c582008-08-14 11:37:28 +01001394 if (rc != 0 && has_capability(tsk, CAP_MAC_OVERRIDE))
Etienne Bassetecfcc532009-04-08 20:40:06 +02001395 rc = 0;
1396
1397 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK);
1398 smk_ad_setfield_u_tsk(&ad, tsk);
Casey Schaufler2f823ff2013-05-22 18:43:03 -07001399 smack_log(file->f_security, tkp->smk_known, MAY_WRITE, rc, &ad);
Casey Schauflere114e472008-02-04 22:29:50 -08001400 return rc;
1401}
1402
1403/**
1404 * smack_file_receive - Smack file receive check
1405 * @file: the object
1406 *
1407 * Returns 0 if current has access, error code otherwise
1408 */
1409static int smack_file_receive(struct file *file)
1410{
1411 int may = 0;
Etienne Bassetecfcc532009-04-08 20:40:06 +02001412 struct smk_audit_info ad;
Casey Schauflere114e472008-02-04 22:29:50 -08001413
Casey Schaufler4482a442013-12-30 17:37:45 -08001414 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
Etienne Bassetecfcc532009-04-08 20:40:06 +02001415 smk_ad_setfield_u_fs_path(&ad, file->f_path);
Casey Schauflere114e472008-02-04 22:29:50 -08001416 /*
1417 * This code relies on bitmasks.
1418 */
1419 if (file->f_mode & FMODE_READ)
1420 may = MAY_READ;
1421 if (file->f_mode & FMODE_WRITE)
1422 may |= MAY_WRITE;
1423
Etienne Bassetecfcc532009-04-08 20:40:06 +02001424 return smk_curacc(file->f_security, may, &ad);
Casey Schauflere114e472008-02-04 22:29:50 -08001425}
1426
Casey Schaufler531f1d42011-09-19 12:41:42 -07001427/**
Eric Paris83d49852012-04-04 13:45:40 -04001428 * smack_file_open - Smack dentry open processing
Casey Schaufler531f1d42011-09-19 12:41:42 -07001429 * @file: the object
1430 * @cred: unused
1431 *
1432 * Set the security blob in the file structure.
1433 *
1434 * Returns 0
1435 */
Eric Paris83d49852012-04-04 13:45:40 -04001436static int smack_file_open(struct file *file, const struct cred *cred)
Casey Schaufler531f1d42011-09-19 12:41:42 -07001437{
Al Viro496ad9a2013-01-23 17:07:38 -05001438 struct inode_smack *isp = file_inode(file)->i_security;
Casey Schaufler531f1d42011-09-19 12:41:42 -07001439
1440 file->f_security = isp->smk_inode;
1441
1442 return 0;
1443}
1444
Casey Schauflere114e472008-02-04 22:29:50 -08001445/*
1446 * Task hooks
1447 */
1448
1449/**
David Howellsee18d642009-09-02 09:14:21 +01001450 * smack_cred_alloc_blank - "allocate" blank task-level security credentials
1451 * @new: the new credentials
1452 * @gfp: the atomicity of any memory allocations
1453 *
1454 * Prepare a blank set of credentials for modification. This must allocate all
1455 * the memory the LSM module might require such that cred_transfer() can
1456 * complete without error.
1457 */
1458static int smack_cred_alloc_blank(struct cred *cred, gfp_t gfp)
1459{
Casey Schaufler7898e1f2011-01-17 08:05:27 -08001460 struct task_smack *tsp;
1461
1462 tsp = new_task_smack(NULL, NULL, gfp);
1463 if (tsp == NULL)
Casey Schaufler676dac42010-12-02 06:43:39 -08001464 return -ENOMEM;
Casey Schaufler7898e1f2011-01-17 08:05:27 -08001465
1466 cred->security = tsp;
1467
David Howellsee18d642009-09-02 09:14:21 +01001468 return 0;
1469}
1470
1471
1472/**
David Howellsf1752ee2008-11-14 10:39:17 +11001473 * smack_cred_free - "free" task-level security credentials
1474 * @cred: the credentials in question
Casey Schauflere114e472008-02-04 22:29:50 -08001475 *
Casey Schauflere114e472008-02-04 22:29:50 -08001476 */
David Howellsf1752ee2008-11-14 10:39:17 +11001477static void smack_cred_free(struct cred *cred)
Casey Schauflere114e472008-02-04 22:29:50 -08001478{
Casey Schaufler7898e1f2011-01-17 08:05:27 -08001479 struct task_smack *tsp = cred->security;
1480 struct smack_rule *rp;
1481 struct list_head *l;
1482 struct list_head *n;
1483
1484 if (tsp == NULL)
1485 return;
1486 cred->security = NULL;
1487
1488 list_for_each_safe(l, n, &tsp->smk_rules) {
1489 rp = list_entry(l, struct smack_rule, list);
1490 list_del(&rp->list);
1491 kfree(rp);
1492 }
1493 kfree(tsp);
Casey Schauflere114e472008-02-04 22:29:50 -08001494}
1495
1496/**
David Howellsd84f4f92008-11-14 10:39:23 +11001497 * smack_cred_prepare - prepare new set of credentials for modification
1498 * @new: the new credentials
1499 * @old: the original credentials
1500 * @gfp: the atomicity of any memory allocations
1501 *
1502 * Prepare a new set of credentials for modification.
1503 */
1504static int smack_cred_prepare(struct cred *new, const struct cred *old,
1505 gfp_t gfp)
1506{
Casey Schaufler676dac42010-12-02 06:43:39 -08001507 struct task_smack *old_tsp = old->security;
1508 struct task_smack *new_tsp;
Casey Schaufler7898e1f2011-01-17 08:05:27 -08001509 int rc;
Casey Schaufler676dac42010-12-02 06:43:39 -08001510
Casey Schaufler7898e1f2011-01-17 08:05:27 -08001511 new_tsp = new_task_smack(old_tsp->smk_task, old_tsp->smk_task, gfp);
Casey Schaufler676dac42010-12-02 06:43:39 -08001512 if (new_tsp == NULL)
1513 return -ENOMEM;
1514
Casey Schaufler7898e1f2011-01-17 08:05:27 -08001515 rc = smk_copy_rules(&new_tsp->smk_rules, &old_tsp->smk_rules, gfp);
1516 if (rc != 0)
1517 return rc;
1518
Casey Schaufler676dac42010-12-02 06:43:39 -08001519 new->security = new_tsp;
David Howellsd84f4f92008-11-14 10:39:23 +11001520 return 0;
1521}
1522
Randy Dunlap251a2a92009-02-18 11:42:33 -08001523/**
David Howellsee18d642009-09-02 09:14:21 +01001524 * smack_cred_transfer - Transfer the old credentials to the new credentials
1525 * @new: the new credentials
1526 * @old: the original credentials
1527 *
1528 * Fill in a set of blank credentials from another set of credentials.
1529 */
1530static void smack_cred_transfer(struct cred *new, const struct cred *old)
1531{
Casey Schaufler676dac42010-12-02 06:43:39 -08001532 struct task_smack *old_tsp = old->security;
1533 struct task_smack *new_tsp = new->security;
1534
1535 new_tsp->smk_task = old_tsp->smk_task;
1536 new_tsp->smk_forked = old_tsp->smk_task;
Casey Schaufler7898e1f2011-01-17 08:05:27 -08001537 mutex_init(&new_tsp->smk_rules_lock);
1538 INIT_LIST_HEAD(&new_tsp->smk_rules);
1539
1540
1541 /* cbs copy rule list */
David Howellsee18d642009-09-02 09:14:21 +01001542}
1543
1544/**
David Howells3a3b7ce2008-11-14 10:39:28 +11001545 * smack_kernel_act_as - Set the subjective context in a set of credentials
Randy Dunlap251a2a92009-02-18 11:42:33 -08001546 * @new: points to the set of credentials to be modified.
1547 * @secid: specifies the security ID to be set
David Howells3a3b7ce2008-11-14 10:39:28 +11001548 *
1549 * Set the security data for a kernel service.
1550 */
1551static int smack_kernel_act_as(struct cred *new, u32 secid)
1552{
Casey Schaufler676dac42010-12-02 06:43:39 -08001553 struct task_smack *new_tsp = new->security;
Casey Schaufler2f823ff2013-05-22 18:43:03 -07001554 struct smack_known *skp = smack_from_secid(secid);
David Howells3a3b7ce2008-11-14 10:39:28 +11001555
Casey Schaufler2f823ff2013-05-22 18:43:03 -07001556 if (skp == NULL)
David Howells3a3b7ce2008-11-14 10:39:28 +11001557 return -EINVAL;
1558
Casey Schaufler2f823ff2013-05-22 18:43:03 -07001559 new_tsp->smk_task = skp;
David Howells3a3b7ce2008-11-14 10:39:28 +11001560 return 0;
1561}
1562
1563/**
1564 * smack_kernel_create_files_as - Set the file creation label in a set of creds
Randy Dunlap251a2a92009-02-18 11:42:33 -08001565 * @new: points to the set of credentials to be modified
1566 * @inode: points to the inode to use as a reference
David Howells3a3b7ce2008-11-14 10:39:28 +11001567 *
1568 * Set the file creation context in a set of credentials to the same
1569 * as the objective context of the specified inode
1570 */
1571static int smack_kernel_create_files_as(struct cred *new,
1572 struct inode *inode)
1573{
1574 struct inode_smack *isp = inode->i_security;
Casey Schaufler676dac42010-12-02 06:43:39 -08001575 struct task_smack *tsp = new->security;
David Howells3a3b7ce2008-11-14 10:39:28 +11001576
Casey Schaufler2f823ff2013-05-22 18:43:03 -07001577 tsp->smk_forked = smk_find_entry(isp->smk_inode);
1578 tsp->smk_task = tsp->smk_forked;
David Howells3a3b7ce2008-11-14 10:39:28 +11001579 return 0;
1580}
1581
1582/**
Etienne Bassetecfcc532009-04-08 20:40:06 +02001583 * smk_curacc_on_task - helper to log task related access
1584 * @p: the task object
Casey Schaufler531f1d42011-09-19 12:41:42 -07001585 * @access: the access requested
1586 * @caller: name of the calling function for audit
Etienne Bassetecfcc532009-04-08 20:40:06 +02001587 *
1588 * Return 0 if access is permitted
1589 */
Casey Schaufler531f1d42011-09-19 12:41:42 -07001590static int smk_curacc_on_task(struct task_struct *p, int access,
1591 const char *caller)
Etienne Bassetecfcc532009-04-08 20:40:06 +02001592{
1593 struct smk_audit_info ad;
Casey Schaufler2f823ff2013-05-22 18:43:03 -07001594 struct smack_known *skp = smk_of_task(task_security(p));
Etienne Bassetecfcc532009-04-08 20:40:06 +02001595
Casey Schaufler531f1d42011-09-19 12:41:42 -07001596 smk_ad_init(&ad, caller, LSM_AUDIT_DATA_TASK);
Etienne Bassetecfcc532009-04-08 20:40:06 +02001597 smk_ad_setfield_u_tsk(&ad, p);
Casey Schaufler2f823ff2013-05-22 18:43:03 -07001598 return smk_curacc(skp->smk_known, access, &ad);
Etienne Bassetecfcc532009-04-08 20:40:06 +02001599}
1600
1601/**
Casey Schauflere114e472008-02-04 22:29:50 -08001602 * smack_task_setpgid - Smack check on setting pgid
1603 * @p: the task object
1604 * @pgid: unused
1605 *
1606 * Return 0 if write access is permitted
1607 */
1608static int smack_task_setpgid(struct task_struct *p, pid_t pgid)
1609{
Casey Schaufler531f1d42011-09-19 12:41:42 -07001610 return smk_curacc_on_task(p, MAY_WRITE, __func__);
Casey Schauflere114e472008-02-04 22:29:50 -08001611}
1612
1613/**
1614 * smack_task_getpgid - Smack access check for getpgid
1615 * @p: the object task
1616 *
1617 * Returns 0 if current can read the object task, error code otherwise
1618 */
1619static int smack_task_getpgid(struct task_struct *p)
1620{
Casey Schaufler531f1d42011-09-19 12:41:42 -07001621 return smk_curacc_on_task(p, MAY_READ, __func__);
Casey Schauflere114e472008-02-04 22:29:50 -08001622}
1623
1624/**
1625 * smack_task_getsid - Smack access check for getsid
1626 * @p: the object task
1627 *
1628 * Returns 0 if current can read the object task, error code otherwise
1629 */
1630static int smack_task_getsid(struct task_struct *p)
1631{
Casey Schaufler531f1d42011-09-19 12:41:42 -07001632 return smk_curacc_on_task(p, MAY_READ, __func__);
Casey Schauflere114e472008-02-04 22:29:50 -08001633}
1634
1635/**
1636 * smack_task_getsecid - get the secid of the task
1637 * @p: the object task
1638 * @secid: where to put the result
1639 *
1640 * Sets the secid to contain a u32 version of the smack label.
1641 */
1642static void smack_task_getsecid(struct task_struct *p, u32 *secid)
1643{
Casey Schaufler2f823ff2013-05-22 18:43:03 -07001644 struct smack_known *skp = smk_of_task(task_security(p));
1645
1646 *secid = skp->smk_secid;
Casey Schauflere114e472008-02-04 22:29:50 -08001647}
1648
1649/**
1650 * smack_task_setnice - Smack check on setting nice
1651 * @p: the task object
1652 * @nice: unused
1653 *
1654 * Return 0 if write access is permitted
1655 */
1656static int smack_task_setnice(struct task_struct *p, int nice)
1657{
Casey Schauflerbcdca222008-02-23 15:24:04 -08001658 int rc;
1659
1660 rc = cap_task_setnice(p, nice);
1661 if (rc == 0)
Casey Schaufler531f1d42011-09-19 12:41:42 -07001662 rc = smk_curacc_on_task(p, MAY_WRITE, __func__);
Casey Schauflerbcdca222008-02-23 15:24:04 -08001663 return rc;
Casey Schauflere114e472008-02-04 22:29:50 -08001664}
1665
1666/**
1667 * smack_task_setioprio - Smack check on setting ioprio
1668 * @p: the task object
1669 * @ioprio: unused
1670 *
1671 * Return 0 if write access is permitted
1672 */
1673static int smack_task_setioprio(struct task_struct *p, int ioprio)
1674{
Casey Schauflerbcdca222008-02-23 15:24:04 -08001675 int rc;
1676
1677 rc = cap_task_setioprio(p, ioprio);
1678 if (rc == 0)
Casey Schaufler531f1d42011-09-19 12:41:42 -07001679 rc = smk_curacc_on_task(p, MAY_WRITE, __func__);
Casey Schauflerbcdca222008-02-23 15:24:04 -08001680 return rc;
Casey Schauflere114e472008-02-04 22:29:50 -08001681}
1682
1683/**
1684 * smack_task_getioprio - Smack check on reading ioprio
1685 * @p: the task object
1686 *
1687 * Return 0 if read access is permitted
1688 */
1689static int smack_task_getioprio(struct task_struct *p)
1690{
Casey Schaufler531f1d42011-09-19 12:41:42 -07001691 return smk_curacc_on_task(p, MAY_READ, __func__);
Casey Schauflere114e472008-02-04 22:29:50 -08001692}
1693
1694/**
1695 * smack_task_setscheduler - Smack check on setting scheduler
1696 * @p: the task object
1697 * @policy: unused
1698 * @lp: unused
1699 *
1700 * Return 0 if read access is permitted
1701 */
KOSAKI Motohirob0ae1982010-10-15 04:21:18 +09001702static int smack_task_setscheduler(struct task_struct *p)
Casey Schauflere114e472008-02-04 22:29:50 -08001703{
Casey Schauflerbcdca222008-02-23 15:24:04 -08001704 int rc;
1705
KOSAKI Motohirob0ae1982010-10-15 04:21:18 +09001706 rc = cap_task_setscheduler(p);
Casey Schauflerbcdca222008-02-23 15:24:04 -08001707 if (rc == 0)
Casey Schaufler531f1d42011-09-19 12:41:42 -07001708 rc = smk_curacc_on_task(p, MAY_WRITE, __func__);
Casey Schauflerbcdca222008-02-23 15:24:04 -08001709 return rc;
Casey Schauflere114e472008-02-04 22:29:50 -08001710}
1711
1712/**
1713 * smack_task_getscheduler - Smack check on reading scheduler
1714 * @p: the task object
1715 *
1716 * Return 0 if read access is permitted
1717 */
1718static int smack_task_getscheduler(struct task_struct *p)
1719{
Casey Schaufler531f1d42011-09-19 12:41:42 -07001720 return smk_curacc_on_task(p, MAY_READ, __func__);
Casey Schauflere114e472008-02-04 22:29:50 -08001721}
1722
1723/**
1724 * smack_task_movememory - Smack check on moving memory
1725 * @p: the task object
1726 *
1727 * Return 0 if write access is permitted
1728 */
1729static int smack_task_movememory(struct task_struct *p)
1730{
Casey Schaufler531f1d42011-09-19 12:41:42 -07001731 return smk_curacc_on_task(p, MAY_WRITE, __func__);
Casey Schauflere114e472008-02-04 22:29:50 -08001732}
1733
1734/**
1735 * smack_task_kill - Smack check on signal delivery
1736 * @p: the task object
1737 * @info: unused
1738 * @sig: unused
1739 * @secid: identifies the smack to use in lieu of current's
1740 *
1741 * Return 0 if write access is permitted
1742 *
1743 * The secid behavior is an artifact of an SELinux hack
1744 * in the USB code. Someday it may go away.
1745 */
1746static int smack_task_kill(struct task_struct *p, struct siginfo *info,
1747 int sig, u32 secid)
1748{
Etienne Bassetecfcc532009-04-08 20:40:06 +02001749 struct smk_audit_info ad;
Casey Schaufler2f823ff2013-05-22 18:43:03 -07001750 struct smack_known *skp;
1751 struct smack_known *tkp = smk_of_task(task_security(p));
Etienne Bassetecfcc532009-04-08 20:40:06 +02001752
1753 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK);
1754 smk_ad_setfield_u_tsk(&ad, p);
Casey Schauflere114e472008-02-04 22:29:50 -08001755 /*
Casey Schauflere114e472008-02-04 22:29:50 -08001756 * Sending a signal requires that the sender
1757 * can write the receiver.
1758 */
1759 if (secid == 0)
Casey Schaufler2f823ff2013-05-22 18:43:03 -07001760 return smk_curacc(tkp->smk_known, MAY_WRITE, &ad);
Casey Schauflere114e472008-02-04 22:29:50 -08001761 /*
1762 * If the secid isn't 0 we're dealing with some USB IO
1763 * specific behavior. This is not clean. For one thing
1764 * we can't take privilege into account.
1765 */
Casey Schaufler2f823ff2013-05-22 18:43:03 -07001766 skp = smack_from_secid(secid);
1767 return smk_access(skp, tkp->smk_known, MAY_WRITE, &ad);
Casey Schauflere114e472008-02-04 22:29:50 -08001768}
1769
1770/**
1771 * smack_task_wait - Smack access check for waiting
1772 * @p: task to wait for
1773 *
Casey Schauflerc00bedb2012-08-09 17:46:38 -07001774 * Returns 0
Casey Schauflere114e472008-02-04 22:29:50 -08001775 */
1776static int smack_task_wait(struct task_struct *p)
1777{
Casey Schauflere114e472008-02-04 22:29:50 -08001778 /*
Casey Schauflerc00bedb2012-08-09 17:46:38 -07001779 * Allow the operation to succeed.
1780 * Zombies are bad.
1781 * In userless environments (e.g. phones) programs
1782 * get marked with SMACK64EXEC and even if the parent
1783 * and child shouldn't be talking the parent still
1784 * may expect to know when the child exits.
Casey Schauflere114e472008-02-04 22:29:50 -08001785 */
Casey Schauflerc00bedb2012-08-09 17:46:38 -07001786 return 0;
Casey Schauflere114e472008-02-04 22:29:50 -08001787}
1788
1789/**
1790 * smack_task_to_inode - copy task smack into the inode blob
1791 * @p: task to copy from
Randy Dunlap251a2a92009-02-18 11:42:33 -08001792 * @inode: inode to copy to
Casey Schauflere114e472008-02-04 22:29:50 -08001793 *
1794 * Sets the smack pointer in the inode security blob
1795 */
1796static void smack_task_to_inode(struct task_struct *p, struct inode *inode)
1797{
1798 struct inode_smack *isp = inode->i_security;
Casey Schaufler2f823ff2013-05-22 18:43:03 -07001799 struct smack_known *skp = smk_of_task(task_security(p));
1800
1801 isp->smk_inode = skp->smk_known;
Casey Schauflere114e472008-02-04 22:29:50 -08001802}
1803
1804/*
1805 * Socket hooks.
1806 */
1807
1808/**
1809 * smack_sk_alloc_security - Allocate a socket blob
1810 * @sk: the socket
1811 * @family: unused
Randy Dunlap251a2a92009-02-18 11:42:33 -08001812 * @gfp_flags: memory allocation flags
Casey Schauflere114e472008-02-04 22:29:50 -08001813 *
1814 * Assign Smack pointers to current
1815 *
1816 * Returns 0 on success, -ENOMEM is there's no memory
1817 */
1818static int smack_sk_alloc_security(struct sock *sk, int family, gfp_t gfp_flags)
1819{
Casey Schaufler2f823ff2013-05-22 18:43:03 -07001820 struct smack_known *skp = smk_of_current();
Casey Schauflere114e472008-02-04 22:29:50 -08001821 struct socket_smack *ssp;
1822
1823 ssp = kzalloc(sizeof(struct socket_smack), gfp_flags);
1824 if (ssp == NULL)
1825 return -ENOMEM;
1826
Casey Schaufler2f823ff2013-05-22 18:43:03 -07001827 ssp->smk_in = skp->smk_known;
1828 ssp->smk_out = skp;
Casey Schaufler272cd7a2011-09-20 12:24:36 -07001829 ssp->smk_packet = NULL;
Casey Schauflere114e472008-02-04 22:29:50 -08001830
1831 sk->sk_security = ssp;
1832
1833 return 0;
1834}
1835
1836/**
1837 * smack_sk_free_security - Free a socket blob
1838 * @sk: the socket
1839 *
1840 * Clears the blob pointer
1841 */
1842static void smack_sk_free_security(struct sock *sk)
1843{
1844 kfree(sk->sk_security);
1845}
1846
1847/**
Paul Moore07feee82009-03-27 17:10:54 -04001848* smack_host_label - check host based restrictions
1849* @sip: the object end
1850*
1851* looks for host based access restrictions
1852*
1853* This version will only be appropriate for really small sets of single label
1854* hosts. The caller is responsible for ensuring that the RCU read lock is
1855* taken before calling this function.
1856*
1857* Returns the label of the far end or NULL if it's not special.
1858*/
1859static char *smack_host_label(struct sockaddr_in *sip)
1860{
1861 struct smk_netlbladdr *snp;
1862 struct in_addr *siap = &sip->sin_addr;
1863
1864 if (siap->s_addr == 0)
1865 return NULL;
1866
1867 list_for_each_entry_rcu(snp, &smk_netlbladdr_list, list)
1868 /*
1869 * we break after finding the first match because
1870 * the list is sorted from longest to shortest mask
1871 * so we have found the most specific match
1872 */
1873 if ((&snp->smk_host.sin_addr)->s_addr ==
Etienne Basset43031542009-03-27 17:11:01 -04001874 (siap->s_addr & (&snp->smk_mask)->s_addr)) {
1875 /* we have found the special CIPSO option */
1876 if (snp->smk_label == smack_cipso_option)
1877 return NULL;
Paul Moore07feee82009-03-27 17:10:54 -04001878 return snp->smk_label;
Etienne Basset43031542009-03-27 17:11:01 -04001879 }
Paul Moore07feee82009-03-27 17:10:54 -04001880
1881 return NULL;
1882}
1883
1884/**
Casey Schauflere114e472008-02-04 22:29:50 -08001885 * smack_netlabel - Set the secattr on a socket
1886 * @sk: the socket
Casey Schaufler6d3dc072008-12-31 12:54:12 -05001887 * @labeled: socket label scheme
Casey Schauflere114e472008-02-04 22:29:50 -08001888 *
1889 * Convert the outbound smack value (smk_out) to a
1890 * secattr and attach it to the socket.
1891 *
1892 * Returns 0 on success or an error code
1893 */
Casey Schaufler6d3dc072008-12-31 12:54:12 -05001894static int smack_netlabel(struct sock *sk, int labeled)
Casey Schauflere114e472008-02-04 22:29:50 -08001895{
Casey Schauflerf7112e62012-05-06 15:22:02 -07001896 struct smack_known *skp;
Paul Moore07feee82009-03-27 17:10:54 -04001897 struct socket_smack *ssp = sk->sk_security;
Casey Schaufler6d3dc072008-12-31 12:54:12 -05001898 int rc = 0;
Casey Schauflere114e472008-02-04 22:29:50 -08001899
Casey Schaufler6d3dc072008-12-31 12:54:12 -05001900 /*
1901 * Usually the netlabel code will handle changing the
1902 * packet labeling based on the label.
1903 * The case of a single label host is different, because
1904 * a single label host should never get a labeled packet
1905 * even though the label is usually associated with a packet
1906 * label.
1907 */
1908 local_bh_disable();
1909 bh_lock_sock_nested(sk);
1910
1911 if (ssp->smk_out == smack_net_ambient ||
1912 labeled == SMACK_UNLABELED_SOCKET)
1913 netlbl_sock_delattr(sk);
1914 else {
Casey Schaufler2f823ff2013-05-22 18:43:03 -07001915 skp = ssp->smk_out;
Casey Schauflerf7112e62012-05-06 15:22:02 -07001916 rc = netlbl_sock_setattr(sk, sk->sk_family, &skp->smk_netlabel);
Casey Schaufler6d3dc072008-12-31 12:54:12 -05001917 }
1918
1919 bh_unlock_sock(sk);
1920 local_bh_enable();
Casey Schaufler4bc87e62008-02-15 15:24:25 -08001921
Casey Schauflere114e472008-02-04 22:29:50 -08001922 return rc;
1923}
1924
1925/**
Paul Moore07feee82009-03-27 17:10:54 -04001926 * smack_netlbel_send - Set the secattr on a socket and perform access checks
1927 * @sk: the socket
1928 * @sap: the destination address
1929 *
1930 * Set the correct secattr for the given socket based on the destination
1931 * address and perform any outbound access checks needed.
1932 *
1933 * Returns 0 on success or an error code.
1934 *
1935 */
1936static int smack_netlabel_send(struct sock *sk, struct sockaddr_in *sap)
1937{
Casey Schaufler2f823ff2013-05-22 18:43:03 -07001938 struct smack_known *skp;
Paul Moore07feee82009-03-27 17:10:54 -04001939 int rc;
1940 int sk_lbl;
1941 char *hostsp;
1942 struct socket_smack *ssp = sk->sk_security;
Etienne Bassetecfcc532009-04-08 20:40:06 +02001943 struct smk_audit_info ad;
Paul Moore07feee82009-03-27 17:10:54 -04001944
1945 rcu_read_lock();
1946 hostsp = smack_host_label(sap);
1947 if (hostsp != NULL) {
Etienne Bassetecfcc532009-04-08 20:40:06 +02001948#ifdef CONFIG_AUDIT
Kees Cook923e9a12012-04-10 13:26:44 -07001949 struct lsm_network_audit net;
1950
Eric Paris48c62af2012-04-02 13:15:44 -04001951 smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net);
1952 ad.a.u.net->family = sap->sin_family;
1953 ad.a.u.net->dport = sap->sin_port;
1954 ad.a.u.net->v4info.daddr = sap->sin_addr.s_addr;
Etienne Bassetecfcc532009-04-08 20:40:06 +02001955#endif
Kees Cook923e9a12012-04-10 13:26:44 -07001956 sk_lbl = SMACK_UNLABELED_SOCKET;
Casey Schaufler2f823ff2013-05-22 18:43:03 -07001957 skp = ssp->smk_out;
1958 rc = smk_access(skp, hostsp, MAY_WRITE, &ad);
Paul Moore07feee82009-03-27 17:10:54 -04001959 } else {
1960 sk_lbl = SMACK_CIPSO_SOCKET;
1961 rc = 0;
1962 }
1963 rcu_read_unlock();
1964 if (rc != 0)
1965 return rc;
1966
1967 return smack_netlabel(sk, sk_lbl);
1968}
1969
1970/**
Casey Schauflerc6739442013-05-22 18:42:56 -07001971 * smk_ipv6_port_label - Smack port access table management
1972 * @sock: socket
1973 * @address: address
1974 *
1975 * Create or update the port list entry
1976 */
1977static void smk_ipv6_port_label(struct socket *sock, struct sockaddr *address)
1978{
1979 struct sock *sk = sock->sk;
1980 struct sockaddr_in6 *addr6;
1981 struct socket_smack *ssp = sock->sk->sk_security;
1982 struct smk_port_label *spp;
1983 unsigned short port = 0;
1984
1985 if (address == NULL) {
1986 /*
1987 * This operation is changing the Smack information
1988 * on the bound socket. Take the changes to the port
1989 * as well.
1990 */
1991 list_for_each_entry(spp, &smk_ipv6_port_list, list) {
1992 if (sk != spp->smk_sock)
1993 continue;
1994 spp->smk_in = ssp->smk_in;
1995 spp->smk_out = ssp->smk_out;
1996 return;
1997 }
1998 /*
1999 * A NULL address is only used for updating existing
2000 * bound entries. If there isn't one, it's OK.
2001 */
2002 return;
2003 }
2004
2005 addr6 = (struct sockaddr_in6 *)address;
2006 port = ntohs(addr6->sin6_port);
2007 /*
2008 * This is a special case that is safely ignored.
2009 */
2010 if (port == 0)
2011 return;
2012
2013 /*
2014 * Look for an existing port list entry.
2015 * This is an indication that a port is getting reused.
2016 */
2017 list_for_each_entry(spp, &smk_ipv6_port_list, list) {
2018 if (spp->smk_port != port)
2019 continue;
2020 spp->smk_port = port;
2021 spp->smk_sock = sk;
2022 spp->smk_in = ssp->smk_in;
2023 spp->smk_out = ssp->smk_out;
2024 return;
2025 }
2026
2027 /*
2028 * A new port entry is required.
2029 */
2030 spp = kzalloc(sizeof(*spp), GFP_KERNEL);
2031 if (spp == NULL)
2032 return;
2033
2034 spp->smk_port = port;
2035 spp->smk_sock = sk;
2036 spp->smk_in = ssp->smk_in;
2037 spp->smk_out = ssp->smk_out;
2038
2039 list_add(&spp->list, &smk_ipv6_port_list);
2040 return;
2041}
2042
2043/**
2044 * smk_ipv6_port_check - check Smack port access
2045 * @sock: socket
2046 * @address: address
2047 *
2048 * Create or update the port list entry
2049 */
Casey Schaufler6ea06242013-08-05 13:21:22 -07002050static int smk_ipv6_port_check(struct sock *sk, struct sockaddr_in6 *address,
Casey Schauflerc6739442013-05-22 18:42:56 -07002051 int act)
2052{
2053 __be16 *bep;
2054 __be32 *be32p;
Casey Schauflerc6739442013-05-22 18:42:56 -07002055 struct smk_port_label *spp;
2056 struct socket_smack *ssp = sk->sk_security;
Casey Schaufler2f823ff2013-05-22 18:43:03 -07002057 struct smack_known *skp;
Casey Schauflerc6739442013-05-22 18:42:56 -07002058 unsigned short port = 0;
Casey Schauflerc6739442013-05-22 18:42:56 -07002059 char *object;
2060 struct smk_audit_info ad;
2061#ifdef CONFIG_AUDIT
2062 struct lsm_network_audit net;
2063#endif
2064
2065 if (act == SMK_RECEIVING) {
Casey Schaufler2f823ff2013-05-22 18:43:03 -07002066 skp = smack_net_ambient;
Casey Schauflerc6739442013-05-22 18:42:56 -07002067 object = ssp->smk_in;
2068 } else {
Casey Schaufler2f823ff2013-05-22 18:43:03 -07002069 skp = ssp->smk_out;
2070 object = smack_net_ambient->smk_known;
Casey Schauflerc6739442013-05-22 18:42:56 -07002071 }
2072
2073 /*
2074 * Get the IP address and port from the address.
2075 */
Casey Schaufler6ea06242013-08-05 13:21:22 -07002076 port = ntohs(address->sin6_port);
2077 bep = (__be16 *)(&address->sin6_addr);
2078 be32p = (__be32 *)(&address->sin6_addr);
Casey Schauflerc6739442013-05-22 18:42:56 -07002079
2080 /*
2081 * It's remote, so port lookup does no good.
2082 */
2083 if (be32p[0] || be32p[1] || be32p[2] || bep[6] || ntohs(bep[7]) != 1)
2084 goto auditout;
2085
2086 /*
2087 * It's local so the send check has to have passed.
2088 */
2089 if (act == SMK_RECEIVING) {
Casey Schaufler2f823ff2013-05-22 18:43:03 -07002090 skp = &smack_known_web;
Casey Schauflerc6739442013-05-22 18:42:56 -07002091 goto auditout;
2092 }
2093
2094 list_for_each_entry(spp, &smk_ipv6_port_list, list) {
2095 if (spp->smk_port != port)
2096 continue;
2097 object = spp->smk_in;
2098 if (act == SMK_CONNECTING)
Casey Schaufler2f823ff2013-05-22 18:43:03 -07002099 ssp->smk_packet = spp->smk_out->smk_known;
Casey Schauflerc6739442013-05-22 18:42:56 -07002100 break;
2101 }
2102
2103auditout:
2104
2105#ifdef CONFIG_AUDIT
2106 smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net);
2107 ad.a.u.net->family = sk->sk_family;
2108 ad.a.u.net->dport = port;
2109 if (act == SMK_RECEIVING)
Casey Schaufler6ea06242013-08-05 13:21:22 -07002110 ad.a.u.net->v6info.saddr = address->sin6_addr;
Casey Schauflerc6739442013-05-22 18:42:56 -07002111 else
Casey Schaufler6ea06242013-08-05 13:21:22 -07002112 ad.a.u.net->v6info.daddr = address->sin6_addr;
Casey Schauflerc6739442013-05-22 18:42:56 -07002113#endif
Casey Schaufler2f823ff2013-05-22 18:43:03 -07002114 return smk_access(skp, object, MAY_WRITE, &ad);
Casey Schauflerc6739442013-05-22 18:42:56 -07002115}
2116
2117/**
Casey Schauflere114e472008-02-04 22:29:50 -08002118 * smack_inode_setsecurity - set smack xattrs
2119 * @inode: the object
2120 * @name: attribute name
2121 * @value: attribute value
2122 * @size: size of the attribute
2123 * @flags: unused
2124 *
2125 * Sets the named attribute in the appropriate blob
2126 *
2127 * Returns 0 on success, or an error code
2128 */
2129static int smack_inode_setsecurity(struct inode *inode, const char *name,
2130 const void *value, size_t size, int flags)
2131{
Casey Schaufler2f823ff2013-05-22 18:43:03 -07002132 struct smack_known *skp;
Casey Schauflere114e472008-02-04 22:29:50 -08002133 struct inode_smack *nsp = inode->i_security;
2134 struct socket_smack *ssp;
2135 struct socket *sock;
Casey Schaufler4bc87e62008-02-15 15:24:25 -08002136 int rc = 0;
Casey Schauflere114e472008-02-04 22:29:50 -08002137
Casey Schauflerf7112e62012-05-06 15:22:02 -07002138 if (value == NULL || size > SMK_LONGLABEL || size == 0)
Casey Schauflere114e472008-02-04 22:29:50 -08002139 return -EACCES;
2140
Casey Schaufler2f823ff2013-05-22 18:43:03 -07002141 skp = smk_import_entry(value, size);
2142 if (skp == NULL)
Casey Schauflere114e472008-02-04 22:29:50 -08002143 return -EINVAL;
2144
2145 if (strcmp(name, XATTR_SMACK_SUFFIX) == 0) {
Casey Schaufler2f823ff2013-05-22 18:43:03 -07002146 nsp->smk_inode = skp->smk_known;
David P. Quigleyddd29ec2009-09-09 14:25:37 -04002147 nsp->smk_flags |= SMK_INODE_INSTANT;
Casey Schauflere114e472008-02-04 22:29:50 -08002148 return 0;
2149 }
2150 /*
2151 * The rest of the Smack xattrs are only on sockets.
2152 */
2153 if (inode->i_sb->s_magic != SOCKFS_MAGIC)
2154 return -EOPNOTSUPP;
2155
2156 sock = SOCKET_I(inode);
Ahmed S. Darwish2e1d1462008-02-13 15:03:34 -08002157 if (sock == NULL || sock->sk == NULL)
Casey Schauflere114e472008-02-04 22:29:50 -08002158 return -EOPNOTSUPP;
2159
2160 ssp = sock->sk->sk_security;
2161
2162 if (strcmp(name, XATTR_SMACK_IPIN) == 0)
Casey Schaufler2f823ff2013-05-22 18:43:03 -07002163 ssp->smk_in = skp->smk_known;
Casey Schauflere114e472008-02-04 22:29:50 -08002164 else if (strcmp(name, XATTR_SMACK_IPOUT) == 0) {
Casey Schaufler2f823ff2013-05-22 18:43:03 -07002165 ssp->smk_out = skp;
Casey Schauflerc6739442013-05-22 18:42:56 -07002166 if (sock->sk->sk_family == PF_INET) {
Casey Schauflerb4e0d5f2010-11-24 17:12:10 -08002167 rc = smack_netlabel(sock->sk, SMACK_CIPSO_SOCKET);
2168 if (rc != 0)
2169 printk(KERN_WARNING
2170 "Smack: \"%s\" netlbl error %d.\n",
2171 __func__, -rc);
2172 }
Casey Schauflere114e472008-02-04 22:29:50 -08002173 } else
2174 return -EOPNOTSUPP;
2175
Casey Schauflerc6739442013-05-22 18:42:56 -07002176 if (sock->sk->sk_family == PF_INET6)
2177 smk_ipv6_port_label(sock, NULL);
2178
Casey Schauflere114e472008-02-04 22:29:50 -08002179 return 0;
2180}
2181
2182/**
2183 * smack_socket_post_create - finish socket setup
2184 * @sock: the socket
2185 * @family: protocol family
2186 * @type: unused
2187 * @protocol: unused
2188 * @kern: unused
2189 *
2190 * Sets the netlabel information on the socket
2191 *
2192 * Returns 0 on success, and error code otherwise
2193 */
2194static int smack_socket_post_create(struct socket *sock, int family,
2195 int type, int protocol, int kern)
2196{
Ahmed S. Darwish2e1d1462008-02-13 15:03:34 -08002197 if (family != PF_INET || sock->sk == NULL)
Casey Schauflere114e472008-02-04 22:29:50 -08002198 return 0;
2199 /*
2200 * Set the outbound netlbl.
2201 */
Casey Schaufler6d3dc072008-12-31 12:54:12 -05002202 return smack_netlabel(sock->sk, SMACK_CIPSO_SOCKET);
2203}
2204
Casey Schaufler6d3dc072008-12-31 12:54:12 -05002205/**
Casey Schauflerc6739442013-05-22 18:42:56 -07002206 * smack_socket_bind - record port binding information.
2207 * @sock: the socket
2208 * @address: the port address
2209 * @addrlen: size of the address
2210 *
2211 * Records the label bound to a port.
2212 *
2213 * Returns 0
2214 */
2215static int smack_socket_bind(struct socket *sock, struct sockaddr *address,
2216 int addrlen)
2217{
2218 if (sock->sk != NULL && sock->sk->sk_family == PF_INET6)
2219 smk_ipv6_port_label(sock, address);
2220
2221 return 0;
2222}
2223
2224/**
Casey Schaufler6d3dc072008-12-31 12:54:12 -05002225 * smack_socket_connect - connect access check
2226 * @sock: the socket
2227 * @sap: the other end
2228 * @addrlen: size of sap
2229 *
2230 * Verifies that a connection may be possible
2231 *
2232 * Returns 0 on success, and error code otherwise
2233 */
2234static int smack_socket_connect(struct socket *sock, struct sockaddr *sap,
2235 int addrlen)
2236{
Casey Schauflerc6739442013-05-22 18:42:56 -07002237 int rc = 0;
Casey Schaufler6d3dc072008-12-31 12:54:12 -05002238
Casey Schauflerc6739442013-05-22 18:42:56 -07002239 if (sock->sk == NULL)
2240 return 0;
2241
2242 switch (sock->sk->sk_family) {
2243 case PF_INET:
2244 if (addrlen < sizeof(struct sockaddr_in))
2245 return -EINVAL;
2246 rc = smack_netlabel_send(sock->sk, (struct sockaddr_in *)sap);
2247 break;
2248 case PF_INET6:
2249 if (addrlen < sizeof(struct sockaddr_in6))
2250 return -EINVAL;
Casey Schaufler6ea06242013-08-05 13:21:22 -07002251 rc = smk_ipv6_port_check(sock->sk, (struct sockaddr_in6 *)sap,
2252 SMK_CONNECTING);
Casey Schauflerc6739442013-05-22 18:42:56 -07002253 break;
2254 }
2255 return rc;
Casey Schauflere114e472008-02-04 22:29:50 -08002256}
2257
2258/**
2259 * smack_flags_to_may - convert S_ to MAY_ values
2260 * @flags: the S_ value
2261 *
2262 * Returns the equivalent MAY_ value
2263 */
2264static int smack_flags_to_may(int flags)
2265{
2266 int may = 0;
2267
2268 if (flags & S_IRUGO)
2269 may |= MAY_READ;
2270 if (flags & S_IWUGO)
2271 may |= MAY_WRITE;
2272 if (flags & S_IXUGO)
2273 may |= MAY_EXEC;
2274
2275 return may;
2276}
2277
2278/**
2279 * smack_msg_msg_alloc_security - Set the security blob for msg_msg
2280 * @msg: the object
2281 *
2282 * Returns 0
2283 */
2284static int smack_msg_msg_alloc_security(struct msg_msg *msg)
2285{
Casey Schaufler2f823ff2013-05-22 18:43:03 -07002286 struct smack_known *skp = smk_of_current();
2287
2288 msg->security = skp->smk_known;
Casey Schauflere114e472008-02-04 22:29:50 -08002289 return 0;
2290}
2291
2292/**
2293 * smack_msg_msg_free_security - Clear the security blob for msg_msg
2294 * @msg: the object
2295 *
2296 * Clears the blob pointer
2297 */
2298static void smack_msg_msg_free_security(struct msg_msg *msg)
2299{
2300 msg->security = NULL;
2301}
2302
2303/**
2304 * smack_of_shm - the smack pointer for the shm
2305 * @shp: the object
2306 *
2307 * Returns a pointer to the smack value
2308 */
2309static char *smack_of_shm(struct shmid_kernel *shp)
2310{
2311 return (char *)shp->shm_perm.security;
2312}
2313
2314/**
2315 * smack_shm_alloc_security - Set the security blob for shm
2316 * @shp: the object
2317 *
2318 * Returns 0
2319 */
2320static int smack_shm_alloc_security(struct shmid_kernel *shp)
2321{
2322 struct kern_ipc_perm *isp = &shp->shm_perm;
Casey Schaufler2f823ff2013-05-22 18:43:03 -07002323 struct smack_known *skp = smk_of_current();
Casey Schauflere114e472008-02-04 22:29:50 -08002324
Casey Schaufler2f823ff2013-05-22 18:43:03 -07002325 isp->security = skp->smk_known;
Casey Schauflere114e472008-02-04 22:29:50 -08002326 return 0;
2327}
2328
2329/**
2330 * smack_shm_free_security - Clear the security blob for shm
2331 * @shp: the object
2332 *
2333 * Clears the blob pointer
2334 */
2335static void smack_shm_free_security(struct shmid_kernel *shp)
2336{
2337 struct kern_ipc_perm *isp = &shp->shm_perm;
2338
2339 isp->security = NULL;
2340}
2341
2342/**
Etienne Bassetecfcc532009-04-08 20:40:06 +02002343 * smk_curacc_shm : check if current has access on shm
2344 * @shp : the object
2345 * @access : access requested
2346 *
2347 * Returns 0 if current has the requested access, error code otherwise
2348 */
2349static int smk_curacc_shm(struct shmid_kernel *shp, int access)
2350{
2351 char *ssp = smack_of_shm(shp);
2352 struct smk_audit_info ad;
2353
2354#ifdef CONFIG_AUDIT
2355 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_IPC);
2356 ad.a.u.ipc_id = shp->shm_perm.id;
2357#endif
2358 return smk_curacc(ssp, access, &ad);
2359}
2360
2361/**
Casey Schauflere114e472008-02-04 22:29:50 -08002362 * smack_shm_associate - Smack access check for shm
2363 * @shp: the object
2364 * @shmflg: access requested
2365 *
2366 * Returns 0 if current has the requested access, error code otherwise
2367 */
2368static int smack_shm_associate(struct shmid_kernel *shp, int shmflg)
2369{
Casey Schauflere114e472008-02-04 22:29:50 -08002370 int may;
2371
2372 may = smack_flags_to_may(shmflg);
Etienne Bassetecfcc532009-04-08 20:40:06 +02002373 return smk_curacc_shm(shp, may);
Casey Schauflere114e472008-02-04 22:29:50 -08002374}
2375
2376/**
2377 * smack_shm_shmctl - Smack access check for shm
2378 * @shp: the object
2379 * @cmd: what it wants to do
2380 *
2381 * Returns 0 if current has the requested access, error code otherwise
2382 */
2383static int smack_shm_shmctl(struct shmid_kernel *shp, int cmd)
2384{
Casey Schauflere114e472008-02-04 22:29:50 -08002385 int may;
2386
2387 switch (cmd) {
2388 case IPC_STAT:
2389 case SHM_STAT:
2390 may = MAY_READ;
2391 break;
2392 case IPC_SET:
2393 case SHM_LOCK:
2394 case SHM_UNLOCK:
2395 case IPC_RMID:
2396 may = MAY_READWRITE;
2397 break;
2398 case IPC_INFO:
2399 case SHM_INFO:
2400 /*
2401 * System level information.
2402 */
2403 return 0;
2404 default:
2405 return -EINVAL;
2406 }
Etienne Bassetecfcc532009-04-08 20:40:06 +02002407 return smk_curacc_shm(shp, may);
Casey Schauflere114e472008-02-04 22:29:50 -08002408}
2409
2410/**
2411 * smack_shm_shmat - Smack access for shmat
2412 * @shp: the object
2413 * @shmaddr: unused
2414 * @shmflg: access requested
2415 *
2416 * Returns 0 if current has the requested access, error code otherwise
2417 */
2418static int smack_shm_shmat(struct shmid_kernel *shp, char __user *shmaddr,
2419 int shmflg)
2420{
Casey Schauflere114e472008-02-04 22:29:50 -08002421 int may;
2422
2423 may = smack_flags_to_may(shmflg);
Etienne Bassetecfcc532009-04-08 20:40:06 +02002424 return smk_curacc_shm(shp, may);
Casey Schauflere114e472008-02-04 22:29:50 -08002425}
2426
2427/**
2428 * smack_of_sem - the smack pointer for the sem
2429 * @sma: the object
2430 *
2431 * Returns a pointer to the smack value
2432 */
2433static char *smack_of_sem(struct sem_array *sma)
2434{
2435 return (char *)sma->sem_perm.security;
2436}
2437
2438/**
2439 * smack_sem_alloc_security - Set the security blob for sem
2440 * @sma: the object
2441 *
2442 * Returns 0
2443 */
2444static int smack_sem_alloc_security(struct sem_array *sma)
2445{
2446 struct kern_ipc_perm *isp = &sma->sem_perm;
Casey Schaufler2f823ff2013-05-22 18:43:03 -07002447 struct smack_known *skp = smk_of_current();
Casey Schauflere114e472008-02-04 22:29:50 -08002448
Casey Schaufler2f823ff2013-05-22 18:43:03 -07002449 isp->security = skp->smk_known;
Casey Schauflere114e472008-02-04 22:29:50 -08002450 return 0;
2451}
2452
2453/**
2454 * smack_sem_free_security - Clear the security blob for sem
2455 * @sma: the object
2456 *
2457 * Clears the blob pointer
2458 */
2459static void smack_sem_free_security(struct sem_array *sma)
2460{
2461 struct kern_ipc_perm *isp = &sma->sem_perm;
2462
2463 isp->security = NULL;
2464}
2465
2466/**
Etienne Bassetecfcc532009-04-08 20:40:06 +02002467 * smk_curacc_sem : check if current has access on sem
2468 * @sma : the object
2469 * @access : access requested
2470 *
2471 * Returns 0 if current has the requested access, error code otherwise
2472 */
2473static int smk_curacc_sem(struct sem_array *sma, int access)
2474{
2475 char *ssp = smack_of_sem(sma);
2476 struct smk_audit_info ad;
2477
2478#ifdef CONFIG_AUDIT
2479 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_IPC);
2480 ad.a.u.ipc_id = sma->sem_perm.id;
2481#endif
2482 return smk_curacc(ssp, access, &ad);
2483}
2484
2485/**
Casey Schauflere114e472008-02-04 22:29:50 -08002486 * smack_sem_associate - Smack access check for sem
2487 * @sma: the object
2488 * @semflg: access requested
2489 *
2490 * Returns 0 if current has the requested access, error code otherwise
2491 */
2492static int smack_sem_associate(struct sem_array *sma, int semflg)
2493{
Casey Schauflere114e472008-02-04 22:29:50 -08002494 int may;
2495
2496 may = smack_flags_to_may(semflg);
Etienne Bassetecfcc532009-04-08 20:40:06 +02002497 return smk_curacc_sem(sma, may);
Casey Schauflere114e472008-02-04 22:29:50 -08002498}
2499
2500/**
2501 * smack_sem_shmctl - Smack access check for sem
2502 * @sma: the object
2503 * @cmd: what it wants to do
2504 *
2505 * Returns 0 if current has the requested access, error code otherwise
2506 */
2507static int smack_sem_semctl(struct sem_array *sma, int cmd)
2508{
Casey Schauflere114e472008-02-04 22:29:50 -08002509 int may;
2510
2511 switch (cmd) {
2512 case GETPID:
2513 case GETNCNT:
2514 case GETZCNT:
2515 case GETVAL:
2516 case GETALL:
2517 case IPC_STAT:
2518 case SEM_STAT:
2519 may = MAY_READ;
2520 break;
2521 case SETVAL:
2522 case SETALL:
2523 case IPC_RMID:
2524 case IPC_SET:
2525 may = MAY_READWRITE;
2526 break;
2527 case IPC_INFO:
2528 case SEM_INFO:
2529 /*
2530 * System level information
2531 */
2532 return 0;
2533 default:
2534 return -EINVAL;
2535 }
2536
Etienne Bassetecfcc532009-04-08 20:40:06 +02002537 return smk_curacc_sem(sma, may);
Casey Schauflere114e472008-02-04 22:29:50 -08002538}
2539
2540/**
2541 * smack_sem_semop - Smack checks of semaphore operations
2542 * @sma: the object
2543 * @sops: unused
2544 * @nsops: unused
2545 * @alter: unused
2546 *
2547 * Treated as read and write in all cases.
2548 *
2549 * Returns 0 if access is allowed, error code otherwise
2550 */
2551static int smack_sem_semop(struct sem_array *sma, struct sembuf *sops,
2552 unsigned nsops, int alter)
2553{
Etienne Bassetecfcc532009-04-08 20:40:06 +02002554 return smk_curacc_sem(sma, MAY_READWRITE);
Casey Schauflere114e472008-02-04 22:29:50 -08002555}
2556
2557/**
2558 * smack_msg_alloc_security - Set the security blob for msg
2559 * @msq: the object
2560 *
2561 * Returns 0
2562 */
2563static int smack_msg_queue_alloc_security(struct msg_queue *msq)
2564{
2565 struct kern_ipc_perm *kisp = &msq->q_perm;
Casey Schaufler2f823ff2013-05-22 18:43:03 -07002566 struct smack_known *skp = smk_of_current();
Casey Schauflere114e472008-02-04 22:29:50 -08002567
Casey Schaufler2f823ff2013-05-22 18:43:03 -07002568 kisp->security = skp->smk_known;
Casey Schauflere114e472008-02-04 22:29:50 -08002569 return 0;
2570}
2571
2572/**
2573 * smack_msg_free_security - Clear the security blob for msg
2574 * @msq: the object
2575 *
2576 * Clears the blob pointer
2577 */
2578static void smack_msg_queue_free_security(struct msg_queue *msq)
2579{
2580 struct kern_ipc_perm *kisp = &msq->q_perm;
2581
2582 kisp->security = NULL;
2583}
2584
2585/**
2586 * smack_of_msq - the smack pointer for the msq
2587 * @msq: the object
2588 *
2589 * Returns a pointer to the smack value
2590 */
2591static char *smack_of_msq(struct msg_queue *msq)
2592{
2593 return (char *)msq->q_perm.security;
2594}
2595
2596/**
Etienne Bassetecfcc532009-04-08 20:40:06 +02002597 * smk_curacc_msq : helper to check if current has access on msq
2598 * @msq : the msq
2599 * @access : access requested
2600 *
2601 * return 0 if current has access, error otherwise
2602 */
2603static int smk_curacc_msq(struct msg_queue *msq, int access)
2604{
2605 char *msp = smack_of_msq(msq);
2606 struct smk_audit_info ad;
2607
2608#ifdef CONFIG_AUDIT
2609 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_IPC);
2610 ad.a.u.ipc_id = msq->q_perm.id;
2611#endif
2612 return smk_curacc(msp, access, &ad);
2613}
2614
2615/**
Casey Schauflere114e472008-02-04 22:29:50 -08002616 * smack_msg_queue_associate - Smack access check for msg_queue
2617 * @msq: the object
2618 * @msqflg: access requested
2619 *
2620 * Returns 0 if current has the requested access, error code otherwise
2621 */
2622static int smack_msg_queue_associate(struct msg_queue *msq, int msqflg)
2623{
Casey Schauflere114e472008-02-04 22:29:50 -08002624 int may;
2625
2626 may = smack_flags_to_may(msqflg);
Etienne Bassetecfcc532009-04-08 20:40:06 +02002627 return smk_curacc_msq(msq, may);
Casey Schauflere114e472008-02-04 22:29:50 -08002628}
2629
2630/**
2631 * smack_msg_queue_msgctl - Smack access check for msg_queue
2632 * @msq: the object
2633 * @cmd: what it wants to do
2634 *
2635 * Returns 0 if current has the requested access, error code otherwise
2636 */
2637static int smack_msg_queue_msgctl(struct msg_queue *msq, int cmd)
2638{
Casey Schauflere114e472008-02-04 22:29:50 -08002639 int may;
2640
2641 switch (cmd) {
2642 case IPC_STAT:
2643 case MSG_STAT:
2644 may = MAY_READ;
2645 break;
2646 case IPC_SET:
2647 case IPC_RMID:
2648 may = MAY_READWRITE;
2649 break;
2650 case IPC_INFO:
2651 case MSG_INFO:
2652 /*
2653 * System level information
2654 */
2655 return 0;
2656 default:
2657 return -EINVAL;
2658 }
2659
Etienne Bassetecfcc532009-04-08 20:40:06 +02002660 return smk_curacc_msq(msq, may);
Casey Schauflere114e472008-02-04 22:29:50 -08002661}
2662
2663/**
2664 * smack_msg_queue_msgsnd - Smack access check for msg_queue
2665 * @msq: the object
2666 * @msg: unused
2667 * @msqflg: access requested
2668 *
2669 * Returns 0 if current has the requested access, error code otherwise
2670 */
2671static int smack_msg_queue_msgsnd(struct msg_queue *msq, struct msg_msg *msg,
2672 int msqflg)
2673{
Etienne Bassetecfcc532009-04-08 20:40:06 +02002674 int may;
Casey Schauflere114e472008-02-04 22:29:50 -08002675
Etienne Bassetecfcc532009-04-08 20:40:06 +02002676 may = smack_flags_to_may(msqflg);
2677 return smk_curacc_msq(msq, may);
Casey Schauflere114e472008-02-04 22:29:50 -08002678}
2679
2680/**
2681 * smack_msg_queue_msgsnd - Smack access check for msg_queue
2682 * @msq: the object
2683 * @msg: unused
2684 * @target: unused
2685 * @type: unused
2686 * @mode: unused
2687 *
2688 * Returns 0 if current has read and write access, error code otherwise
2689 */
2690static int smack_msg_queue_msgrcv(struct msg_queue *msq, struct msg_msg *msg,
2691 struct task_struct *target, long type, int mode)
2692{
Etienne Bassetecfcc532009-04-08 20:40:06 +02002693 return smk_curacc_msq(msq, MAY_READWRITE);
Casey Schauflere114e472008-02-04 22:29:50 -08002694}
2695
2696/**
2697 * smack_ipc_permission - Smack access for ipc_permission()
2698 * @ipp: the object permissions
2699 * @flag: access requested
2700 *
2701 * Returns 0 if current has read and write access, error code otherwise
2702 */
2703static int smack_ipc_permission(struct kern_ipc_perm *ipp, short flag)
2704{
2705 char *isp = ipp->security;
Etienne Bassetecfcc532009-04-08 20:40:06 +02002706 int may = smack_flags_to_may(flag);
2707 struct smk_audit_info ad;
Casey Schauflere114e472008-02-04 22:29:50 -08002708
Etienne Bassetecfcc532009-04-08 20:40:06 +02002709#ifdef CONFIG_AUDIT
2710 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_IPC);
2711 ad.a.u.ipc_id = ipp->id;
2712#endif
2713 return smk_curacc(isp, may, &ad);
Casey Schauflere114e472008-02-04 22:29:50 -08002714}
2715
Ahmed S. Darwishd20bdda2008-04-30 08:34:10 +10002716/**
2717 * smack_ipc_getsecid - Extract smack security id
Randy Dunlap251a2a92009-02-18 11:42:33 -08002718 * @ipp: the object permissions
Ahmed S. Darwishd20bdda2008-04-30 08:34:10 +10002719 * @secid: where result will be saved
2720 */
2721static void smack_ipc_getsecid(struct kern_ipc_perm *ipp, u32 *secid)
2722{
2723 char *smack = ipp->security;
2724
2725 *secid = smack_to_secid(smack);
2726}
2727
Casey Schauflere114e472008-02-04 22:29:50 -08002728/**
2729 * smack_d_instantiate - Make sure the blob is correct on an inode
Dan Carpenter3e62cbb2010-06-01 09:14:04 +02002730 * @opt_dentry: dentry where inode will be attached
Casey Schauflere114e472008-02-04 22:29:50 -08002731 * @inode: the object
2732 *
2733 * Set the inode's security blob if it hasn't been done already.
2734 */
2735static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode)
2736{
2737 struct super_block *sbp;
2738 struct superblock_smack *sbsp;
2739 struct inode_smack *isp;
Casey Schaufler2f823ff2013-05-22 18:43:03 -07002740 struct smack_known *skp;
2741 struct smack_known *ckp = smk_of_current();
Casey Schauflere114e472008-02-04 22:29:50 -08002742 char *final;
Jarkko Sakkinen5c6d1122010-12-07 13:34:01 +02002743 char trattr[TRANS_TRUE_SIZE];
2744 int transflag = 0;
Casey Schaufler2267b132012-03-13 19:14:19 -07002745 int rc;
Casey Schauflere114e472008-02-04 22:29:50 -08002746 struct dentry *dp;
2747
2748 if (inode == NULL)
2749 return;
2750
2751 isp = inode->i_security;
2752
2753 mutex_lock(&isp->smk_lock);
2754 /*
2755 * If the inode is already instantiated
2756 * take the quick way out
2757 */
2758 if (isp->smk_flags & SMK_INODE_INSTANT)
2759 goto unlockandout;
2760
2761 sbp = inode->i_sb;
2762 sbsp = sbp->s_security;
2763 /*
2764 * We're going to use the superblock default label
2765 * if there's no label on the file.
2766 */
2767 final = sbsp->smk_default;
2768
2769 /*
Casey Schauflere97dcb02008-06-02 10:04:32 -07002770 * If this is the root inode the superblock
2771 * may be in the process of initialization.
2772 * If that is the case use the root value out
2773 * of the superblock.
2774 */
2775 if (opt_dentry->d_parent == opt_dentry) {
2776 isp->smk_inode = sbsp->smk_root;
2777 isp->smk_flags |= SMK_INODE_INSTANT;
2778 goto unlockandout;
2779 }
2780
2781 /*
Casey Schauflere114e472008-02-04 22:29:50 -08002782 * This is pretty hackish.
2783 * Casey says that we shouldn't have to do
2784 * file system specific code, but it does help
2785 * with keeping it simple.
2786 */
2787 switch (sbp->s_magic) {
2788 case SMACK_MAGIC:
2789 /*
Lucas De Marchi25985ed2011-03-30 22:57:33 -03002790 * Casey says that it's a little embarrassing
Casey Schauflere114e472008-02-04 22:29:50 -08002791 * that the smack file system doesn't do
2792 * extended attributes.
2793 */
2794 final = smack_known_star.smk_known;
2795 break;
2796 case PIPEFS_MAGIC:
2797 /*
2798 * Casey says pipes are easy (?)
2799 */
2800 final = smack_known_star.smk_known;
2801 break;
2802 case DEVPTS_SUPER_MAGIC:
2803 /*
2804 * devpts seems content with the label of the task.
2805 * Programs that change smack have to treat the
2806 * pty with respect.
2807 */
Casey Schaufler2f823ff2013-05-22 18:43:03 -07002808 final = ckp->smk_known;
Casey Schauflere114e472008-02-04 22:29:50 -08002809 break;
2810 case SOCKFS_MAGIC:
2811 /*
Casey Schauflerb4e0d5f2010-11-24 17:12:10 -08002812 * Socket access is controlled by the socket
2813 * structures associated with the task involved.
Casey Schauflere114e472008-02-04 22:29:50 -08002814 */
Casey Schauflerb4e0d5f2010-11-24 17:12:10 -08002815 final = smack_known_star.smk_known;
Casey Schauflere114e472008-02-04 22:29:50 -08002816 break;
2817 case PROC_SUPER_MAGIC:
2818 /*
2819 * Casey says procfs appears not to care.
2820 * The superblock default suffices.
2821 */
2822 break;
2823 case TMPFS_MAGIC:
2824 /*
2825 * Device labels should come from the filesystem,
2826 * but watch out, because they're volitile,
2827 * getting recreated on every reboot.
2828 */
2829 final = smack_known_star.smk_known;
2830 /*
2831 * No break.
2832 *
2833 * If a smack value has been set we want to use it,
2834 * but since tmpfs isn't giving us the opportunity
2835 * to set mount options simulate setting the
2836 * superblock default.
2837 */
2838 default:
2839 /*
2840 * This isn't an understood special case.
2841 * Get the value from the xattr.
Casey Schauflerb4e0d5f2010-11-24 17:12:10 -08002842 */
2843
2844 /*
2845 * UNIX domain sockets use lower level socket data.
2846 */
2847 if (S_ISSOCK(inode->i_mode)) {
2848 final = smack_known_star.smk_known;
2849 break;
2850 }
2851 /*
Casey Schauflere114e472008-02-04 22:29:50 -08002852 * No xattr support means, alas, no SMACK label.
2853 * Use the aforeapplied default.
2854 * It would be curious if the label of the task
2855 * does not match that assigned.
2856 */
2857 if (inode->i_op->getxattr == NULL)
2858 break;
2859 /*
2860 * Get the dentry for xattr.
2861 */
Dan Carpenter3e62cbb2010-06-01 09:14:04 +02002862 dp = dget(opt_dentry);
Casey Schaufler2f823ff2013-05-22 18:43:03 -07002863 skp = smk_fetch(XATTR_NAME_SMACK, inode, dp);
2864 if (skp != NULL)
2865 final = skp->smk_known;
Casey Schaufler2267b132012-03-13 19:14:19 -07002866
2867 /*
2868 * Transmuting directory
2869 */
2870 if (S_ISDIR(inode->i_mode)) {
2871 /*
2872 * If this is a new directory and the label was
2873 * transmuted when the inode was initialized
2874 * set the transmute attribute on the directory
2875 * and mark the inode.
2876 *
2877 * If there is a transmute attribute on the
2878 * directory mark the inode.
2879 */
2880 if (isp->smk_flags & SMK_INODE_CHANGED) {
2881 isp->smk_flags &= ~SMK_INODE_CHANGED;
2882 rc = inode->i_op->setxattr(dp,
Jarkko Sakkinen5c6d1122010-12-07 13:34:01 +02002883 XATTR_NAME_SMACKTRANSMUTE,
Casey Schaufler2267b132012-03-13 19:14:19 -07002884 TRANS_TRUE, TRANS_TRUE_SIZE,
2885 0);
2886 } else {
2887 rc = inode->i_op->getxattr(dp,
2888 XATTR_NAME_SMACKTRANSMUTE, trattr,
2889 TRANS_TRUE_SIZE);
2890 if (rc >= 0 && strncmp(trattr, TRANS_TRUE,
2891 TRANS_TRUE_SIZE) != 0)
2892 rc = -EINVAL;
Jarkko Sakkinen5c6d1122010-12-07 13:34:01 +02002893 }
Casey Schaufler2267b132012-03-13 19:14:19 -07002894 if (rc >= 0)
2895 transflag = SMK_INODE_TRANSMUTE;
Jarkko Sakkinen5c6d1122010-12-07 13:34:01 +02002896 }
Casey Schaufler19760ad2013-12-16 16:27:26 -08002897 /*
2898 * Don't let the exec or mmap label be "*" or "@".
2899 */
2900 skp = smk_fetch(XATTR_NAME_SMACKEXEC, inode, dp);
2901 if (skp == &smack_known_star || skp == &smack_known_web)
2902 skp = NULL;
2903 isp->smk_task = skp;
2904 skp = smk_fetch(XATTR_NAME_SMACKMMAP, inode, dp);
2905 if (skp == &smack_known_star || skp == &smack_known_web)
2906 skp = NULL;
2907 isp->smk_mmap = skp;
Casey Schaufler676dac42010-12-02 06:43:39 -08002908
Casey Schauflere114e472008-02-04 22:29:50 -08002909 dput(dp);
2910 break;
2911 }
2912
2913 if (final == NULL)
Casey Schaufler2f823ff2013-05-22 18:43:03 -07002914 isp->smk_inode = ckp->smk_known;
Casey Schauflere114e472008-02-04 22:29:50 -08002915 else
2916 isp->smk_inode = final;
2917
Jarkko Sakkinen5c6d1122010-12-07 13:34:01 +02002918 isp->smk_flags |= (SMK_INODE_INSTANT | transflag);
Casey Schauflere114e472008-02-04 22:29:50 -08002919
2920unlockandout:
2921 mutex_unlock(&isp->smk_lock);
2922 return;
2923}
2924
2925/**
2926 * smack_getprocattr - Smack process attribute access
2927 * @p: the object task
2928 * @name: the name of the attribute in /proc/.../attr
2929 * @value: where to put the result
2930 *
2931 * Places a copy of the task Smack into value
2932 *
2933 * Returns the length of the smack label or an error code
2934 */
2935static int smack_getprocattr(struct task_struct *p, char *name, char **value)
2936{
Casey Schaufler2f823ff2013-05-22 18:43:03 -07002937 struct smack_known *skp = smk_of_task(task_security(p));
Casey Schauflere114e472008-02-04 22:29:50 -08002938 char *cp;
2939 int slen;
2940
2941 if (strcmp(name, "current") != 0)
2942 return -EINVAL;
2943
Casey Schaufler2f823ff2013-05-22 18:43:03 -07002944 cp = kstrdup(skp->smk_known, GFP_KERNEL);
Casey Schauflere114e472008-02-04 22:29:50 -08002945 if (cp == NULL)
2946 return -ENOMEM;
2947
2948 slen = strlen(cp);
2949 *value = cp;
2950 return slen;
2951}
2952
2953/**
2954 * smack_setprocattr - Smack process attribute setting
2955 * @p: the object task
2956 * @name: the name of the attribute in /proc/.../attr
2957 * @value: the value to set
2958 * @size: the size of the value
2959 *
2960 * Sets the Smack value of the task. Only setting self
2961 * is permitted and only with privilege
2962 *
2963 * Returns the length of the smack label or an error code
2964 */
2965static int smack_setprocattr(struct task_struct *p, char *name,
2966 void *value, size_t size)
2967{
Casey Schaufler676dac42010-12-02 06:43:39 -08002968 struct task_smack *tsp;
David Howellsd84f4f92008-11-14 10:39:23 +11002969 struct cred *new;
Casey Schaufler2f823ff2013-05-22 18:43:03 -07002970 struct smack_known *skp;
Casey Schauflere114e472008-02-04 22:29:50 -08002971
Casey Schauflere114e472008-02-04 22:29:50 -08002972 /*
2973 * Changing another process' Smack value is too dangerous
2974 * and supports no sane use case.
2975 */
2976 if (p != current)
2977 return -EPERM;
2978
Casey Schaufler1880eff2012-06-05 15:28:30 -07002979 if (!smack_privileged(CAP_MAC_ADMIN))
David Howells5cd9c582008-08-14 11:37:28 +01002980 return -EPERM;
2981
Casey Schauflerf7112e62012-05-06 15:22:02 -07002982 if (value == NULL || size == 0 || size >= SMK_LONGLABEL)
Casey Schauflere114e472008-02-04 22:29:50 -08002983 return -EINVAL;
2984
2985 if (strcmp(name, "current") != 0)
2986 return -EINVAL;
2987
Casey Schaufler2f823ff2013-05-22 18:43:03 -07002988 skp = smk_import_entry(value, size);
2989 if (skp == NULL)
Casey Schauflere114e472008-02-04 22:29:50 -08002990 return -EINVAL;
2991
Casey Schaufler6d3dc072008-12-31 12:54:12 -05002992 /*
2993 * No process is ever allowed the web ("@") label.
2994 */
Casey Schaufler2f823ff2013-05-22 18:43:03 -07002995 if (skp == &smack_known_web)
Casey Schaufler6d3dc072008-12-31 12:54:12 -05002996 return -EPERM;
2997
David Howellsd84f4f92008-11-14 10:39:23 +11002998 new = prepare_creds();
Casey Schaufler6d3dc072008-12-31 12:54:12 -05002999 if (new == NULL)
David Howellsd84f4f92008-11-14 10:39:23 +11003000 return -ENOMEM;
Casey Schaufler7898e1f2011-01-17 08:05:27 -08003001
Casey Schaufler46a2f3b2012-08-22 11:44:03 -07003002 tsp = new->security;
Casey Schaufler2f823ff2013-05-22 18:43:03 -07003003 tsp->smk_task = skp;
Casey Schaufler7898e1f2011-01-17 08:05:27 -08003004
David Howellsd84f4f92008-11-14 10:39:23 +11003005 commit_creds(new);
Casey Schauflere114e472008-02-04 22:29:50 -08003006 return size;
3007}
3008
3009/**
3010 * smack_unix_stream_connect - Smack access on UDS
David S. Miller3610cda2011-01-05 15:38:53 -08003011 * @sock: one sock
3012 * @other: the other sock
Casey Schauflere114e472008-02-04 22:29:50 -08003013 * @newsk: unused
3014 *
3015 * Return 0 if a subject with the smack of sock could access
3016 * an object with the smack of other, otherwise an error code
3017 */
David S. Miller3610cda2011-01-05 15:38:53 -08003018static int smack_unix_stream_connect(struct sock *sock,
3019 struct sock *other, struct sock *newsk)
Casey Schauflere114e472008-02-04 22:29:50 -08003020{
Casey Schaufler2f823ff2013-05-22 18:43:03 -07003021 struct smack_known *skp;
James Morrisd2e7ad12011-01-10 09:46:24 +11003022 struct socket_smack *ssp = sock->sk_security;
3023 struct socket_smack *osp = other->sk_security;
Casey Schaufler975d5e52011-09-26 14:43:39 -07003024 struct socket_smack *nsp = newsk->sk_security;
Etienne Bassetecfcc532009-04-08 20:40:06 +02003025 struct smk_audit_info ad;
Casey Schauflerb4e0d5f2010-11-24 17:12:10 -08003026 int rc = 0;
Casey Schauflere114e472008-02-04 22:29:50 -08003027
Kees Cook923e9a12012-04-10 13:26:44 -07003028#ifdef CONFIG_AUDIT
3029 struct lsm_network_audit net;
3030
Eric Paris48c62af2012-04-02 13:15:44 -04003031 smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net);
David S. Miller3610cda2011-01-05 15:38:53 -08003032 smk_ad_setfield_u_net_sk(&ad, other);
Kees Cook923e9a12012-04-10 13:26:44 -07003033#endif
Casey Schauflerb4e0d5f2010-11-24 17:12:10 -08003034
Casey Schaufler2f823ff2013-05-22 18:43:03 -07003035 if (!smack_privileged(CAP_MAC_OVERRIDE)) {
3036 skp = ssp->smk_out;
3037 rc = smk_access(skp, osp->smk_in, MAY_WRITE, &ad);
3038 }
Casey Schauflerb4e0d5f2010-11-24 17:12:10 -08003039
Casey Schaufler975d5e52011-09-26 14:43:39 -07003040 /*
3041 * Cross reference the peer labels for SO_PEERSEC.
3042 */
3043 if (rc == 0) {
Casey Schaufler2f823ff2013-05-22 18:43:03 -07003044 nsp->smk_packet = ssp->smk_out->smk_known;
3045 ssp->smk_packet = osp->smk_out->smk_known;
Casey Schaufler975d5e52011-09-26 14:43:39 -07003046 }
3047
Casey Schauflerb4e0d5f2010-11-24 17:12:10 -08003048 return rc;
Casey Schauflere114e472008-02-04 22:29:50 -08003049}
3050
3051/**
3052 * smack_unix_may_send - Smack access on UDS
3053 * @sock: one socket
3054 * @other: the other socket
3055 *
3056 * Return 0 if a subject with the smack of sock could access
3057 * an object with the smack of other, otherwise an error code
3058 */
3059static int smack_unix_may_send(struct socket *sock, struct socket *other)
3060{
Casey Schauflerb4e0d5f2010-11-24 17:12:10 -08003061 struct socket_smack *ssp = sock->sk->sk_security;
3062 struct socket_smack *osp = other->sk->sk_security;
Casey Schaufler2f823ff2013-05-22 18:43:03 -07003063 struct smack_known *skp;
Etienne Bassetecfcc532009-04-08 20:40:06 +02003064 struct smk_audit_info ad;
Casey Schauflere114e472008-02-04 22:29:50 -08003065
Kees Cook923e9a12012-04-10 13:26:44 -07003066#ifdef CONFIG_AUDIT
3067 struct lsm_network_audit net;
3068
Eric Paris48c62af2012-04-02 13:15:44 -04003069 smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net);
Etienne Bassetecfcc532009-04-08 20:40:06 +02003070 smk_ad_setfield_u_net_sk(&ad, other->sk);
Kees Cook923e9a12012-04-10 13:26:44 -07003071#endif
Casey Schauflerb4e0d5f2010-11-24 17:12:10 -08003072
Casey Schaufler2f823ff2013-05-22 18:43:03 -07003073 if (smack_privileged(CAP_MAC_OVERRIDE))
3074 return 0;
Casey Schauflerb4e0d5f2010-11-24 17:12:10 -08003075
Casey Schaufler2f823ff2013-05-22 18:43:03 -07003076 skp = ssp->smk_out;
3077 return smk_access(skp, osp->smk_in, MAY_WRITE, &ad);
Casey Schauflere114e472008-02-04 22:29:50 -08003078}
3079
3080/**
Casey Schaufler6d3dc072008-12-31 12:54:12 -05003081 * smack_socket_sendmsg - Smack check based on destination host
3082 * @sock: the socket
Randy Dunlap251a2a92009-02-18 11:42:33 -08003083 * @msg: the message
Casey Schaufler6d3dc072008-12-31 12:54:12 -05003084 * @size: the size of the message
3085 *
Casey Schauflerc6739442013-05-22 18:42:56 -07003086 * Return 0 if the current subject can write to the destination host.
3087 * For IPv4 this is only a question if the destination is a single label host.
3088 * For IPv6 this is a check against the label of the port.
Casey Schaufler6d3dc072008-12-31 12:54:12 -05003089 */
3090static int smack_socket_sendmsg(struct socket *sock, struct msghdr *msg,
3091 int size)
3092{
3093 struct sockaddr_in *sip = (struct sockaddr_in *) msg->msg_name;
Casey Schaufler6ea06242013-08-05 13:21:22 -07003094 struct sockaddr_in6 *sap = (struct sockaddr_in6 *) msg->msg_name;
Casey Schauflerc6739442013-05-22 18:42:56 -07003095 int rc = 0;
Casey Schaufler6d3dc072008-12-31 12:54:12 -05003096
3097 /*
3098 * Perfectly reasonable for this to be NULL
3099 */
Casey Schauflerc6739442013-05-22 18:42:56 -07003100 if (sip == NULL)
Casey Schaufler6d3dc072008-12-31 12:54:12 -05003101 return 0;
3102
Casey Schauflerc6739442013-05-22 18:42:56 -07003103 switch (sip->sin_family) {
3104 case AF_INET:
3105 rc = smack_netlabel_send(sock->sk, sip);
3106 break;
3107 case AF_INET6:
3108 rc = smk_ipv6_port_check(sock->sk, sap, SMK_SENDING);
3109 break;
3110 }
3111 return rc;
Casey Schaufler6d3dc072008-12-31 12:54:12 -05003112}
3113
Casey Schaufler6d3dc072008-12-31 12:54:12 -05003114/**
Randy Dunlap251a2a92009-02-18 11:42:33 -08003115 * smack_from_secattr - Convert a netlabel attr.mls.lvl/attr.mls.cat pair to smack
Casey Schauflere114e472008-02-04 22:29:50 -08003116 * @sap: netlabel secattr
Casey Schaufler272cd7a2011-09-20 12:24:36 -07003117 * @ssp: socket security information
Casey Schauflere114e472008-02-04 22:29:50 -08003118 *
Casey Schaufler2f823ff2013-05-22 18:43:03 -07003119 * Returns a pointer to a Smack label entry found on the label list.
Casey Schauflere114e472008-02-04 22:29:50 -08003120 */
Casey Schaufler2f823ff2013-05-22 18:43:03 -07003121static struct smack_known *smack_from_secattr(struct netlbl_lsm_secattr *sap,
3122 struct socket_smack *ssp)
Casey Schauflere114e472008-02-04 22:29:50 -08003123{
Casey Schaufler2f823ff2013-05-22 18:43:03 -07003124 struct smack_known *skp;
Casey Schauflerf7112e62012-05-06 15:22:02 -07003125 int found = 0;
Casey Schaufler677264e2013-06-28 13:47:07 -07003126 int acat;
3127 int kcat;
Casey Schauflere114e472008-02-04 22:29:50 -08003128
Casey Schaufler6d3dc072008-12-31 12:54:12 -05003129 if ((sap->flags & NETLBL_SECATTR_MLS_LVL) != 0) {
Casey Schauflere114e472008-02-04 22:29:50 -08003130 /*
Casey Schaufler6d3dc072008-12-31 12:54:12 -05003131 * Looks like a CIPSO packet.
Casey Schauflere114e472008-02-04 22:29:50 -08003132 * If there are flags but no level netlabel isn't
3133 * behaving the way we expect it to.
3134 *
Casey Schauflerf7112e62012-05-06 15:22:02 -07003135 * Look it up in the label table
Casey Schauflere114e472008-02-04 22:29:50 -08003136 * Without guidance regarding the smack value
3137 * for the packet fall back on the network
3138 * ambient value.
3139 */
Casey Schauflerf7112e62012-05-06 15:22:02 -07003140 rcu_read_lock();
Casey Schaufler2f823ff2013-05-22 18:43:03 -07003141 list_for_each_entry(skp, &smack_known_list, list) {
3142 if (sap->attr.mls.lvl != skp->smk_netlabel.attr.mls.lvl)
Casey Schauflerf7112e62012-05-06 15:22:02 -07003143 continue;
Casey Schaufler677264e2013-06-28 13:47:07 -07003144 /*
3145 * Compare the catsets. Use the netlbl APIs.
3146 */
3147 if ((sap->flags & NETLBL_SECATTR_MLS_CAT) == 0) {
3148 if ((skp->smk_netlabel.flags &
3149 NETLBL_SECATTR_MLS_CAT) == 0)
3150 found = 1;
3151 break;
3152 }
3153 for (acat = -1, kcat = -1; acat == kcat; ) {
3154 acat = netlbl_secattr_catmap_walk(
3155 sap->attr.mls.cat, acat + 1);
3156 kcat = netlbl_secattr_catmap_walk(
3157 skp->smk_netlabel.attr.mls.cat,
3158 kcat + 1);
3159 if (acat < 0 || kcat < 0)
3160 break;
3161 }
3162 if (acat == kcat) {
3163 found = 1;
3164 break;
3165 }
Casey Schauflere114e472008-02-04 22:29:50 -08003166 }
Casey Schauflerf7112e62012-05-06 15:22:02 -07003167 rcu_read_unlock();
3168
3169 if (found)
Casey Schaufler2f823ff2013-05-22 18:43:03 -07003170 return skp;
Casey Schauflerf7112e62012-05-06 15:22:02 -07003171
Casey Schaufler272cd7a2011-09-20 12:24:36 -07003172 if (ssp != NULL && ssp->smk_in == smack_known_star.smk_known)
Casey Schaufler2f823ff2013-05-22 18:43:03 -07003173 return &smack_known_web;
3174 return &smack_known_star;
Casey Schaufler6d3dc072008-12-31 12:54:12 -05003175 }
3176 if ((sap->flags & NETLBL_SECATTR_SECID) != 0) {
3177 /*
3178 * Looks like a fallback, which gives us a secid.
3179 */
Casey Schaufler2f823ff2013-05-22 18:43:03 -07003180 skp = smack_from_secid(sap->attr.secid);
Casey Schaufler6d3dc072008-12-31 12:54:12 -05003181 /*
3182 * This has got to be a bug because it is
3183 * impossible to specify a fallback without
3184 * specifying the label, which will ensure
3185 * it has a secid, and the only way to get a
3186 * secid is from a fallback.
3187 */
Casey Schaufler2f823ff2013-05-22 18:43:03 -07003188 BUG_ON(skp == NULL);
3189 return skp;
Casey Schauflere114e472008-02-04 22:29:50 -08003190 }
3191 /*
Casey Schaufler6d3dc072008-12-31 12:54:12 -05003192 * Without guidance regarding the smack value
3193 * for the packet fall back on the network
3194 * ambient value.
Casey Schauflere114e472008-02-04 22:29:50 -08003195 */
Casey Schaufler272cd7a2011-09-20 12:24:36 -07003196 return smack_net_ambient;
Casey Schauflere114e472008-02-04 22:29:50 -08003197}
3198
Casey Schaufler6ea06242013-08-05 13:21:22 -07003199static int smk_skb_to_addr_ipv6(struct sk_buff *skb, struct sockaddr_in6 *sip)
Casey Schauflerc6739442013-05-22 18:42:56 -07003200{
Casey Schauflerc6739442013-05-22 18:42:56 -07003201 u8 nexthdr;
3202 int offset;
3203 int proto = -EINVAL;
3204 struct ipv6hdr _ipv6h;
3205 struct ipv6hdr *ip6;
3206 __be16 frag_off;
3207 struct tcphdr _tcph, *th;
3208 struct udphdr _udph, *uh;
3209 struct dccp_hdr _dccph, *dh;
3210
3211 sip->sin6_port = 0;
3212
3213 offset = skb_network_offset(skb);
3214 ip6 = skb_header_pointer(skb, offset, sizeof(_ipv6h), &_ipv6h);
3215 if (ip6 == NULL)
3216 return -EINVAL;
3217 sip->sin6_addr = ip6->saddr;
3218
3219 nexthdr = ip6->nexthdr;
3220 offset += sizeof(_ipv6h);
3221 offset = ipv6_skip_exthdr(skb, offset, &nexthdr, &frag_off);
3222 if (offset < 0)
3223 return -EINVAL;
3224
3225 proto = nexthdr;
3226 switch (proto) {
3227 case IPPROTO_TCP:
3228 th = skb_header_pointer(skb, offset, sizeof(_tcph), &_tcph);
3229 if (th != NULL)
3230 sip->sin6_port = th->source;
3231 break;
3232 case IPPROTO_UDP:
3233 uh = skb_header_pointer(skb, offset, sizeof(_udph), &_udph);
3234 if (uh != NULL)
3235 sip->sin6_port = uh->source;
3236 break;
3237 case IPPROTO_DCCP:
3238 dh = skb_header_pointer(skb, offset, sizeof(_dccph), &_dccph);
3239 if (dh != NULL)
3240 sip->sin6_port = dh->dccph_sport;
3241 break;
3242 }
3243 return proto;
3244}
3245
Casey Schauflere114e472008-02-04 22:29:50 -08003246/**
3247 * smack_socket_sock_rcv_skb - Smack packet delivery access check
3248 * @sk: socket
3249 * @skb: packet
3250 *
3251 * Returns 0 if the packet should be delivered, an error code otherwise
3252 */
3253static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
3254{
3255 struct netlbl_lsm_secattr secattr;
3256 struct socket_smack *ssp = sk->sk_security;
Casey Schaufler2f823ff2013-05-22 18:43:03 -07003257 struct smack_known *skp;
Casey Schaufler6ea06242013-08-05 13:21:22 -07003258 struct sockaddr_in6 sadd;
Casey Schauflerc6739442013-05-22 18:42:56 -07003259 int rc = 0;
Etienne Bassetecfcc532009-04-08 20:40:06 +02003260 struct smk_audit_info ad;
Kees Cook923e9a12012-04-10 13:26:44 -07003261#ifdef CONFIG_AUDIT
Eric Paris48c62af2012-04-02 13:15:44 -04003262 struct lsm_network_audit net;
Kees Cook923e9a12012-04-10 13:26:44 -07003263#endif
Casey Schauflerc6739442013-05-22 18:42:56 -07003264 switch (sk->sk_family) {
3265 case PF_INET:
3266 /*
3267 * Translate what netlabel gave us.
3268 */
3269 netlbl_secattr_init(&secattr);
Casey Schauflere114e472008-02-04 22:29:50 -08003270
Casey Schauflerc6739442013-05-22 18:42:56 -07003271 rc = netlbl_skbuff_getattr(skb, sk->sk_family, &secattr);
3272 if (rc == 0)
Casey Schaufler2f823ff2013-05-22 18:43:03 -07003273 skp = smack_from_secattr(&secattr, ssp);
Casey Schauflerc6739442013-05-22 18:42:56 -07003274 else
Casey Schaufler2f823ff2013-05-22 18:43:03 -07003275 skp = smack_net_ambient;
Casey Schaufler6d3dc072008-12-31 12:54:12 -05003276
Casey Schauflerc6739442013-05-22 18:42:56 -07003277 netlbl_secattr_destroy(&secattr);
Casey Schaufler6d3dc072008-12-31 12:54:12 -05003278
Etienne Bassetecfcc532009-04-08 20:40:06 +02003279#ifdef CONFIG_AUDIT
Casey Schauflerc6739442013-05-22 18:42:56 -07003280 smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net);
3281 ad.a.u.net->family = sk->sk_family;
3282 ad.a.u.net->netif = skb->skb_iif;
3283 ipv4_skb_to_auditdata(skb, &ad.a, NULL);
Etienne Bassetecfcc532009-04-08 20:40:06 +02003284#endif
Casey Schauflerc6739442013-05-22 18:42:56 -07003285 /*
3286 * Receiving a packet requires that the other end
3287 * be able to write here. Read access is not required.
3288 * This is the simplist possible security model
3289 * for networking.
3290 */
Casey Schaufler2f823ff2013-05-22 18:43:03 -07003291 rc = smk_access(skp, ssp->smk_in, MAY_WRITE, &ad);
Casey Schauflerc6739442013-05-22 18:42:56 -07003292 if (rc != 0)
3293 netlbl_skbuff_err(skb, rc, 0);
3294 break;
3295 case PF_INET6:
3296 rc = smk_skb_to_addr_ipv6(skb, &sadd);
3297 if (rc == IPPROTO_UDP || rc == IPPROTO_TCP)
3298 rc = smk_ipv6_port_check(sk, &sadd, SMK_RECEIVING);
3299 else
3300 rc = 0;
3301 break;
3302 }
Paul Moorea8134292008-10-10 10:16:31 -04003303 return rc;
Casey Schauflere114e472008-02-04 22:29:50 -08003304}
3305
3306/**
3307 * smack_socket_getpeersec_stream - pull in packet label
3308 * @sock: the socket
3309 * @optval: user's destination
3310 * @optlen: size thereof
Randy Dunlap251a2a92009-02-18 11:42:33 -08003311 * @len: max thereof
Casey Schauflere114e472008-02-04 22:29:50 -08003312 *
3313 * returns zero on success, an error code otherwise
3314 */
3315static int smack_socket_getpeersec_stream(struct socket *sock,
3316 char __user *optval,
3317 int __user *optlen, unsigned len)
3318{
3319 struct socket_smack *ssp;
Casey Schaufler272cd7a2011-09-20 12:24:36 -07003320 char *rcp = "";
3321 int slen = 1;
Casey Schauflere114e472008-02-04 22:29:50 -08003322 int rc = 0;
3323
3324 ssp = sock->sk->sk_security;
Casey Schaufler272cd7a2011-09-20 12:24:36 -07003325 if (ssp->smk_packet != NULL) {
3326 rcp = ssp->smk_packet;
3327 slen = strlen(rcp) + 1;
3328 }
Casey Schauflere114e472008-02-04 22:29:50 -08003329
3330 if (slen > len)
3331 rc = -ERANGE;
Casey Schaufler272cd7a2011-09-20 12:24:36 -07003332 else if (copy_to_user(optval, rcp, slen) != 0)
Casey Schauflere114e472008-02-04 22:29:50 -08003333 rc = -EFAULT;
3334
3335 if (put_user(slen, optlen) != 0)
3336 rc = -EFAULT;
3337
3338 return rc;
3339}
3340
3341
3342/**
3343 * smack_socket_getpeersec_dgram - pull in packet label
Casey Schauflerb4e0d5f2010-11-24 17:12:10 -08003344 * @sock: the peer socket
Casey Schauflere114e472008-02-04 22:29:50 -08003345 * @skb: packet data
3346 * @secid: pointer to where to put the secid of the packet
3347 *
3348 * Sets the netlabel socket state on sk from parent
3349 */
3350static int smack_socket_getpeersec_dgram(struct socket *sock,
3351 struct sk_buff *skb, u32 *secid)
3352
3353{
3354 struct netlbl_lsm_secattr secattr;
Casey Schaufler272cd7a2011-09-20 12:24:36 -07003355 struct socket_smack *ssp = NULL;
Casey Schaufler2f823ff2013-05-22 18:43:03 -07003356 struct smack_known *skp;
Casey Schauflerb4e0d5f2010-11-24 17:12:10 -08003357 int family = PF_UNSPEC;
3358 u32 s = 0; /* 0 is the invalid secid */
Casey Schauflere114e472008-02-04 22:29:50 -08003359 int rc;
3360
Casey Schauflerb4e0d5f2010-11-24 17:12:10 -08003361 if (skb != NULL) {
3362 if (skb->protocol == htons(ETH_P_IP))
3363 family = PF_INET;
3364 else if (skb->protocol == htons(ETH_P_IPV6))
3365 family = PF_INET6;
Casey Schauflere114e472008-02-04 22:29:50 -08003366 }
Casey Schauflerb4e0d5f2010-11-24 17:12:10 -08003367 if (family == PF_UNSPEC && sock != NULL)
3368 family = sock->sk->sk_family;
Casey Schauflere114e472008-02-04 22:29:50 -08003369
Casey Schauflerb4e0d5f2010-11-24 17:12:10 -08003370 if (family == PF_UNIX) {
Casey Schaufler272cd7a2011-09-20 12:24:36 -07003371 ssp = sock->sk->sk_security;
Casey Schaufler2f823ff2013-05-22 18:43:03 -07003372 s = ssp->smk_out->smk_secid;
Casey Schauflerb4e0d5f2010-11-24 17:12:10 -08003373 } else if (family == PF_INET || family == PF_INET6) {
3374 /*
3375 * Translate what netlabel gave us.
3376 */
Casey Schaufler272cd7a2011-09-20 12:24:36 -07003377 if (sock != NULL && sock->sk != NULL)
3378 ssp = sock->sk->sk_security;
Casey Schauflerb4e0d5f2010-11-24 17:12:10 -08003379 netlbl_secattr_init(&secattr);
3380 rc = netlbl_skbuff_getattr(skb, family, &secattr);
3381 if (rc == 0) {
Casey Schaufler2f823ff2013-05-22 18:43:03 -07003382 skp = smack_from_secattr(&secattr, ssp);
3383 s = skp->smk_secid;
Casey Schauflerb4e0d5f2010-11-24 17:12:10 -08003384 }
3385 netlbl_secattr_destroy(&secattr);
3386 }
3387 *secid = s;
Casey Schauflere114e472008-02-04 22:29:50 -08003388 if (s == 0)
3389 return -EINVAL;
Casey Schauflere114e472008-02-04 22:29:50 -08003390 return 0;
3391}
3392
3393/**
Paul Moore07feee82009-03-27 17:10:54 -04003394 * smack_sock_graft - Initialize a newly created socket with an existing sock
3395 * @sk: child sock
3396 * @parent: parent socket
Casey Schauflere114e472008-02-04 22:29:50 -08003397 *
Paul Moore07feee82009-03-27 17:10:54 -04003398 * Set the smk_{in,out} state of an existing sock based on the process that
3399 * is creating the new socket.
Casey Schauflere114e472008-02-04 22:29:50 -08003400 */
3401static void smack_sock_graft(struct sock *sk, struct socket *parent)
3402{
3403 struct socket_smack *ssp;
Casey Schaufler2f823ff2013-05-22 18:43:03 -07003404 struct smack_known *skp = smk_of_current();
Casey Schauflere114e472008-02-04 22:29:50 -08003405
Paul Moore07feee82009-03-27 17:10:54 -04003406 if (sk == NULL ||
3407 (sk->sk_family != PF_INET && sk->sk_family != PF_INET6))
Casey Schauflere114e472008-02-04 22:29:50 -08003408 return;
3409
3410 ssp = sk->sk_security;
Casey Schaufler2f823ff2013-05-22 18:43:03 -07003411 ssp->smk_in = skp->smk_known;
3412 ssp->smk_out = skp;
Paul Moore07feee82009-03-27 17:10:54 -04003413 /* cssp->smk_packet is already set in smack_inet_csk_clone() */
Casey Schauflere114e472008-02-04 22:29:50 -08003414}
3415
3416/**
3417 * smack_inet_conn_request - Smack access check on connect
3418 * @sk: socket involved
3419 * @skb: packet
3420 * @req: unused
3421 *
3422 * Returns 0 if a task with the packet label could write to
3423 * the socket, otherwise an error code
3424 */
3425static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb,
3426 struct request_sock *req)
3427{
Paul Moore07feee82009-03-27 17:10:54 -04003428 u16 family = sk->sk_family;
Casey Schauflerf7112e62012-05-06 15:22:02 -07003429 struct smack_known *skp;
Casey Schauflere114e472008-02-04 22:29:50 -08003430 struct socket_smack *ssp = sk->sk_security;
Paul Moore07feee82009-03-27 17:10:54 -04003431 struct netlbl_lsm_secattr secattr;
3432 struct sockaddr_in addr;
3433 struct iphdr *hdr;
Casey Schauflerf7112e62012-05-06 15:22:02 -07003434 char *hsp;
Casey Schauflere114e472008-02-04 22:29:50 -08003435 int rc;
Etienne Bassetecfcc532009-04-08 20:40:06 +02003436 struct smk_audit_info ad;
Kees Cook923e9a12012-04-10 13:26:44 -07003437#ifdef CONFIG_AUDIT
Eric Paris48c62af2012-04-02 13:15:44 -04003438 struct lsm_network_audit net;
Kees Cook923e9a12012-04-10 13:26:44 -07003439#endif
Casey Schauflere114e472008-02-04 22:29:50 -08003440
Casey Schauflerc6739442013-05-22 18:42:56 -07003441 if (family == PF_INET6) {
3442 /*
3443 * Handle mapped IPv4 packets arriving
3444 * via IPv6 sockets. Don't set up netlabel
3445 * processing on IPv6.
3446 */
3447 if (skb->protocol == htons(ETH_P_IP))
3448 family = PF_INET;
3449 else
3450 return 0;
3451 }
Casey Schauflere114e472008-02-04 22:29:50 -08003452
Paul Moore07feee82009-03-27 17:10:54 -04003453 netlbl_secattr_init(&secattr);
3454 rc = netlbl_skbuff_getattr(skb, family, &secattr);
Casey Schauflere114e472008-02-04 22:29:50 -08003455 if (rc == 0)
Casey Schaufler2f823ff2013-05-22 18:43:03 -07003456 skp = smack_from_secattr(&secattr, ssp);
Casey Schauflere114e472008-02-04 22:29:50 -08003457 else
Casey Schaufler2f823ff2013-05-22 18:43:03 -07003458 skp = &smack_known_huh;
Paul Moore07feee82009-03-27 17:10:54 -04003459 netlbl_secattr_destroy(&secattr);
3460
Etienne Bassetecfcc532009-04-08 20:40:06 +02003461#ifdef CONFIG_AUDIT
Eric Paris48c62af2012-04-02 13:15:44 -04003462 smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net);
3463 ad.a.u.net->family = family;
3464 ad.a.u.net->netif = skb->skb_iif;
Etienne Bassetecfcc532009-04-08 20:40:06 +02003465 ipv4_skb_to_auditdata(skb, &ad.a, NULL);
3466#endif
Casey Schauflere114e472008-02-04 22:29:50 -08003467 /*
Paul Moore07feee82009-03-27 17:10:54 -04003468 * Receiving a packet requires that the other end be able to write
3469 * here. Read access is not required.
Casey Schauflere114e472008-02-04 22:29:50 -08003470 */
Casey Schaufler2f823ff2013-05-22 18:43:03 -07003471 rc = smk_access(skp, ssp->smk_in, MAY_WRITE, &ad);
Paul Moore07feee82009-03-27 17:10:54 -04003472 if (rc != 0)
3473 return rc;
3474
3475 /*
3476 * Save the peer's label in the request_sock so we can later setup
3477 * smk_packet in the child socket so that SO_PEERCRED can report it.
3478 */
Casey Schaufler2f823ff2013-05-22 18:43:03 -07003479 req->peer_secid = skp->smk_secid;
Paul Moore07feee82009-03-27 17:10:54 -04003480
3481 /*
3482 * We need to decide if we want to label the incoming connection here
3483 * if we do we only need to label the request_sock and the stack will
Lucas De Marchi25985ed2011-03-30 22:57:33 -03003484 * propagate the wire-label to the sock when it is created.
Paul Moore07feee82009-03-27 17:10:54 -04003485 */
3486 hdr = ip_hdr(skb);
3487 addr.sin_addr.s_addr = hdr->saddr;
3488 rcu_read_lock();
Casey Schauflerf7112e62012-05-06 15:22:02 -07003489 hsp = smack_host_label(&addr);
3490 rcu_read_unlock();
3491
Casey Schaufler2f823ff2013-05-22 18:43:03 -07003492 if (hsp == NULL)
Casey Schauflerf7112e62012-05-06 15:22:02 -07003493 rc = netlbl_req_setattr(req, &skp->smk_netlabel);
Casey Schaufler2f823ff2013-05-22 18:43:03 -07003494 else
Paul Moore07feee82009-03-27 17:10:54 -04003495 netlbl_req_delattr(req);
Casey Schauflere114e472008-02-04 22:29:50 -08003496
3497 return rc;
3498}
3499
Paul Moore07feee82009-03-27 17:10:54 -04003500/**
3501 * smack_inet_csk_clone - Copy the connection information to the new socket
3502 * @sk: the new socket
3503 * @req: the connection's request_sock
3504 *
3505 * Transfer the connection's peer label to the newly created socket.
3506 */
3507static void smack_inet_csk_clone(struct sock *sk,
3508 const struct request_sock *req)
3509{
3510 struct socket_smack *ssp = sk->sk_security;
Casey Schaufler2f823ff2013-05-22 18:43:03 -07003511 struct smack_known *skp;
Paul Moore07feee82009-03-27 17:10:54 -04003512
Casey Schaufler2f823ff2013-05-22 18:43:03 -07003513 if (req->peer_secid != 0) {
3514 skp = smack_from_secid(req->peer_secid);
3515 ssp->smk_packet = skp->smk_known;
3516 } else
Casey Schaufler272cd7a2011-09-20 12:24:36 -07003517 ssp->smk_packet = NULL;
Paul Moore07feee82009-03-27 17:10:54 -04003518}
3519
Casey Schauflere114e472008-02-04 22:29:50 -08003520/*
3521 * Key management security hooks
3522 *
3523 * Casey has not tested key support very heavily.
3524 * The permission check is most likely too restrictive.
3525 * If you care about keys please have a look.
3526 */
3527#ifdef CONFIG_KEYS
3528
3529/**
3530 * smack_key_alloc - Set the key security blob
3531 * @key: object
David Howellsd84f4f92008-11-14 10:39:23 +11003532 * @cred: the credentials to use
Casey Schauflere114e472008-02-04 22:29:50 -08003533 * @flags: unused
3534 *
3535 * No allocation required
3536 *
3537 * Returns 0
3538 */
David Howellsd84f4f92008-11-14 10:39:23 +11003539static int smack_key_alloc(struct key *key, const struct cred *cred,
Casey Schauflere114e472008-02-04 22:29:50 -08003540 unsigned long flags)
3541{
Casey Schaufler2f823ff2013-05-22 18:43:03 -07003542 struct smack_known *skp = smk_of_task(cred->security);
3543
3544 key->security = skp->smk_known;
Casey Schauflere114e472008-02-04 22:29:50 -08003545 return 0;
3546}
3547
3548/**
3549 * smack_key_free - Clear the key security blob
3550 * @key: the object
3551 *
3552 * Clear the blob pointer
3553 */
3554static void smack_key_free(struct key *key)
3555{
3556 key->security = NULL;
3557}
3558
3559/*
3560 * smack_key_permission - Smack access on a key
3561 * @key_ref: gets to the object
David Howellsd84f4f92008-11-14 10:39:23 +11003562 * @cred: the credentials to use
Casey Schauflere114e472008-02-04 22:29:50 -08003563 * @perm: unused
3564 *
3565 * Return 0 if the task has read and write to the object,
3566 * an error code otherwise
3567 */
3568static int smack_key_permission(key_ref_t key_ref,
David Howellsd84f4f92008-11-14 10:39:23 +11003569 const struct cred *cred, key_perm_t perm)
Casey Schauflere114e472008-02-04 22:29:50 -08003570{
3571 struct key *keyp;
Etienne Bassetecfcc532009-04-08 20:40:06 +02003572 struct smk_audit_info ad;
Casey Schaufler2f823ff2013-05-22 18:43:03 -07003573 struct smack_known *tkp = smk_of_task(cred->security);
Casey Schauflere114e472008-02-04 22:29:50 -08003574
3575 keyp = key_ref_to_ptr(key_ref);
3576 if (keyp == NULL)
3577 return -EINVAL;
3578 /*
3579 * If the key hasn't been initialized give it access so that
3580 * it may do so.
3581 */
3582 if (keyp->security == NULL)
3583 return 0;
3584 /*
3585 * This should not occur
3586 */
Casey Schaufler2f823ff2013-05-22 18:43:03 -07003587 if (tkp == NULL)
Casey Schauflere114e472008-02-04 22:29:50 -08003588 return -EACCES;
Etienne Bassetecfcc532009-04-08 20:40:06 +02003589#ifdef CONFIG_AUDIT
3590 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_KEY);
3591 ad.a.u.key_struct.key = keyp->serial;
3592 ad.a.u.key_struct.key_desc = keyp->description;
3593#endif
Casey Schaufler2f823ff2013-05-22 18:43:03 -07003594 return smk_access(tkp, keyp->security, MAY_READWRITE, &ad);
Casey Schauflere114e472008-02-04 22:29:50 -08003595}
3596#endif /* CONFIG_KEYS */
3597
3598/*
Ahmed S. Darwishd20bdda2008-04-30 08:34:10 +10003599 * Smack Audit hooks
3600 *
3601 * Audit requires a unique representation of each Smack specific
3602 * rule. This unique representation is used to distinguish the
3603 * object to be audited from remaining kernel objects and also
3604 * works as a glue between the audit hooks.
3605 *
3606 * Since repository entries are added but never deleted, we'll use
3607 * the smack_known label address related to the given audit rule as
3608 * the needed unique representation. This also better fits the smack
3609 * model where nearly everything is a label.
3610 */
3611#ifdef CONFIG_AUDIT
3612
3613/**
3614 * smack_audit_rule_init - Initialize a smack audit rule
3615 * @field: audit rule fields given from user-space (audit.h)
3616 * @op: required testing operator (=, !=, >, <, ...)
3617 * @rulestr: smack label to be audited
3618 * @vrule: pointer to save our own audit rule representation
3619 *
3620 * Prepare to audit cases where (@field @op @rulestr) is true.
3621 * The label to be audited is created if necessay.
3622 */
3623static int smack_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule)
3624{
3625 char **rule = (char **)vrule;
3626 *rule = NULL;
3627
3628 if (field != AUDIT_SUBJ_USER && field != AUDIT_OBJ_USER)
3629 return -EINVAL;
3630
Al Viro5af75d82008-12-16 05:59:26 -05003631 if (op != Audit_equal && op != Audit_not_equal)
Ahmed S. Darwishd20bdda2008-04-30 08:34:10 +10003632 return -EINVAL;
3633
3634 *rule = smk_import(rulestr, 0);
3635
3636 return 0;
3637}
3638
3639/**
3640 * smack_audit_rule_known - Distinguish Smack audit rules
3641 * @krule: rule of interest, in Audit kernel representation format
3642 *
3643 * This is used to filter Smack rules from remaining Audit ones.
3644 * If it's proved that this rule belongs to us, the
3645 * audit_rule_match hook will be called to do the final judgement.
3646 */
3647static int smack_audit_rule_known(struct audit_krule *krule)
3648{
3649 struct audit_field *f;
3650 int i;
3651
3652 for (i = 0; i < krule->field_count; i++) {
3653 f = &krule->fields[i];
3654
3655 if (f->type == AUDIT_SUBJ_USER || f->type == AUDIT_OBJ_USER)
3656 return 1;
3657 }
3658
3659 return 0;
3660}
3661
3662/**
3663 * smack_audit_rule_match - Audit given object ?
3664 * @secid: security id for identifying the object to test
3665 * @field: audit rule flags given from user-space
3666 * @op: required testing operator
3667 * @vrule: smack internal rule presentation
3668 * @actx: audit context associated with the check
3669 *
3670 * The core Audit hook. It's used to take the decision of
3671 * whether to audit or not to audit a given object.
3672 */
3673static int smack_audit_rule_match(u32 secid, u32 field, u32 op, void *vrule,
3674 struct audit_context *actx)
3675{
Casey Schaufler2f823ff2013-05-22 18:43:03 -07003676 struct smack_known *skp;
Ahmed S. Darwishd20bdda2008-04-30 08:34:10 +10003677 char *rule = vrule;
3678
3679 if (!rule) {
Tetsuo Handaceffec552012-03-29 16:19:05 +09003680 audit_log(actx, GFP_ATOMIC, AUDIT_SELINUX_ERR,
Ahmed S. Darwishd20bdda2008-04-30 08:34:10 +10003681 "Smack: missing rule\n");
3682 return -ENOENT;
3683 }
3684
3685 if (field != AUDIT_SUBJ_USER && field != AUDIT_OBJ_USER)
3686 return 0;
3687
Casey Schaufler2f823ff2013-05-22 18:43:03 -07003688 skp = smack_from_secid(secid);
Ahmed S. Darwishd20bdda2008-04-30 08:34:10 +10003689
3690 /*
3691 * No need to do string comparisons. If a match occurs,
3692 * both pointers will point to the same smack_known
3693 * label.
3694 */
Al Viro5af75d82008-12-16 05:59:26 -05003695 if (op == Audit_equal)
Casey Schaufler2f823ff2013-05-22 18:43:03 -07003696 return (rule == skp->smk_known);
Al Viro5af75d82008-12-16 05:59:26 -05003697 if (op == Audit_not_equal)
Casey Schaufler2f823ff2013-05-22 18:43:03 -07003698 return (rule != skp->smk_known);
Ahmed S. Darwishd20bdda2008-04-30 08:34:10 +10003699
3700 return 0;
3701}
3702
3703/**
3704 * smack_audit_rule_free - free smack rule representation
3705 * @vrule: rule to be freed.
3706 *
3707 * No memory was allocated.
3708 */
3709static void smack_audit_rule_free(void *vrule)
3710{
3711 /* No-op */
3712}
3713
3714#endif /* CONFIG_AUDIT */
3715
Randy Dunlap251a2a92009-02-18 11:42:33 -08003716/**
David Quigley746df9b2013-05-22 12:50:35 -04003717 * smack_ismaclabel - check if xattr @name references a smack MAC label
3718 * @name: Full xattr name to check.
3719 */
3720static int smack_ismaclabel(const char *name)
3721{
3722 return (strcmp(name, XATTR_SMACK_SUFFIX) == 0);
3723}
3724
3725
3726/**
Casey Schauflere114e472008-02-04 22:29:50 -08003727 * smack_secid_to_secctx - return the smack label for a secid
3728 * @secid: incoming integer
3729 * @secdata: destination
3730 * @seclen: how long it is
3731 *
3732 * Exists for networking code.
3733 */
3734static int smack_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
3735{
Casey Schaufler2f823ff2013-05-22 18:43:03 -07003736 struct smack_known *skp = smack_from_secid(secid);
Casey Schauflere114e472008-02-04 22:29:50 -08003737
Eric Parisd5630b92010-10-13 16:24:48 -04003738 if (secdata)
Casey Schaufler2f823ff2013-05-22 18:43:03 -07003739 *secdata = skp->smk_known;
3740 *seclen = strlen(skp->smk_known);
Casey Schauflere114e472008-02-04 22:29:50 -08003741 return 0;
3742}
3743
Randy Dunlap251a2a92009-02-18 11:42:33 -08003744/**
Casey Schaufler4bc87e62008-02-15 15:24:25 -08003745 * smack_secctx_to_secid - return the secid for a smack label
3746 * @secdata: smack label
3747 * @seclen: how long result is
3748 * @secid: outgoing integer
3749 *
3750 * Exists for audit and networking code.
3751 */
David Howellse52c17642008-04-29 20:52:51 +01003752static int smack_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid)
Casey Schaufler4bc87e62008-02-15 15:24:25 -08003753{
3754 *secid = smack_to_secid(secdata);
3755 return 0;
3756}
3757
Randy Dunlap251a2a92009-02-18 11:42:33 -08003758/**
Casey Schauflere114e472008-02-04 22:29:50 -08003759 * smack_release_secctx - don't do anything.
Randy Dunlap251a2a92009-02-18 11:42:33 -08003760 * @secdata: unused
3761 * @seclen: unused
Casey Schauflere114e472008-02-04 22:29:50 -08003762 *
3763 * Exists to make sure nothing gets done, and properly
3764 */
3765static void smack_release_secctx(char *secdata, u32 seclen)
3766{
3767}
3768
David P. Quigley1ee65e32009-09-03 14:25:57 -04003769static int smack_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen)
3770{
3771 return smack_inode_setsecurity(inode, XATTR_SMACK_SUFFIX, ctx, ctxlen, 0);
3772}
3773
3774static int smack_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen)
3775{
3776 return __vfs_setxattr_noperm(dentry, XATTR_NAME_SMACK, ctx, ctxlen, 0);
3777}
3778
3779static int smack_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen)
3780{
3781 int len = 0;
3782 len = smack_inode_getsecurity(inode, XATTR_SMACK_SUFFIX, ctx, true);
3783
3784 if (len < 0)
3785 return len;
3786 *ctxlen = len;
3787 return 0;
3788}
3789
Ahmed S. Darwish076c54c2008-03-06 18:09:10 +02003790struct security_operations smack_ops = {
3791 .name = "smack",
3792
Ingo Molnar9e488582009-05-07 19:26:19 +10003793 .ptrace_access_check = smack_ptrace_access_check,
David Howells5cd9c582008-08-14 11:37:28 +01003794 .ptrace_traceme = smack_ptrace_traceme,
Casey Schauflere114e472008-02-04 22:29:50 -08003795 .syslog = smack_syslog,
Casey Schauflere114e472008-02-04 22:29:50 -08003796
3797 .sb_alloc_security = smack_sb_alloc_security,
3798 .sb_free_security = smack_sb_free_security,
3799 .sb_copy_data = smack_sb_copy_data,
3800 .sb_kern_mount = smack_sb_kern_mount,
3801 .sb_statfs = smack_sb_statfs,
Casey Schauflere114e472008-02-04 22:29:50 -08003802
Casey Schaufler676dac42010-12-02 06:43:39 -08003803 .bprm_set_creds = smack_bprm_set_creds,
Jarkko Sakkinen84088ba2011-10-07 09:27:53 +03003804 .bprm_committing_creds = smack_bprm_committing_creds,
3805 .bprm_secureexec = smack_bprm_secureexec,
Casey Schaufler676dac42010-12-02 06:43:39 -08003806
Casey Schauflere114e472008-02-04 22:29:50 -08003807 .inode_alloc_security = smack_inode_alloc_security,
3808 .inode_free_security = smack_inode_free_security,
3809 .inode_init_security = smack_inode_init_security,
3810 .inode_link = smack_inode_link,
3811 .inode_unlink = smack_inode_unlink,
3812 .inode_rmdir = smack_inode_rmdir,
3813 .inode_rename = smack_inode_rename,
3814 .inode_permission = smack_inode_permission,
3815 .inode_setattr = smack_inode_setattr,
3816 .inode_getattr = smack_inode_getattr,
3817 .inode_setxattr = smack_inode_setxattr,
3818 .inode_post_setxattr = smack_inode_post_setxattr,
3819 .inode_getxattr = smack_inode_getxattr,
3820 .inode_removexattr = smack_inode_removexattr,
3821 .inode_getsecurity = smack_inode_getsecurity,
3822 .inode_setsecurity = smack_inode_setsecurity,
3823 .inode_listsecurity = smack_inode_listsecurity,
Ahmed S. Darwishd20bdda2008-04-30 08:34:10 +10003824 .inode_getsecid = smack_inode_getsecid,
Casey Schauflere114e472008-02-04 22:29:50 -08003825
3826 .file_permission = smack_file_permission,
3827 .file_alloc_security = smack_file_alloc_security,
3828 .file_free_security = smack_file_free_security,
3829 .file_ioctl = smack_file_ioctl,
3830 .file_lock = smack_file_lock,
3831 .file_fcntl = smack_file_fcntl,
Al Viroe5467852012-05-30 13:30:51 -04003832 .mmap_file = smack_mmap_file,
3833 .mmap_addr = cap_mmap_addr,
Casey Schauflere114e472008-02-04 22:29:50 -08003834 .file_set_fowner = smack_file_set_fowner,
3835 .file_send_sigiotask = smack_file_send_sigiotask,
3836 .file_receive = smack_file_receive,
3837
Eric Paris83d49852012-04-04 13:45:40 -04003838 .file_open = smack_file_open,
Casey Schaufler531f1d42011-09-19 12:41:42 -07003839
David Howellsee18d642009-09-02 09:14:21 +01003840 .cred_alloc_blank = smack_cred_alloc_blank,
David Howellsf1752ee2008-11-14 10:39:17 +11003841 .cred_free = smack_cred_free,
David Howellsd84f4f92008-11-14 10:39:23 +11003842 .cred_prepare = smack_cred_prepare,
David Howellsee18d642009-09-02 09:14:21 +01003843 .cred_transfer = smack_cred_transfer,
David Howells3a3b7ce2008-11-14 10:39:28 +11003844 .kernel_act_as = smack_kernel_act_as,
3845 .kernel_create_files_as = smack_kernel_create_files_as,
Casey Schauflere114e472008-02-04 22:29:50 -08003846 .task_setpgid = smack_task_setpgid,
3847 .task_getpgid = smack_task_getpgid,
3848 .task_getsid = smack_task_getsid,
3849 .task_getsecid = smack_task_getsecid,
3850 .task_setnice = smack_task_setnice,
3851 .task_setioprio = smack_task_setioprio,
3852 .task_getioprio = smack_task_getioprio,
3853 .task_setscheduler = smack_task_setscheduler,
3854 .task_getscheduler = smack_task_getscheduler,
3855 .task_movememory = smack_task_movememory,
3856 .task_kill = smack_task_kill,
3857 .task_wait = smack_task_wait,
Casey Schauflere114e472008-02-04 22:29:50 -08003858 .task_to_inode = smack_task_to_inode,
3859
3860 .ipc_permission = smack_ipc_permission,
Ahmed S. Darwishd20bdda2008-04-30 08:34:10 +10003861 .ipc_getsecid = smack_ipc_getsecid,
Casey Schauflere114e472008-02-04 22:29:50 -08003862
3863 .msg_msg_alloc_security = smack_msg_msg_alloc_security,
3864 .msg_msg_free_security = smack_msg_msg_free_security,
3865
3866 .msg_queue_alloc_security = smack_msg_queue_alloc_security,
3867 .msg_queue_free_security = smack_msg_queue_free_security,
3868 .msg_queue_associate = smack_msg_queue_associate,
3869 .msg_queue_msgctl = smack_msg_queue_msgctl,
3870 .msg_queue_msgsnd = smack_msg_queue_msgsnd,
3871 .msg_queue_msgrcv = smack_msg_queue_msgrcv,
3872
3873 .shm_alloc_security = smack_shm_alloc_security,
3874 .shm_free_security = smack_shm_free_security,
3875 .shm_associate = smack_shm_associate,
3876 .shm_shmctl = smack_shm_shmctl,
3877 .shm_shmat = smack_shm_shmat,
3878
3879 .sem_alloc_security = smack_sem_alloc_security,
3880 .sem_free_security = smack_sem_free_security,
3881 .sem_associate = smack_sem_associate,
3882 .sem_semctl = smack_sem_semctl,
3883 .sem_semop = smack_sem_semop,
3884
Casey Schauflere114e472008-02-04 22:29:50 -08003885 .d_instantiate = smack_d_instantiate,
3886
3887 .getprocattr = smack_getprocattr,
3888 .setprocattr = smack_setprocattr,
3889
3890 .unix_stream_connect = smack_unix_stream_connect,
3891 .unix_may_send = smack_unix_may_send,
3892
3893 .socket_post_create = smack_socket_post_create,
Casey Schauflerc6739442013-05-22 18:42:56 -07003894 .socket_bind = smack_socket_bind,
Casey Schaufler6d3dc072008-12-31 12:54:12 -05003895 .socket_connect = smack_socket_connect,
3896 .socket_sendmsg = smack_socket_sendmsg,
Casey Schauflere114e472008-02-04 22:29:50 -08003897 .socket_sock_rcv_skb = smack_socket_sock_rcv_skb,
3898 .socket_getpeersec_stream = smack_socket_getpeersec_stream,
3899 .socket_getpeersec_dgram = smack_socket_getpeersec_dgram,
3900 .sk_alloc_security = smack_sk_alloc_security,
3901 .sk_free_security = smack_sk_free_security,
3902 .sock_graft = smack_sock_graft,
3903 .inet_conn_request = smack_inet_conn_request,
Paul Moore07feee82009-03-27 17:10:54 -04003904 .inet_csk_clone = smack_inet_csk_clone,
Ahmed S. Darwishd20bdda2008-04-30 08:34:10 +10003905
Casey Schauflere114e472008-02-04 22:29:50 -08003906 /* key management security hooks */
3907#ifdef CONFIG_KEYS
3908 .key_alloc = smack_key_alloc,
3909 .key_free = smack_key_free,
3910 .key_permission = smack_key_permission,
3911#endif /* CONFIG_KEYS */
Ahmed S. Darwishd20bdda2008-04-30 08:34:10 +10003912
3913 /* Audit hooks */
3914#ifdef CONFIG_AUDIT
3915 .audit_rule_init = smack_audit_rule_init,
3916 .audit_rule_known = smack_audit_rule_known,
3917 .audit_rule_match = smack_audit_rule_match,
3918 .audit_rule_free = smack_audit_rule_free,
3919#endif /* CONFIG_AUDIT */
3920
David Quigley746df9b2013-05-22 12:50:35 -04003921 .ismaclabel = smack_ismaclabel,
Casey Schauflere114e472008-02-04 22:29:50 -08003922 .secid_to_secctx = smack_secid_to_secctx,
Casey Schaufler4bc87e62008-02-15 15:24:25 -08003923 .secctx_to_secid = smack_secctx_to_secid,
Casey Schauflere114e472008-02-04 22:29:50 -08003924 .release_secctx = smack_release_secctx,
David P. Quigley1ee65e32009-09-03 14:25:57 -04003925 .inode_notifysecctx = smack_inode_notifysecctx,
3926 .inode_setsecctx = smack_inode_setsecctx,
3927 .inode_getsecctx = smack_inode_getsecctx,
Casey Schauflere114e472008-02-04 22:29:50 -08003928};
3929
Etienne Basset7198e2e2009-03-24 20:53:24 +01003930
Casey Schaufler86812bb2012-04-17 18:55:46 -07003931static __init void init_smack_known_list(void)
Etienne Basset7198e2e2009-03-24 20:53:24 +01003932{
Casey Schaufler86812bb2012-04-17 18:55:46 -07003933 /*
Casey Schaufler86812bb2012-04-17 18:55:46 -07003934 * Initialize rule list locks
3935 */
3936 mutex_init(&smack_known_huh.smk_rules_lock);
3937 mutex_init(&smack_known_hat.smk_rules_lock);
3938 mutex_init(&smack_known_floor.smk_rules_lock);
3939 mutex_init(&smack_known_star.smk_rules_lock);
3940 mutex_init(&smack_known_invalid.smk_rules_lock);
3941 mutex_init(&smack_known_web.smk_rules_lock);
3942 /*
3943 * Initialize rule lists
3944 */
3945 INIT_LIST_HEAD(&smack_known_huh.smk_rules);
3946 INIT_LIST_HEAD(&smack_known_hat.smk_rules);
3947 INIT_LIST_HEAD(&smack_known_star.smk_rules);
3948 INIT_LIST_HEAD(&smack_known_floor.smk_rules);
3949 INIT_LIST_HEAD(&smack_known_invalid.smk_rules);
3950 INIT_LIST_HEAD(&smack_known_web.smk_rules);
3951 /*
3952 * Create the known labels list
3953 */
Tomasz Stanislawski4d7cf4a2013-06-11 14:55:13 +02003954 smk_insert_entry(&smack_known_huh);
3955 smk_insert_entry(&smack_known_hat);
3956 smk_insert_entry(&smack_known_star);
3957 smk_insert_entry(&smack_known_floor);
3958 smk_insert_entry(&smack_known_invalid);
3959 smk_insert_entry(&smack_known_web);
Etienne Basset7198e2e2009-03-24 20:53:24 +01003960}
3961
Casey Schauflere114e472008-02-04 22:29:50 -08003962/**
3963 * smack_init - initialize the smack system
3964 *
3965 * Returns 0
3966 */
3967static __init int smack_init(void)
3968{
David Howellsd84f4f92008-11-14 10:39:23 +11003969 struct cred *cred;
Casey Schaufler676dac42010-12-02 06:43:39 -08003970 struct task_smack *tsp;
David Howellsd84f4f92008-11-14 10:39:23 +11003971
Casey Schaufler7898e1f2011-01-17 08:05:27 -08003972 if (!security_module_enable(&smack_ops))
3973 return 0;
3974
Casey Schaufler2f823ff2013-05-22 18:43:03 -07003975 tsp = new_task_smack(&smack_known_floor, &smack_known_floor,
3976 GFP_KERNEL);
Casey Schaufler676dac42010-12-02 06:43:39 -08003977 if (tsp == NULL)
3978 return -ENOMEM;
3979
Casey Schauflere114e472008-02-04 22:29:50 -08003980 printk(KERN_INFO "Smack: Initializing.\n");
3981
3982 /*
3983 * Set the security state for the initial task.
3984 */
David Howellsd84f4f92008-11-14 10:39:23 +11003985 cred = (struct cred *) current->cred;
Casey Schaufler676dac42010-12-02 06:43:39 -08003986 cred->security = tsp;
Casey Schauflere114e472008-02-04 22:29:50 -08003987
Casey Schaufler86812bb2012-04-17 18:55:46 -07003988 /* initialize the smack_known_list */
3989 init_smack_known_list();
Casey Schauflere114e472008-02-04 22:29:50 -08003990
3991 /*
3992 * Register with LSM
3993 */
3994 if (register_security(&smack_ops))
3995 panic("smack: Unable to register with kernel.\n");
3996
3997 return 0;
3998}
3999
4000/*
4001 * Smack requires early initialization in order to label
4002 * all processes and objects when they are created.
4003 */
4004security_initcall(smack_init);