Blame view

security/smack/smack_lsm.c 86.5 KB
e114e4737   Casey Schaufler   Smack: Simplified...
1
2
3
4
5
  /*
   *  Simplified MAC Kernel (smack) security module
   *
   *  This file contains the smack hook function implementations.
   *
5c6d1125f   Jarkko Sakkinen   Smack: Transmute ...
6
   *  Authors:
e114e4737   Casey Schaufler   Smack: Simplified...
7
   *	Casey Schaufler <casey@schaufler-ca.com>
84088ba23   Jarkko Sakkinen   Smack: domain tra...
8
   *	Jarkko Sakkinen <jarkko.sakkinen@intel.com>
e114e4737   Casey Schaufler   Smack: Simplified...
9
10
   *
   *  Copyright (C) 2007 Casey Schaufler <casey@schaufler-ca.com>
07feee8f8   Paul Moore   netlabel: Cleanup...
11
   *  Copyright (C) 2009 Hewlett-Packard Development Company, L.P.
82c21bfab   Paul Moore   doc: Update the e...
12
   *                Paul Moore <paul@paul-moore.com>
5c6d1125f   Jarkko Sakkinen   Smack: Transmute ...
13
   *  Copyright (C) 2010 Nokia Corporation
84088ba23   Jarkko Sakkinen   Smack: domain tra...
14
   *  Copyright (C) 2011 Intel Corporation.
e114e4737   Casey Schaufler   Smack: Simplified...
15
16
17
18
19
20
21
22
23
24
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License version 2,
   *      as published by the Free Software Foundation.
   */
  
  #include <linux/xattr.h>
  #include <linux/pagemap.h>
  #include <linux/mount.h>
  #include <linux/stat.h>
e114e4737   Casey Schaufler   Smack: Simplified...
25
26
  #include <linux/kd.h>
  #include <asm/ioctls.h>
07feee8f8   Paul Moore   netlabel: Cleanup...
27
  #include <linux/ip.h>
e114e4737   Casey Schaufler   Smack: Simplified...
28
29
  #include <linux/tcp.h>
  #include <linux/udp.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
30
  #include <linux/slab.h>
e114e4737   Casey Schaufler   Smack: Simplified...
31
32
33
34
  #include <linux/mutex.h>
  #include <linux/pipe_fs_i.h>
  #include <net/netlabel.h>
  #include <net/cipso_ipv4.h>
d20bdda6d   Ahmed S. Darwish   Smack: Integrate ...
35
  #include <linux/audit.h>
1fd7317d0   Nick Black   Move magic number...
36
  #include <linux/magic.h>
2a7dba391   Eric Paris   fs/vfs/security: ...
37
  #include <linux/dcache.h>
16014d875   Jarkko Sakkinen   Smack: compilatio...
38
  #include <linux/personality.h>
e114e4737   Casey Schaufler   Smack: Simplified...
39
  #include "smack.h"
c69e8d9c0   David Howells   CRED: Use RCU to ...
40
  #define task_security(task)	(task_cred_xxx((task), security))
5c6d1125f   Jarkko Sakkinen   Smack: Transmute ...
41
42
  #define TRANS_TRUE	"TRUE"
  #define TRANS_TRUE_SIZE	4
e114e4737   Casey Schaufler   Smack: Simplified...
43
44
45
46
47
48
49
50
  /**
   * smk_fetch - Fetch the smack label from a file.
   * @ip: a pointer to the inode
   * @dp: a pointer to the dentry
   *
   * Returns a pointer to the master list entry for the Smack label
   * or NULL if there was no label to fetch.
   */
676dac4b1   Casey Schaufler   This patch adds a...
51
  static char *smk_fetch(const char *name, struct inode *ip, struct dentry *dp)
e114e4737   Casey Schaufler   Smack: Simplified...
52
53
54
55
56
57
  {
  	int rc;
  	char in[SMK_LABELLEN];
  
  	if (ip->i_op->getxattr == NULL)
  		return NULL;
676dac4b1   Casey Schaufler   This patch adds a...
58
  	rc = ip->i_op->getxattr(dp, name, in, SMK_LABELLEN);
e114e4737   Casey Schaufler   Smack: Simplified...
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
  	if (rc < 0)
  		return NULL;
  
  	return smk_import(in, rc);
  }
  
  /**
   * new_inode_smack - allocate an inode security blob
   * @smack: a pointer to the Smack label to use in the blob
   *
   * Returns the new blob or NULL if there's no memory available
   */
  struct inode_smack *new_inode_smack(char *smack)
  {
  	struct inode_smack *isp;
  
  	isp = kzalloc(sizeof(struct inode_smack), GFP_KERNEL);
  	if (isp == NULL)
  		return NULL;
  
  	isp->smk_inode = smack;
  	isp->smk_flags = 0;
  	mutex_init(&isp->smk_lock);
  
  	return isp;
  }
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
  /**
   * new_task_smack - allocate a task security blob
   * @smack: a pointer to the Smack label to use in the blob
   *
   * Returns the new blob or NULL if there's no memory available
   */
  static struct task_smack *new_task_smack(char *task, char *forked, gfp_t gfp)
  {
  	struct task_smack *tsp;
  
  	tsp = kzalloc(sizeof(struct task_smack), gfp);
  	if (tsp == NULL)
  		return NULL;
  
  	tsp->smk_task = task;
  	tsp->smk_forked = forked;
  	INIT_LIST_HEAD(&tsp->smk_rules);
  	mutex_init(&tsp->smk_rules_lock);
  
  	return tsp;
  }
  
  /**
   * smk_copy_rules - copy a rule set
   * @nhead - new rules header pointer
   * @ohead - old rules header pointer
   *
   * Returns 0 on success, -ENOMEM on error
   */
  static int smk_copy_rules(struct list_head *nhead, struct list_head *ohead,
  				gfp_t gfp)
  {
  	struct smack_rule *nrp;
  	struct smack_rule *orp;
  	int rc = 0;
  
  	INIT_LIST_HEAD(nhead);
  
  	list_for_each_entry_rcu(orp, ohead, list) {
  		nrp = kzalloc(sizeof(struct smack_rule), gfp);
  		if (nrp == NULL) {
  			rc = -ENOMEM;
  			break;
  		}
  		*nrp = *orp;
  		list_add_rcu(&nrp->list, nhead);
  	}
  	return rc;
  }
e114e4737   Casey Schaufler   Smack: Simplified...
134
135
136
137
138
139
  /*
   * LSM hooks.
   * We he, that is fun!
   */
  
  /**
9e48858f7   Ingo Molnar   security: rename ...
140
   * smack_ptrace_access_check - Smack approval on PTRACE_ATTACH
e114e4737   Casey Schaufler   Smack: Simplified...
141
   * @ctp: child task pointer
251a2a958   Randy Dunlap   smack: fix lots o...
142
   * @mode: ptrace attachment mode
e114e4737   Casey Schaufler   Smack: Simplified...
143
144
145
146
147
   *
   * Returns 0 if access is OK, an error code otherwise
   *
   * Do the capability checks, and require read and write.
   */
9e48858f7   Ingo Molnar   security: rename ...
148
  static int smack_ptrace_access_check(struct task_struct *ctp, unsigned int mode)
e114e4737   Casey Schaufler   Smack: Simplified...
149
150
  {
  	int rc;
ecfcc53fe   Etienne Basset   smack: implement ...
151
  	struct smk_audit_info ad;
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
152
  	char *tsp;
e114e4737   Casey Schaufler   Smack: Simplified...
153

9e48858f7   Ingo Molnar   security: rename ...
154
  	rc = cap_ptrace_access_check(ctp, mode);
e114e4737   Casey Schaufler   Smack: Simplified...
155
156
  	if (rc != 0)
  		return rc;
676dac4b1   Casey Schaufler   This patch adds a...
157
  	tsp = smk_of_task(task_security(ctp));
ecfcc53fe   Etienne Basset   smack: implement ...
158
159
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK);
  	smk_ad_setfield_u_tsk(&ad, ctp);
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
160
  	rc = smk_curacc(tsp, MAY_READWRITE, &ad);
5cd9c58fb   David Howells   security: Fix set...
161
162
163
164
165
166
167
168
169
170
171
172
173
174
  	return rc;
  }
  
  /**
   * smack_ptrace_traceme - Smack approval on PTRACE_TRACEME
   * @ptp: parent task pointer
   *
   * Returns 0 if access is OK, an error code otherwise
   *
   * Do the capability checks, and require read and write.
   */
  static int smack_ptrace_traceme(struct task_struct *ptp)
  {
  	int rc;
ecfcc53fe   Etienne Basset   smack: implement ...
175
  	struct smk_audit_info ad;
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
176
  	char *tsp;
5cd9c58fb   David Howells   security: Fix set...
177
178
179
180
  
  	rc = cap_ptrace_traceme(ptp);
  	if (rc != 0)
  		return rc;
e114e4737   Casey Schaufler   Smack: Simplified...
181

7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
182
  	tsp = smk_of_task(task_security(ptp));
ecfcc53fe   Etienne Basset   smack: implement ...
183
184
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK);
  	smk_ad_setfield_u_tsk(&ad, ptp);
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
185
  	rc = smk_curacc(tsp, MAY_READWRITE, &ad);
e114e4737   Casey Schaufler   Smack: Simplified...
186
187
188
189
190
191
192
193
194
195
196
  	return rc;
  }
  
  /**
   * smack_syslog - Smack approval on syslog
   * @type: message type
   *
   * Require that the task has the floor label
   *
   * Returns 0 on success, error code otherwise.
   */
12b3052c3   Eric Paris   capabilities/sysl...
197
  static int smack_syslog(int typefrom_file)
e114e4737   Casey Schaufler   Smack: Simplified...
198
  {
12b3052c3   Eric Paris   capabilities/sysl...
199
  	int rc = 0;
676dac4b1   Casey Schaufler   This patch adds a...
200
  	char *sp = smk_of_current();
e114e4737   Casey Schaufler   Smack: Simplified...
201

e114e4737   Casey Schaufler   Smack: Simplified...
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
  	if (capable(CAP_MAC_OVERRIDE))
  		return 0;
  
  	 if (sp != smack_known_floor.smk_known)
  		rc = -EACCES;
  
  	return rc;
  }
  
  
  /*
   * Superblock Hooks.
   */
  
  /**
   * smack_sb_alloc_security - allocate a superblock blob
   * @sb: the superblock getting the blob
   *
   * Returns 0 on success or -ENOMEM on error.
   */
  static int smack_sb_alloc_security(struct super_block *sb)
  {
  	struct superblock_smack *sbsp;
  
  	sbsp = kzalloc(sizeof(struct superblock_smack), GFP_KERNEL);
  
  	if (sbsp == NULL)
  		return -ENOMEM;
  
  	sbsp->smk_root = smack_known_floor.smk_known;
  	sbsp->smk_default = smack_known_floor.smk_known;
  	sbsp->smk_floor = smack_known_floor.smk_known;
  	sbsp->smk_hat = smack_known_hat.smk_known;
  	sbsp->smk_initialized = 0;
  	spin_lock_init(&sbsp->smk_sblock);
  
  	sb->s_security = sbsp;
  
  	return 0;
  }
  
  /**
   * smack_sb_free_security - free a superblock blob
   * @sb: the superblock getting the blob
   *
   */
  static void smack_sb_free_security(struct super_block *sb)
  {
  	kfree(sb->s_security);
  	sb->s_security = NULL;
  }
  
  /**
   * smack_sb_copy_data - copy mount options data for processing
e114e4737   Casey Schaufler   Smack: Simplified...
256
   * @orig: where to start
251a2a958   Randy Dunlap   smack: fix lots o...
257
   * @smackopts: mount options string
e114e4737   Casey Schaufler   Smack: Simplified...
258
259
260
261
262
263
   *
   * Returns 0 on success or -ENOMEM on error.
   *
   * Copy the Smack specific mount options out of the mount
   * options list.
   */
e00075298   Eric Paris   LSM/SELinux: Inte...
264
  static int smack_sb_copy_data(char *orig, char *smackopts)
e114e4737   Casey Schaufler   Smack: Simplified...
265
266
  {
  	char *cp, *commap, *otheropts, *dp;
e114e4737   Casey Schaufler   Smack: Simplified...
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
  	otheropts = (char *)get_zeroed_page(GFP_KERNEL);
  	if (otheropts == NULL)
  		return -ENOMEM;
  
  	for (cp = orig, commap = orig; commap != NULL; cp = commap + 1) {
  		if (strstr(cp, SMK_FSDEFAULT) == cp)
  			dp = smackopts;
  		else if (strstr(cp, SMK_FSFLOOR) == cp)
  			dp = smackopts;
  		else if (strstr(cp, SMK_FSHAT) == cp)
  			dp = smackopts;
  		else if (strstr(cp, SMK_FSROOT) == cp)
  			dp = smackopts;
  		else
  			dp = otheropts;
  
  		commap = strchr(cp, ',');
  		if (commap != NULL)
  			*commap = '\0';
  
  		if (*dp != '\0')
  			strcat(dp, ",");
  		strcat(dp, cp);
  	}
  
  	strcpy(orig, otheropts);
  	free_page((unsigned long)otheropts);
  
  	return 0;
  }
  
  /**
   * smack_sb_kern_mount - Smack specific mount processing
   * @sb: the file system superblock
12204e24b   James Morris   security: pass mo...
301
   * @flags: the mount flags
e114e4737   Casey Schaufler   Smack: Simplified...
302
303
304
305
   * @data: the smack mount options
   *
   * Returns 0 on success, an error code on failure
   */
12204e24b   James Morris   security: pass mo...
306
  static int smack_sb_kern_mount(struct super_block *sb, int flags, void *data)
e114e4737   Casey Schaufler   Smack: Simplified...
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
  {
  	struct dentry *root = sb->s_root;
  	struct inode *inode = root->d_inode;
  	struct superblock_smack *sp = sb->s_security;
  	struct inode_smack *isp;
  	char *op;
  	char *commap;
  	char *nsp;
  
  	spin_lock(&sp->smk_sblock);
  	if (sp->smk_initialized != 0) {
  		spin_unlock(&sp->smk_sblock);
  		return 0;
  	}
  	sp->smk_initialized = 1;
  	spin_unlock(&sp->smk_sblock);
  
  	for (op = data; op != NULL; op = commap) {
  		commap = strchr(op, ',');
  		if (commap != NULL)
  			*commap++ = '\0';
  
  		if (strncmp(op, SMK_FSHAT, strlen(SMK_FSHAT)) == 0) {
  			op += strlen(SMK_FSHAT);
  			nsp = smk_import(op, 0);
  			if (nsp != NULL)
  				sp->smk_hat = nsp;
  		} else if (strncmp(op, SMK_FSFLOOR, strlen(SMK_FSFLOOR)) == 0) {
  			op += strlen(SMK_FSFLOOR);
  			nsp = smk_import(op, 0);
  			if (nsp != NULL)
  				sp->smk_floor = nsp;
  		} else if (strncmp(op, SMK_FSDEFAULT,
  				   strlen(SMK_FSDEFAULT)) == 0) {
  			op += strlen(SMK_FSDEFAULT);
  			nsp = smk_import(op, 0);
  			if (nsp != NULL)
  				sp->smk_default = nsp;
  		} else if (strncmp(op, SMK_FSROOT, strlen(SMK_FSROOT)) == 0) {
  			op += strlen(SMK_FSROOT);
  			nsp = smk_import(op, 0);
  			if (nsp != NULL)
  				sp->smk_root = nsp;
  		}
  	}
  
  	/*
  	 * Initialize the root inode.
  	 */
  	isp = inode->i_security;
  	if (isp == NULL)
  		inode->i_security = new_inode_smack(sp->smk_root);
  	else
  		isp->smk_inode = sp->smk_root;
  
  	return 0;
  }
  
  /**
   * smack_sb_statfs - Smack check on statfs
   * @dentry: identifies the file system in question
   *
   * Returns 0 if current can read the floor of the filesystem,
   * and error code otherwise
   */
  static int smack_sb_statfs(struct dentry *dentry)
  {
  	struct superblock_smack *sbp = dentry->d_sb->s_security;
ecfcc53fe   Etienne Basset   smack: implement ...
375
376
  	int rc;
  	struct smk_audit_info ad;
a269434d2   Eric Paris   LSM: separate LSM...
377
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
ecfcc53fe   Etienne Basset   smack: implement ...
378
  	smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
e114e4737   Casey Schaufler   Smack: Simplified...
379

ecfcc53fe   Etienne Basset   smack: implement ...
380
381
  	rc = smk_curacc(sbp->smk_floor, MAY_READ, &ad);
  	return rc;
e114e4737   Casey Schaufler   Smack: Simplified...
382
383
384
385
386
  }
  
  /**
   * smack_sb_mount - Smack check for mounting
   * @dev_name: unused
251a2a958   Randy Dunlap   smack: fix lots o...
387
   * @path: mount point
e114e4737   Casey Schaufler   Smack: Simplified...
388
389
390
391
392
393
394
   * @type: unused
   * @flags: unused
   * @data: unused
   *
   * Returns 0 if current can write the floor of the filesystem
   * being mounted on, an error code otherwise.
   */
b5266eb4c   Al Viro   [PATCH] switch a ...
395
  static int smack_sb_mount(char *dev_name, struct path *path,
e114e4737   Casey Schaufler   Smack: Simplified...
396
397
  			  char *type, unsigned long flags, void *data)
  {
d8c9584ea   Al Viro   vfs: prefer ->den...
398
  	struct superblock_smack *sbp = path->dentry->d_sb->s_security;
ecfcc53fe   Etienne Basset   smack: implement ...
399
  	struct smk_audit_info ad;
e114e4737   Casey Schaufler   Smack: Simplified...
400

f48b73998   Eric Paris   LSM: split LSM_AU...
401
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
ecfcc53fe   Etienne Basset   smack: implement ...
402
403
404
  	smk_ad_setfield_u_fs_path(&ad, *path);
  
  	return smk_curacc(sbp->smk_floor, MAY_WRITE, &ad);
e114e4737   Casey Schaufler   Smack: Simplified...
405
406
407
408
409
410
411
412
413
414
415
416
417
  }
  
  /**
   * smack_sb_umount - Smack check for unmounting
   * @mnt: file system to unmount
   * @flags: unused
   *
   * Returns 0 if current can write the floor of the filesystem
   * being unmounted, an error code otherwise.
   */
  static int smack_sb_umount(struct vfsmount *mnt, int flags)
  {
  	struct superblock_smack *sbp;
ecfcc53fe   Etienne Basset   smack: implement ...
418
  	struct smk_audit_info ad;
a269434d2   Eric Paris   LSM: separate LSM...
419
  	struct path path;
e114e4737   Casey Schaufler   Smack: Simplified...
420

a269434d2   Eric Paris   LSM: separate LSM...
421
422
  	path.dentry = mnt->mnt_root;
  	path.mnt = mnt;
e114e4737   Casey Schaufler   Smack: Simplified...
423

f48b73998   Eric Paris   LSM: split LSM_AU...
424
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
a269434d2   Eric Paris   LSM: separate LSM...
425
  	smk_ad_setfield_u_fs_path(&ad, path);
e114e4737   Casey Schaufler   Smack: Simplified...
426

d8c9584ea   Al Viro   vfs: prefer ->den...
427
  	sbp = path.dentry->d_sb->s_security;
ecfcc53fe   Etienne Basset   smack: implement ...
428
  	return smk_curacc(sbp->smk_floor, MAY_WRITE, &ad);
e114e4737   Casey Schaufler   Smack: Simplified...
429
430
431
  }
  
  /*
676dac4b1   Casey Schaufler   This patch adds a...
432
433
   * BPRM hooks
   */
ce8a43219   Casey Schaufler   Smack: Clean up c...
434
435
436
437
438
439
  /**
   * smack_bprm_set_creds - set creds for exec
   * @bprm: the exec information
   *
   * Returns 0 if it gets a blob, -ENOMEM otherwise
   */
676dac4b1   Casey Schaufler   This patch adds a...
440
441
  static int smack_bprm_set_creds(struct linux_binprm *bprm)
  {
84088ba23   Jarkko Sakkinen   Smack: domain tra...
442
443
  	struct inode *inode = bprm->file->f_path.dentry->d_inode;
  	struct task_smack *bsp = bprm->cred->security;
676dac4b1   Casey Schaufler   This patch adds a...
444
  	struct inode_smack *isp;
676dac4b1   Casey Schaufler   This patch adds a...
445
446
447
448
449
450
451
452
  	int rc;
  
  	rc = cap_bprm_set_creds(bprm);
  	if (rc != 0)
  		return rc;
  
  	if (bprm->cred_prepared)
  		return 0;
84088ba23   Jarkko Sakkinen   Smack: domain tra...
453
454
  	isp = inode->i_security;
  	if (isp->smk_task == NULL || isp->smk_task == bsp->smk_task)
676dac4b1   Casey Schaufler   This patch adds a...
455
  		return 0;
84088ba23   Jarkko Sakkinen   Smack: domain tra...
456
457
  	if (bprm->unsafe)
  		return -EPERM;
676dac4b1   Casey Schaufler   This patch adds a...
458

84088ba23   Jarkko Sakkinen   Smack: domain tra...
459
460
  	bsp->smk_task = isp->smk_task;
  	bprm->per_clear |= PER_CLEAR_ON_SETID;
676dac4b1   Casey Schaufler   This patch adds a...
461

84088ba23   Jarkko Sakkinen   Smack: domain tra...
462
463
  	return 0;
  }
676dac4b1   Casey Schaufler   This patch adds a...
464

84088ba23   Jarkko Sakkinen   Smack: domain tra...
465
466
467
468
469
470
471
472
473
  /**
   * smack_bprm_committing_creds - Prepare to install the new credentials
   * from bprm.
   *
   * @bprm: binprm for exec
   */
  static void smack_bprm_committing_creds(struct linux_binprm *bprm)
  {
  	struct task_smack *bsp = bprm->cred->security;
676dac4b1   Casey Schaufler   This patch adds a...
474

84088ba23   Jarkko Sakkinen   Smack: domain tra...
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
  	if (bsp->smk_task != bsp->smk_forked)
  		current->pdeath_signal = 0;
  }
  
  /**
   * smack_bprm_secureexec - Return the decision to use secureexec.
   * @bprm: binprm for exec
   *
   * Returns 0 on success.
   */
  static int smack_bprm_secureexec(struct linux_binprm *bprm)
  {
  	struct task_smack *tsp = current_security();
  	int ret = cap_bprm_secureexec(bprm);
  
  	if (!ret && (tsp->smk_task != tsp->smk_forked))
  		ret = 1;
  
  	return ret;
676dac4b1   Casey Schaufler   This patch adds a...
494
495
496
  }
  
  /*
e114e4737   Casey Schaufler   Smack: Simplified...
497
498
499
500
501
   * Inode hooks
   */
  
  /**
   * smack_inode_alloc_security - allocate an inode blob
251a2a958   Randy Dunlap   smack: fix lots o...
502
   * @inode: the inode in need of a blob
e114e4737   Casey Schaufler   Smack: Simplified...
503
504
505
506
507
   *
   * Returns 0 if it gets a blob, -ENOMEM otherwise
   */
  static int smack_inode_alloc_security(struct inode *inode)
  {
676dac4b1   Casey Schaufler   This patch adds a...
508
  	inode->i_security = new_inode_smack(smk_of_current());
e114e4737   Casey Schaufler   Smack: Simplified...
509
510
511
512
513
514
515
  	if (inode->i_security == NULL)
  		return -ENOMEM;
  	return 0;
  }
  
  /**
   * smack_inode_free_security - free an inode blob
251a2a958   Randy Dunlap   smack: fix lots o...
516
   * @inode: the inode with a blob
e114e4737   Casey Schaufler   Smack: Simplified...
517
518
519
520
521
522
523
524
525
526
527
528
529
   *
   * Clears the blob pointer in inode
   */
  static void smack_inode_free_security(struct inode *inode)
  {
  	kfree(inode->i_security);
  	inode->i_security = NULL;
  }
  
  /**
   * smack_inode_init_security - copy out the smack from an inode
   * @inode: the inode
   * @dir: unused
2a7dba391   Eric Paris   fs/vfs/security: ...
530
   * @qstr: unused
e114e4737   Casey Schaufler   Smack: Simplified...
531
532
533
534
535
536
537
   * @name: where to put the attribute name
   * @value: where to put the attribute value
   * @len: where to put the length of the attribute
   *
   * Returns 0 if it all works out, -ENOMEM if there's no memory
   */
  static int smack_inode_init_security(struct inode *inode, struct inode *dir,
2a7dba391   Eric Paris   fs/vfs/security: ...
538
539
  				     const struct qstr *qstr, char **name,
  				     void **value, size_t *len)
e114e4737   Casey Schaufler   Smack: Simplified...
540
  {
272cd7a8c   Casey Schaufler   Smack: Rule list ...
541
542
  	struct smack_known *skp;
  	char *csp = smk_of_current();
e114e4737   Casey Schaufler   Smack: Simplified...
543
  	char *isp = smk_of_inode(inode);
5c6d1125f   Jarkko Sakkinen   Smack: Transmute ...
544
  	char *dsp = smk_of_inode(dir);
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
545
  	int may;
e114e4737   Casey Schaufler   Smack: Simplified...
546
547
548
549
550
551
552
553
  
  	if (name) {
  		*name = kstrdup(XATTR_SMACK_SUFFIX, GFP_KERNEL);
  		if (*name == NULL)
  			return -ENOMEM;
  	}
  
  	if (value) {
272cd7a8c   Casey Schaufler   Smack: Rule list ...
554
  		skp = smk_find_entry(csp);
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
555
  		rcu_read_lock();
272cd7a8c   Casey Schaufler   Smack: Rule list ...
556
  		may = smk_access_entry(csp, dsp, &skp->smk_rules);
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
557
  		rcu_read_unlock();
5c6d1125f   Jarkko Sakkinen   Smack: Transmute ...
558
559
560
561
562
563
  
  		/*
  		 * If the access rule allows transmutation and
  		 * the directory requests transmutation then
  		 * by all means transmute.
  		 */
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
564
565
  		if (may > 0 && ((may & MAY_TRANSMUTE) != 0) &&
  		    smk_inode_transmutable(dir))
5c6d1125f   Jarkko Sakkinen   Smack: Transmute ...
566
  			isp = dsp;
e114e4737   Casey Schaufler   Smack: Simplified...
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
  		*value = kstrdup(isp, GFP_KERNEL);
  		if (*value == NULL)
  			return -ENOMEM;
  	}
  
  	if (len)
  		*len = strlen(isp) + 1;
  
  	return 0;
  }
  
  /**
   * smack_inode_link - Smack check on link
   * @old_dentry: the existing object
   * @dir: unused
   * @new_dentry: the new object
   *
   * Returns 0 if access is permitted, an error code otherwise
   */
  static int smack_inode_link(struct dentry *old_dentry, struct inode *dir,
  			    struct dentry *new_dentry)
  {
e114e4737   Casey Schaufler   Smack: Simplified...
589
  	char *isp;
ecfcc53fe   Etienne Basset   smack: implement ...
590
591
  	struct smk_audit_info ad;
  	int rc;
a269434d2   Eric Paris   LSM: separate LSM...
592
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
ecfcc53fe   Etienne Basset   smack: implement ...
593
  	smk_ad_setfield_u_fs_path_dentry(&ad, old_dentry);
e114e4737   Casey Schaufler   Smack: Simplified...
594
595
  
  	isp = smk_of_inode(old_dentry->d_inode);
ecfcc53fe   Etienne Basset   smack: implement ...
596
  	rc = smk_curacc(isp, MAY_WRITE, &ad);
e114e4737   Casey Schaufler   Smack: Simplified...
597
598
599
  
  	if (rc == 0 && new_dentry->d_inode != NULL) {
  		isp = smk_of_inode(new_dentry->d_inode);
ecfcc53fe   Etienne Basset   smack: implement ...
600
601
  		smk_ad_setfield_u_fs_path_dentry(&ad, new_dentry);
  		rc = smk_curacc(isp, MAY_WRITE, &ad);
e114e4737   Casey Schaufler   Smack: Simplified...
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
  	}
  
  	return rc;
  }
  
  /**
   * smack_inode_unlink - Smack check on inode deletion
   * @dir: containing directory object
   * @dentry: file to unlink
   *
   * Returns 0 if current can write the containing directory
   * and the object, error code otherwise
   */
  static int smack_inode_unlink(struct inode *dir, struct dentry *dentry)
  {
  	struct inode *ip = dentry->d_inode;
ecfcc53fe   Etienne Basset   smack: implement ...
618
  	struct smk_audit_info ad;
e114e4737   Casey Schaufler   Smack: Simplified...
619
  	int rc;
a269434d2   Eric Paris   LSM: separate LSM...
620
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
ecfcc53fe   Etienne Basset   smack: implement ...
621
  	smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
e114e4737   Casey Schaufler   Smack: Simplified...
622
623
624
  	/*
  	 * You need write access to the thing you're unlinking
  	 */
ecfcc53fe   Etienne Basset   smack: implement ...
625
626
  	rc = smk_curacc(smk_of_inode(ip), MAY_WRITE, &ad);
  	if (rc == 0) {
e114e4737   Casey Schaufler   Smack: Simplified...
627
628
629
  		/*
  		 * You also need write access to the containing directory
  		 */
ecfcc53fe   Etienne Basset   smack: implement ...
630
631
632
633
  		smk_ad_setfield_u_fs_path_dentry(&ad, NULL);
  		smk_ad_setfield_u_fs_inode(&ad, dir);
  		rc = smk_curacc(smk_of_inode(dir), MAY_WRITE, &ad);
  	}
e114e4737   Casey Schaufler   Smack: Simplified...
634
635
636
637
638
639
640
641
642
643
644
645
646
  	return rc;
  }
  
  /**
   * smack_inode_rmdir - Smack check on directory deletion
   * @dir: containing directory object
   * @dentry: directory to unlink
   *
   * Returns 0 if current can write the containing directory
   * and the directory, error code otherwise
   */
  static int smack_inode_rmdir(struct inode *dir, struct dentry *dentry)
  {
ecfcc53fe   Etienne Basset   smack: implement ...
647
  	struct smk_audit_info ad;
e114e4737   Casey Schaufler   Smack: Simplified...
648
  	int rc;
a269434d2   Eric Paris   LSM: separate LSM...
649
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
ecfcc53fe   Etienne Basset   smack: implement ...
650
  	smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
e114e4737   Casey Schaufler   Smack: Simplified...
651
652
653
  	/*
  	 * You need write access to the thing you're removing
  	 */
ecfcc53fe   Etienne Basset   smack: implement ...
654
655
  	rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE, &ad);
  	if (rc == 0) {
e114e4737   Casey Schaufler   Smack: Simplified...
656
657
658
  		/*
  		 * You also need write access to the containing directory
  		 */
ecfcc53fe   Etienne Basset   smack: implement ...
659
660
661
662
  		smk_ad_setfield_u_fs_path_dentry(&ad, NULL);
  		smk_ad_setfield_u_fs_inode(&ad, dir);
  		rc = smk_curacc(smk_of_inode(dir), MAY_WRITE, &ad);
  	}
e114e4737   Casey Schaufler   Smack: Simplified...
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
  
  	return rc;
  }
  
  /**
   * smack_inode_rename - Smack check on rename
   * @old_inode: the old directory
   * @old_dentry: unused
   * @new_inode: the new directory
   * @new_dentry: unused
   *
   * Read and write access is required on both the old and
   * new directories.
   *
   * Returns 0 if access is permitted, an error code otherwise
   */
  static int smack_inode_rename(struct inode *old_inode,
  			      struct dentry *old_dentry,
  			      struct inode *new_inode,
  			      struct dentry *new_dentry)
  {
  	int rc;
  	char *isp;
ecfcc53fe   Etienne Basset   smack: implement ...
686
  	struct smk_audit_info ad;
a269434d2   Eric Paris   LSM: separate LSM...
687
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
ecfcc53fe   Etienne Basset   smack: implement ...
688
  	smk_ad_setfield_u_fs_path_dentry(&ad, old_dentry);
e114e4737   Casey Schaufler   Smack: Simplified...
689
690
  
  	isp = smk_of_inode(old_dentry->d_inode);
ecfcc53fe   Etienne Basset   smack: implement ...
691
  	rc = smk_curacc(isp, MAY_READWRITE, &ad);
e114e4737   Casey Schaufler   Smack: Simplified...
692
693
694
  
  	if (rc == 0 && new_dentry->d_inode != NULL) {
  		isp = smk_of_inode(new_dentry->d_inode);
ecfcc53fe   Etienne Basset   smack: implement ...
695
696
  		smk_ad_setfield_u_fs_path_dentry(&ad, new_dentry);
  		rc = smk_curacc(isp, MAY_READWRITE, &ad);
e114e4737   Casey Schaufler   Smack: Simplified...
697
  	}
e114e4737   Casey Schaufler   Smack: Simplified...
698
699
700
701
702
703
704
  	return rc;
  }
  
  /**
   * smack_inode_permission - Smack version of permission()
   * @inode: the inode in question
   * @mask: the access requested
e114e4737   Casey Schaufler   Smack: Simplified...
705
706
707
708
709
   *
   * This is the important Smack hook.
   *
   * Returns 0 if access is permitted, -EACCES otherwise
   */
e74f71eb7   Al Viro   ->permission() sa...
710
  static int smack_inode_permission(struct inode *inode, int mask)
e114e4737   Casey Schaufler   Smack: Simplified...
711
  {
ecfcc53fe   Etienne Basset   smack: implement ...
712
  	struct smk_audit_info ad;
e74f71eb7   Al Viro   ->permission() sa...
713
  	int no_block = mask & MAY_NOT_BLOCK;
d09ca7397   Eric Paris   security: make LS...
714
715
  
  	mask &= (MAY_READ|MAY_WRITE|MAY_EXEC|MAY_APPEND);
e114e4737   Casey Schaufler   Smack: Simplified...
716
717
718
719
720
  	/*
  	 * No permission to check. Existence test. Yup, it's there.
  	 */
  	if (mask == 0)
  		return 0;
8c9e80ed2   Andi Kleen   SECURITY: Move ex...
721
722
  
  	/* May be droppable after audit */
e74f71eb7   Al Viro   ->permission() sa...
723
  	if (no_block)
8c9e80ed2   Andi Kleen   SECURITY: Move ex...
724
  		return -ECHILD;
f48b73998   Eric Paris   LSM: split LSM_AU...
725
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_INODE);
ecfcc53fe   Etienne Basset   smack: implement ...
726
727
  	smk_ad_setfield_u_fs_inode(&ad, inode);
  	return smk_curacc(smk_of_inode(inode), mask, &ad);
e114e4737   Casey Schaufler   Smack: Simplified...
728
729
730
731
732
733
734
735
736
737
738
  }
  
  /**
   * smack_inode_setattr - Smack check for setting attributes
   * @dentry: the object
   * @iattr: for the force flag
   *
   * Returns 0 if access is permitted, an error code otherwise
   */
  static int smack_inode_setattr(struct dentry *dentry, struct iattr *iattr)
  {
ecfcc53fe   Etienne Basset   smack: implement ...
739
  	struct smk_audit_info ad;
e114e4737   Casey Schaufler   Smack: Simplified...
740
741
742
743
744
  	/*
  	 * Need to allow for clearing the setuid bit.
  	 */
  	if (iattr->ia_valid & ATTR_FORCE)
  		return 0;
a269434d2   Eric Paris   LSM: separate LSM...
745
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
ecfcc53fe   Etienne Basset   smack: implement ...
746
  	smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
e114e4737   Casey Schaufler   Smack: Simplified...
747

ecfcc53fe   Etienne Basset   smack: implement ...
748
  	return smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE, &ad);
e114e4737   Casey Schaufler   Smack: Simplified...
749
750
751
752
753
754
755
756
757
758
759
  }
  
  /**
   * smack_inode_getattr - Smack check for getting attributes
   * @mnt: unused
   * @dentry: the object
   *
   * Returns 0 if access is permitted, an error code otherwise
   */
  static int smack_inode_getattr(struct vfsmount *mnt, struct dentry *dentry)
  {
ecfcc53fe   Etienne Basset   smack: implement ...
760
  	struct smk_audit_info ad;
a269434d2   Eric Paris   LSM: separate LSM...
761
  	struct path path;
ecfcc53fe   Etienne Basset   smack: implement ...
762

a269434d2   Eric Paris   LSM: separate LSM...
763
764
  	path.dentry = dentry;
  	path.mnt = mnt;
ecfcc53fe   Etienne Basset   smack: implement ...
765

f48b73998   Eric Paris   LSM: split LSM_AU...
766
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
a269434d2   Eric Paris   LSM: separate LSM...
767
  	smk_ad_setfield_u_fs_path(&ad, path);
ecfcc53fe   Etienne Basset   smack: implement ...
768
  	return smk_curacc(smk_of_inode(dentry->d_inode), MAY_READ, &ad);
e114e4737   Casey Schaufler   Smack: Simplified...
769
770
771
772
773
774
775
776
777
778
779
780
781
782
  }
  
  /**
   * smack_inode_setxattr - Smack check for setting xattrs
   * @dentry: the object
   * @name: name of the attribute
   * @value: unused
   * @size: unused
   * @flags: unused
   *
   * This protects the Smack attribute explicitly.
   *
   * Returns 0 if access is permitted, an error code otherwise
   */
8f0cfa52a   David Howells   xattr: add missin...
783
784
  static int smack_inode_setxattr(struct dentry *dentry, const char *name,
  				const void *value, size_t size, int flags)
e114e4737   Casey Schaufler   Smack: Simplified...
785
  {
ecfcc53fe   Etienne Basset   smack: implement ...
786
  	struct smk_audit_info ad;
bcdca225b   Casey Schaufler   Smack: update for...
787
  	int rc = 0;
e114e4737   Casey Schaufler   Smack: Simplified...
788

bcdca225b   Casey Schaufler   Smack: update for...
789
790
  	if (strcmp(name, XATTR_NAME_SMACK) == 0 ||
  	    strcmp(name, XATTR_NAME_SMACKIPIN) == 0 ||
676dac4b1   Casey Schaufler   This patch adds a...
791
  	    strcmp(name, XATTR_NAME_SMACKIPOUT) == 0 ||
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
792
793
  	    strcmp(name, XATTR_NAME_SMACKEXEC) == 0 ||
  	    strcmp(name, XATTR_NAME_SMACKMMAP) == 0) {
bcdca225b   Casey Schaufler   Smack: update for...
794
795
  		if (!capable(CAP_MAC_ADMIN))
  			rc = -EPERM;
defc433ba   Etienne Basset   Smack: check for ...
796
797
798
799
800
801
  		/*
  		 * check label validity here so import wont fail on
  		 * post_setxattr
  		 */
  		if (size == 0 || size >= SMK_LABELLEN ||
  		    smk_import(value, size) == NULL)
4303154e8   Etienne Basset   smack: Add a new ...
802
  			rc = -EINVAL;
5c6d1125f   Jarkko Sakkinen   Smack: Transmute ...
803
804
805
806
807
808
  	} else if (strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0) {
  		if (!capable(CAP_MAC_ADMIN))
  			rc = -EPERM;
  		if (size != TRANS_TRUE_SIZE ||
  		    strncmp(value, TRANS_TRUE, TRANS_TRUE_SIZE) != 0)
  			rc = -EINVAL;
bcdca225b   Casey Schaufler   Smack: update for...
809
810
  	} else
  		rc = cap_inode_setxattr(dentry, name, value, size, flags);
a269434d2   Eric Paris   LSM: separate LSM...
811
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
ecfcc53fe   Etienne Basset   smack: implement ...
812
  	smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
bcdca225b   Casey Schaufler   Smack: update for...
813
  	if (rc == 0)
ecfcc53fe   Etienne Basset   smack: implement ...
814
  		rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE, &ad);
bcdca225b   Casey Schaufler   Smack: update for...
815
816
  
  	return rc;
e114e4737   Casey Schaufler   Smack: Simplified...
817
818
819
820
821
822
823
824
825
826
827
828
829
  }
  
  /**
   * smack_inode_post_setxattr - Apply the Smack update approved above
   * @dentry: object
   * @name: attribute name
   * @value: attribute value
   * @size: attribute size
   * @flags: unused
   *
   * Set the pointer in the inode blob to the entry found
   * in the master label list.
   */
8f0cfa52a   David Howells   xattr: add missin...
830
831
  static void smack_inode_post_setxattr(struct dentry *dentry, const char *name,
  				      const void *value, size_t size, int flags)
e114e4737   Casey Schaufler   Smack: Simplified...
832
  {
e114e4737   Casey Schaufler   Smack: Simplified...
833
  	char *nsp;
5c6d1125f   Jarkko Sakkinen   Smack: Transmute ...
834
  	struct inode_smack *isp = dentry->d_inode->i_security;
676dac4b1   Casey Schaufler   This patch adds a...
835
836
  
  	if (strcmp(name, XATTR_NAME_SMACK) == 0) {
5c6d1125f   Jarkko Sakkinen   Smack: Transmute ...
837
  		nsp = smk_import(value, size);
676dac4b1   Casey Schaufler   This patch adds a...
838
839
840
841
  		if (nsp != NULL)
  			isp->smk_inode = nsp;
  		else
  			isp->smk_inode = smack_known_invalid.smk_known;
5c6d1125f   Jarkko Sakkinen   Smack: Transmute ...
842
843
  	} else if (strcmp(name, XATTR_NAME_SMACKEXEC) == 0) {
  		nsp = smk_import(value, size);
676dac4b1   Casey Schaufler   This patch adds a...
844
845
846
847
  		if (nsp != NULL)
  			isp->smk_task = nsp;
  		else
  			isp->smk_task = smack_known_invalid.smk_known;
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
848
849
850
851
852
853
  	} else if (strcmp(name, XATTR_NAME_SMACKMMAP) == 0) {
  		nsp = smk_import(value, size);
  		if (nsp != NULL)
  			isp->smk_mmap = nsp;
  		else
  			isp->smk_mmap = smack_known_invalid.smk_known;
5c6d1125f   Jarkko Sakkinen   Smack: Transmute ...
854
855
  	} else if (strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0)
  		isp->smk_flags |= SMK_INODE_TRANSMUTE;
e114e4737   Casey Schaufler   Smack: Simplified...
856
857
858
  
  	return;
  }
ce8a43219   Casey Schaufler   Smack: Clean up c...
859
  /**
e114e4737   Casey Schaufler   Smack: Simplified...
860
861
862
863
864
865
   * smack_inode_getxattr - Smack check on getxattr
   * @dentry: the object
   * @name: unused
   *
   * Returns 0 if access is permitted, an error code otherwise
   */
8f0cfa52a   David Howells   xattr: add missin...
866
  static int smack_inode_getxattr(struct dentry *dentry, const char *name)
e114e4737   Casey Schaufler   Smack: Simplified...
867
  {
ecfcc53fe   Etienne Basset   smack: implement ...
868
  	struct smk_audit_info ad;
a269434d2   Eric Paris   LSM: separate LSM...
869
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
ecfcc53fe   Etienne Basset   smack: implement ...
870
871
872
  	smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
  
  	return smk_curacc(smk_of_inode(dentry->d_inode), MAY_READ, &ad);
e114e4737   Casey Schaufler   Smack: Simplified...
873
  }
ce8a43219   Casey Schaufler   Smack: Clean up c...
874
  /**
e114e4737   Casey Schaufler   Smack: Simplified...
875
876
877
878
879
880
881
882
   * smack_inode_removexattr - Smack check on removexattr
   * @dentry: the object
   * @name: name of the attribute
   *
   * Removing the Smack attribute requires CAP_MAC_ADMIN
   *
   * Returns 0 if access is permitted, an error code otherwise
   */
8f0cfa52a   David Howells   xattr: add missin...
883
  static int smack_inode_removexattr(struct dentry *dentry, const char *name)
e114e4737   Casey Schaufler   Smack: Simplified...
884
  {
676dac4b1   Casey Schaufler   This patch adds a...
885
  	struct inode_smack *isp;
ecfcc53fe   Etienne Basset   smack: implement ...
886
  	struct smk_audit_info ad;
bcdca225b   Casey Schaufler   Smack: update for...
887
  	int rc = 0;
e114e4737   Casey Schaufler   Smack: Simplified...
888

bcdca225b   Casey Schaufler   Smack: update for...
889
890
  	if (strcmp(name, XATTR_NAME_SMACK) == 0 ||
  	    strcmp(name, XATTR_NAME_SMACKIPIN) == 0 ||
676dac4b1   Casey Schaufler   This patch adds a...
891
  	    strcmp(name, XATTR_NAME_SMACKIPOUT) == 0 ||
5c6d1125f   Jarkko Sakkinen   Smack: Transmute ...
892
  	    strcmp(name, XATTR_NAME_SMACKEXEC) == 0 ||
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
893
894
  	    strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0 ||
  	    strcmp(name, XATTR_NAME_SMACKMMAP)) {
bcdca225b   Casey Schaufler   Smack: update for...
895
896
897
898
  		if (!capable(CAP_MAC_ADMIN))
  			rc = -EPERM;
  	} else
  		rc = cap_inode_removexattr(dentry, name);
a269434d2   Eric Paris   LSM: separate LSM...
899
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
ecfcc53fe   Etienne Basset   smack: implement ...
900
  	smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
bcdca225b   Casey Schaufler   Smack: update for...
901
  	if (rc == 0)
ecfcc53fe   Etienne Basset   smack: implement ...
902
  		rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE, &ad);
bcdca225b   Casey Schaufler   Smack: update for...
903

676dac4b1   Casey Schaufler   This patch adds a...
904
905
906
  	if (rc == 0) {
  		isp = dentry->d_inode->i_security;
  		isp->smk_task = NULL;
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
907
  		isp->smk_mmap = NULL;
676dac4b1   Casey Schaufler   This patch adds a...
908
  	}
bcdca225b   Casey Schaufler   Smack: update for...
909
  	return rc;
e114e4737   Casey Schaufler   Smack: Simplified...
910
911
912
913
914
915
916
  }
  
  /**
   * smack_inode_getsecurity - get smack xattrs
   * @inode: the object
   * @name: attribute name
   * @buffer: where to put the result
251a2a958   Randy Dunlap   smack: fix lots o...
917
   * @alloc: unused
e114e4737   Casey Schaufler   Smack: Simplified...
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
   *
   * Returns the size of the attribute or an error code
   */
  static int smack_inode_getsecurity(const struct inode *inode,
  				   const char *name, void **buffer,
  				   bool alloc)
  {
  	struct socket_smack *ssp;
  	struct socket *sock;
  	struct super_block *sbp;
  	struct inode *ip = (struct inode *)inode;
  	char *isp;
  	int ilen;
  	int rc = 0;
  
  	if (strcmp(name, XATTR_SMACK_SUFFIX) == 0) {
  		isp = smk_of_inode(inode);
  		ilen = strlen(isp) + 1;
  		*buffer = isp;
  		return ilen;
  	}
  
  	/*
  	 * The rest of the Smack xattrs are only on sockets.
  	 */
  	sbp = ip->i_sb;
  	if (sbp->s_magic != SOCKFS_MAGIC)
  		return -EOPNOTSUPP;
  
  	sock = SOCKET_I(ip);
2e1d146a1   Ahmed S. Darwish   Smack: check for ...
948
  	if (sock == NULL || sock->sk == NULL)
e114e4737   Casey Schaufler   Smack: Simplified...
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
  		return -EOPNOTSUPP;
  
  	ssp = sock->sk->sk_security;
  
  	if (strcmp(name, XATTR_SMACK_IPIN) == 0)
  		isp = ssp->smk_in;
  	else if (strcmp(name, XATTR_SMACK_IPOUT) == 0)
  		isp = ssp->smk_out;
  	else
  		return -EOPNOTSUPP;
  
  	ilen = strlen(isp) + 1;
  	if (rc == 0) {
  		*buffer = isp;
  		rc = ilen;
  	}
  
  	return rc;
  }
  
  
  /**
   * smack_inode_listsecurity - list the Smack attributes
   * @inode: the object
   * @buffer: where they go
   * @buffer_size: size of buffer
   *
   * Returns 0 on success, -EINVAL otherwise
   */
  static int smack_inode_listsecurity(struct inode *inode, char *buffer,
  				    size_t buffer_size)
  {
  	int len = strlen(XATTR_NAME_SMACK);
  
  	if (buffer != NULL && len <= buffer_size) {
  		memcpy(buffer, XATTR_NAME_SMACK, len);
  		return len;
  	}
  	return -EINVAL;
  }
d20bdda6d   Ahmed S. Darwish   Smack: Integrate ...
989
990
991
992
993
994
995
996
997
998
999
  /**
   * smack_inode_getsecid - Extract inode's security id
   * @inode: inode to extract the info from
   * @secid: where result will be saved
   */
  static void smack_inode_getsecid(const struct inode *inode, u32 *secid)
  {
  	struct inode_smack *isp = inode->i_security;
  
  	*secid = smack_to_secid(isp->smk_inode);
  }
e114e4737   Casey Schaufler   Smack: Simplified...
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
  /*
   * File Hooks
   */
  
  /**
   * smack_file_permission - Smack check on file operations
   * @file: unused
   * @mask: unused
   *
   * Returns 0
   *
   * Should access checks be done on each read or write?
   * UNICOS and SELinux say yes.
   * Trusted Solaris, Trusted Irix, and just about everyone else says no.
   *
   * I'll say no for now. Smack does not do the frequent
   * label changing that SELinux does.
   */
  static int smack_file_permission(struct file *file, int mask)
  {
  	return 0;
  }
  
  /**
   * smack_file_alloc_security - assign a file security blob
   * @file: the object
   *
   * The security blob for a file is a pointer to the master
   * label list, so no allocation is done.
   *
   * Returns 0
   */
  static int smack_file_alloc_security(struct file *file)
  {
676dac4b1   Casey Schaufler   This patch adds a...
1034
  	file->f_security = smk_of_current();
e114e4737   Casey Schaufler   Smack: Simplified...
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
  	return 0;
  }
  
  /**
   * smack_file_free_security - clear a file security blob
   * @file: the object
   *
   * The security blob for a file is a pointer to the master
   * label list, so no memory is freed.
   */
  static void smack_file_free_security(struct file *file)
  {
  	file->f_security = NULL;
  }
  
  /**
   * smack_file_ioctl - Smack check on ioctls
   * @file: the object
   * @cmd: what to do
   * @arg: unused
   *
   * Relies heavily on the correct use of the ioctl command conventions.
   *
   * Returns 0 if allowed, error code otherwise
   */
  static int smack_file_ioctl(struct file *file, unsigned int cmd,
  			    unsigned long arg)
  {
  	int rc = 0;
ecfcc53fe   Etienne Basset   smack: implement ...
1064
  	struct smk_audit_info ad;
f48b73998   Eric Paris   LSM: split LSM_AU...
1065
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
ecfcc53fe   Etienne Basset   smack: implement ...
1066
  	smk_ad_setfield_u_fs_path(&ad, file->f_path);
e114e4737   Casey Schaufler   Smack: Simplified...
1067
1068
  
  	if (_IOC_DIR(cmd) & _IOC_WRITE)
ecfcc53fe   Etienne Basset   smack: implement ...
1069
  		rc = smk_curacc(file->f_security, MAY_WRITE, &ad);
e114e4737   Casey Schaufler   Smack: Simplified...
1070
1071
  
  	if (rc == 0 && (_IOC_DIR(cmd) & _IOC_READ))
ecfcc53fe   Etienne Basset   smack: implement ...
1072
  		rc = smk_curacc(file->f_security, MAY_READ, &ad);
e114e4737   Casey Schaufler   Smack: Simplified...
1073
1074
1075
1076
1077
1078
1079
  
  	return rc;
  }
  
  /**
   * smack_file_lock - Smack check on file locking
   * @file: the object
251a2a958   Randy Dunlap   smack: fix lots o...
1080
   * @cmd: unused
e114e4737   Casey Schaufler   Smack: Simplified...
1081
1082
1083
1084
1085
   *
   * Returns 0 if current has write access, error code otherwise
   */
  static int smack_file_lock(struct file *file, unsigned int cmd)
  {
ecfcc53fe   Etienne Basset   smack: implement ...
1086
  	struct smk_audit_info ad;
92f425090   Eric Paris   SMACK: smack_file...
1087
1088
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
  	smk_ad_setfield_u_fs_path(&ad, file->f_path);
ecfcc53fe   Etienne Basset   smack: implement ...
1089
  	return smk_curacc(file->f_security, MAY_WRITE, &ad);
e114e4737   Casey Schaufler   Smack: Simplified...
1090
1091
1092
1093
1094
1095
1096
1097
  }
  
  /**
   * smack_file_fcntl - Smack check on fcntl
   * @file: the object
   * @cmd: what action to check
   * @arg: unused
   *
531f1d453   Casey Schaufler   Smack: Repair pro...
1098
1099
1100
1101
   * Generally these operations are harmless.
   * File locking operations present an obvious mechanism
   * for passing information, so they require write access.
   *
e114e4737   Casey Schaufler   Smack: Simplified...
1102
1103
1104
1105
1106
   * Returns 0 if current has access, error code otherwise
   */
  static int smack_file_fcntl(struct file *file, unsigned int cmd,
  			    unsigned long arg)
  {
ecfcc53fe   Etienne Basset   smack: implement ...
1107
  	struct smk_audit_info ad;
531f1d453   Casey Schaufler   Smack: Repair pro...
1108
  	int rc = 0;
e114e4737   Casey Schaufler   Smack: Simplified...
1109

ecfcc53fe   Etienne Basset   smack: implement ...
1110

e114e4737   Casey Schaufler   Smack: Simplified...
1111
  	switch (cmd) {
e114e4737   Casey Schaufler   Smack: Simplified...
1112
  	case F_GETLK:
e114e4737   Casey Schaufler   Smack: Simplified...
1113
1114
1115
1116
  	case F_SETLK:
  	case F_SETLKW:
  	case F_SETOWN:
  	case F_SETSIG:
531f1d453   Casey Schaufler   Smack: Repair pro...
1117
1118
  		smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
  		smk_ad_setfield_u_fs_path(&ad, file->f_path);
ecfcc53fe   Etienne Basset   smack: implement ...
1119
  		rc = smk_curacc(file->f_security, MAY_WRITE, &ad);
e114e4737   Casey Schaufler   Smack: Simplified...
1120
1121
  		break;
  	default:
531f1d453   Casey Schaufler   Smack: Repair pro...
1122
  		break;
e114e4737   Casey Schaufler   Smack: Simplified...
1123
1124
1125
1126
1127
1128
  	}
  
  	return rc;
  }
  
  /**
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
   * smack_file_mmap :
   * Check permissions for a mmap operation.  The @file may be NULL, e.g.
   * if mapping anonymous memory.
   * @file contains the file structure for file to map (may be NULL).
   * @reqprot contains the protection requested by the application.
   * @prot contains the protection that will be applied by the kernel.
   * @flags contains the operational flags.
   * Return 0 if permission is granted.
   */
  static int smack_file_mmap(struct file *file,
  			   unsigned long reqprot, unsigned long prot,
  			   unsigned long flags, unsigned long addr,
  			   unsigned long addr_only)
  {
272cd7a8c   Casey Schaufler   Smack: Rule list ...
1143
  	struct smack_known *skp;
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1144
1145
1146
1147
  	struct smack_rule *srp;
  	struct task_smack *tsp;
  	char *sp;
  	char *msmack;
0e0a070d3   Casey Schaufler   Smack: correct be...
1148
  	char *osmack;
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1149
1150
  	struct inode_smack *isp;
  	struct dentry *dp;
0e0a070d3   Casey Schaufler   Smack: correct be...
1151
1152
1153
  	int may;
  	int mmay;
  	int tmay;
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
  	int rc;
  
  	/* do DAC check on address space usage */
  	rc = cap_file_mmap(file, reqprot, prot, flags, addr, addr_only);
  	if (rc || addr_only)
  		return rc;
  
  	if (file == NULL || file->f_dentry == NULL)
  		return 0;
  
  	dp = file->f_dentry;
  
  	if (dp->d_inode == NULL)
  		return 0;
  
  	isp = dp->d_inode->i_security;
  	if (isp->smk_mmap == NULL)
  		return 0;
  	msmack = isp->smk_mmap;
  
  	tsp = current_security();
  	sp = smk_of_current();
272cd7a8c   Casey Schaufler   Smack: Rule list ...
1176
  	skp = smk_find_entry(sp);
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1177
1178
1179
1180
1181
1182
1183
  	rc = 0;
  
  	rcu_read_lock();
  	/*
  	 * For each Smack rule associated with the subject
  	 * label verify that the SMACK64MMAP also has access
  	 * to that rule's object label.
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1184
  	 */
272cd7a8c   Casey Schaufler   Smack: Rule list ...
1185
  	list_for_each_entry_rcu(srp, &skp->smk_rules, list) {
0e0a070d3   Casey Schaufler   Smack: correct be...
1186
  		osmack = srp->smk_object;
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1187
1188
1189
  		/*
  		 * Matching labels always allows access.
  		 */
0e0a070d3   Casey Schaufler   Smack: correct be...
1190
  		if (msmack == osmack)
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1191
  			continue;
0e0a070d3   Casey Schaufler   Smack: correct be...
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
  		/*
  		 * If there is a matching local rule take
  		 * that into account as well.
  		 */
  		may = smk_access_entry(srp->smk_subject, osmack,
  					&tsp->smk_rules);
  		if (may == -ENOENT)
  			may = srp->smk_access;
  		else
  			may &= srp->smk_access;
  		/*
  		 * If may is zero the SMACK64MMAP subject can't
  		 * possibly have less access.
  		 */
  		if (may == 0)
  			continue;
  
  		/*
  		 * Fetch the global list entry.
  		 * If there isn't one a SMACK64MMAP subject
  		 * can't have as much access as current.
  		 */
272cd7a8c   Casey Schaufler   Smack: Rule list ...
1214
1215
  		skp = smk_find_entry(msmack);
  		mmay = smk_access_entry(msmack, osmack, &skp->smk_rules);
0e0a070d3   Casey Schaufler   Smack: correct be...
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
  		if (mmay == -ENOENT) {
  			rc = -EACCES;
  			break;
  		}
  		/*
  		 * If there is a local entry it modifies the
  		 * potential access, too.
  		 */
  		tmay = smk_access_entry(msmack, osmack, &tsp->smk_rules);
  		if (tmay != -ENOENT)
  			mmay &= tmay;
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1227

0e0a070d3   Casey Schaufler   Smack: correct be...
1228
1229
1230
1231
1232
  		/*
  		 * If there is any access available to current that is
  		 * not available to a SMACK64MMAP subject
  		 * deny access.
  		 */
75a25637b   Casey Schaufler   Smack: correct fi...
1233
  		if ((may | mmay) != mmay) {
0e0a070d3   Casey Schaufler   Smack: correct be...
1234
  			rc = -EACCES;
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1235
  			break;
0e0a070d3   Casey Schaufler   Smack: correct be...
1236
  		}
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1237
1238
1239
1240
1241
1242
1243
1244
  	}
  
  	rcu_read_unlock();
  
  	return rc;
  }
  
  /**
e114e4737   Casey Schaufler   Smack: Simplified...
1245
1246
1247
1248
1249
1250
1251
1252
   * smack_file_set_fowner - set the file security blob value
   * @file: object in question
   *
   * Returns 0
   * Further research may be required on this one.
   */
  static int smack_file_set_fowner(struct file *file)
  {
676dac4b1   Casey Schaufler   This patch adds a...
1253
  	file->f_security = smk_of_current();
e114e4737   Casey Schaufler   Smack: Simplified...
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
  	return 0;
  }
  
  /**
   * smack_file_send_sigiotask - Smack on sigio
   * @tsk: The target task
   * @fown: the object the signal come from
   * @signum: unused
   *
   * Allow a privileged task to get signals even if it shouldn't
   *
   * Returns 0 if a subject with the object's smack could
   * write to the task, an error code otherwise.
   */
  static int smack_file_send_sigiotask(struct task_struct *tsk,
  				     struct fown_struct *fown, int signum)
  {
  	struct file *file;
  	int rc;
676dac4b1   Casey Schaufler   This patch adds a...
1273
  	char *tsp = smk_of_task(tsk->cred->security);
ecfcc53fe   Etienne Basset   smack: implement ...
1274
  	struct smk_audit_info ad;
e114e4737   Casey Schaufler   Smack: Simplified...
1275
1276
1277
1278
1279
  
  	/*
  	 * struct fown_struct is never outside the context of a struct file
  	 */
  	file = container_of(fown, struct file, f_owner);
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1280

ecfcc53fe   Etienne Basset   smack: implement ...
1281
1282
  	/* we don't log here as rc can be overriden */
  	rc = smk_access(file->f_security, tsp, MAY_WRITE, NULL);
5cd9c58fb   David Howells   security: Fix set...
1283
  	if (rc != 0 && has_capability(tsk, CAP_MAC_OVERRIDE))
ecfcc53fe   Etienne Basset   smack: implement ...
1284
1285
1286
1287
1288
  		rc = 0;
  
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK);
  	smk_ad_setfield_u_tsk(&ad, tsk);
  	smack_log(file->f_security, tsp, MAY_WRITE, rc, &ad);
e114e4737   Casey Schaufler   Smack: Simplified...
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
  	return rc;
  }
  
  /**
   * smack_file_receive - Smack file receive check
   * @file: the object
   *
   * Returns 0 if current has access, error code otherwise
   */
  static int smack_file_receive(struct file *file)
  {
  	int may = 0;
ecfcc53fe   Etienne Basset   smack: implement ...
1301
  	struct smk_audit_info ad;
e114e4737   Casey Schaufler   Smack: Simplified...
1302

ecfcc53fe   Etienne Basset   smack: implement ...
1303
1304
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK);
  	smk_ad_setfield_u_fs_path(&ad, file->f_path);
e114e4737   Casey Schaufler   Smack: Simplified...
1305
1306
1307
1308
1309
1310
1311
  	/*
  	 * This code relies on bitmasks.
  	 */
  	if (file->f_mode & FMODE_READ)
  		may = MAY_READ;
  	if (file->f_mode & FMODE_WRITE)
  		may |= MAY_WRITE;
ecfcc53fe   Etienne Basset   smack: implement ...
1312
  	return smk_curacc(file->f_security, may, &ad);
e114e4737   Casey Schaufler   Smack: Simplified...
1313
  }
531f1d453   Casey Schaufler   Smack: Repair pro...
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
  /**
   * smack_dentry_open - Smack dentry open processing
   * @file: the object
   * @cred: unused
   *
   * Set the security blob in the file structure.
   *
   * Returns 0
   */
  static int smack_dentry_open(struct file *file, const struct cred *cred)
  {
  	struct inode_smack *isp = file->f_path.dentry->d_inode->i_security;
  
  	file->f_security = isp->smk_inode;
  
  	return 0;
  }
e114e4737   Casey Schaufler   Smack: Simplified...
1331
1332
1333
1334
1335
  /*
   * Task hooks
   */
  
  /**
ee18d64c1   David Howells   KEYS: Add a keyct...
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
   * smack_cred_alloc_blank - "allocate" blank task-level security credentials
   * @new: the new credentials
   * @gfp: the atomicity of any memory allocations
   *
   * Prepare a blank set of credentials for modification.  This must allocate all
   * the memory the LSM module might require such that cred_transfer() can
   * complete without error.
   */
  static int smack_cred_alloc_blank(struct cred *cred, gfp_t gfp)
  {
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1346
1347
1348
1349
  	struct task_smack *tsp;
  
  	tsp = new_task_smack(NULL, NULL, gfp);
  	if (tsp == NULL)
676dac4b1   Casey Schaufler   This patch adds a...
1350
  		return -ENOMEM;
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1351
1352
  
  	cred->security = tsp;
ee18d64c1   David Howells   KEYS: Add a keyct...
1353
1354
1355
1356
1357
  	return 0;
  }
  
  
  /**
f1752eec6   David Howells   CRED: Detach the ...
1358
1359
   * smack_cred_free - "free" task-level security credentials
   * @cred: the credentials in question
e114e4737   Casey Schaufler   Smack: Simplified...
1360
   *
e114e4737   Casey Schaufler   Smack: Simplified...
1361
   */
f1752eec6   David Howells   CRED: Detach the ...
1362
  static void smack_cred_free(struct cred *cred)
e114e4737   Casey Schaufler   Smack: Simplified...
1363
  {
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
  	struct task_smack *tsp = cred->security;
  	struct smack_rule *rp;
  	struct list_head *l;
  	struct list_head *n;
  
  	if (tsp == NULL)
  		return;
  	cred->security = NULL;
  
  	list_for_each_safe(l, n, &tsp->smk_rules) {
  		rp = list_entry(l, struct smack_rule, list);
  		list_del(&rp->list);
  		kfree(rp);
  	}
  	kfree(tsp);
e114e4737   Casey Schaufler   Smack: Simplified...
1379
1380
1381
  }
  
  /**
d84f4f992   David Howells   CRED: Inaugurate ...
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
   * smack_cred_prepare - prepare new set of credentials for modification
   * @new: the new credentials
   * @old: the original credentials
   * @gfp: the atomicity of any memory allocations
   *
   * Prepare a new set of credentials for modification.
   */
  static int smack_cred_prepare(struct cred *new, const struct cred *old,
  			      gfp_t gfp)
  {
676dac4b1   Casey Schaufler   This patch adds a...
1392
1393
  	struct task_smack *old_tsp = old->security;
  	struct task_smack *new_tsp;
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1394
  	int rc;
676dac4b1   Casey Schaufler   This patch adds a...
1395

7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1396
  	new_tsp = new_task_smack(old_tsp->smk_task, old_tsp->smk_task, gfp);
676dac4b1   Casey Schaufler   This patch adds a...
1397
1398
  	if (new_tsp == NULL)
  		return -ENOMEM;
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1399
1400
1401
  	rc = smk_copy_rules(&new_tsp->smk_rules, &old_tsp->smk_rules, gfp);
  	if (rc != 0)
  		return rc;
676dac4b1   Casey Schaufler   This patch adds a...
1402
  	new->security = new_tsp;
d84f4f992   David Howells   CRED: Inaugurate ...
1403
1404
  	return 0;
  }
251a2a958   Randy Dunlap   smack: fix lots o...
1405
  /**
ee18d64c1   David Howells   KEYS: Add a keyct...
1406
1407
1408
1409
1410
1411
1412
1413
   * smack_cred_transfer - Transfer the old credentials to the new credentials
   * @new: the new credentials
   * @old: the original credentials
   *
   * Fill in a set of blank credentials from another set of credentials.
   */
  static void smack_cred_transfer(struct cred *new, const struct cred *old)
  {
676dac4b1   Casey Schaufler   This patch adds a...
1414
1415
1416
1417
1418
  	struct task_smack *old_tsp = old->security;
  	struct task_smack *new_tsp = new->security;
  
  	new_tsp->smk_task = old_tsp->smk_task;
  	new_tsp->smk_forked = old_tsp->smk_task;
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1419
1420
1421
1422
1423
  	mutex_init(&new_tsp->smk_rules_lock);
  	INIT_LIST_HEAD(&new_tsp->smk_rules);
  
  
  	/* cbs copy rule list */
ee18d64c1   David Howells   KEYS: Add a keyct...
1424
1425
1426
  }
  
  /**
3a3b7ce93   David Howells   CRED: Allow kerne...
1427
   * smack_kernel_act_as - Set the subjective context in a set of credentials
251a2a958   Randy Dunlap   smack: fix lots o...
1428
1429
   * @new: points to the set of credentials to be modified.
   * @secid: specifies the security ID to be set
3a3b7ce93   David Howells   CRED: Allow kerne...
1430
1431
1432
1433
1434
   *
   * Set the security data for a kernel service.
   */
  static int smack_kernel_act_as(struct cred *new, u32 secid)
  {
676dac4b1   Casey Schaufler   This patch adds a...
1435
  	struct task_smack *new_tsp = new->security;
3a3b7ce93   David Howells   CRED: Allow kerne...
1436
1437
1438
1439
  	char *smack = smack_from_secid(secid);
  
  	if (smack == NULL)
  		return -EINVAL;
676dac4b1   Casey Schaufler   This patch adds a...
1440
  	new_tsp->smk_task = smack;
3a3b7ce93   David Howells   CRED: Allow kerne...
1441
1442
1443
1444
1445
  	return 0;
  }
  
  /**
   * smack_kernel_create_files_as - Set the file creation label in a set of creds
251a2a958   Randy Dunlap   smack: fix lots o...
1446
1447
   * @new: points to the set of credentials to be modified
   * @inode: points to the inode to use as a reference
3a3b7ce93   David Howells   CRED: Allow kerne...
1448
1449
1450
1451
1452
1453
1454
1455
   *
   * Set the file creation context in a set of credentials to the same
   * as the objective context of the specified inode
   */
  static int smack_kernel_create_files_as(struct cred *new,
  					struct inode *inode)
  {
  	struct inode_smack *isp = inode->i_security;
676dac4b1   Casey Schaufler   This patch adds a...
1456
  	struct task_smack *tsp = new->security;
3a3b7ce93   David Howells   CRED: Allow kerne...
1457

676dac4b1   Casey Schaufler   This patch adds a...
1458
1459
  	tsp->smk_forked = isp->smk_inode;
  	tsp->smk_task = isp->smk_inode;
3a3b7ce93   David Howells   CRED: Allow kerne...
1460
1461
1462
1463
  	return 0;
  }
  
  /**
ecfcc53fe   Etienne Basset   smack: implement ...
1464
1465
   * smk_curacc_on_task - helper to log task related access
   * @p: the task object
531f1d453   Casey Schaufler   Smack: Repair pro...
1466
1467
   * @access: the access requested
   * @caller: name of the calling function for audit
ecfcc53fe   Etienne Basset   smack: implement ...
1468
1469
1470
   *
   * Return 0 if access is permitted
   */
531f1d453   Casey Schaufler   Smack: Repair pro...
1471
1472
  static int smk_curacc_on_task(struct task_struct *p, int access,
  				const char *caller)
ecfcc53fe   Etienne Basset   smack: implement ...
1473
1474
  {
  	struct smk_audit_info ad;
531f1d453   Casey Schaufler   Smack: Repair pro...
1475
  	smk_ad_init(&ad, caller, LSM_AUDIT_DATA_TASK);
ecfcc53fe   Etienne Basset   smack: implement ...
1476
  	smk_ad_setfield_u_tsk(&ad, p);
676dac4b1   Casey Schaufler   This patch adds a...
1477
  	return smk_curacc(smk_of_task(task_security(p)), access, &ad);
ecfcc53fe   Etienne Basset   smack: implement ...
1478
1479
1480
  }
  
  /**
e114e4737   Casey Schaufler   Smack: Simplified...
1481
1482
1483
1484
1485
1486
1487
1488
   * smack_task_setpgid - Smack check on setting pgid
   * @p: the task object
   * @pgid: unused
   *
   * Return 0 if write access is permitted
   */
  static int smack_task_setpgid(struct task_struct *p, pid_t pgid)
  {
531f1d453   Casey Schaufler   Smack: Repair pro...
1489
  	return smk_curacc_on_task(p, MAY_WRITE, __func__);
e114e4737   Casey Schaufler   Smack: Simplified...
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
  }
  
  /**
   * smack_task_getpgid - Smack access check for getpgid
   * @p: the object task
   *
   * Returns 0 if current can read the object task, error code otherwise
   */
  static int smack_task_getpgid(struct task_struct *p)
  {
531f1d453   Casey Schaufler   Smack: Repair pro...
1500
  	return smk_curacc_on_task(p, MAY_READ, __func__);
e114e4737   Casey Schaufler   Smack: Simplified...
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
  }
  
  /**
   * smack_task_getsid - Smack access check for getsid
   * @p: the object task
   *
   * Returns 0 if current can read the object task, error code otherwise
   */
  static int smack_task_getsid(struct task_struct *p)
  {
531f1d453   Casey Schaufler   Smack: Repair pro...
1511
  	return smk_curacc_on_task(p, MAY_READ, __func__);
e114e4737   Casey Schaufler   Smack: Simplified...
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
  }
  
  /**
   * smack_task_getsecid - get the secid of the task
   * @p: the object task
   * @secid: where to put the result
   *
   * Sets the secid to contain a u32 version of the smack label.
   */
  static void smack_task_getsecid(struct task_struct *p, u32 *secid)
  {
676dac4b1   Casey Schaufler   This patch adds a...
1523
  	*secid = smack_to_secid(smk_of_task(task_security(p)));
e114e4737   Casey Schaufler   Smack: Simplified...
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
  }
  
  /**
   * smack_task_setnice - Smack check on setting nice
   * @p: the task object
   * @nice: unused
   *
   * Return 0 if write access is permitted
   */
  static int smack_task_setnice(struct task_struct *p, int nice)
  {
bcdca225b   Casey Schaufler   Smack: update for...
1535
1536
1537
1538
  	int rc;
  
  	rc = cap_task_setnice(p, nice);
  	if (rc == 0)
531f1d453   Casey Schaufler   Smack: Repair pro...
1539
  		rc = smk_curacc_on_task(p, MAY_WRITE, __func__);
bcdca225b   Casey Schaufler   Smack: update for...
1540
  	return rc;
e114e4737   Casey Schaufler   Smack: Simplified...
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
  }
  
  /**
   * smack_task_setioprio - Smack check on setting ioprio
   * @p: the task object
   * @ioprio: unused
   *
   * Return 0 if write access is permitted
   */
  static int smack_task_setioprio(struct task_struct *p, int ioprio)
  {
bcdca225b   Casey Schaufler   Smack: update for...
1552
1553
1554
1555
  	int rc;
  
  	rc = cap_task_setioprio(p, ioprio);
  	if (rc == 0)
531f1d453   Casey Schaufler   Smack: Repair pro...
1556
  		rc = smk_curacc_on_task(p, MAY_WRITE, __func__);
bcdca225b   Casey Schaufler   Smack: update for...
1557
  	return rc;
e114e4737   Casey Schaufler   Smack: Simplified...
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
  }
  
  /**
   * smack_task_getioprio - Smack check on reading ioprio
   * @p: the task object
   *
   * Return 0 if read access is permitted
   */
  static int smack_task_getioprio(struct task_struct *p)
  {
531f1d453   Casey Schaufler   Smack: Repair pro...
1568
  	return smk_curacc_on_task(p, MAY_READ, __func__);
e114e4737   Casey Schaufler   Smack: Simplified...
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
  }
  
  /**
   * smack_task_setscheduler - Smack check on setting scheduler
   * @p: the task object
   * @policy: unused
   * @lp: unused
   *
   * Return 0 if read access is permitted
   */
b0ae19811   KOSAKI Motohiro   security: remove ...
1579
  static int smack_task_setscheduler(struct task_struct *p)
e114e4737   Casey Schaufler   Smack: Simplified...
1580
  {
bcdca225b   Casey Schaufler   Smack: update for...
1581
  	int rc;
b0ae19811   KOSAKI Motohiro   security: remove ...
1582
  	rc = cap_task_setscheduler(p);
bcdca225b   Casey Schaufler   Smack: update for...
1583
  	if (rc == 0)
531f1d453   Casey Schaufler   Smack: Repair pro...
1584
  		rc = smk_curacc_on_task(p, MAY_WRITE, __func__);
bcdca225b   Casey Schaufler   Smack: update for...
1585
  	return rc;
e114e4737   Casey Schaufler   Smack: Simplified...
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
  }
  
  /**
   * smack_task_getscheduler - Smack check on reading scheduler
   * @p: the task object
   *
   * Return 0 if read access is permitted
   */
  static int smack_task_getscheduler(struct task_struct *p)
  {
531f1d453   Casey Schaufler   Smack: Repair pro...
1596
  	return smk_curacc_on_task(p, MAY_READ, __func__);
e114e4737   Casey Schaufler   Smack: Simplified...
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
  }
  
  /**
   * smack_task_movememory - Smack check on moving memory
   * @p: the task object
   *
   * Return 0 if write access is permitted
   */
  static int smack_task_movememory(struct task_struct *p)
  {
531f1d453   Casey Schaufler   Smack: Repair pro...
1607
  	return smk_curacc_on_task(p, MAY_WRITE, __func__);
e114e4737   Casey Schaufler   Smack: Simplified...
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
  }
  
  /**
   * smack_task_kill - Smack check on signal delivery
   * @p: the task object
   * @info: unused
   * @sig: unused
   * @secid: identifies the smack to use in lieu of current's
   *
   * Return 0 if write access is permitted
   *
   * The secid behavior is an artifact of an SELinux hack
   * in the USB code. Someday it may go away.
   */
  static int smack_task_kill(struct task_struct *p, struct siginfo *info,
  			   int sig, u32 secid)
  {
ecfcc53fe   Etienne Basset   smack: implement ...
1625
1626
1627
1628
  	struct smk_audit_info ad;
  
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK);
  	smk_ad_setfield_u_tsk(&ad, p);
e114e4737   Casey Schaufler   Smack: Simplified...
1629
  	/*
e114e4737   Casey Schaufler   Smack: Simplified...
1630
1631
1632
1633
  	 * Sending a signal requires that the sender
  	 * can write the receiver.
  	 */
  	if (secid == 0)
676dac4b1   Casey Schaufler   This patch adds a...
1634
1635
  		return smk_curacc(smk_of_task(task_security(p)), MAY_WRITE,
  				  &ad);
e114e4737   Casey Schaufler   Smack: Simplified...
1636
1637
1638
1639
1640
  	/*
  	 * If the secid isn't 0 we're dealing with some USB IO
  	 * specific behavior. This is not clean. For one thing
  	 * we can't take privilege into account.
  	 */
676dac4b1   Casey Schaufler   This patch adds a...
1641
1642
  	return smk_access(smack_from_secid(secid),
  			  smk_of_task(task_security(p)), MAY_WRITE, &ad);
e114e4737   Casey Schaufler   Smack: Simplified...
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
  }
  
  /**
   * smack_task_wait - Smack access check for waiting
   * @p: task to wait for
   *
   * Returns 0 if current can wait for p, error code otherwise
   */
  static int smack_task_wait(struct task_struct *p)
  {
ecfcc53fe   Etienne Basset   smack: implement ...
1653
  	struct smk_audit_info ad;
676dac4b1   Casey Schaufler   This patch adds a...
1654
1655
  	char *sp = smk_of_current();
  	char *tsp = smk_of_forked(task_security(p));
e114e4737   Casey Schaufler   Smack: Simplified...
1656
  	int rc;
ecfcc53fe   Etienne Basset   smack: implement ...
1657
  	/* we don't log here, we can be overriden */
676dac4b1   Casey Schaufler   This patch adds a...
1658
  	rc = smk_access(tsp, sp, MAY_WRITE, NULL);
e114e4737   Casey Schaufler   Smack: Simplified...
1659
  	if (rc == 0)
ecfcc53fe   Etienne Basset   smack: implement ...
1660
  		goto out_log;
e114e4737   Casey Schaufler   Smack: Simplified...
1661
1662
1663
1664
1665
1666
1667
  
  	/*
  	 * Allow the operation to succeed if either task
  	 * has privilege to perform operations that might
  	 * account for the smack labels having gotten to
  	 * be different in the first place.
  	 *
5cd9c58fb   David Howells   security: Fix set...
1668
  	 * This breaks the strict subject/object access
e114e4737   Casey Schaufler   Smack: Simplified...
1669
1670
1671
1672
  	 * control ideal, taking the object's privilege
  	 * state into account in the decision as well as
  	 * the smack value.
  	 */
5cd9c58fb   David Howells   security: Fix set...
1673
  	if (capable(CAP_MAC_OVERRIDE) || has_capability(p, CAP_MAC_OVERRIDE))
ecfcc53fe   Etienne Basset   smack: implement ...
1674
1675
1676
1677
1678
  		rc = 0;
  	/* we log only if we didn't get overriden */
   out_log:
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK);
  	smk_ad_setfield_u_tsk(&ad, p);
676dac4b1   Casey Schaufler   This patch adds a...
1679
  	smack_log(tsp, sp, MAY_WRITE, rc, &ad);
e114e4737   Casey Schaufler   Smack: Simplified...
1680
1681
1682
1683
1684
1685
  	return rc;
  }
  
  /**
   * smack_task_to_inode - copy task smack into the inode blob
   * @p: task to copy from
251a2a958   Randy Dunlap   smack: fix lots o...
1686
   * @inode: inode to copy to
e114e4737   Casey Schaufler   Smack: Simplified...
1687
1688
1689
1690
1691
1692
   *
   * Sets the smack pointer in the inode security blob
   */
  static void smack_task_to_inode(struct task_struct *p, struct inode *inode)
  {
  	struct inode_smack *isp = inode->i_security;
676dac4b1   Casey Schaufler   This patch adds a...
1693
  	isp->smk_inode = smk_of_task(task_security(p));
e114e4737   Casey Schaufler   Smack: Simplified...
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
  }
  
  /*
   * Socket hooks.
   */
  
  /**
   * smack_sk_alloc_security - Allocate a socket blob
   * @sk: the socket
   * @family: unused
251a2a958   Randy Dunlap   smack: fix lots o...
1704
   * @gfp_flags: memory allocation flags
e114e4737   Casey Schaufler   Smack: Simplified...
1705
1706
1707
1708
1709
1710
1711
   *
   * Assign Smack pointers to current
   *
   * Returns 0 on success, -ENOMEM is there's no memory
   */
  static int smack_sk_alloc_security(struct sock *sk, int family, gfp_t gfp_flags)
  {
676dac4b1   Casey Schaufler   This patch adds a...
1712
  	char *csp = smk_of_current();
e114e4737   Casey Schaufler   Smack: Simplified...
1713
1714
1715
1716
1717
1718
1719
1720
  	struct socket_smack *ssp;
  
  	ssp = kzalloc(sizeof(struct socket_smack), gfp_flags);
  	if (ssp == NULL)
  		return -ENOMEM;
  
  	ssp->smk_in = csp;
  	ssp->smk_out = csp;
272cd7a8c   Casey Schaufler   Smack: Rule list ...
1721
  	ssp->smk_packet = NULL;
e114e4737   Casey Schaufler   Smack: Simplified...
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
  
  	sk->sk_security = ssp;
  
  	return 0;
  }
  
  /**
   * smack_sk_free_security - Free a socket blob
   * @sk: the socket
   *
   * Clears the blob pointer
   */
  static void smack_sk_free_security(struct sock *sk)
  {
  	kfree(sk->sk_security);
  }
  
  /**
07feee8f8   Paul Moore   netlabel: Cleanup...
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
  * smack_host_label - check host based restrictions
  * @sip: the object end
  *
  * looks for host based access restrictions
  *
  * This version will only be appropriate for really small sets of single label
  * hosts.  The caller is responsible for ensuring that the RCU read lock is
  * taken before calling this function.
  *
  * Returns the label of the far end or NULL if it's not special.
  */
  static char *smack_host_label(struct sockaddr_in *sip)
  {
  	struct smk_netlbladdr *snp;
  	struct in_addr *siap = &sip->sin_addr;
  
  	if (siap->s_addr == 0)
  		return NULL;
  
  	list_for_each_entry_rcu(snp, &smk_netlbladdr_list, list)
  		/*
  		* we break after finding the first match because
  		* the list is sorted from longest to shortest mask
  		* so we have found the most specific match
  		*/
  		if ((&snp->smk_host.sin_addr)->s_addr ==
4303154e8   Etienne Basset   smack: Add a new ...
1766
1767
1768
1769
  		    (siap->s_addr & (&snp->smk_mask)->s_addr)) {
  			/* we have found the special CIPSO option */
  			if (snp->smk_label == smack_cipso_option)
  				return NULL;
07feee8f8   Paul Moore   netlabel: Cleanup...
1770
  			return snp->smk_label;
4303154e8   Etienne Basset   smack: Add a new ...
1771
  		}
07feee8f8   Paul Moore   netlabel: Cleanup...
1772
1773
1774
1775
1776
  
  	return NULL;
  }
  
  /**
e114e4737   Casey Schaufler   Smack: Simplified...
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
   * smack_set_catset - convert a capset to netlabel mls categories
   * @catset: the Smack categories
   * @sap: where to put the netlabel categories
   *
   * Allocates and fills attr.mls.cat
   */
  static void smack_set_catset(char *catset, struct netlbl_lsm_secattr *sap)
  {
  	unsigned char *cp;
  	unsigned char m;
  	int cat;
  	int rc;
  	int byte;
c60264c49   Harvey Harrison   smack: fix intege...
1790
  	if (!catset)
e114e4737   Casey Schaufler   Smack: Simplified...
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
  		return;
  
  	sap->flags |= NETLBL_SECATTR_MLS_CAT;
  	sap->attr.mls.cat = netlbl_secattr_catmap_alloc(GFP_ATOMIC);
  	sap->attr.mls.cat->startbit = 0;
  
  	for (cat = 1, cp = catset, byte = 0; byte < SMK_LABELLEN; cp++, byte++)
  		for (m = 0x80; m != 0; m >>= 1, cat++) {
  			if ((m & *cp) == 0)
  				continue;
  			rc = netlbl_secattr_catmap_setbit(sap->attr.mls.cat,
  							  cat, GFP_ATOMIC);
  		}
  }
  
  /**
   * smack_to_secattr - fill a secattr from a smack value
   * @smack: the smack value
   * @nlsp: where the result goes
   *
   * Casey says that CIPSO is good enough for now.
   * It can be used to effect.
   * It can also be abused to effect when necessary.
25985edce   Lucas De Marchi   Fix common misspe...
1814
   * Apologies to the TSIG group in general and GW in particular.
e114e4737   Casey Schaufler   Smack: Simplified...
1815
1816
1817
1818
1819
   */
  static void smack_to_secattr(char *smack, struct netlbl_lsm_secattr *nlsp)
  {
  	struct smack_cipso cipso;
  	int rc;
6d3dc07cb   Casey Schaufler   smack: Add suppor...
1820
1821
  	nlsp->domain = smack;
  	nlsp->flags = NETLBL_SECATTR_DOMAIN | NETLBL_SECATTR_MLS_LVL;
e114e4737   Casey Schaufler   Smack: Simplified...
1822

6d3dc07cb   Casey Schaufler   smack: Add suppor...
1823
1824
1825
1826
1827
1828
1829
  	rc = smack_to_cipso(smack, &cipso);
  	if (rc == 0) {
  		nlsp->attr.mls.lvl = cipso.smk_level;
  		smack_set_catset(cipso.smk_catset, nlsp);
  	} else {
  		nlsp->attr.mls.lvl = smack_cipso_direct;
  		smack_set_catset(smack, nlsp);
e114e4737   Casey Schaufler   Smack: Simplified...
1830
1831
1832
1833
1834
1835
  	}
  }
  
  /**
   * smack_netlabel - Set the secattr on a socket
   * @sk: the socket
6d3dc07cb   Casey Schaufler   smack: Add suppor...
1836
   * @labeled: socket label scheme
e114e4737   Casey Schaufler   Smack: Simplified...
1837
1838
1839
1840
1841
1842
   *
   * Convert the outbound smack value (smk_out) to a
   * secattr and attach it to the socket.
   *
   * Returns 0 on success or an error code
   */
6d3dc07cb   Casey Schaufler   smack: Add suppor...
1843
  static int smack_netlabel(struct sock *sk, int labeled)
e114e4737   Casey Schaufler   Smack: Simplified...
1844
  {
07feee8f8   Paul Moore   netlabel: Cleanup...
1845
  	struct socket_smack *ssp = sk->sk_security;
e114e4737   Casey Schaufler   Smack: Simplified...
1846
  	struct netlbl_lsm_secattr secattr;
6d3dc07cb   Casey Schaufler   smack: Add suppor...
1847
  	int rc = 0;
e114e4737   Casey Schaufler   Smack: Simplified...
1848

6d3dc07cb   Casey Schaufler   smack: Add suppor...
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
  	/*
  	 * Usually the netlabel code will handle changing the
  	 * packet labeling based on the label.
  	 * The case of a single label host is different, because
  	 * a single label host should never get a labeled packet
  	 * even though the label is usually associated with a packet
  	 * label.
  	 */
  	local_bh_disable();
  	bh_lock_sock_nested(sk);
  
  	if (ssp->smk_out == smack_net_ambient ||
  	    labeled == SMACK_UNLABELED_SOCKET)
  		netlbl_sock_delattr(sk);
  	else {
  		netlbl_secattr_init(&secattr);
  		smack_to_secattr(ssp->smk_out, &secattr);
389fb800a   Paul Moore   netlabel: Label i...
1866
  		rc = netlbl_sock_setattr(sk, sk->sk_family, &secattr);
6d3dc07cb   Casey Schaufler   smack: Add suppor...
1867
1868
1869
1870
1871
  		netlbl_secattr_destroy(&secattr);
  	}
  
  	bh_unlock_sock(sk);
  	local_bh_enable();
4bc87e627   Casey Schaufler   Smack: unlabeled ...
1872

e114e4737   Casey Schaufler   Smack: Simplified...
1873
1874
1875
1876
  	return rc;
  }
  
  /**
07feee8f8   Paul Moore   netlabel: Cleanup...
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
   * smack_netlbel_send - Set the secattr on a socket and perform access checks
   * @sk: the socket
   * @sap: the destination address
   *
   * Set the correct secattr for the given socket based on the destination
   * address and perform any outbound access checks needed.
   *
   * Returns 0 on success or an error code.
   *
   */
  static int smack_netlabel_send(struct sock *sk, struct sockaddr_in *sap)
  {
  	int rc;
  	int sk_lbl;
  	char *hostsp;
  	struct socket_smack *ssp = sk->sk_security;
ecfcc53fe   Etienne Basset   smack: implement ...
1893
  	struct smk_audit_info ad;
07feee8f8   Paul Moore   netlabel: Cleanup...
1894
1895
1896
1897
1898
  
  	rcu_read_lock();
  	hostsp = smack_host_label(sap);
  	if (hostsp != NULL) {
  		sk_lbl = SMACK_UNLABELED_SOCKET;
ecfcc53fe   Etienne Basset   smack: implement ...
1899
1900
1901
1902
1903
1904
1905
  #ifdef CONFIG_AUDIT
  		smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_NET);
  		ad.a.u.net.family = sap->sin_family;
  		ad.a.u.net.dport = sap->sin_port;
  		ad.a.u.net.v4info.daddr = sap->sin_addr.s_addr;
  #endif
  		rc = smk_access(ssp->smk_out, hostsp, MAY_WRITE, &ad);
07feee8f8   Paul Moore   netlabel: Cleanup...
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
  	} else {
  		sk_lbl = SMACK_CIPSO_SOCKET;
  		rc = 0;
  	}
  	rcu_read_unlock();
  	if (rc != 0)
  		return rc;
  
  	return smack_netlabel(sk, sk_lbl);
  }
  
  /**
e114e4737   Casey Schaufler   Smack: Simplified...
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
   * smack_inode_setsecurity - set smack xattrs
   * @inode: the object
   * @name: attribute name
   * @value: attribute value
   * @size: size of the attribute
   * @flags: unused
   *
   * Sets the named attribute in the appropriate blob
   *
   * Returns 0 on success, or an error code
   */
  static int smack_inode_setsecurity(struct inode *inode, const char *name,
  				   const void *value, size_t size, int flags)
  {
  	char *sp;
  	struct inode_smack *nsp = inode->i_security;
  	struct socket_smack *ssp;
  	struct socket *sock;
4bc87e627   Casey Schaufler   Smack: unlabeled ...
1936
  	int rc = 0;
e114e4737   Casey Schaufler   Smack: Simplified...
1937

4303154e8   Etienne Basset   smack: Add a new ...
1938
  	if (value == NULL || size > SMK_LABELLEN || size == 0)
e114e4737   Casey Schaufler   Smack: Simplified...
1939
1940
1941
1942
1943
1944
1945
1946
  		return -EACCES;
  
  	sp = smk_import(value, size);
  	if (sp == NULL)
  		return -EINVAL;
  
  	if (strcmp(name, XATTR_SMACK_SUFFIX) == 0) {
  		nsp->smk_inode = sp;
ddd29ec65   David P. Quigley   sysfs: Add labeli...
1947
  		nsp->smk_flags |= SMK_INODE_INSTANT;
e114e4737   Casey Schaufler   Smack: Simplified...
1948
1949
1950
1951
1952
1953
1954
1955
1956
  		return 0;
  	}
  	/*
  	 * The rest of the Smack xattrs are only on sockets.
  	 */
  	if (inode->i_sb->s_magic != SOCKFS_MAGIC)
  		return -EOPNOTSUPP;
  
  	sock = SOCKET_I(inode);
2e1d146a1   Ahmed S. Darwish   Smack: check for ...
1957
  	if (sock == NULL || sock->sk == NULL)
e114e4737   Casey Schaufler   Smack: Simplified...
1958
1959
1960
1961
1962
1963
1964
1965
  		return -EOPNOTSUPP;
  
  	ssp = sock->sk->sk_security;
  
  	if (strcmp(name, XATTR_SMACK_IPIN) == 0)
  		ssp->smk_in = sp;
  	else if (strcmp(name, XATTR_SMACK_IPOUT) == 0) {
  		ssp->smk_out = sp;
b4e0d5f07   Casey Schaufler   Smack: UDS revision
1966
1967
1968
1969
1970
1971
1972
1973
  		if (sock->sk->sk_family != PF_UNIX) {
  			rc = smack_netlabel(sock->sk, SMACK_CIPSO_SOCKET);
  			if (rc != 0)
  				printk(KERN_WARNING
  					"Smack: \"%s\" netlbl error %d.
  ",
  					__func__, -rc);
  		}
e114e4737   Casey Schaufler   Smack: Simplified...
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
  	} else
  		return -EOPNOTSUPP;
  
  	return 0;
  }
  
  /**
   * smack_socket_post_create - finish socket setup
   * @sock: the socket
   * @family: protocol family
   * @type: unused
   * @protocol: unused
   * @kern: unused
   *
   * Sets the netlabel information on the socket
   *
   * Returns 0 on success, and error code otherwise
   */
  static int smack_socket_post_create(struct socket *sock, int family,
  				    int type, int protocol, int kern)
  {
2e1d146a1   Ahmed S. Darwish   Smack: check for ...
1995
  	if (family != PF_INET || sock->sk == NULL)
e114e4737   Casey Schaufler   Smack: Simplified...
1996
1997
1998
1999
  		return 0;
  	/*
  	 * Set the outbound netlbl.
  	 */
6d3dc07cb   Casey Schaufler   smack: Add suppor...
2000
2001
  	return smack_netlabel(sock->sk, SMACK_CIPSO_SOCKET);
  }
6d3dc07cb   Casey Schaufler   smack: Add suppor...
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
  /**
   * smack_socket_connect - connect access check
   * @sock: the socket
   * @sap: the other end
   * @addrlen: size of sap
   *
   * Verifies that a connection may be possible
   *
   * Returns 0 on success, and error code otherwise
   */
  static int smack_socket_connect(struct socket *sock, struct sockaddr *sap,
  				int addrlen)
  {
6d3dc07cb   Casey Schaufler   smack: Add suppor...
2015
2016
  	if (sock->sk == NULL || sock->sk->sk_family != PF_INET)
  		return 0;
6d3dc07cb   Casey Schaufler   smack: Add suppor...
2017
2018
  	if (addrlen < sizeof(struct sockaddr_in))
  		return -EINVAL;
07feee8f8   Paul Moore   netlabel: Cleanup...
2019
  	return smack_netlabel_send(sock->sk, (struct sockaddr_in *)sap);
e114e4737   Casey Schaufler   Smack: Simplified...
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
  }
  
  /**
   * smack_flags_to_may - convert S_ to MAY_ values
   * @flags: the S_ value
   *
   * Returns the equivalent MAY_ value
   */
  static int smack_flags_to_may(int flags)
  {
  	int may = 0;
  
  	if (flags & S_IRUGO)
  		may |= MAY_READ;
  	if (flags & S_IWUGO)
  		may |= MAY_WRITE;
  	if (flags & S_IXUGO)
  		may |= MAY_EXEC;
  
  	return may;
  }
  
  /**
   * smack_msg_msg_alloc_security - Set the security blob for msg_msg
   * @msg: the object
   *
   * Returns 0
   */
  static int smack_msg_msg_alloc_security(struct msg_msg *msg)
  {
676dac4b1   Casey Schaufler   This patch adds a...
2050
  	msg->security = smk_of_current();
e114e4737   Casey Schaufler   Smack: Simplified...
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
  	return 0;
  }
  
  /**
   * smack_msg_msg_free_security - Clear the security blob for msg_msg
   * @msg: the object
   *
   * Clears the blob pointer
   */
  static void smack_msg_msg_free_security(struct msg_msg *msg)
  {
  	msg->security = NULL;
  }
  
  /**
   * smack_of_shm - the smack pointer for the shm
   * @shp: the object
   *
   * Returns a pointer to the smack value
   */
  static char *smack_of_shm(struct shmid_kernel *shp)
  {
  	return (char *)shp->shm_perm.security;
  }
  
  /**
   * smack_shm_alloc_security - Set the security blob for shm
   * @shp: the object
   *
   * Returns 0
   */
  static int smack_shm_alloc_security(struct shmid_kernel *shp)
  {
  	struct kern_ipc_perm *isp = &shp->shm_perm;
676dac4b1   Casey Schaufler   This patch adds a...
2085
  	isp->security = smk_of_current();
e114e4737   Casey Schaufler   Smack: Simplified...
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
  	return 0;
  }
  
  /**
   * smack_shm_free_security - Clear the security blob for shm
   * @shp: the object
   *
   * Clears the blob pointer
   */
  static void smack_shm_free_security(struct shmid_kernel *shp)
  {
  	struct kern_ipc_perm *isp = &shp->shm_perm;
  
  	isp->security = NULL;
  }
  
  /**
ecfcc53fe   Etienne Basset   smack: implement ...
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
   * smk_curacc_shm : check if current has access on shm
   * @shp : the object
   * @access : access requested
   *
   * Returns 0 if current has the requested access, error code otherwise
   */
  static int smk_curacc_shm(struct shmid_kernel *shp, int access)
  {
  	char *ssp = smack_of_shm(shp);
  	struct smk_audit_info ad;
  
  #ifdef CONFIG_AUDIT
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_IPC);
  	ad.a.u.ipc_id = shp->shm_perm.id;
  #endif
  	return smk_curacc(ssp, access, &ad);
  }
  
  /**
e114e4737   Casey Schaufler   Smack: Simplified...
2122
2123
2124
2125
2126
2127
2128
2129
   * smack_shm_associate - Smack access check for shm
   * @shp: the object
   * @shmflg: access requested
   *
   * Returns 0 if current has the requested access, error code otherwise
   */
  static int smack_shm_associate(struct shmid_kernel *shp, int shmflg)
  {
e114e4737   Casey Schaufler   Smack: Simplified...
2130
2131
2132
  	int may;
  
  	may = smack_flags_to_may(shmflg);
ecfcc53fe   Etienne Basset   smack: implement ...
2133
  	return smk_curacc_shm(shp, may);
e114e4737   Casey Schaufler   Smack: Simplified...
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
  }
  
  /**
   * smack_shm_shmctl - Smack access check for shm
   * @shp: the object
   * @cmd: what it wants to do
   *
   * Returns 0 if current has the requested access, error code otherwise
   */
  static int smack_shm_shmctl(struct shmid_kernel *shp, int cmd)
  {
e114e4737   Casey Schaufler   Smack: Simplified...
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
  	int may;
  
  	switch (cmd) {
  	case IPC_STAT:
  	case SHM_STAT:
  		may = MAY_READ;
  		break;
  	case IPC_SET:
  	case SHM_LOCK:
  	case SHM_UNLOCK:
  	case IPC_RMID:
  		may = MAY_READWRITE;
  		break;
  	case IPC_INFO:
  	case SHM_INFO:
  		/*
  		 * System level information.
  		 */
  		return 0;
  	default:
  		return -EINVAL;
  	}
ecfcc53fe   Etienne Basset   smack: implement ...
2167
  	return smk_curacc_shm(shp, may);
e114e4737   Casey Schaufler   Smack: Simplified...
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
  }
  
  /**
   * smack_shm_shmat - Smack access for shmat
   * @shp: the object
   * @shmaddr: unused
   * @shmflg: access requested
   *
   * Returns 0 if current has the requested access, error code otherwise
   */
  static int smack_shm_shmat(struct shmid_kernel *shp, char __user *shmaddr,
  			   int shmflg)
  {
e114e4737   Casey Schaufler   Smack: Simplified...
2181
2182
2183
  	int may;
  
  	may = smack_flags_to_may(shmflg);
ecfcc53fe   Etienne Basset   smack: implement ...
2184
  	return smk_curacc_shm(shp, may);
e114e4737   Casey Schaufler   Smack: Simplified...
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
  }
  
  /**
   * smack_of_sem - the smack pointer for the sem
   * @sma: the object
   *
   * Returns a pointer to the smack value
   */
  static char *smack_of_sem(struct sem_array *sma)
  {
  	return (char *)sma->sem_perm.security;
  }
  
  /**
   * smack_sem_alloc_security - Set the security blob for sem
   * @sma: the object
   *
   * Returns 0
   */
  static int smack_sem_alloc_security(struct sem_array *sma)
  {
  	struct kern_ipc_perm *isp = &sma->sem_perm;
676dac4b1   Casey Schaufler   This patch adds a...
2207
  	isp->security = smk_of_current();
e114e4737   Casey Schaufler   Smack: Simplified...
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
  	return 0;
  }
  
  /**
   * smack_sem_free_security - Clear the security blob for sem
   * @sma: the object
   *
   * Clears the blob pointer
   */
  static void smack_sem_free_security(struct sem_array *sma)
  {
  	struct kern_ipc_perm *isp = &sma->sem_perm;
  
  	isp->security = NULL;
  }
  
  /**
ecfcc53fe   Etienne Basset   smack: implement ...
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
   * smk_curacc_sem : check if current has access on sem
   * @sma : the object
   * @access : access requested
   *
   * Returns 0 if current has the requested access, error code otherwise
   */
  static int smk_curacc_sem(struct sem_array *sma, int access)
  {
  	char *ssp = smack_of_sem(sma);
  	struct smk_audit_info ad;
  
  #ifdef CONFIG_AUDIT
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_IPC);
  	ad.a.u.ipc_id = sma->sem_perm.id;
  #endif
  	return smk_curacc(ssp, access, &ad);
  }
  
  /**
e114e4737   Casey Schaufler   Smack: Simplified...
2244
2245
2246
2247
2248
2249
2250
2251
   * smack_sem_associate - Smack access check for sem
   * @sma: the object
   * @semflg: access requested
   *
   * Returns 0 if current has the requested access, error code otherwise
   */
  static int smack_sem_associate(struct sem_array *sma, int semflg)
  {
e114e4737   Casey Schaufler   Smack: Simplified...
2252
2253
2254
  	int may;
  
  	may = smack_flags_to_may(semflg);
ecfcc53fe   Etienne Basset   smack: implement ...
2255
  	return smk_curacc_sem(sma, may);
e114e4737   Casey Schaufler   Smack: Simplified...
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
  }
  
  /**
   * smack_sem_shmctl - Smack access check for sem
   * @sma: the object
   * @cmd: what it wants to do
   *
   * Returns 0 if current has the requested access, error code otherwise
   */
  static int smack_sem_semctl(struct sem_array *sma, int cmd)
  {
e114e4737   Casey Schaufler   Smack: Simplified...
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
  	int may;
  
  	switch (cmd) {
  	case GETPID:
  	case GETNCNT:
  	case GETZCNT:
  	case GETVAL:
  	case GETALL:
  	case IPC_STAT:
  	case SEM_STAT:
  		may = MAY_READ;
  		break;
  	case SETVAL:
  	case SETALL:
  	case IPC_RMID:
  	case IPC_SET:
  		may = MAY_READWRITE;
  		break;
  	case IPC_INFO:
  	case SEM_INFO:
  		/*
  		 * System level information
  		 */
  		return 0;
  	default:
  		return -EINVAL;
  	}
ecfcc53fe   Etienne Basset   smack: implement ...
2294
  	return smk_curacc_sem(sma, may);
e114e4737   Casey Schaufler   Smack: Simplified...
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
  }
  
  /**
   * smack_sem_semop - Smack checks of semaphore operations
   * @sma: the object
   * @sops: unused
   * @nsops: unused
   * @alter: unused
   *
   * Treated as read and write in all cases.
   *
   * Returns 0 if access is allowed, error code otherwise
   */
  static int smack_sem_semop(struct sem_array *sma, struct sembuf *sops,
  			   unsigned nsops, int alter)
  {
ecfcc53fe   Etienne Basset   smack: implement ...
2311
  	return smk_curacc_sem(sma, MAY_READWRITE);
e114e4737   Casey Schaufler   Smack: Simplified...
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
  }
  
  /**
   * smack_msg_alloc_security - Set the security blob for msg
   * @msq: the object
   *
   * Returns 0
   */
  static int smack_msg_queue_alloc_security(struct msg_queue *msq)
  {
  	struct kern_ipc_perm *kisp = &msq->q_perm;
676dac4b1   Casey Schaufler   This patch adds a...
2323
  	kisp->security = smk_of_current();
e114e4737   Casey Schaufler   Smack: Simplified...
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
  	return 0;
  }
  
  /**
   * smack_msg_free_security - Clear the security blob for msg
   * @msq: the object
   *
   * Clears the blob pointer
   */
  static void smack_msg_queue_free_security(struct msg_queue *msq)
  {
  	struct kern_ipc_perm *kisp = &msq->q_perm;
  
  	kisp->security = NULL;
  }
  
  /**
   * smack_of_msq - the smack pointer for the msq
   * @msq: the object
   *
   * Returns a pointer to the smack value
   */
  static char *smack_of_msq(struct msg_queue *msq)
  {
  	return (char *)msq->q_perm.security;
  }
  
  /**
ecfcc53fe   Etienne Basset   smack: implement ...
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
   * smk_curacc_msq : helper to check if current has access on msq
   * @msq : the msq
   * @access : access requested
   *
   * return 0 if current has access, error otherwise
   */
  static int smk_curacc_msq(struct msg_queue *msq, int access)
  {
  	char *msp = smack_of_msq(msq);
  	struct smk_audit_info ad;
  
  #ifdef CONFIG_AUDIT
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_IPC);
  	ad.a.u.ipc_id = msq->q_perm.id;
  #endif
  	return smk_curacc(msp, access, &ad);
  }
  
  /**
e114e4737   Casey Schaufler   Smack: Simplified...
2371
2372
2373
2374
2375
2376
2377
2378
   * smack_msg_queue_associate - Smack access check for msg_queue
   * @msq: the object
   * @msqflg: access requested
   *
   * Returns 0 if current has the requested access, error code otherwise
   */
  static int smack_msg_queue_associate(struct msg_queue *msq, int msqflg)
  {
e114e4737   Casey Schaufler   Smack: Simplified...
2379
2380
2381
  	int may;
  
  	may = smack_flags_to_may(msqflg);
ecfcc53fe   Etienne Basset   smack: implement ...
2382
  	return smk_curacc_msq(msq, may);
e114e4737   Casey Schaufler   Smack: Simplified...
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
  }
  
  /**
   * smack_msg_queue_msgctl - Smack access check for msg_queue
   * @msq: the object
   * @cmd: what it wants to do
   *
   * Returns 0 if current has the requested access, error code otherwise
   */
  static int smack_msg_queue_msgctl(struct msg_queue *msq, int cmd)
  {
e114e4737   Casey Schaufler   Smack: Simplified...
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
  	int may;
  
  	switch (cmd) {
  	case IPC_STAT:
  	case MSG_STAT:
  		may = MAY_READ;
  		break;
  	case IPC_SET:
  	case IPC_RMID:
  		may = MAY_READWRITE;
  		break;
  	case IPC_INFO:
  	case MSG_INFO:
  		/*
  		 * System level information
  		 */
  		return 0;
  	default:
  		return -EINVAL;
  	}
ecfcc53fe   Etienne Basset   smack: implement ...
2414
  	return smk_curacc_msq(msq, may);
e114e4737   Casey Schaufler   Smack: Simplified...
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
  }
  
  /**
   * smack_msg_queue_msgsnd - Smack access check for msg_queue
   * @msq: the object
   * @msg: unused
   * @msqflg: access requested
   *
   * Returns 0 if current has the requested access, error code otherwise
   */
  static int smack_msg_queue_msgsnd(struct msg_queue *msq, struct msg_msg *msg,
  				  int msqflg)
  {
ecfcc53fe   Etienne Basset   smack: implement ...
2428
  	int may;
e114e4737   Casey Schaufler   Smack: Simplified...
2429

ecfcc53fe   Etienne Basset   smack: implement ...
2430
2431
  	may = smack_flags_to_may(msqflg);
  	return smk_curacc_msq(msq, may);
e114e4737   Casey Schaufler   Smack: Simplified...
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
  }
  
  /**
   * smack_msg_queue_msgsnd - Smack access check for msg_queue
   * @msq: the object
   * @msg: unused
   * @target: unused
   * @type: unused
   * @mode: unused
   *
   * Returns 0 if current has read and write access, error code otherwise
   */
  static int smack_msg_queue_msgrcv(struct msg_queue *msq, struct msg_msg *msg,
  			struct task_struct *target, long type, int mode)
  {
ecfcc53fe   Etienne Basset   smack: implement ...
2447
  	return smk_curacc_msq(msq, MAY_READWRITE);
e114e4737   Casey Schaufler   Smack: Simplified...
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
  }
  
  /**
   * smack_ipc_permission - Smack access for ipc_permission()
   * @ipp: the object permissions
   * @flag: access requested
   *
   * Returns 0 if current has read and write access, error code otherwise
   */
  static int smack_ipc_permission(struct kern_ipc_perm *ipp, short flag)
  {
  	char *isp = ipp->security;
ecfcc53fe   Etienne Basset   smack: implement ...
2460
2461
  	int may = smack_flags_to_may(flag);
  	struct smk_audit_info ad;
e114e4737   Casey Schaufler   Smack: Simplified...
2462

ecfcc53fe   Etienne Basset   smack: implement ...
2463
2464
2465
2466
2467
  #ifdef CONFIG_AUDIT
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_IPC);
  	ad.a.u.ipc_id = ipp->id;
  #endif
  	return smk_curacc(isp, may, &ad);
e114e4737   Casey Schaufler   Smack: Simplified...
2468
  }
d20bdda6d   Ahmed S. Darwish   Smack: Integrate ...
2469
2470
  /**
   * smack_ipc_getsecid - Extract smack security id
251a2a958   Randy Dunlap   smack: fix lots o...
2471
   * @ipp: the object permissions
d20bdda6d   Ahmed S. Darwish   Smack: Integrate ...
2472
2473
2474
2475
2476
2477
2478
2479
   * @secid: where result will be saved
   */
  static void smack_ipc_getsecid(struct kern_ipc_perm *ipp, u32 *secid)
  {
  	char *smack = ipp->security;
  
  	*secid = smack_to_secid(smack);
  }
e114e4737   Casey Schaufler   Smack: Simplified...
2480
2481
  /**
   * smack_d_instantiate - Make sure the blob is correct on an inode
3e62cbb84   Dan Carpenter   smack: opt_dentry...
2482
   * @opt_dentry: dentry where inode will be attached
e114e4737   Casey Schaufler   Smack: Simplified...
2483
2484
2485
2486
2487
2488
2489
2490
2491
   * @inode: the object
   *
   * Set the inode's security blob if it hasn't been done already.
   */
  static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode)
  {
  	struct super_block *sbp;
  	struct superblock_smack *sbsp;
  	struct inode_smack *isp;
676dac4b1   Casey Schaufler   This patch adds a...
2492
  	char *csp = smk_of_current();
e114e4737   Casey Schaufler   Smack: Simplified...
2493
2494
  	char *fetched;
  	char *final;
5c6d1125f   Jarkko Sakkinen   Smack: Transmute ...
2495
2496
  	char trattr[TRANS_TRUE_SIZE];
  	int transflag = 0;
e114e4737   Casey Schaufler   Smack: Simplified...
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
  	struct dentry *dp;
  
  	if (inode == NULL)
  		return;
  
  	isp = inode->i_security;
  
  	mutex_lock(&isp->smk_lock);
  	/*
  	 * If the inode is already instantiated
  	 * take the quick way out
  	 */
  	if (isp->smk_flags & SMK_INODE_INSTANT)
  		goto unlockandout;
  
  	sbp = inode->i_sb;
  	sbsp = sbp->s_security;
  	/*
  	 * We're going to use the superblock default label
  	 * if there's no label on the file.
  	 */
  	final = sbsp->smk_default;
  
  	/*
e97dcb0ea   Casey Schaufler   Smack: fuse mount...
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
  	 * If this is the root inode the superblock
  	 * may be in the process of initialization.
  	 * If that is the case use the root value out
  	 * of the superblock.
  	 */
  	if (opt_dentry->d_parent == opt_dentry) {
  		isp->smk_inode = sbsp->smk_root;
  		isp->smk_flags |= SMK_INODE_INSTANT;
  		goto unlockandout;
  	}
  
  	/*
e114e4737   Casey Schaufler   Smack: Simplified...
2533
2534
2535
2536
2537
2538
2539
2540
  	 * This is pretty hackish.
  	 * Casey says that we shouldn't have to do
  	 * file system specific code, but it does help
  	 * with keeping it simple.
  	 */
  	switch (sbp->s_magic) {
  	case SMACK_MAGIC:
  		/*
25985edce   Lucas De Marchi   Fix common misspe...
2541
  		 * Casey says that it's a little embarrassing
e114e4737   Casey Schaufler   Smack: Simplified...
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
  		 * that the smack file system doesn't do
  		 * extended attributes.
  		 */
  		final = smack_known_star.smk_known;
  		break;
  	case PIPEFS_MAGIC:
  		/*
  		 * Casey says pipes are easy (?)
  		 */
  		final = smack_known_star.smk_known;
  		break;
  	case DEVPTS_SUPER_MAGIC:
  		/*
  		 * devpts seems content with the label of the task.
  		 * Programs that change smack have to treat the
  		 * pty with respect.
  		 */
  		final = csp;
  		break;
  	case SOCKFS_MAGIC:
  		/*
b4e0d5f07   Casey Schaufler   Smack: UDS revision
2563
2564
  		 * Socket access is controlled by the socket
  		 * structures associated with the task involved.
e114e4737   Casey Schaufler   Smack: Simplified...
2565
  		 */
b4e0d5f07   Casey Schaufler   Smack: UDS revision
2566
  		final = smack_known_star.smk_known;
e114e4737   Casey Schaufler   Smack: Simplified...
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
  		break;
  	case PROC_SUPER_MAGIC:
  		/*
  		 * Casey says procfs appears not to care.
  		 * The superblock default suffices.
  		 */
  		break;
  	case TMPFS_MAGIC:
  		/*
  		 * Device labels should come from the filesystem,
  		 * but watch out, because they're volitile,
  		 * getting recreated on every reboot.
  		 */
  		final = smack_known_star.smk_known;
  		/*
  		 * No break.
  		 *
  		 * If a smack value has been set we want to use it,
  		 * but since tmpfs isn't giving us the opportunity
  		 * to set mount options simulate setting the
  		 * superblock default.
  		 */
  	default:
  		/*
  		 * This isn't an understood special case.
  		 * Get the value from the xattr.
b4e0d5f07   Casey Schaufler   Smack: UDS revision
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
  		 */
  
  		/*
  		 * UNIX domain sockets use lower level socket data.
  		 */
  		if (S_ISSOCK(inode->i_mode)) {
  			final = smack_known_star.smk_known;
  			break;
  		}
  		/*
e114e4737   Casey Schaufler   Smack: Simplified...
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
  		 * No xattr support means, alas, no SMACK label.
  		 * Use the aforeapplied default.
  		 * It would be curious if the label of the task
  		 * does not match that assigned.
  		 */
  		if (inode->i_op->getxattr == NULL)
  			break;
  		/*
  		 * Get the dentry for xattr.
  		 */
3e62cbb84   Dan Carpenter   smack: opt_dentry...
2613
  		dp = dget(opt_dentry);
676dac4b1   Casey Schaufler   This patch adds a...
2614
  		fetched = smk_fetch(XATTR_NAME_SMACK, inode, dp);
5c6d1125f   Jarkko Sakkinen   Smack: Transmute ...
2615
  		if (fetched != NULL) {
e114e4737   Casey Schaufler   Smack: Simplified...
2616
  			final = fetched;
5c6d1125f   Jarkko Sakkinen   Smack: Transmute ...
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
  			if (S_ISDIR(inode->i_mode)) {
  				trattr[0] = '\0';
  				inode->i_op->getxattr(dp,
  					XATTR_NAME_SMACKTRANSMUTE,
  					trattr, TRANS_TRUE_SIZE);
  				if (strncmp(trattr, TRANS_TRUE,
  					    TRANS_TRUE_SIZE) == 0)
  					transflag = SMK_INODE_TRANSMUTE;
  			}
  		}
  		isp->smk_task = smk_fetch(XATTR_NAME_SMACKEXEC, inode, dp);
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
2628
  		isp->smk_mmap = smk_fetch(XATTR_NAME_SMACKMMAP, inode, dp);
676dac4b1   Casey Schaufler   This patch adds a...
2629

e114e4737   Casey Schaufler   Smack: Simplified...
2630
2631
2632
2633
2634
2635
2636
2637
  		dput(dp);
  		break;
  	}
  
  	if (final == NULL)
  		isp->smk_inode = csp;
  	else
  		isp->smk_inode = final;
5c6d1125f   Jarkko Sakkinen   Smack: Transmute ...
2638
  	isp->smk_flags |= (SMK_INODE_INSTANT | transflag);
e114e4737   Casey Schaufler   Smack: Simplified...
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
  
  unlockandout:
  	mutex_unlock(&isp->smk_lock);
  	return;
  }
  
  /**
   * smack_getprocattr - Smack process attribute access
   * @p: the object task
   * @name: the name of the attribute in /proc/.../attr
   * @value: where to put the result
   *
   * Places a copy of the task Smack into value
   *
   * Returns the length of the smack label or an error code
   */
  static int smack_getprocattr(struct task_struct *p, char *name, char **value)
  {
  	char *cp;
  	int slen;
  
  	if (strcmp(name, "current") != 0)
  		return -EINVAL;
676dac4b1   Casey Schaufler   This patch adds a...
2662
  	cp = kstrdup(smk_of_task(task_security(p)), GFP_KERNEL);
e114e4737   Casey Schaufler   Smack: Simplified...
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
  	if (cp == NULL)
  		return -ENOMEM;
  
  	slen = strlen(cp);
  	*value = cp;
  	return slen;
  }
  
  /**
   * smack_setprocattr - Smack process attribute setting
   * @p: the object task
   * @name: the name of the attribute in /proc/.../attr
   * @value: the value to set
   * @size: the size of the value
   *
   * Sets the Smack value of the task. Only setting self
   * is permitted and only with privilege
   *
   * Returns the length of the smack label or an error code
   */
  static int smack_setprocattr(struct task_struct *p, char *name,
  			     void *value, size_t size)
  {
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
2686
  	int rc;
676dac4b1   Casey Schaufler   This patch adds a...
2687
  	struct task_smack *tsp;
5c6d1125f   Jarkko Sakkinen   Smack: Transmute ...
2688
  	struct task_smack *oldtsp;
d84f4f992   David Howells   CRED: Inaugurate ...
2689
  	struct cred *new;
e114e4737   Casey Schaufler   Smack: Simplified...
2690
  	char *newsmack;
e114e4737   Casey Schaufler   Smack: Simplified...
2691
2692
2693
2694
2695
2696
  	/*
  	 * Changing another process' Smack value is too dangerous
  	 * and supports no sane use case.
  	 */
  	if (p != current)
  		return -EPERM;
5cd9c58fb   David Howells   security: Fix set...
2697
2698
  	if (!capable(CAP_MAC_ADMIN))
  		return -EPERM;
e114e4737   Casey Schaufler   Smack: Simplified...
2699
2700
2701
2702
2703
2704
2705
2706
2707
  	if (value == NULL || size == 0 || size >= SMK_LABELLEN)
  		return -EINVAL;
  
  	if (strcmp(name, "current") != 0)
  		return -EINVAL;
  
  	newsmack = smk_import(value, size);
  	if (newsmack == NULL)
  		return -EINVAL;
6d3dc07cb   Casey Schaufler   smack: Add suppor...
2708
2709
2710
2711
2712
  	/*
  	 * No process is ever allowed the web ("@") label.
  	 */
  	if (newsmack == smack_known_web.smk_known)
  		return -EPERM;
5c6d1125f   Jarkko Sakkinen   Smack: Transmute ...
2713
  	oldtsp = p->cred->security;
d84f4f992   David Howells   CRED: Inaugurate ...
2714
  	new = prepare_creds();
6d3dc07cb   Casey Schaufler   smack: Add suppor...
2715
  	if (new == NULL)
d84f4f992   David Howells   CRED: Inaugurate ...
2716
  		return -ENOMEM;
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
2717
2718
  
  	tsp = new_task_smack(newsmack, oldtsp->smk_forked, GFP_KERNEL);
676dac4b1   Casey Schaufler   This patch adds a...
2719
2720
2721
2722
  	if (tsp == NULL) {
  		kfree(new);
  		return -ENOMEM;
  	}
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
2723
2724
2725
  	rc = smk_copy_rules(&tsp->smk_rules, &oldtsp->smk_rules, GFP_KERNEL);
  	if (rc != 0)
  		return rc;
676dac4b1   Casey Schaufler   This patch adds a...
2726
  	new->security = tsp;
d84f4f992   David Howells   CRED: Inaugurate ...
2727
  	commit_creds(new);
e114e4737   Casey Schaufler   Smack: Simplified...
2728
2729
2730
2731
2732
  	return size;
  }
  
  /**
   * smack_unix_stream_connect - Smack access on UDS
3610cda53   David S. Miller   af_unix: Avoid so...
2733
2734
   * @sock: one sock
   * @other: the other sock
e114e4737   Casey Schaufler   Smack: Simplified...
2735
2736
2737
2738
2739
   * @newsk: unused
   *
   * Return 0 if a subject with the smack of sock could access
   * an object with the smack of other, otherwise an error code
   */
3610cda53   David S. Miller   af_unix: Avoid so...
2740
2741
  static int smack_unix_stream_connect(struct sock *sock,
  				     struct sock *other, struct sock *newsk)
e114e4737   Casey Schaufler   Smack: Simplified...
2742
  {
d2e7ad192   James Morris   Merge branch 'mas...
2743
2744
  	struct socket_smack *ssp = sock->sk_security;
  	struct socket_smack *osp = other->sk_security;
975d5e55c   Casey Schaufler   Smack: Provide in...
2745
  	struct socket_smack *nsp = newsk->sk_security;
ecfcc53fe   Etienne Basset   smack: implement ...
2746
  	struct smk_audit_info ad;
b4e0d5f07   Casey Schaufler   Smack: UDS revision
2747
  	int rc = 0;
e114e4737   Casey Schaufler   Smack: Simplified...
2748

ecfcc53fe   Etienne Basset   smack: implement ...
2749
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_NET);
3610cda53   David S. Miller   af_unix: Avoid so...
2750
  	smk_ad_setfield_u_net_sk(&ad, other);
b4e0d5f07   Casey Schaufler   Smack: UDS revision
2751
2752
2753
  
  	if (!capable(CAP_MAC_OVERRIDE))
  		rc = smk_access(ssp->smk_out, osp->smk_in, MAY_WRITE, &ad);
975d5e55c   Casey Schaufler   Smack: Provide in...
2754
2755
2756
2757
2758
2759
2760
  	/*
  	 * Cross reference the peer labels for SO_PEERSEC.
  	 */
  	if (rc == 0) {
  		nsp->smk_packet = ssp->smk_out;
  		ssp->smk_packet = osp->smk_out;
  	}
b4e0d5f07   Casey Schaufler   Smack: UDS revision
2761
  	return rc;
e114e4737   Casey Schaufler   Smack: Simplified...
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
  }
  
  /**
   * smack_unix_may_send - Smack access on UDS
   * @sock: one socket
   * @other: the other socket
   *
   * Return 0 if a subject with the smack of sock could access
   * an object with the smack of other, otherwise an error code
   */
  static int smack_unix_may_send(struct socket *sock, struct socket *other)
  {
b4e0d5f07   Casey Schaufler   Smack: UDS revision
2774
2775
  	struct socket_smack *ssp = sock->sk->sk_security;
  	struct socket_smack *osp = other->sk->sk_security;
ecfcc53fe   Etienne Basset   smack: implement ...
2776
  	struct smk_audit_info ad;
b4e0d5f07   Casey Schaufler   Smack: UDS revision
2777
  	int rc = 0;
e114e4737   Casey Schaufler   Smack: Simplified...
2778

ecfcc53fe   Etienne Basset   smack: implement ...
2779
2780
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_NET);
  	smk_ad_setfield_u_net_sk(&ad, other->sk);
b4e0d5f07   Casey Schaufler   Smack: UDS revision
2781
2782
2783
2784
2785
  
  	if (!capable(CAP_MAC_OVERRIDE))
  		rc = smk_access(ssp->smk_out, osp->smk_in, MAY_WRITE, &ad);
  
  	return rc;
e114e4737   Casey Schaufler   Smack: Simplified...
2786
2787
2788
  }
  
  /**
6d3dc07cb   Casey Schaufler   smack: Add suppor...
2789
2790
   * smack_socket_sendmsg - Smack check based on destination host
   * @sock: the socket
251a2a958   Randy Dunlap   smack: fix lots o...
2791
   * @msg: the message
6d3dc07cb   Casey Schaufler   smack: Add suppor...
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
   * @size: the size of the message
   *
   * Return 0 if the current subject can write to the destination
   * host. This is only a question if the destination is a single
   * label host.
   */
  static int smack_socket_sendmsg(struct socket *sock, struct msghdr *msg,
  				int size)
  {
  	struct sockaddr_in *sip = (struct sockaddr_in *) msg->msg_name;
6d3dc07cb   Casey Schaufler   smack: Add suppor...
2802
2803
2804
2805
  
  	/*
  	 * Perfectly reasonable for this to be NULL
  	 */
da34d4248   Julia Lawall   security/smack: U...
2806
  	if (sip == NULL || sip->sin_family != AF_INET)
6d3dc07cb   Casey Schaufler   smack: Add suppor...
2807
  		return 0;
07feee8f8   Paul Moore   netlabel: Cleanup...
2808
  	return smack_netlabel_send(sock->sk, sip);
6d3dc07cb   Casey Schaufler   smack: Add suppor...
2809
  }
6d3dc07cb   Casey Schaufler   smack: Add suppor...
2810
  /**
251a2a958   Randy Dunlap   smack: fix lots o...
2811
   * smack_from_secattr - Convert a netlabel attr.mls.lvl/attr.mls.cat pair to smack
e114e4737   Casey Schaufler   Smack: Simplified...
2812
   * @sap: netlabel secattr
272cd7a8c   Casey Schaufler   Smack: Rule list ...
2813
   * @ssp: socket security information
e114e4737   Casey Schaufler   Smack: Simplified...
2814
   *
272cd7a8c   Casey Schaufler   Smack: Rule list ...
2815
   * Returns a pointer to a Smack label found on the label list.
e114e4737   Casey Schaufler   Smack: Simplified...
2816
   */
272cd7a8c   Casey Schaufler   Smack: Rule list ...
2817
2818
  static char *smack_from_secattr(struct netlbl_lsm_secattr *sap,
  				struct socket_smack *ssp)
e114e4737   Casey Schaufler   Smack: Simplified...
2819
  {
272cd7a8c   Casey Schaufler   Smack: Rule list ...
2820
  	struct smack_known *skp;
e114e4737   Casey Schaufler   Smack: Simplified...
2821
  	char smack[SMK_LABELLEN];
6d3dc07cb   Casey Schaufler   smack: Add suppor...
2822
  	char *sp;
e114e4737   Casey Schaufler   Smack: Simplified...
2823
  	int pcat;
6d3dc07cb   Casey Schaufler   smack: Add suppor...
2824
  	if ((sap->flags & NETLBL_SECATTR_MLS_LVL) != 0) {
e114e4737   Casey Schaufler   Smack: Simplified...
2825
  		/*
6d3dc07cb   Casey Schaufler   smack: Add suppor...
2826
  		 * Looks like a CIPSO packet.
e114e4737   Casey Schaufler   Smack: Simplified...
2827
2828
2829
  		 * If there are flags but no level netlabel isn't
  		 * behaving the way we expect it to.
  		 *
6d3dc07cb   Casey Schaufler   smack: Add suppor...
2830
  		 * Get the categories, if any
e114e4737   Casey Schaufler   Smack: Simplified...
2831
2832
2833
2834
  		 * Without guidance regarding the smack value
  		 * for the packet fall back on the network
  		 * ambient value.
  		 */
6d3dc07cb   Casey Schaufler   smack: Add suppor...
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
  		memset(smack, '\0', SMK_LABELLEN);
  		if ((sap->flags & NETLBL_SECATTR_MLS_CAT) != 0)
  			for (pcat = -1;;) {
  				pcat = netlbl_secattr_catmap_walk(
  					sap->attr.mls.cat, pcat + 1);
  				if (pcat < 0)
  					break;
  				smack_catset_bit(pcat, smack);
  			}
  		/*
  		 * If it is CIPSO using smack direct mapping
  		 * we are already done. WeeHee.
  		 */
  		if (sap->attr.mls.lvl == smack_cipso_direct) {
272cd7a8c   Casey Schaufler   Smack: Rule list ...
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
  			/*
  			 * The label sent is usually on the label list.
  			 *
  			 * If it is not we may still want to allow the
  			 * delivery.
  			 *
  			 * If the recipient is accepting all packets
  			 * because it is using the star ("*") label
  			 * for SMACK64IPIN provide the web ("@") label
  			 * so that a directed response will succeed.
  			 * This is not very correct from a MAC point
  			 * of view, but gets around the problem that
  			 * locking prevents adding the newly discovered
  			 * label to the list.
  			 * The case where the recipient is not using
  			 * the star label should obviously fail.
  			 * The easy way to do this is to provide the
  			 * star label as the subject label.
  			 */
  			skp = smk_find_entry(smack);
  			if (skp != NULL)
  				return skp->smk_known;
  			if (ssp != NULL &&
  			    ssp->smk_in == smack_known_star.smk_known)
  				return smack_known_web.smk_known;
  			return smack_known_star.smk_known;
6d3dc07cb   Casey Schaufler   smack: Add suppor...
2875
2876
2877
2878
2879
  		}
  		/*
  		 * Look it up in the supplied table if it is not
  		 * a direct mapping.
  		 */
272cd7a8c   Casey Schaufler   Smack: Rule list ...
2880
2881
2882
2883
2884
2885
  		sp = smack_from_cipso(sap->attr.mls.lvl, smack);
  		if (sp != NULL)
  			return sp;
  		if (ssp != NULL && ssp->smk_in == smack_known_star.smk_known)
  			return smack_known_web.smk_known;
  		return smack_known_star.smk_known;
e114e4737   Casey Schaufler   Smack: Simplified...
2886
  	}
6d3dc07cb   Casey Schaufler   smack: Add suppor...
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
  	if ((sap->flags & NETLBL_SECATTR_SECID) != 0) {
  		/*
  		 * Looks like a fallback, which gives us a secid.
  		 */
  		sp = smack_from_secid(sap->attr.secid);
  		/*
  		 * This has got to be a bug because it is
  		 * impossible to specify a fallback without
  		 * specifying the label, which will ensure
  		 * it has a secid, and the only way to get a
  		 * secid is from a fallback.
  		 */
  		BUG_ON(sp == NULL);
272cd7a8c   Casey Schaufler   Smack: Rule list ...
2900
  		return sp;
e114e4737   Casey Schaufler   Smack: Simplified...
2901
2902
  	}
  	/*
6d3dc07cb   Casey Schaufler   smack: Add suppor...
2903
2904
2905
  	 * Without guidance regarding the smack value
  	 * for the packet fall back on the network
  	 * ambient value.
e114e4737   Casey Schaufler   Smack: Simplified...
2906
  	 */
272cd7a8c   Casey Schaufler   Smack: Rule list ...
2907
  	return smack_net_ambient;
e114e4737   Casey Schaufler   Smack: Simplified...
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
  }
  
  /**
   * smack_socket_sock_rcv_skb - Smack packet delivery access check
   * @sk: socket
   * @skb: packet
   *
   * Returns 0 if the packet should be delivered, an error code otherwise
   */
  static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
  {
  	struct netlbl_lsm_secattr secattr;
  	struct socket_smack *ssp = sk->sk_security;
6d3dc07cb   Casey Schaufler   smack: Add suppor...
2921
  	char *csp;
e114e4737   Casey Schaufler   Smack: Simplified...
2922
  	int rc;
ecfcc53fe   Etienne Basset   smack: implement ...
2923
  	struct smk_audit_info ad;
e114e4737   Casey Schaufler   Smack: Simplified...
2924
2925
2926
2927
2928
2929
  	if (sk->sk_family != PF_INET && sk->sk_family != PF_INET6)
  		return 0;
  
  	/*
  	 * Translate what netlabel gave us.
  	 */
e114e4737   Casey Schaufler   Smack: Simplified...
2930
  	netlbl_secattr_init(&secattr);
6d3dc07cb   Casey Schaufler   smack: Add suppor...
2931

e114e4737   Casey Schaufler   Smack: Simplified...
2932
  	rc = netlbl_skbuff_getattr(skb, sk->sk_family, &secattr);
272cd7a8c   Casey Schaufler   Smack: Rule list ...
2933
2934
2935
  	if (rc == 0)
  		csp = smack_from_secattr(&secattr, ssp);
  	else
6d3dc07cb   Casey Schaufler   smack: Add suppor...
2936
  		csp = smack_net_ambient;
e114e4737   Casey Schaufler   Smack: Simplified...
2937
  	netlbl_secattr_destroy(&secattr);
6d3dc07cb   Casey Schaufler   smack: Add suppor...
2938

ecfcc53fe   Etienne Basset   smack: implement ...
2939
2940
2941
  #ifdef CONFIG_AUDIT
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_NET);
  	ad.a.u.net.family = sk->sk_family;
8964be4a9   Eric Dumazet   net: rename skb->...
2942
  	ad.a.u.net.netif = skb->skb_iif;
ecfcc53fe   Etienne Basset   smack: implement ...
2943
2944
  	ipv4_skb_to_auditdata(skb, &ad.a, NULL);
  #endif
e114e4737   Casey Schaufler   Smack: Simplified...
2945
2946
2947
2948
2949
2950
  	/*
  	 * Receiving a packet requires that the other end
  	 * be able to write here. Read access is not required.
  	 * This is the simplist possible security model
  	 * for networking.
  	 */
ecfcc53fe   Etienne Basset   smack: implement ...
2951
  	rc = smk_access(csp, ssp->smk_in, MAY_WRITE, &ad);
a8134296b   Paul Moore   smack: Fix missin...
2952
2953
2954
  	if (rc != 0)
  		netlbl_skbuff_err(skb, rc, 0);
  	return rc;
e114e4737   Casey Schaufler   Smack: Simplified...
2955
2956
2957
2958
2959
2960
2961
  }
  
  /**
   * smack_socket_getpeersec_stream - pull in packet label
   * @sock: the socket
   * @optval: user's destination
   * @optlen: size thereof
251a2a958   Randy Dunlap   smack: fix lots o...
2962
   * @len: max thereof
e114e4737   Casey Schaufler   Smack: Simplified...
2963
2964
2965
2966
2967
2968
2969
2970
   *
   * returns zero on success, an error code otherwise
   */
  static int smack_socket_getpeersec_stream(struct socket *sock,
  					  char __user *optval,
  					  int __user *optlen, unsigned len)
  {
  	struct socket_smack *ssp;
272cd7a8c   Casey Schaufler   Smack: Rule list ...
2971
2972
  	char *rcp = "";
  	int slen = 1;
e114e4737   Casey Schaufler   Smack: Simplified...
2973
2974
2975
  	int rc = 0;
  
  	ssp = sock->sk->sk_security;
272cd7a8c   Casey Schaufler   Smack: Rule list ...
2976
2977
2978
2979
  	if (ssp->smk_packet != NULL) {
  		rcp = ssp->smk_packet;
  		slen = strlen(rcp) + 1;
  	}
e114e4737   Casey Schaufler   Smack: Simplified...
2980
2981
2982
  
  	if (slen > len)
  		rc = -ERANGE;
272cd7a8c   Casey Schaufler   Smack: Rule list ...
2983
  	else if (copy_to_user(optval, rcp, slen) != 0)
e114e4737   Casey Schaufler   Smack: Simplified...
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
  		rc = -EFAULT;
  
  	if (put_user(slen, optlen) != 0)
  		rc = -EFAULT;
  
  	return rc;
  }
  
  
  /**
   * smack_socket_getpeersec_dgram - pull in packet label
b4e0d5f07   Casey Schaufler   Smack: UDS revision
2995
   * @sock: the peer socket
e114e4737   Casey Schaufler   Smack: Simplified...
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
   * @skb: packet data
   * @secid: pointer to where to put the secid of the packet
   *
   * Sets the netlabel socket state on sk from parent
   */
  static int smack_socket_getpeersec_dgram(struct socket *sock,
  					 struct sk_buff *skb, u32 *secid)
  
  {
  	struct netlbl_lsm_secattr secattr;
272cd7a8c   Casey Schaufler   Smack: Rule list ...
3006
3007
  	struct socket_smack *ssp = NULL;
  	char *sp;
b4e0d5f07   Casey Schaufler   Smack: UDS revision
3008
3009
  	int family = PF_UNSPEC;
  	u32 s = 0;	/* 0 is the invalid secid */
e114e4737   Casey Schaufler   Smack: Simplified...
3010
  	int rc;
b4e0d5f07   Casey Schaufler   Smack: UDS revision
3011
3012
3013
3014
3015
  	if (skb != NULL) {
  		if (skb->protocol == htons(ETH_P_IP))
  			family = PF_INET;
  		else if (skb->protocol == htons(ETH_P_IPV6))
  			family = PF_INET6;
e114e4737   Casey Schaufler   Smack: Simplified...
3016
  	}
b4e0d5f07   Casey Schaufler   Smack: UDS revision
3017
3018
  	if (family == PF_UNSPEC && sock != NULL)
  		family = sock->sk->sk_family;
e114e4737   Casey Schaufler   Smack: Simplified...
3019

b4e0d5f07   Casey Schaufler   Smack: UDS revision
3020
  	if (family == PF_UNIX) {
272cd7a8c   Casey Schaufler   Smack: Rule list ...
3021
3022
  		ssp = sock->sk->sk_security;
  		s = smack_to_secid(ssp->smk_out);
b4e0d5f07   Casey Schaufler   Smack: UDS revision
3023
3024
3025
3026
  	} else if (family == PF_INET || family == PF_INET6) {
  		/*
  		 * Translate what netlabel gave us.
  		 */
272cd7a8c   Casey Schaufler   Smack: Rule list ...
3027
3028
  		if (sock != NULL && sock->sk != NULL)
  			ssp = sock->sk->sk_security;
b4e0d5f07   Casey Schaufler   Smack: UDS revision
3029
3030
3031
  		netlbl_secattr_init(&secattr);
  		rc = netlbl_skbuff_getattr(skb, family, &secattr);
  		if (rc == 0) {
272cd7a8c   Casey Schaufler   Smack: Rule list ...
3032
3033
  			sp = smack_from_secattr(&secattr, ssp);
  			s = smack_to_secid(sp);
b4e0d5f07   Casey Schaufler   Smack: UDS revision
3034
3035
3036
3037
  		}
  		netlbl_secattr_destroy(&secattr);
  	}
  	*secid = s;
e114e4737   Casey Schaufler   Smack: Simplified...
3038
3039
  	if (s == 0)
  		return -EINVAL;
e114e4737   Casey Schaufler   Smack: Simplified...
3040
3041
3042
3043
  	return 0;
  }
  
  /**
07feee8f8   Paul Moore   netlabel: Cleanup...
3044
3045
3046
   * smack_sock_graft - Initialize a newly created socket with an existing sock
   * @sk: child sock
   * @parent: parent socket
e114e4737   Casey Schaufler   Smack: Simplified...
3047
   *
07feee8f8   Paul Moore   netlabel: Cleanup...
3048
3049
   * Set the smk_{in,out} state of an existing sock based on the process that
   * is creating the new socket.
e114e4737   Casey Schaufler   Smack: Simplified...
3050
3051
3052
3053
   */
  static void smack_sock_graft(struct sock *sk, struct socket *parent)
  {
  	struct socket_smack *ssp;
e114e4737   Casey Schaufler   Smack: Simplified...
3054

07feee8f8   Paul Moore   netlabel: Cleanup...
3055
3056
  	if (sk == NULL ||
  	    (sk->sk_family != PF_INET && sk->sk_family != PF_INET6))
e114e4737   Casey Schaufler   Smack: Simplified...
3057
3058
3059
  		return;
  
  	ssp = sk->sk_security;
676dac4b1   Casey Schaufler   This patch adds a...
3060
  	ssp->smk_in = ssp->smk_out = smk_of_current();
07feee8f8   Paul Moore   netlabel: Cleanup...
3061
  	/* cssp->smk_packet is already set in smack_inet_csk_clone() */
e114e4737   Casey Schaufler   Smack: Simplified...
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
  }
  
  /**
   * smack_inet_conn_request - Smack access check on connect
   * @sk: socket involved
   * @skb: packet
   * @req: unused
   *
   * Returns 0 if a task with the packet label could write to
   * the socket, otherwise an error code
   */
  static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb,
  				   struct request_sock *req)
  {
07feee8f8   Paul Moore   netlabel: Cleanup...
3076
  	u16 family = sk->sk_family;
e114e4737   Casey Schaufler   Smack: Simplified...
3077
  	struct socket_smack *ssp = sk->sk_security;
07feee8f8   Paul Moore   netlabel: Cleanup...
3078
3079
3080
  	struct netlbl_lsm_secattr secattr;
  	struct sockaddr_in addr;
  	struct iphdr *hdr;
272cd7a8c   Casey Schaufler   Smack: Rule list ...
3081
  	char *sp;
e114e4737   Casey Schaufler   Smack: Simplified...
3082
  	int rc;
ecfcc53fe   Etienne Basset   smack: implement ...
3083
  	struct smk_audit_info ad;
e114e4737   Casey Schaufler   Smack: Simplified...
3084

07feee8f8   Paul Moore   netlabel: Cleanup...
3085
3086
3087
  	/* handle mapped IPv4 packets arriving via IPv6 sockets */
  	if (family == PF_INET6 && skb->protocol == htons(ETH_P_IP))
  		family = PF_INET;
e114e4737   Casey Schaufler   Smack: Simplified...
3088

07feee8f8   Paul Moore   netlabel: Cleanup...
3089
3090
  	netlbl_secattr_init(&secattr);
  	rc = netlbl_skbuff_getattr(skb, family, &secattr);
e114e4737   Casey Schaufler   Smack: Simplified...
3091
  	if (rc == 0)
272cd7a8c   Casey Schaufler   Smack: Rule list ...
3092
  		sp = smack_from_secattr(&secattr, ssp);
e114e4737   Casey Schaufler   Smack: Simplified...
3093
  	else
272cd7a8c   Casey Schaufler   Smack: Rule list ...
3094
  		sp = smack_known_huh.smk_known;
07feee8f8   Paul Moore   netlabel: Cleanup...
3095
  	netlbl_secattr_destroy(&secattr);
ecfcc53fe   Etienne Basset   smack: implement ...
3096
3097
3098
  #ifdef CONFIG_AUDIT
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_NET);
  	ad.a.u.net.family = family;
8964be4a9   Eric Dumazet   net: rename skb->...
3099
  	ad.a.u.net.netif = skb->skb_iif;
ecfcc53fe   Etienne Basset   smack: implement ...
3100
3101
  	ipv4_skb_to_auditdata(skb, &ad.a, NULL);
  #endif
e114e4737   Casey Schaufler   Smack: Simplified...
3102
  	/*
07feee8f8   Paul Moore   netlabel: Cleanup...
3103
3104
  	 * Receiving a packet requires that the other end be able to write
  	 * here. Read access is not required.
e114e4737   Casey Schaufler   Smack: Simplified...
3105
  	 */
272cd7a8c   Casey Schaufler   Smack: Rule list ...
3106
  	rc = smk_access(sp, ssp->smk_in, MAY_WRITE, &ad);
07feee8f8   Paul Moore   netlabel: Cleanup...
3107
3108
3109
3110
3111
3112
3113
  	if (rc != 0)
  		return rc;
  
  	/*
  	 * Save the peer's label in the request_sock so we can later setup
  	 * smk_packet in the child socket so that SO_PEERCRED can report it.
  	 */
272cd7a8c   Casey Schaufler   Smack: Rule list ...
3114
  	req->peer_secid = smack_to_secid(sp);
07feee8f8   Paul Moore   netlabel: Cleanup...
3115
3116
3117
3118
  
  	/*
  	 * We need to decide if we want to label the incoming connection here
  	 * if we do we only need to label the request_sock and the stack will
25985edce   Lucas De Marchi   Fix common misspe...
3119
  	 * propagate the wire-label to the sock when it is created.
07feee8f8   Paul Moore   netlabel: Cleanup...
3120
3121
3122
3123
3124
3125
3126
  	 */
  	hdr = ip_hdr(skb);
  	addr.sin_addr.s_addr = hdr->saddr;
  	rcu_read_lock();
  	if (smack_host_label(&addr) == NULL) {
  		rcu_read_unlock();
  		netlbl_secattr_init(&secattr);
272cd7a8c   Casey Schaufler   Smack: Rule list ...
3127
  		smack_to_secattr(sp, &secattr);
07feee8f8   Paul Moore   netlabel: Cleanup...
3128
3129
3130
3131
3132
3133
  		rc = netlbl_req_setattr(req, &secattr);
  		netlbl_secattr_destroy(&secattr);
  	} else {
  		rcu_read_unlock();
  		netlbl_req_delattr(req);
  	}
e114e4737   Casey Schaufler   Smack: Simplified...
3134
3135
3136
  
  	return rc;
  }
07feee8f8   Paul Moore   netlabel: Cleanup...
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
  /**
   * smack_inet_csk_clone - Copy the connection information to the new socket
   * @sk: the new socket
   * @req: the connection's request_sock
   *
   * Transfer the connection's peer label to the newly created socket.
   */
  static void smack_inet_csk_clone(struct sock *sk,
  				 const struct request_sock *req)
  {
  	struct socket_smack *ssp = sk->sk_security;
07feee8f8   Paul Moore   netlabel: Cleanup...
3148

272cd7a8c   Casey Schaufler   Smack: Rule list ...
3149
3150
3151
3152
  	if (req->peer_secid != 0)
  		ssp->smk_packet = smack_from_secid(req->peer_secid);
  	else
  		ssp->smk_packet = NULL;
07feee8f8   Paul Moore   netlabel: Cleanup...
3153
  }
e114e4737   Casey Schaufler   Smack: Simplified...
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
  /*
   * Key management security hooks
   *
   * Casey has not tested key support very heavily.
   * The permission check is most likely too restrictive.
   * If you care about keys please have a look.
   */
  #ifdef CONFIG_KEYS
  
  /**
   * smack_key_alloc - Set the key security blob
   * @key: object
d84f4f992   David Howells   CRED: Inaugurate ...
3166
   * @cred: the credentials to use
e114e4737   Casey Schaufler   Smack: Simplified...
3167
3168
3169
3170
3171
3172
   * @flags: unused
   *
   * No allocation required
   *
   * Returns 0
   */
d84f4f992   David Howells   CRED: Inaugurate ...
3173
  static int smack_key_alloc(struct key *key, const struct cred *cred,
e114e4737   Casey Schaufler   Smack: Simplified...
3174
3175
  			   unsigned long flags)
  {
676dac4b1   Casey Schaufler   This patch adds a...
3176
  	key->security = smk_of_task(cred->security);
e114e4737   Casey Schaufler   Smack: Simplified...
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
  	return 0;
  }
  
  /**
   * smack_key_free - Clear the key security blob
   * @key: the object
   *
   * Clear the blob pointer
   */
  static void smack_key_free(struct key *key)
  {
  	key->security = NULL;
  }
  
  /*
   * smack_key_permission - Smack access on a key
   * @key_ref: gets to the object
d84f4f992   David Howells   CRED: Inaugurate ...
3194
   * @cred: the credentials to use
e114e4737   Casey Schaufler   Smack: Simplified...
3195
3196
3197
3198
3199
3200
   * @perm: unused
   *
   * Return 0 if the task has read and write to the object,
   * an error code otherwise
   */
  static int smack_key_permission(key_ref_t key_ref,
d84f4f992   David Howells   CRED: Inaugurate ...
3201
  				const struct cred *cred, key_perm_t perm)
e114e4737   Casey Schaufler   Smack: Simplified...
3202
3203
  {
  	struct key *keyp;
ecfcc53fe   Etienne Basset   smack: implement ...
3204
  	struct smk_audit_info ad;
676dac4b1   Casey Schaufler   This patch adds a...
3205
  	char *tsp = smk_of_task(cred->security);
e114e4737   Casey Schaufler   Smack: Simplified...
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
  
  	keyp = key_ref_to_ptr(key_ref);
  	if (keyp == NULL)
  		return -EINVAL;
  	/*
  	 * If the key hasn't been initialized give it access so that
  	 * it may do so.
  	 */
  	if (keyp->security == NULL)
  		return 0;
  	/*
  	 * This should not occur
  	 */
676dac4b1   Casey Schaufler   This patch adds a...
3219
  	if (tsp == NULL)
e114e4737   Casey Schaufler   Smack: Simplified...
3220
  		return -EACCES;
ecfcc53fe   Etienne Basset   smack: implement ...
3221
3222
3223
3224
3225
  #ifdef CONFIG_AUDIT
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_KEY);
  	ad.a.u.key_struct.key = keyp->serial;
  	ad.a.u.key_struct.key_desc = keyp->description;
  #endif
676dac4b1   Casey Schaufler   This patch adds a...
3226
  	return smk_access(tsp, keyp->security,
ecfcc53fe   Etienne Basset   smack: implement ...
3227
  				 MAY_READWRITE, &ad);
e114e4737   Casey Schaufler   Smack: Simplified...
3228
3229
3230
3231
  }
  #endif /* CONFIG_KEYS */
  
  /*
d20bdda6d   Ahmed S. Darwish   Smack: Integrate ...
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
   * Smack Audit hooks
   *
   * Audit requires a unique representation of each Smack specific
   * rule. This unique representation is used to distinguish the
   * object to be audited from remaining kernel objects and also
   * works as a glue between the audit hooks.
   *
   * Since repository entries are added but never deleted, we'll use
   * the smack_known label address related to the given audit rule as
   * the needed unique representation. This also better fits the smack
   * model where nearly everything is a label.
   */
  #ifdef CONFIG_AUDIT
  
  /**
   * smack_audit_rule_init - Initialize a smack audit rule
   * @field: audit rule fields given from user-space (audit.h)
   * @op: required testing operator (=, !=, >, <, ...)
   * @rulestr: smack label to be audited
   * @vrule: pointer to save our own audit rule representation
   *
   * Prepare to audit cases where (@field @op @rulestr) is true.
   * The label to be audited is created if necessay.
   */
  static int smack_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule)
  {
  	char **rule = (char **)vrule;
  	*rule = NULL;
  
  	if (field != AUDIT_SUBJ_USER && field != AUDIT_OBJ_USER)
  		return -EINVAL;
5af75d8d5   Al Viro   audit: validate c...
3263
  	if (op != Audit_equal && op != Audit_not_equal)
d20bdda6d   Ahmed S. Darwish   Smack: Integrate ...
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
  		return -EINVAL;
  
  	*rule = smk_import(rulestr, 0);
  
  	return 0;
  }
  
  /**
   * smack_audit_rule_known - Distinguish Smack audit rules
   * @krule: rule of interest, in Audit kernel representation format
   *
   * This is used to filter Smack rules from remaining Audit ones.
   * If it's proved that this rule belongs to us, the
   * audit_rule_match hook will be called to do the final judgement.
   */
  static int smack_audit_rule_known(struct audit_krule *krule)
  {
  	struct audit_field *f;
  	int i;
  
  	for (i = 0; i < krule->field_count; i++) {
  		f = &krule->fields[i];
  
  		if (f->type == AUDIT_SUBJ_USER || f->type == AUDIT_OBJ_USER)
  			return 1;
  	}
  
  	return 0;
  }
  
  /**
   * smack_audit_rule_match - Audit given object ?
   * @secid: security id for identifying the object to test
   * @field: audit rule flags given from user-space
   * @op: required testing operator
   * @vrule: smack internal rule presentation
   * @actx: audit context associated with the check
   *
   * The core Audit hook. It's used to take the decision of
   * whether to audit or not to audit a given object.
   */
  static int smack_audit_rule_match(u32 secid, u32 field, u32 op, void *vrule,
  				  struct audit_context *actx)
  {
  	char *smack;
  	char *rule = vrule;
  
  	if (!rule) {
  		audit_log(actx, GFP_KERNEL, AUDIT_SELINUX_ERR,
  			  "Smack: missing rule
  ");
  		return -ENOENT;
  	}
  
  	if (field != AUDIT_SUBJ_USER && field != AUDIT_OBJ_USER)
  		return 0;
  
  	smack = smack_from_secid(secid);
  
  	/*
  	 * No need to do string comparisons. If a match occurs,
  	 * both pointers will point to the same smack_known
  	 * label.
  	 */
5af75d8d5   Al Viro   audit: validate c...
3328
  	if (op == Audit_equal)
d20bdda6d   Ahmed S. Darwish   Smack: Integrate ...
3329
  		return (rule == smack);
5af75d8d5   Al Viro   audit: validate c...
3330
  	if (op == Audit_not_equal)
d20bdda6d   Ahmed S. Darwish   Smack: Integrate ...
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
  		return (rule != smack);
  
  	return 0;
  }
  
  /**
   * smack_audit_rule_free - free smack rule representation
   * @vrule: rule to be freed.
   *
   * No memory was allocated.
   */
  static void smack_audit_rule_free(void *vrule)
  {
  	/* No-op */
  }
  
  #endif /* CONFIG_AUDIT */
251a2a958   Randy Dunlap   smack: fix lots o...
3348
  /**
e114e4737   Casey Schaufler   Smack: Simplified...
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
   * smack_secid_to_secctx - return the smack label for a secid
   * @secid: incoming integer
   * @secdata: destination
   * @seclen: how long it is
   *
   * Exists for networking code.
   */
  static int smack_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
  {
  	char *sp = smack_from_secid(secid);
d5630b9d2   Eric Paris   security: secid_t...
3359
3360
  	if (secdata)
  		*secdata = sp;
e114e4737   Casey Schaufler   Smack: Simplified...
3361
3362
3363
  	*seclen = strlen(sp);
  	return 0;
  }
251a2a958   Randy Dunlap   smack: fix lots o...
3364
  /**
4bc87e627   Casey Schaufler   Smack: unlabeled ...
3365
3366
3367
3368
3369
3370
3371
   * smack_secctx_to_secid - return the secid for a smack label
   * @secdata: smack label
   * @seclen: how long result is
   * @secid: outgoing integer
   *
   * Exists for audit and networking code.
   */
e52c1764f   David Howells   Security: Make se...
3372
  static int smack_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid)
4bc87e627   Casey Schaufler   Smack: unlabeled ...
3373
3374
3375
3376
  {
  	*secid = smack_to_secid(secdata);
  	return 0;
  }
251a2a958   Randy Dunlap   smack: fix lots o...
3377
  /**
e114e4737   Casey Schaufler   Smack: Simplified...
3378
   * smack_release_secctx - don't do anything.
251a2a958   Randy Dunlap   smack: fix lots o...
3379
3380
   * @secdata: unused
   * @seclen: unused
e114e4737   Casey Schaufler   Smack: Simplified...
3381
3382
3383
3384
3385
3386
   *
   * Exists to make sure nothing gets done, and properly
   */
  static void smack_release_secctx(char *secdata, u32 seclen)
  {
  }
1ee65e37e   David P. Quigley   LSM/SELinux: inod...
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
  static int smack_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen)
  {
  	return smack_inode_setsecurity(inode, XATTR_SMACK_SUFFIX, ctx, ctxlen, 0);
  }
  
  static int smack_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen)
  {
  	return __vfs_setxattr_noperm(dentry, XATTR_NAME_SMACK, ctx, ctxlen, 0);
  }
  
  static int smack_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen)
  {
  	int len = 0;
  	len = smack_inode_getsecurity(inode, XATTR_SMACK_SUFFIX, ctx, true);
  
  	if (len < 0)
  		return len;
  	*ctxlen = len;
  	return 0;
  }
076c54c5b   Ahmed S. Darwish   Security: Introdu...
3407
3408
  struct security_operations smack_ops = {
  	.name =				"smack",
9e48858f7   Ingo Molnar   security: rename ...
3409
  	.ptrace_access_check =		smack_ptrace_access_check,
5cd9c58fb   David Howells   security: Fix set...
3410
  	.ptrace_traceme =		smack_ptrace_traceme,
e114e4737   Casey Schaufler   Smack: Simplified...
3411
  	.syslog = 			smack_syslog,
e114e4737   Casey Schaufler   Smack: Simplified...
3412
3413
3414
3415
3416
3417
3418
3419
  
  	.sb_alloc_security = 		smack_sb_alloc_security,
  	.sb_free_security = 		smack_sb_free_security,
  	.sb_copy_data = 		smack_sb_copy_data,
  	.sb_kern_mount = 		smack_sb_kern_mount,
  	.sb_statfs = 			smack_sb_statfs,
  	.sb_mount = 			smack_sb_mount,
  	.sb_umount = 			smack_sb_umount,
676dac4b1   Casey Schaufler   This patch adds a...
3420
  	.bprm_set_creds =		smack_bprm_set_creds,
84088ba23   Jarkko Sakkinen   Smack: domain tra...
3421
3422
  	.bprm_committing_creds =	smack_bprm_committing_creds,
  	.bprm_secureexec =		smack_bprm_secureexec,
676dac4b1   Casey Schaufler   This patch adds a...
3423

e114e4737   Casey Schaufler   Smack: Simplified...
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
  	.inode_alloc_security = 	smack_inode_alloc_security,
  	.inode_free_security = 		smack_inode_free_security,
  	.inode_init_security = 		smack_inode_init_security,
  	.inode_link = 			smack_inode_link,
  	.inode_unlink = 		smack_inode_unlink,
  	.inode_rmdir = 			smack_inode_rmdir,
  	.inode_rename = 		smack_inode_rename,
  	.inode_permission = 		smack_inode_permission,
  	.inode_setattr = 		smack_inode_setattr,
  	.inode_getattr = 		smack_inode_getattr,
  	.inode_setxattr = 		smack_inode_setxattr,
  	.inode_post_setxattr = 		smack_inode_post_setxattr,
  	.inode_getxattr = 		smack_inode_getxattr,
  	.inode_removexattr = 		smack_inode_removexattr,
  	.inode_getsecurity = 		smack_inode_getsecurity,
  	.inode_setsecurity = 		smack_inode_setsecurity,
  	.inode_listsecurity = 		smack_inode_listsecurity,
d20bdda6d   Ahmed S. Darwish   Smack: Integrate ...
3441
  	.inode_getsecid =		smack_inode_getsecid,
e114e4737   Casey Schaufler   Smack: Simplified...
3442
3443
3444
3445
3446
3447
3448
  
  	.file_permission = 		smack_file_permission,
  	.file_alloc_security = 		smack_file_alloc_security,
  	.file_free_security = 		smack_file_free_security,
  	.file_ioctl = 			smack_file_ioctl,
  	.file_lock = 			smack_file_lock,
  	.file_fcntl = 			smack_file_fcntl,
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
3449
  	.file_mmap =			smack_file_mmap,
e114e4737   Casey Schaufler   Smack: Simplified...
3450
3451
3452
  	.file_set_fowner = 		smack_file_set_fowner,
  	.file_send_sigiotask = 		smack_file_send_sigiotask,
  	.file_receive = 		smack_file_receive,
531f1d453   Casey Schaufler   Smack: Repair pro...
3453
  	.dentry_open =			smack_dentry_open,
ee18d64c1   David Howells   KEYS: Add a keyct...
3454
  	.cred_alloc_blank =		smack_cred_alloc_blank,
f1752eec6   David Howells   CRED: Detach the ...
3455
  	.cred_free =			smack_cred_free,
d84f4f992   David Howells   CRED: Inaugurate ...
3456
  	.cred_prepare =			smack_cred_prepare,
ee18d64c1   David Howells   KEYS: Add a keyct...
3457
  	.cred_transfer =		smack_cred_transfer,
3a3b7ce93   David Howells   CRED: Allow kerne...
3458
3459
  	.kernel_act_as =		smack_kernel_act_as,
  	.kernel_create_files_as =	smack_kernel_create_files_as,
e114e4737   Casey Schaufler   Smack: Simplified...
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
  	.task_setpgid = 		smack_task_setpgid,
  	.task_getpgid = 		smack_task_getpgid,
  	.task_getsid = 			smack_task_getsid,
  	.task_getsecid = 		smack_task_getsecid,
  	.task_setnice = 		smack_task_setnice,
  	.task_setioprio = 		smack_task_setioprio,
  	.task_getioprio = 		smack_task_getioprio,
  	.task_setscheduler = 		smack_task_setscheduler,
  	.task_getscheduler = 		smack_task_getscheduler,
  	.task_movememory = 		smack_task_movememory,
  	.task_kill = 			smack_task_kill,
  	.task_wait = 			smack_task_wait,
e114e4737   Casey Schaufler   Smack: Simplified...
3472
3473
3474
  	.task_to_inode = 		smack_task_to_inode,
  
  	.ipc_permission = 		smack_ipc_permission,
d20bdda6d   Ahmed S. Darwish   Smack: Integrate ...
3475
  	.ipc_getsecid =			smack_ipc_getsecid,
e114e4737   Casey Schaufler   Smack: Simplified...
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
  
  	.msg_msg_alloc_security = 	smack_msg_msg_alloc_security,
  	.msg_msg_free_security = 	smack_msg_msg_free_security,
  
  	.msg_queue_alloc_security = 	smack_msg_queue_alloc_security,
  	.msg_queue_free_security = 	smack_msg_queue_free_security,
  	.msg_queue_associate = 		smack_msg_queue_associate,
  	.msg_queue_msgctl = 		smack_msg_queue_msgctl,
  	.msg_queue_msgsnd = 		smack_msg_queue_msgsnd,
  	.msg_queue_msgrcv = 		smack_msg_queue_msgrcv,
  
  	.shm_alloc_security = 		smack_shm_alloc_security,
  	.shm_free_security = 		smack_shm_free_security,
  	.shm_associate = 		smack_shm_associate,
  	.shm_shmctl = 			smack_shm_shmctl,
  	.shm_shmat = 			smack_shm_shmat,
  
  	.sem_alloc_security = 		smack_sem_alloc_security,
  	.sem_free_security = 		smack_sem_free_security,
  	.sem_associate = 		smack_sem_associate,
  	.sem_semctl = 			smack_sem_semctl,
  	.sem_semop = 			smack_sem_semop,
e114e4737   Casey Schaufler   Smack: Simplified...
3498
3499
3500
3501
3502
3503
3504
3505
3506
  	.d_instantiate = 		smack_d_instantiate,
  
  	.getprocattr = 			smack_getprocattr,
  	.setprocattr = 			smack_setprocattr,
  
  	.unix_stream_connect = 		smack_unix_stream_connect,
  	.unix_may_send = 		smack_unix_may_send,
  
  	.socket_post_create = 		smack_socket_post_create,
6d3dc07cb   Casey Schaufler   smack: Add suppor...
3507
3508
  	.socket_connect =		smack_socket_connect,
  	.socket_sendmsg =		smack_socket_sendmsg,
e114e4737   Casey Schaufler   Smack: Simplified...
3509
3510
3511
3512
3513
3514
3515
  	.socket_sock_rcv_skb = 		smack_socket_sock_rcv_skb,
  	.socket_getpeersec_stream =	smack_socket_getpeersec_stream,
  	.socket_getpeersec_dgram =	smack_socket_getpeersec_dgram,
  	.sk_alloc_security = 		smack_sk_alloc_security,
  	.sk_free_security = 		smack_sk_free_security,
  	.sock_graft = 			smack_sock_graft,
  	.inet_conn_request = 		smack_inet_conn_request,
07feee8f8   Paul Moore   netlabel: Cleanup...
3516
  	.inet_csk_clone =		smack_inet_csk_clone,
d20bdda6d   Ahmed S. Darwish   Smack: Integrate ...
3517

e114e4737   Casey Schaufler   Smack: Simplified...
3518
3519
3520
3521
3522
3523
   /* key management security hooks */
  #ifdef CONFIG_KEYS
  	.key_alloc = 			smack_key_alloc,
  	.key_free = 			smack_key_free,
  	.key_permission = 		smack_key_permission,
  #endif /* CONFIG_KEYS */
d20bdda6d   Ahmed S. Darwish   Smack: Integrate ...
3524
3525
3526
3527
3528
3529
3530
3531
  
   /* Audit hooks */
  #ifdef CONFIG_AUDIT
  	.audit_rule_init =		smack_audit_rule_init,
  	.audit_rule_known =		smack_audit_rule_known,
  	.audit_rule_match =		smack_audit_rule_match,
  	.audit_rule_free =		smack_audit_rule_free,
  #endif /* CONFIG_AUDIT */
e114e4737   Casey Schaufler   Smack: Simplified...
3532
  	.secid_to_secctx = 		smack_secid_to_secctx,
4bc87e627   Casey Schaufler   Smack: unlabeled ...
3533
  	.secctx_to_secid = 		smack_secctx_to_secid,
e114e4737   Casey Schaufler   Smack: Simplified...
3534
  	.release_secctx = 		smack_release_secctx,
1ee65e37e   David P. Quigley   LSM/SELinux: inod...
3535
3536
3537
  	.inode_notifysecctx =		smack_inode_notifysecctx,
  	.inode_setsecctx =		smack_inode_setsecctx,
  	.inode_getsecctx =		smack_inode_getsecctx,
e114e4737   Casey Schaufler   Smack: Simplified...
3538
  };
7198e2eeb   Etienne Basset   smack: convert sm...
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
  
  static __init void init_smack_know_list(void)
  {
  	list_add(&smack_known_huh.list, &smack_known_list);
  	list_add(&smack_known_hat.list, &smack_known_list);
  	list_add(&smack_known_star.list, &smack_known_list);
  	list_add(&smack_known_floor.list, &smack_known_list);
  	list_add(&smack_known_invalid.list, &smack_known_list);
  	list_add(&smack_known_web.list, &smack_known_list);
  }
e114e4737   Casey Schaufler   Smack: Simplified...
3549
3550
3551
3552
3553
3554
3555
  /**
   * smack_init - initialize the smack system
   *
   * Returns 0
   */
  static __init int smack_init(void)
  {
d84f4f992   David Howells   CRED: Inaugurate ...
3556
  	struct cred *cred;
676dac4b1   Casey Schaufler   This patch adds a...
3557
  	struct task_smack *tsp;
d84f4f992   David Howells   CRED: Inaugurate ...
3558

7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
3559
3560
3561
3562
3563
  	if (!security_module_enable(&smack_ops))
  		return 0;
  
  	tsp = new_task_smack(smack_known_floor.smk_known,
  				smack_known_floor.smk_known, GFP_KERNEL);
676dac4b1   Casey Schaufler   This patch adds a...
3564
3565
  	if (tsp == NULL)
  		return -ENOMEM;
e114e4737   Casey Schaufler   Smack: Simplified...
3566
3567
3568
3569
3570
3571
  	printk(KERN_INFO "Smack:  Initializing.
  ");
  
  	/*
  	 * Set the security state for the initial task.
  	 */
d84f4f992   David Howells   CRED: Inaugurate ...
3572
  	cred = (struct cred *) current->cred;
676dac4b1   Casey Schaufler   This patch adds a...
3573
  	cred->security = tsp;
e114e4737   Casey Schaufler   Smack: Simplified...
3574

421f91d21   Uwe Kleine-König   fix typos concern...
3575
  	/* initialize the smack_know_list */
7198e2eeb   Etienne Basset   smack: convert sm...
3576
  	init_smack_know_list();
e114e4737   Casey Schaufler   Smack: Simplified...
3577
3578
3579
  	/*
  	 * Initialize locks
  	 */
e114e4737   Casey Schaufler   Smack: Simplified...
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
  	spin_lock_init(&smack_known_huh.smk_cipsolock);
  	spin_lock_init(&smack_known_hat.smk_cipsolock);
  	spin_lock_init(&smack_known_star.smk_cipsolock);
  	spin_lock_init(&smack_known_floor.smk_cipsolock);
  	spin_lock_init(&smack_known_invalid.smk_cipsolock);
  
  	/*
  	 * Register with LSM
  	 */
  	if (register_security(&smack_ops))
  		panic("smack: Unable to register with kernel.
  ");
  
  	return 0;
  }
  
  /*
   * Smack requires early initialization in order to label
   * all processes and objects when they are created.
   */
  security_initcall(smack_init);