Blame view

security/smack/smack_lsm.c 116 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>
c67394434   Casey Schaufler   Smack: Local IPv6...
30
  #include <linux/dccp.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
31
  #include <linux/slab.h>
e114e4737   Casey Schaufler   Smack: Simplified...
32
33
  #include <linux/mutex.h>
  #include <linux/pipe_fs_i.h>
e114e4737   Casey Schaufler   Smack: Simplified...
34
  #include <net/cipso_ipv4.h>
c67394434   Casey Schaufler   Smack: Local IPv6...
35
36
  #include <net/ip.h>
  #include <net/ipv6.h>
d20bdda6d   Ahmed S. Darwish   Smack: Integrate ...
37
  #include <linux/audit.h>
1fd7317d0   Nick Black   Move magic number...
38
  #include <linux/magic.h>
2a7dba391   Eric Paris   fs/vfs/security: ...
39
  #include <linux/dcache.h>
16014d875   Jarkko Sakkinen   Smack: compilatio...
40
  #include <linux/personality.h>
404015308   Al Viro   security: trim se...
41
42
43
  #include <linux/msg.h>
  #include <linux/shm.h>
  #include <linux/binfmts.h>
3bf2789ca   Vivek Trivedi   smack: allow moun...
44
  #include <linux/parser.h>
e114e4737   Casey Schaufler   Smack: Simplified...
45
  #include "smack.h"
5c6d1125f   Jarkko Sakkinen   Smack: Transmute ...
46
47
  #define TRANS_TRUE	"TRUE"
  #define TRANS_TRUE_SIZE	4
c67394434   Casey Schaufler   Smack: Local IPv6...
48
49
50
  #define SMK_CONNECTING	0
  #define SMK_RECEIVING	1
  #define SMK_SENDING	2
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
51
  #ifdef SMACK_IPV6_PORT_LABELING
3c7ce3427   Vishal Goel   SMACK: Add the rc...
52
  DEFINE_MUTEX(smack_ipv6_lock);
8b549ef42   Geliang Tang   smack: smk_ipv6_p...
53
  static LIST_HEAD(smk_ipv6_port_list);
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
54
  #endif
1a5b472bd   Rohit   Security: smack: ...
55
  static struct kmem_cache *smack_inode_cache;
69f287ae6   Casey Schaufler   Smack: secmark su...
56
  int smack_enabled;
c67394434   Casey Schaufler   Smack: Local IPv6...
57

3d04c9240   Casey Schaufler   Smack - Fix build...
58
  static const match_table_t smk_mount_tokens = {
3bf2789ca   Vivek Trivedi   smack: allow moun...
59
60
61
62
63
64
65
  	{Opt_fsdefault, SMK_FSDEFAULT "%s"},
  	{Opt_fsfloor, SMK_FSFLOOR "%s"},
  	{Opt_fshat, SMK_FSHAT "%s"},
  	{Opt_fsroot, SMK_FSROOT "%s"},
  	{Opt_fstransmute, SMK_FSTRANS "%s"},
  	{Opt_error, NULL},
  };
3d04c9240   Casey Schaufler   Smack - Fix build...
66
67
68
69
70
71
72
  #ifdef CONFIG_SECURITY_SMACK_BRINGUP
  static char *smk_bu_mess[] = {
  	"Bringup Error",	/* Unused */
  	"Bringup",		/* SMACK_BRINGUP_ALLOW */
  	"Unconfined Subject",	/* SMACK_UNCONFINED_SUBJECT */
  	"Unconfined Object",	/* SMACK_UNCONFINED_OBJECT */
  };
d166c8024   Casey Schaufler   Smack: Bring-up a...
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
  static void smk_bu_mode(int mode, char *s)
  {
  	int i = 0;
  
  	if (mode & MAY_READ)
  		s[i++] = 'r';
  	if (mode & MAY_WRITE)
  		s[i++] = 'w';
  	if (mode & MAY_EXEC)
  		s[i++] = 'x';
  	if (mode & MAY_APPEND)
  		s[i++] = 'a';
  	if (mode & MAY_TRANSMUTE)
  		s[i++] = 't';
  	if (mode & MAY_LOCK)
  		s[i++] = 'l';
  	if (i == 0)
  		s[i++] = '-';
  	s[i] = '\0';
  }
  #endif
  
  #ifdef CONFIG_SECURITY_SMACK_BRINGUP
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
96
97
  static int smk_bu_note(char *note, struct smack_known *sskp,
  		       struct smack_known *oskp, int mode, int rc)
d166c8024   Casey Schaufler   Smack: Bring-up a...
98
99
100
101
102
  {
  	char acc[SMK_NUM_ACCESS_TYPE + 1];
  
  	if (rc <= 0)
  		return rc;
bf4b2fee9   Casey Schaufler   Smack: Allow an u...
103
104
  	if (rc > SMACK_UNCONFINED_OBJECT)
  		rc = 0;
d166c8024   Casey Schaufler   Smack: Bring-up a...
105
106
  
  	smk_bu_mode(mode, acc);
bf4b2fee9   Casey Schaufler   Smack: Allow an u...
107
108
  	pr_info("Smack %s: (%s %s %s) %s
  ", smk_bu_mess[rc],
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
109
  		sskp->smk_known, oskp->smk_known, acc, note);
d166c8024   Casey Schaufler   Smack: Bring-up a...
110
111
112
  	return 0;
  }
  #else
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
113
  #define smk_bu_note(note, sskp, oskp, mode, RC) (RC)
d166c8024   Casey Schaufler   Smack: Bring-up a...
114
115
116
  #endif
  
  #ifdef CONFIG_SECURITY_SMACK_BRINGUP
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
117
118
  static int smk_bu_current(char *note, struct smack_known *oskp,
  			  int mode, int rc)
d166c8024   Casey Schaufler   Smack: Bring-up a...
119
120
121
122
123
124
  {
  	struct task_smack *tsp = current_security();
  	char acc[SMK_NUM_ACCESS_TYPE + 1];
  
  	if (rc <= 0)
  		return rc;
bf4b2fee9   Casey Schaufler   Smack: Allow an u...
125
126
  	if (rc > SMACK_UNCONFINED_OBJECT)
  		rc = 0;
d166c8024   Casey Schaufler   Smack: Bring-up a...
127
128
  
  	smk_bu_mode(mode, acc);
bf4b2fee9   Casey Schaufler   Smack: Allow an u...
129
130
  	pr_info("Smack %s: (%s %s %s) %s %s
  ", smk_bu_mess[rc],
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
131
132
  		tsp->smk_task->smk_known, oskp->smk_known,
  		acc, current->comm, note);
d166c8024   Casey Schaufler   Smack: Bring-up a...
133
134
135
  	return 0;
  }
  #else
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
136
  #define smk_bu_current(note, oskp, mode, RC) (RC)
d166c8024   Casey Schaufler   Smack: Bring-up a...
137
138
139
140
141
142
  #endif
  
  #ifdef CONFIG_SECURITY_SMACK_BRINGUP
  static int smk_bu_task(struct task_struct *otp, int mode, int rc)
  {
  	struct task_smack *tsp = current_security();
6d1cff2a8   Andrey Ryabinin   smack: fix possib...
143
  	struct smack_known *smk_task = smk_of_task_struct(otp);
d166c8024   Casey Schaufler   Smack: Bring-up a...
144
145
146
147
  	char acc[SMK_NUM_ACCESS_TYPE + 1];
  
  	if (rc <= 0)
  		return rc;
bf4b2fee9   Casey Schaufler   Smack: Allow an u...
148
149
  	if (rc > SMACK_UNCONFINED_OBJECT)
  		rc = 0;
d166c8024   Casey Schaufler   Smack: Bring-up a...
150
151
  
  	smk_bu_mode(mode, acc);
bf4b2fee9   Casey Schaufler   Smack: Allow an u...
152
153
  	pr_info("Smack %s: (%s %s %s) %s to %s
  ", smk_bu_mess[rc],
6d1cff2a8   Andrey Ryabinin   smack: fix possib...
154
  		tsp->smk_task->smk_known, smk_task->smk_known, acc,
d166c8024   Casey Schaufler   Smack: Bring-up a...
155
156
157
158
159
160
161
162
163
164
165
  		current->comm, otp->comm);
  	return 0;
  }
  #else
  #define smk_bu_task(otp, mode, RC) (RC)
  #endif
  
  #ifdef CONFIG_SECURITY_SMACK_BRINGUP
  static int smk_bu_inode(struct inode *inode, int mode, int rc)
  {
  	struct task_smack *tsp = current_security();
bf4b2fee9   Casey Schaufler   Smack: Allow an u...
166
  	struct inode_smack *isp = inode->i_security;
d166c8024   Casey Schaufler   Smack: Bring-up a...
167
  	char acc[SMK_NUM_ACCESS_TYPE + 1];
bf4b2fee9   Casey Schaufler   Smack: Allow an u...
168
169
170
171
  	if (isp->smk_flags & SMK_INODE_IMPURE)
  		pr_info("Smack Unconfined Corruption: inode=(%s %ld) %s
  ",
  			inode->i_sb->s_id, inode->i_ino, current->comm);
d166c8024   Casey Schaufler   Smack: Bring-up a...
172
173
  	if (rc <= 0)
  		return rc;
bf4b2fee9   Casey Schaufler   Smack: Allow an u...
174
175
176
177
178
  	if (rc > SMACK_UNCONFINED_OBJECT)
  		rc = 0;
  	if (rc == SMACK_UNCONFINED_SUBJECT &&
  	    (mode & (MAY_WRITE | MAY_APPEND)))
  		isp->smk_flags |= SMK_INODE_IMPURE;
d166c8024   Casey Schaufler   Smack: Bring-up a...
179
180
  
  	smk_bu_mode(mode, acc);
bf4b2fee9   Casey Schaufler   Smack: Allow an u...
181
182
183
184
  
  	pr_info("Smack %s: (%s %s %s) inode=(%s %ld) %s
  ", smk_bu_mess[rc],
  		tsp->smk_task->smk_known, isp->smk_inode->smk_known, acc,
d166c8024   Casey Schaufler   Smack: Bring-up a...
185
186
187
188
189
190
191
192
193
194
195
196
  		inode->i_sb->s_id, inode->i_ino, current->comm);
  	return 0;
  }
  #else
  #define smk_bu_inode(inode, mode, RC) (RC)
  #endif
  
  #ifdef CONFIG_SECURITY_SMACK_BRINGUP
  static int smk_bu_file(struct file *file, int mode, int rc)
  {
  	struct task_smack *tsp = current_security();
  	struct smack_known *sskp = tsp->smk_task;
5e7270a6d   Casey Schaufler   Smack: Rework fil...
197
  	struct inode *inode = file_inode(file);
bf4b2fee9   Casey Schaufler   Smack: Allow an u...
198
  	struct inode_smack *isp = inode->i_security;
d166c8024   Casey Schaufler   Smack: Bring-up a...
199
  	char acc[SMK_NUM_ACCESS_TYPE + 1];
bf4b2fee9   Casey Schaufler   Smack: Allow an u...
200
201
202
203
  	if (isp->smk_flags & SMK_INODE_IMPURE)
  		pr_info("Smack Unconfined Corruption: inode=(%s %ld) %s
  ",
  			inode->i_sb->s_id, inode->i_ino, current->comm);
d166c8024   Casey Schaufler   Smack: Bring-up a...
204
205
  	if (rc <= 0)
  		return rc;
bf4b2fee9   Casey Schaufler   Smack: Allow an u...
206
207
  	if (rc > SMACK_UNCONFINED_OBJECT)
  		rc = 0;
d166c8024   Casey Schaufler   Smack: Bring-up a...
208
209
  
  	smk_bu_mode(mode, acc);
bf4b2fee9   Casey Schaufler   Smack: Allow an u...
210
211
  	pr_info("Smack %s: (%s %s %s) file=(%s %ld %pD) %s
  ", smk_bu_mess[rc],
5e7270a6d   Casey Schaufler   Smack: Rework fil...
212
  		sskp->smk_known, smk_of_inode(inode)->smk_known, acc,
a455589f1   Al Viro   assorted conversi...
213
  		inode->i_sb->s_id, inode->i_ino, file,
d166c8024   Casey Schaufler   Smack: Bring-up a...
214
215
216
217
218
219
220
221
222
223
224
225
226
  		current->comm);
  	return 0;
  }
  #else
  #define smk_bu_file(file, mode, RC) (RC)
  #endif
  
  #ifdef CONFIG_SECURITY_SMACK_BRINGUP
  static int smk_bu_credfile(const struct cred *cred, struct file *file,
  				int mode, int rc)
  {
  	struct task_smack *tsp = cred->security;
  	struct smack_known *sskp = tsp->smk_task;
450630975   Al Viro   don't open-code f...
227
  	struct inode *inode = file_inode(file);
bf4b2fee9   Casey Schaufler   Smack: Allow an u...
228
  	struct inode_smack *isp = inode->i_security;
d166c8024   Casey Schaufler   Smack: Bring-up a...
229
  	char acc[SMK_NUM_ACCESS_TYPE + 1];
bf4b2fee9   Casey Schaufler   Smack: Allow an u...
230
231
232
233
  	if (isp->smk_flags & SMK_INODE_IMPURE)
  		pr_info("Smack Unconfined Corruption: inode=(%s %ld) %s
  ",
  			inode->i_sb->s_id, inode->i_ino, current->comm);
d166c8024   Casey Schaufler   Smack: Bring-up a...
234
235
  	if (rc <= 0)
  		return rc;
bf4b2fee9   Casey Schaufler   Smack: Allow an u...
236
237
  	if (rc > SMACK_UNCONFINED_OBJECT)
  		rc = 0;
d166c8024   Casey Schaufler   Smack: Bring-up a...
238
239
  
  	smk_bu_mode(mode, acc);
bf4b2fee9   Casey Schaufler   Smack: Allow an u...
240
241
  	pr_info("Smack %s: (%s %s %s) file=(%s %ld %pD) %s
  ", smk_bu_mess[rc],
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
242
  		sskp->smk_known, smk_of_inode(inode)->smk_known, acc,
a455589f1   Al Viro   assorted conversi...
243
  		inode->i_sb->s_id, inode->i_ino, file,
d166c8024   Casey Schaufler   Smack: Bring-up a...
244
245
246
247
248
249
  		current->comm);
  	return 0;
  }
  #else
  #define smk_bu_credfile(cred, file, mode, RC) (RC)
  #endif
e114e4737   Casey Schaufler   Smack: Simplified...
250
251
  /**
   * smk_fetch - Fetch the smack label from a file.
1a28979b3   Lukasz Pawelczyk   smack: miscellane...
252
   * @name: type of the label (attribute)
e114e4737   Casey Schaufler   Smack: Simplified...
253
254
255
   * @ip: a pointer to the inode
   * @dp: a pointer to the dentry
   *
e774ad683   Lukasz Pawelczyk   smack: pass error...
256
257
   * Returns a pointer to the master list entry for the Smack label,
   * NULL if there was no label to fetch, or an error code.
e114e4737   Casey Schaufler   Smack: Simplified...
258
   */
2f823ff8b   Casey Schaufler   Smack: Improve ac...
259
260
  static struct smack_known *smk_fetch(const char *name, struct inode *ip,
  					struct dentry *dp)
e114e4737   Casey Schaufler   Smack: Simplified...
261
262
  {
  	int rc;
f7112e6c9   Casey Schaufler   Smack: allow for ...
263
  	char *buffer;
2f823ff8b   Casey Schaufler   Smack: Improve ac...
264
  	struct smack_known *skp = NULL;
e114e4737   Casey Schaufler   Smack: Simplified...
265

5d6c31910   Andreas Gruenbacher   xattr: Add __vfs_...
266
  	if (!(ip->i_opflags & IOP_XATTR))
e774ad683   Lukasz Pawelczyk   smack: pass error...
267
  		return ERR_PTR(-EOPNOTSUPP);
e114e4737   Casey Schaufler   Smack: Simplified...
268

f7112e6c9   Casey Schaufler   Smack: allow for ...
269
270
  	buffer = kzalloc(SMK_LONGLABEL, GFP_KERNEL);
  	if (buffer == NULL)
e774ad683   Lukasz Pawelczyk   smack: pass error...
271
  		return ERR_PTR(-ENOMEM);
e114e4737   Casey Schaufler   Smack: Simplified...
272

5d6c31910   Andreas Gruenbacher   xattr: Add __vfs_...
273
  	rc = __vfs_getxattr(dp, ip, name, buffer, SMK_LONGLABEL);
e774ad683   Lukasz Pawelczyk   smack: pass error...
274
275
276
277
278
  	if (rc < 0)
  		skp = ERR_PTR(rc);
  	else if (rc == 0)
  		skp = NULL;
  	else
2f823ff8b   Casey Schaufler   Smack: Improve ac...
279
  		skp = smk_import_entry(buffer, rc);
f7112e6c9   Casey Schaufler   Smack: allow for ...
280
281
  
  	kfree(buffer);
2f823ff8b   Casey Schaufler   Smack: Improve ac...
282
  	return skp;
e114e4737   Casey Schaufler   Smack: Simplified...
283
284
285
286
  }
  
  /**
   * new_inode_smack - allocate an inode security blob
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
287
   * @skp: a pointer to the Smack label entry to use in the blob
e114e4737   Casey Schaufler   Smack: Simplified...
288
289
290
   *
   * Returns the new blob or NULL if there's no memory available
   */
1eddfe8ed   Casey Schaufler   Smack: Three symb...
291
  static struct inode_smack *new_inode_smack(struct smack_known *skp)
e114e4737   Casey Schaufler   Smack: Simplified...
292
293
  {
  	struct inode_smack *isp;
1a5b472bd   Rohit   Security: smack: ...
294
  	isp = kmem_cache_zalloc(smack_inode_cache, GFP_NOFS);
e114e4737   Casey Schaufler   Smack: Simplified...
295
296
  	if (isp == NULL)
  		return NULL;
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
297
  	isp->smk_inode = skp;
e114e4737   Casey Schaufler   Smack: Simplified...
298
299
300
301
302
  	isp->smk_flags = 0;
  	mutex_init(&isp->smk_lock);
  
  	return isp;
  }
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
303
304
  /**
   * new_task_smack - allocate a task security blob
1a28979b3   Lukasz Pawelczyk   smack: miscellane...
305
306
307
   * @task: a pointer to the Smack label for the running task
   * @forked: a pointer to the Smack label for the forked task
   * @gfp: type of the memory for the allocation
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
308
309
310
   *
   * Returns the new blob or NULL if there's no memory available
   */
2f823ff8b   Casey Schaufler   Smack: Improve ac...
311
312
  static struct task_smack *new_task_smack(struct smack_known *task,
  					struct smack_known *forked, gfp_t gfp)
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
313
314
315
316
317
318
319
320
321
322
  {
  	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);
38416e539   Zbigniew Jasinski   Smack: limited ca...
323
  	INIT_LIST_HEAD(&tsp->smk_relabel);
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
324
325
326
327
328
329
330
  	mutex_init(&tsp->smk_rules_lock);
  
  	return tsp;
  }
  
  /**
   * smk_copy_rules - copy a rule set
1a28979b3   Lukasz Pawelczyk   smack: miscellane...
331
332
333
   * @nhead: new rules header pointer
   * @ohead: old rules header pointer
   * @gfp: type of the memory for the allocation
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
334
335
336
337
338
339
340
341
342
   *
   * 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;
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
343
344
345
346
347
348
349
350
351
352
353
  	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;
  }
5663884ca   Lukasz Pawelczyk   Smack: unify all ...
354
  /**
38416e539   Zbigniew Jasinski   Smack: limited ca...
355
356
357
358
359
360
361
362
363
364
365
366
   * smk_copy_relabel - copy smk_relabel labels list
   * @nhead: new rules header pointer
   * @ohead: old rules header pointer
   * @gfp: type of the memory for the allocation
   *
   * Returns 0 on success, -ENOMEM on error
   */
  static int smk_copy_relabel(struct list_head *nhead, struct list_head *ohead,
  				gfp_t gfp)
  {
  	struct smack_known_list_elem *nklep;
  	struct smack_known_list_elem *oklep;
38416e539   Zbigniew Jasinski   Smack: limited ca...
367
368
369
370
371
372
373
374
375
376
377
378
379
380
  	list_for_each_entry(oklep, ohead, list) {
  		nklep = kzalloc(sizeof(struct smack_known_list_elem), gfp);
  		if (nklep == NULL) {
  			smk_destroy_label_list(nhead);
  			return -ENOMEM;
  		}
  		nklep->smk_label = oklep->smk_label;
  		list_add(&nklep->list, nhead);
  	}
  
  	return 0;
  }
  
  /**
5663884ca   Lukasz Pawelczyk   Smack: unify all ...
381
382
383
384
385
386
387
   * smk_ptrace_mode - helper function for converting PTRACE_MODE_* into MAY_*
   * @mode - input mode in form of PTRACE_MODE_*
   *
   * Returns a converted MAY_* mode usable by smack rules
   */
  static inline unsigned int smk_ptrace_mode(unsigned int mode)
  {
3dfb7d8cd   Jann Horn   security: let sec...
388
  	if (mode & PTRACE_MODE_ATTACH)
5663884ca   Lukasz Pawelczyk   Smack: unify all ...
389
  		return MAY_READWRITE;
3dfb7d8cd   Jann Horn   security: let sec...
390
391
  	if (mode & PTRACE_MODE_READ)
  		return MAY_READ;
5663884ca   Lukasz Pawelczyk   Smack: unify all ...
392
393
394
395
396
397
398
  
  	return 0;
  }
  
  /**
   * smk_ptrace_rule_check - helper for ptrace access
   * @tracer: tracer process
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
399
   * @tracee_known: label entry of the process that's about to be traced
5663884ca   Lukasz Pawelczyk   Smack: unify all ...
400
401
402
403
404
   * @mode: ptrace attachment mode (PTRACE_MODE_*)
   * @func: name of the function that called us, used for audit
   *
   * Returns 0 on access granted, -error on error
   */
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
405
406
  static int smk_ptrace_rule_check(struct task_struct *tracer,
  				 struct smack_known *tracee_known,
5663884ca   Lukasz Pawelczyk   Smack: unify all ...
407
408
409
410
411
  				 unsigned int mode, const char *func)
  {
  	int rc;
  	struct smk_audit_info ad, *saip = NULL;
  	struct task_smack *tsp;
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
412
  	struct smack_known *tracer_known;
5663884ca   Lukasz Pawelczyk   Smack: unify all ...
413
414
415
416
417
418
  
  	if ((mode & PTRACE_MODE_NOAUDIT) == 0) {
  		smk_ad_init(&ad, func, LSM_AUDIT_DATA_TASK);
  		smk_ad_setfield_u_tsk(&ad, tracer);
  		saip = &ad;
  	}
6d1cff2a8   Andrey Ryabinin   smack: fix possib...
419
420
  	rcu_read_lock();
  	tsp = __task_cred(tracer)->security;
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
421
  	tracer_known = smk_of_task(tsp);
5663884ca   Lukasz Pawelczyk   Smack: unify all ...
422

668678185   Lukasz Pawelczyk   Smack: adds smack...
423
424
425
  	if ((mode & PTRACE_MODE_ATTACH) &&
  	    (smack_ptrace_rule == SMACK_PTRACE_EXACT ||
  	     smack_ptrace_rule == SMACK_PTRACE_DRACONIAN)) {
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
426
  		if (tracer_known->smk_known == tracee_known->smk_known)
668678185   Lukasz Pawelczyk   Smack: adds smack...
427
428
429
430
431
432
433
434
435
  			rc = 0;
  		else if (smack_ptrace_rule == SMACK_PTRACE_DRACONIAN)
  			rc = -EACCES;
  		else if (capable(CAP_SYS_PTRACE))
  			rc = 0;
  		else
  			rc = -EACCES;
  
  		if (saip)
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
436
437
438
  			smack_log(tracer_known->smk_known,
  				  tracee_known->smk_known,
  				  0, rc, saip);
668678185   Lukasz Pawelczyk   Smack: adds smack...
439

6d1cff2a8   Andrey Ryabinin   smack: fix possib...
440
  		rcu_read_unlock();
668678185   Lukasz Pawelczyk   Smack: adds smack...
441
442
443
444
  		return rc;
  	}
  
  	/* In case of rule==SMACK_PTRACE_DEFAULT or mode==PTRACE_MODE_READ */
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
445
  	rc = smk_tskacc(tsp, tracee_known, smk_ptrace_mode(mode), saip);
6d1cff2a8   Andrey Ryabinin   smack: fix possib...
446
447
  
  	rcu_read_unlock();
5663884ca   Lukasz Pawelczyk   Smack: unify all ...
448
449
  	return rc;
  }
e114e4737   Casey Schaufler   Smack: Simplified...
450
451
452
453
454
455
  /*
   * LSM hooks.
   * We he, that is fun!
   */
  
  /**
9e48858f7   Ingo Molnar   security: rename ...
456
   * smack_ptrace_access_check - Smack approval on PTRACE_ATTACH
e114e4737   Casey Schaufler   Smack: Simplified...
457
   * @ctp: child task pointer
5663884ca   Lukasz Pawelczyk   Smack: unify all ...
458
   * @mode: ptrace attachment mode (PTRACE_MODE_*)
e114e4737   Casey Schaufler   Smack: Simplified...
459
460
461
   *
   * Returns 0 if access is OK, an error code otherwise
   *
5663884ca   Lukasz Pawelczyk   Smack: unify all ...
462
   * Do the capability checks.
e114e4737   Casey Schaufler   Smack: Simplified...
463
   */
9e48858f7   Ingo Molnar   security: rename ...
464
  static int smack_ptrace_access_check(struct task_struct *ctp, unsigned int mode)
e114e4737   Casey Schaufler   Smack: Simplified...
465
  {
2f823ff8b   Casey Schaufler   Smack: Improve ac...
466
  	struct smack_known *skp;
e114e4737   Casey Schaufler   Smack: Simplified...
467

6d1cff2a8   Andrey Ryabinin   smack: fix possib...
468
  	skp = smk_of_task_struct(ctp);
ecfcc53fe   Etienne Basset   smack: implement ...
469

b1d9e6b06   Casey Schaufler   LSM: Switch to li...
470
  	return smk_ptrace_rule_check(current, skp, mode, __func__);
5cd9c58fb   David Howells   security: Fix set...
471
472
473
474
475
476
477
478
  }
  
  /**
   * smack_ptrace_traceme - Smack approval on PTRACE_TRACEME
   * @ptp: parent task pointer
   *
   * Returns 0 if access is OK, an error code otherwise
   *
5663884ca   Lukasz Pawelczyk   Smack: unify all ...
479
   * Do the capability checks, and require PTRACE_MODE_ATTACH.
5cd9c58fb   David Howells   security: Fix set...
480
481
482
483
   */
  static int smack_ptrace_traceme(struct task_struct *ptp)
  {
  	int rc;
2f823ff8b   Casey Schaufler   Smack: Improve ac...
484
  	struct smack_known *skp;
5cd9c58fb   David Howells   security: Fix set...
485

959e6c7f1   Lukasz Pawelczyk   Smack: fix the su...
486
  	skp = smk_of_task(current_security());
ecfcc53fe   Etienne Basset   smack: implement ...
487

21c7eae21   Lukasz Pawelczyk   Make Smack operat...
488
  	rc = smk_ptrace_rule_check(ptp, skp, PTRACE_MODE_ATTACH, __func__);
e114e4737   Casey Schaufler   Smack: Simplified...
489
490
491
492
493
494
495
  	return rc;
  }
  
  /**
   * smack_syslog - Smack approval on syslog
   * @type: message type
   *
e114e4737   Casey Schaufler   Smack: Simplified...
496
497
   * Returns 0 on success, error code otherwise.
   */
12b3052c3   Eric Paris   capabilities/sysl...
498
  static int smack_syslog(int typefrom_file)
e114e4737   Casey Schaufler   Smack: Simplified...
499
  {
12b3052c3   Eric Paris   capabilities/sysl...
500
  	int rc = 0;
2f823ff8b   Casey Schaufler   Smack: Improve ac...
501
  	struct smack_known *skp = smk_of_current();
e114e4737   Casey Schaufler   Smack: Simplified...
502

1880eff77   Casey Schaufler   Smack: onlycap li...
503
  	if (smack_privileged(CAP_MAC_OVERRIDE))
e114e4737   Casey Schaufler   Smack: Simplified...
504
  		return 0;
24ea1b6ef   Casey Schaufler   Smack: Rationaliz...
505
  	if (smack_syslog_label != NULL && smack_syslog_label != skp)
e114e4737   Casey Schaufler   Smack: Simplified...
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
  		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;
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
530
531
532
533
  	sbsp->smk_root = &smack_known_floor;
  	sbsp->smk_default = &smack_known_floor;
  	sbsp->smk_floor = &smack_known_floor;
  	sbsp->smk_hat = &smack_known_hat;
e830b3941   Casey Schaufler   Smack: Add smkfst...
534
  	/*
9f50eda2a   Seth Forshee   Smack: Add suppor...
535
  	 * SMK_SB_INITIALIZED will be zero from kzalloc.
e830b3941   Casey Schaufler   Smack: Add smkfst...
536
  	 */
e114e4737   Casey Schaufler   Smack: Simplified...
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
  	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...
555
   * @orig: where to start
251a2a958   Randy Dunlap   smack: fix lots o...
556
   * @smackopts: mount options string
e114e4737   Casey Schaufler   Smack: Simplified...
557
558
559
560
561
562
   *
   * 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...
563
  static int smack_sb_copy_data(char *orig, char *smackopts)
e114e4737   Casey Schaufler   Smack: Simplified...
564
565
  {
  	char *cp, *commap, *otheropts, *dp;
e114e4737   Casey Schaufler   Smack: Simplified...
566
567
568
569
570
571
572
573
574
575
576
577
578
  	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;
e830b3941   Casey Schaufler   Smack: Add smkfst...
579
580
  		else if (strstr(cp, SMK_FSTRANS) == cp)
  			dp = smackopts;
e114e4737   Casey Schaufler   Smack: Simplified...
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
  		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;
  }
  
  /**
3bf2789ca   Vivek Trivedi   smack: allow moun...
600
601
602
603
604
605
606
607
608
609
610
611
   * smack_parse_opts_str - parse Smack specific mount options
   * @options: mount options string
   * @opts: where to store converted mount opts
   *
   * Returns 0 on success or -ENOMEM on error.
   *
   * converts Smack specific mount options to generic security option format
   */
  static int smack_parse_opts_str(char *options,
  		struct security_mnt_opts *opts)
  {
  	char *p;
3d04c9240   Casey Schaufler   Smack - Fix build...
612
613
614
615
616
617
618
619
  	char *fsdefault = NULL;
  	char *fsfloor = NULL;
  	char *fshat = NULL;
  	char *fsroot = NULL;
  	char *fstransmute = NULL;
  	int rc = -ENOMEM;
  	int num_mnt_opts = 0;
  	int token;
3bf2789ca   Vivek Trivedi   smack: allow moun...
620
621
622
623
624
625
626
  
  	opts->num_mnt_opts = 0;
  
  	if (!options)
  		return 0;
  
  	while ((p = strsep(&options, ",")) != NULL) {
3bf2789ca   Vivek Trivedi   smack: allow moun...
627
628
629
630
  		substring_t args[MAX_OPT_ARGS];
  
  		if (!*p)
  			continue;
3d04c9240   Casey Schaufler   Smack - Fix build...
631
  		token = match_token(p, smk_mount_tokens, args);
3bf2789ca   Vivek Trivedi   smack: allow moun...
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
  
  		switch (token) {
  		case Opt_fsdefault:
  			if (fsdefault)
  				goto out_opt_err;
  			fsdefault = match_strdup(&args[0]);
  			if (!fsdefault)
  				goto out_err;
  			break;
  		case Opt_fsfloor:
  			if (fsfloor)
  				goto out_opt_err;
  			fsfloor = match_strdup(&args[0]);
  			if (!fsfloor)
  				goto out_err;
  			break;
  		case Opt_fshat:
  			if (fshat)
  				goto out_opt_err;
  			fshat = match_strdup(&args[0]);
  			if (!fshat)
  				goto out_err;
  			break;
  		case Opt_fsroot:
  			if (fsroot)
  				goto out_opt_err;
  			fsroot = match_strdup(&args[0]);
  			if (!fsroot)
  				goto out_err;
  			break;
  		case Opt_fstransmute:
  			if (fstransmute)
  				goto out_opt_err;
  			fstransmute = match_strdup(&args[0]);
  			if (!fstransmute)
  				goto out_err;
  			break;
  		default:
  			rc = -EINVAL;
  			pr_warn("Smack:  unknown mount option
  ");
  			goto out_err;
  		}
  	}
8c15d66e4   Tetsuo Handa   Smack: Use GFP_KE...
676
  	opts->mnt_opts = kcalloc(NUM_SMK_MNT_OPTS, sizeof(char *), GFP_KERNEL);
3bf2789ca   Vivek Trivedi   smack: allow moun...
677
678
679
680
  	if (!opts->mnt_opts)
  		goto out_err;
  
  	opts->mnt_opts_flags = kcalloc(NUM_SMK_MNT_OPTS, sizeof(int),
8c15d66e4   Tetsuo Handa   Smack: Use GFP_KE...
681
  			GFP_KERNEL);
c3c8dc9f1   Tetsuo Handa   smack: fix double...
682
  	if (!opts->mnt_opts_flags)
3bf2789ca   Vivek Trivedi   smack: allow moun...
683
  		goto out_err;
3bf2789ca   Vivek Trivedi   smack: allow moun...
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
  
  	if (fsdefault) {
  		opts->mnt_opts[num_mnt_opts] = fsdefault;
  		opts->mnt_opts_flags[num_mnt_opts++] = FSDEFAULT_MNT;
  	}
  	if (fsfloor) {
  		opts->mnt_opts[num_mnt_opts] = fsfloor;
  		opts->mnt_opts_flags[num_mnt_opts++] = FSFLOOR_MNT;
  	}
  	if (fshat) {
  		opts->mnt_opts[num_mnt_opts] = fshat;
  		opts->mnt_opts_flags[num_mnt_opts++] = FSHAT_MNT;
  	}
  	if (fsroot) {
  		opts->mnt_opts[num_mnt_opts] = fsroot;
  		opts->mnt_opts_flags[num_mnt_opts++] = FSROOT_MNT;
  	}
  	if (fstransmute) {
  		opts->mnt_opts[num_mnt_opts] = fstransmute;
  		opts->mnt_opts_flags[num_mnt_opts++] = FSTRANS_MNT;
  	}
  
  	opts->num_mnt_opts = num_mnt_opts;
  	return 0;
  
  out_opt_err:
  	rc = -EINVAL;
  	pr_warn("Smack: duplicate mount options
  ");
  
  out_err:
  	kfree(fsdefault);
  	kfree(fsfloor);
  	kfree(fshat);
  	kfree(fsroot);
  	kfree(fstransmute);
  	return rc;
  }
  
  /**
   * smack_set_mnt_opts - set Smack specific mount options
e114e4737   Casey Schaufler   Smack: Simplified...
725
   * @sb: the file system superblock
3bf2789ca   Vivek Trivedi   smack: allow moun...
726
727
728
   * @opts: Smack mount options
   * @kern_flags: mount option from kernel space or user space
   * @set_kern_flags: where to store converted mount opts
e114e4737   Casey Schaufler   Smack: Simplified...
729
730
   *
   * Returns 0 on success, an error code on failure
3bf2789ca   Vivek Trivedi   smack: allow moun...
731
732
733
   *
   * Allow filesystems with binary mount data to explicitly set Smack mount
   * labels.
e114e4737   Casey Schaufler   Smack: Simplified...
734
   */
3bf2789ca   Vivek Trivedi   smack: allow moun...
735
736
737
738
  static int smack_set_mnt_opts(struct super_block *sb,
  		struct security_mnt_opts *opts,
  		unsigned long kern_flags,
  		unsigned long *set_kern_flags)
e114e4737   Casey Schaufler   Smack: Simplified...
739
740
  {
  	struct dentry *root = sb->s_root;
c6f493d63   David Howells   VFS: security/: d...
741
  	struct inode *inode = d_backing_inode(root);
e114e4737   Casey Schaufler   Smack: Simplified...
742
743
  	struct superblock_smack *sp = sb->s_security;
  	struct inode_smack *isp;
24ea1b6ef   Casey Schaufler   Smack: Rationaliz...
744
  	struct smack_known *skp;
3bf2789ca   Vivek Trivedi   smack: allow moun...
745
746
  	int i;
  	int num_opts = opts->num_mnt_opts;
e830b3941   Casey Schaufler   Smack: Add smkfst...
747
  	int transmute = 0;
e114e4737   Casey Schaufler   Smack: Simplified...
748

9f50eda2a   Seth Forshee   Smack: Add suppor...
749
  	if (sp->smk_flags & SMK_SB_INITIALIZED)
e114e4737   Casey Schaufler   Smack: Simplified...
750
  		return 0;
eb982cb4c   Casey Schaufler   Smack: fix smack_...
751

2097f5992   Himanshu Shukla   smack: parse mnt ...
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
  	if (!smack_privileged(CAP_MAC_ADMIN)) {
  		/*
  		 * Unprivileged mounts don't get to specify Smack values.
  		 */
  		if (num_opts)
  			return -EPERM;
  		/*
  		 * Unprivileged mounts get root and default from the caller.
  		 */
  		skp = smk_of_current();
  		sp->smk_root = skp;
  		sp->smk_default = skp;
  		/*
  		 * For a handful of fs types with no user-controlled
  		 * backing store it's okay to trust security labels
  		 * in the filesystem. The rest are untrusted.
  		 */
  		if (sb->s_user_ns != &init_user_ns &&
  		    sb->s_magic != SYSFS_MAGIC && sb->s_magic != TMPFS_MAGIC &&
  		    sb->s_magic != RAMFS_MAGIC) {
  			transmute = 1;
  			sp->smk_flags |= SMK_SB_UNTRUSTED;
  		}
  	}
9f50eda2a   Seth Forshee   Smack: Add suppor...
776
  	sp->smk_flags |= SMK_SB_INITIALIZED;
e114e4737   Casey Schaufler   Smack: Simplified...
777

3bf2789ca   Vivek Trivedi   smack: allow moun...
778
779
780
781
  	for (i = 0; i < num_opts; i++) {
  		switch (opts->mnt_opts_flags[i]) {
  		case FSDEFAULT_MNT:
  			skp = smk_import_entry(opts->mnt_opts[i], 0);
e774ad683   Lukasz Pawelczyk   smack: pass error...
782
783
  			if (IS_ERR(skp))
  				return PTR_ERR(skp);
3bf2789ca   Vivek Trivedi   smack: allow moun...
784
785
786
787
  			sp->smk_default = skp;
  			break;
  		case FSFLOOR_MNT:
  			skp = smk_import_entry(opts->mnt_opts[i], 0);
e774ad683   Lukasz Pawelczyk   smack: pass error...
788
789
790
  			if (IS_ERR(skp))
  				return PTR_ERR(skp);
  			sp->smk_floor = skp;
3bf2789ca   Vivek Trivedi   smack: allow moun...
791
792
793
  			break;
  		case FSHAT_MNT:
  			skp = smk_import_entry(opts->mnt_opts[i], 0);
e774ad683   Lukasz Pawelczyk   smack: pass error...
794
795
  			if (IS_ERR(skp))
  				return PTR_ERR(skp);
3bf2789ca   Vivek Trivedi   smack: allow moun...
796
797
798
799
  			sp->smk_hat = skp;
  			break;
  		case FSROOT_MNT:
  			skp = smk_import_entry(opts->mnt_opts[i], 0);
e774ad683   Lukasz Pawelczyk   smack: pass error...
800
801
802
  			if (IS_ERR(skp))
  				return PTR_ERR(skp);
  			sp->smk_root = skp;
3bf2789ca   Vivek Trivedi   smack: allow moun...
803
804
805
  			break;
  		case FSTRANS_MNT:
  			skp = smk_import_entry(opts->mnt_opts[i], 0);
e774ad683   Lukasz Pawelczyk   smack: pass error...
806
807
808
809
  			if (IS_ERR(skp))
  				return PTR_ERR(skp);
  			sp->smk_root = skp;
  			transmute = 1;
3bf2789ca   Vivek Trivedi   smack: allow moun...
810
811
812
  			break;
  		default:
  			break;
e114e4737   Casey Schaufler   Smack: Simplified...
813
814
815
816
817
818
819
  		}
  	}
  
  	/*
  	 * Initialize the root inode.
  	 */
  	isp = inode->i_security;
55dfc5da1   José Bollo   Minor improvement...
820
821
822
823
824
  	if (isp == NULL) {
  		isp = new_inode_smack(sp->smk_root);
  		if (isp == NULL)
  			return -ENOMEM;
  		inode->i_security = isp;
e830b3941   Casey Schaufler   Smack: Add smkfst...
825
  	} else
e114e4737   Casey Schaufler   Smack: Simplified...
826
  		isp->smk_inode = sp->smk_root;
e830b3941   Casey Schaufler   Smack: Add smkfst...
827
828
  	if (transmute)
  		isp->smk_flags |= SMK_INODE_TRANSMUTE;
e114e4737   Casey Schaufler   Smack: Simplified...
829
830
831
832
  	return 0;
  }
  
  /**
3bf2789ca   Vivek Trivedi   smack: allow moun...
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
   * smack_sb_kern_mount - Smack specific mount processing
   * @sb: the file system superblock
   * @flags: the mount flags
   * @data: the smack mount options
   *
   * Returns 0 on success, an error code on failure
   */
  static int smack_sb_kern_mount(struct super_block *sb, int flags, void *data)
  {
  	int rc = 0;
  	char *options = data;
  	struct security_mnt_opts opts;
  
  	security_init_mnt_opts(&opts);
  
  	if (!options)
  		goto out;
  
  	rc = smack_parse_opts_str(options, &opts);
  	if (rc)
  		goto out_err;
  
  out:
  	rc = smack_set_mnt_opts(sb, &opts, 0, NULL);
  
  out_err:
  	security_free_mnt_opts(&opts);
  	return rc;
  }
  
  /**
e114e4737   Casey Schaufler   Smack: Simplified...
864
865
866
867
868
869
870
871
872
   * 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 ...
873
874
  	int rc;
  	struct smk_audit_info ad;
a269434d2   Eric Paris   LSM: separate LSM...
875
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
ecfcc53fe   Etienne Basset   smack: implement ...
876
  	smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
e114e4737   Casey Schaufler   Smack: Simplified...
877

ecfcc53fe   Etienne Basset   smack: implement ...
878
  	rc = smk_curacc(sbp->smk_floor, MAY_READ, &ad);
d166c8024   Casey Schaufler   Smack: Bring-up a...
879
  	rc = smk_bu_current("statfs", sbp->smk_floor, MAY_READ, rc);
ecfcc53fe   Etienne Basset   smack: implement ...
880
  	return rc;
e114e4737   Casey Schaufler   Smack: Simplified...
881
  }
e114e4737   Casey Schaufler   Smack: Simplified...
882
  /*
676dac4b1   Casey Schaufler   This patch adds a...
883
884
   * BPRM hooks
   */
ce8a43219   Casey Schaufler   Smack: Clean up c...
885
886
887
888
  /**
   * smack_bprm_set_creds - set creds for exec
   * @bprm: the exec information
   *
5663884ca   Lukasz Pawelczyk   Smack: unify all ...
889
   * Returns 0 if it gets a blob, -EPERM if exec forbidden and -ENOMEM otherwise
ce8a43219   Casey Schaufler   Smack: Clean up c...
890
   */
676dac4b1   Casey Schaufler   This patch adds a...
891
892
  static int smack_bprm_set_creds(struct linux_binprm *bprm)
  {
496ad9aa8   Al Viro   new helper: file_...
893
  	struct inode *inode = file_inode(bprm->file);
84088ba23   Jarkko Sakkinen   Smack: domain tra...
894
  	struct task_smack *bsp = bprm->cred->security;
676dac4b1   Casey Schaufler   This patch adds a...
895
  	struct inode_smack *isp;
809c02e09   Seth Forshee   Smack: Handle lab...
896
  	struct superblock_smack *sbsp;
676dac4b1   Casey Schaufler   This patch adds a...
897
  	int rc;
ddb4a1442   Kees Cook   exec: Rename bprm...
898
  	if (bprm->called_set_creds)
676dac4b1   Casey Schaufler   This patch adds a...
899
  		return 0;
84088ba23   Jarkko Sakkinen   Smack: domain tra...
900
901
  	isp = inode->i_security;
  	if (isp->smk_task == NULL || isp->smk_task == bsp->smk_task)
676dac4b1   Casey Schaufler   This patch adds a...
902
  		return 0;
809c02e09   Seth Forshee   Smack: Handle lab...
903
904
905
906
  	sbsp = inode->i_sb->s_security;
  	if ((sbsp->smk_flags & SMK_SB_UNTRUSTED) &&
  	    isp->smk_task != sbsp->smk_root)
  		return 0;
9227dd2a8   Eric W. Biederman   exec: Remove LSM_...
907
  	if (bprm->unsafe & LSM_UNSAFE_PTRACE) {
5663884ca   Lukasz Pawelczyk   Smack: unify all ...
908
909
910
911
912
913
914
  		struct task_struct *tracer;
  		rc = 0;
  
  		rcu_read_lock();
  		tracer = ptrace_parent(current);
  		if (likely(tracer != NULL))
  			rc = smk_ptrace_rule_check(tracer,
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
915
  						   isp->smk_task,
5663884ca   Lukasz Pawelczyk   Smack: unify all ...
916
917
918
919
920
921
922
  						   PTRACE_MODE_ATTACH,
  						   __func__);
  		rcu_read_unlock();
  
  		if (rc != 0)
  			return rc;
  	} else if (bprm->unsafe)
84088ba23   Jarkko Sakkinen   Smack: domain tra...
923
  		return -EPERM;
676dac4b1   Casey Schaufler   This patch adds a...
924

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

ccbb6e106   Kees Cook   smack: Refactor t...
928
929
930
  	/* Decide if this is a secure exec. */
  	if (bsp->smk_task != bsp->smk_forked)
  		bprm->secureexec = 1;
84088ba23   Jarkko Sakkinen   Smack: domain tra...
931
932
  	return 0;
  }
676dac4b1   Casey Schaufler   This patch adds a...
933

676dac4b1   Casey Schaufler   This patch adds a...
934
  /*
e114e4737   Casey Schaufler   Smack: Simplified...
935
936
937
938
939
   * Inode hooks
   */
  
  /**
   * smack_inode_alloc_security - allocate an inode blob
251a2a958   Randy Dunlap   smack: fix lots o...
940
   * @inode: the inode in need of a blob
e114e4737   Casey Schaufler   Smack: Simplified...
941
942
943
944
945
   *
   * Returns 0 if it gets a blob, -ENOMEM otherwise
   */
  static int smack_inode_alloc_security(struct inode *inode)
  {
2f823ff8b   Casey Schaufler   Smack: Improve ac...
946
  	struct smack_known *skp = smk_of_current();
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
947
  	inode->i_security = new_inode_smack(skp);
e114e4737   Casey Schaufler   Smack: Simplified...
948
949
950
951
952
953
  	if (inode->i_security == NULL)
  		return -ENOMEM;
  	return 0;
  }
  
  /**
3d4f673a6   Himanshu Shukla   SMACK: Free the i...
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
   * smack_inode_free_rcu - Free inode_smack blob from cache
   * @head: the rcu_head for getting inode_smack pointer
   *
   *  Call back function called from call_rcu() to free
   *  the i_security blob pointer in inode
   */
  static void smack_inode_free_rcu(struct rcu_head *head)
  {
  	struct inode_smack *issp;
  
  	issp = container_of(head, struct inode_smack, smk_rcu);
  	kmem_cache_free(smack_inode_cache, issp);
  }
  
  /**
   * smack_inode_free_security - free an inode blob using call_rcu()
251a2a958   Randy Dunlap   smack: fix lots o...
970
   * @inode: the inode with a blob
e114e4737   Casey Schaufler   Smack: Simplified...
971
   *
3d4f673a6   Himanshu Shukla   SMACK: Free the i...
972
   * Clears the blob pointer in inode using RCU
e114e4737   Casey Schaufler   Smack: Simplified...
973
974
975
   */
  static void smack_inode_free_security(struct inode *inode)
  {
3d4f673a6   Himanshu Shukla   SMACK: Free the i...
976
977
978
979
980
981
982
983
984
985
986
  	struct inode_smack *issp = inode->i_security;
  
  	/*
  	 * The inode may still be referenced in a path walk and
  	 * a call to smack_inode_permission() can be made
  	 * after smack_inode_free_security() is called.
  	 * To avoid race condition free the i_security via RCU
  	 * and leave the current inode->i_security pointer intact.
  	 * The inode will be freed after the RCU grace period too.
  	 */
  	call_rcu(&issp->smk_rcu, smack_inode_free_rcu);
e114e4737   Casey Schaufler   Smack: Simplified...
987
988
989
990
  }
  
  /**
   * smack_inode_init_security - copy out the smack from an inode
e95ef49b7   Lukasz Pawelczyk   Small fixes in co...
991
992
   * @inode: the newly created inode
   * @dir: containing directory object
2a7dba391   Eric Paris   fs/vfs/security: ...
993
   * @qstr: unused
e114e4737   Casey Schaufler   Smack: Simplified...
994
995
996
997
998
999
1000
   * @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,
9548906b2   Tetsuo Handa   xattr: Constify -...
1001
  				     const struct qstr *qstr, const char **name,
2a7dba391   Eric Paris   fs/vfs/security: ...
1002
  				     void **value, size_t *len)
e114e4737   Casey Schaufler   Smack: Simplified...
1003
  {
2267b13a7   Casey Schaufler   Smack: recursive ...
1004
  	struct inode_smack *issp = inode->i_security;
2f823ff8b   Casey Schaufler   Smack: Improve ac...
1005
  	struct smack_known *skp = smk_of_current();
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
1006
1007
  	struct smack_known *isp = smk_of_inode(inode);
  	struct smack_known *dsp = smk_of_inode(dir);
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1008
  	int may;
e114e4737   Casey Schaufler   Smack: Simplified...
1009

9548906b2   Tetsuo Handa   xattr: Constify -...
1010
1011
  	if (name)
  		*name = XATTR_SMACK_SUFFIX;
e114e4737   Casey Schaufler   Smack: Simplified...
1012

68390ccf8   Lukasz Pawelczyk   smack: fix logic ...
1013
  	if (value && len) {
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1014
  		rcu_read_lock();
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
1015
1016
  		may = smk_access_entry(skp->smk_known, dsp->smk_known,
  				       &skp->smk_rules);
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1017
  		rcu_read_unlock();
5c6d1125f   Jarkko Sakkinen   Smack: Transmute ...
1018
1019
1020
1021
1022
  
  		/*
  		 * If the access rule allows transmutation and
  		 * the directory requests transmutation then
  		 * by all means transmute.
2267b13a7   Casey Schaufler   Smack: recursive ...
1023
  		 * Mark the inode as changed.
5c6d1125f   Jarkko Sakkinen   Smack: Transmute ...
1024
  		 */
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1025
  		if (may > 0 && ((may & MAY_TRANSMUTE) != 0) &&
2267b13a7   Casey Schaufler   Smack: recursive ...
1026
  		    smk_inode_transmutable(dir)) {
5c6d1125f   Jarkko Sakkinen   Smack: Transmute ...
1027
  			isp = dsp;
2267b13a7   Casey Schaufler   Smack: recursive ...
1028
1029
  			issp->smk_flags |= SMK_INODE_CHANGED;
  		}
5c6d1125f   Jarkko Sakkinen   Smack: Transmute ...
1030

21c7eae21   Lukasz Pawelczyk   Make Smack operat...
1031
  		*value = kstrdup(isp->smk_known, GFP_NOFS);
e114e4737   Casey Schaufler   Smack: Simplified...
1032
1033
  		if (*value == NULL)
  			return -ENOMEM;
e114e4737   Casey Schaufler   Smack: Simplified...
1034

21c7eae21   Lukasz Pawelczyk   Make Smack operat...
1035
  		*len = strlen(isp->smk_known);
68390ccf8   Lukasz Pawelczyk   smack: fix logic ...
1036
  	}
e114e4737   Casey Schaufler   Smack: Simplified...
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
  
  	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)
  {
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
1052
  	struct smack_known *isp;
ecfcc53fe   Etienne Basset   smack: implement ...
1053
1054
  	struct smk_audit_info ad;
  	int rc;
a269434d2   Eric Paris   LSM: separate LSM...
1055
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
ecfcc53fe   Etienne Basset   smack: implement ...
1056
  	smk_ad_setfield_u_fs_path_dentry(&ad, old_dentry);
e114e4737   Casey Schaufler   Smack: Simplified...
1057

c6f493d63   David Howells   VFS: security/: d...
1058
  	isp = smk_of_inode(d_backing_inode(old_dentry));
ecfcc53fe   Etienne Basset   smack: implement ...
1059
  	rc = smk_curacc(isp, MAY_WRITE, &ad);
c6f493d63   David Howells   VFS: security/: d...
1060
  	rc = smk_bu_inode(d_backing_inode(old_dentry), MAY_WRITE, rc);
e114e4737   Casey Schaufler   Smack: Simplified...
1061

8802565b6   David Howells   Smack: Use d_is_p...
1062
  	if (rc == 0 && d_is_positive(new_dentry)) {
c6f493d63   David Howells   VFS: security/: d...
1063
  		isp = smk_of_inode(d_backing_inode(new_dentry));
ecfcc53fe   Etienne Basset   smack: implement ...
1064
1065
  		smk_ad_setfield_u_fs_path_dentry(&ad, new_dentry);
  		rc = smk_curacc(isp, MAY_WRITE, &ad);
c6f493d63   David Howells   VFS: security/: d...
1066
  		rc = smk_bu_inode(d_backing_inode(new_dentry), MAY_WRITE, rc);
e114e4737   Casey Schaufler   Smack: Simplified...
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
  	}
  
  	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)
  {
c6f493d63   David Howells   VFS: security/: d...
1082
  	struct inode *ip = d_backing_inode(dentry);
ecfcc53fe   Etienne Basset   smack: implement ...
1083
  	struct smk_audit_info ad;
e114e4737   Casey Schaufler   Smack: Simplified...
1084
  	int rc;
a269434d2   Eric Paris   LSM: separate LSM...
1085
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
ecfcc53fe   Etienne Basset   smack: implement ...
1086
  	smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
e114e4737   Casey Schaufler   Smack: Simplified...
1087
1088
1089
  	/*
  	 * You need write access to the thing you're unlinking
  	 */
ecfcc53fe   Etienne Basset   smack: implement ...
1090
  	rc = smk_curacc(smk_of_inode(ip), MAY_WRITE, &ad);
d166c8024   Casey Schaufler   Smack: Bring-up a...
1091
  	rc = smk_bu_inode(ip, MAY_WRITE, rc);
ecfcc53fe   Etienne Basset   smack: implement ...
1092
  	if (rc == 0) {
e114e4737   Casey Schaufler   Smack: Simplified...
1093
1094
1095
  		/*
  		 * You also need write access to the containing directory
  		 */
cdb56b608   Igor Zhbanov   Fix NULL pointer ...
1096
  		smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_INODE);
ecfcc53fe   Etienne Basset   smack: implement ...
1097
1098
  		smk_ad_setfield_u_fs_inode(&ad, dir);
  		rc = smk_curacc(smk_of_inode(dir), MAY_WRITE, &ad);
d166c8024   Casey Schaufler   Smack: Bring-up a...
1099
  		rc = smk_bu_inode(dir, MAY_WRITE, rc);
ecfcc53fe   Etienne Basset   smack: implement ...
1100
  	}
e114e4737   Casey Schaufler   Smack: Simplified...
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
  	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 ...
1114
  	struct smk_audit_info ad;
e114e4737   Casey Schaufler   Smack: Simplified...
1115
  	int rc;
a269434d2   Eric Paris   LSM: separate LSM...
1116
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
ecfcc53fe   Etienne Basset   smack: implement ...
1117
  	smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
e114e4737   Casey Schaufler   Smack: Simplified...
1118
1119
1120
  	/*
  	 * You need write access to the thing you're removing
  	 */
c6f493d63   David Howells   VFS: security/: d...
1121
1122
  	rc = smk_curacc(smk_of_inode(d_backing_inode(dentry)), MAY_WRITE, &ad);
  	rc = smk_bu_inode(d_backing_inode(dentry), MAY_WRITE, rc);
ecfcc53fe   Etienne Basset   smack: implement ...
1123
  	if (rc == 0) {
e114e4737   Casey Schaufler   Smack: Simplified...
1124
1125
1126
  		/*
  		 * You also need write access to the containing directory
  		 */
cdb56b608   Igor Zhbanov   Fix NULL pointer ...
1127
  		smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_INODE);
ecfcc53fe   Etienne Basset   smack: implement ...
1128
1129
  		smk_ad_setfield_u_fs_inode(&ad, dir);
  		rc = smk_curacc(smk_of_inode(dir), MAY_WRITE, &ad);
d166c8024   Casey Schaufler   Smack: Bring-up a...
1130
  		rc = smk_bu_inode(dir, MAY_WRITE, rc);
ecfcc53fe   Etienne Basset   smack: implement ...
1131
  	}
e114e4737   Casey Schaufler   Smack: Simplified...
1132
1133
1134
1135
1136
1137
  
  	return rc;
  }
  
  /**
   * smack_inode_rename - Smack check on rename
e95ef49b7   Lukasz Pawelczyk   Small fixes in co...
1138
1139
1140
1141
   * @old_inode: unused
   * @old_dentry: the old object
   * @new_inode: unused
   * @new_dentry: the new object
e114e4737   Casey Schaufler   Smack: Simplified...
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
   *
   * 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;
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
1154
  	struct smack_known *isp;
ecfcc53fe   Etienne Basset   smack: implement ...
1155
  	struct smk_audit_info ad;
a269434d2   Eric Paris   LSM: separate LSM...
1156
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
ecfcc53fe   Etienne Basset   smack: implement ...
1157
  	smk_ad_setfield_u_fs_path_dentry(&ad, old_dentry);
e114e4737   Casey Schaufler   Smack: Simplified...
1158

c6f493d63   David Howells   VFS: security/: d...
1159
  	isp = smk_of_inode(d_backing_inode(old_dentry));
ecfcc53fe   Etienne Basset   smack: implement ...
1160
  	rc = smk_curacc(isp, MAY_READWRITE, &ad);
c6f493d63   David Howells   VFS: security/: d...
1161
  	rc = smk_bu_inode(d_backing_inode(old_dentry), MAY_READWRITE, rc);
e114e4737   Casey Schaufler   Smack: Simplified...
1162

8802565b6   David Howells   Smack: Use d_is_p...
1163
  	if (rc == 0 && d_is_positive(new_dentry)) {
c6f493d63   David Howells   VFS: security/: d...
1164
  		isp = smk_of_inode(d_backing_inode(new_dentry));
ecfcc53fe   Etienne Basset   smack: implement ...
1165
1166
  		smk_ad_setfield_u_fs_path_dentry(&ad, new_dentry);
  		rc = smk_curacc(isp, MAY_READWRITE, &ad);
c6f493d63   David Howells   VFS: security/: d...
1167
  		rc = smk_bu_inode(d_backing_inode(new_dentry), MAY_READWRITE, rc);
e114e4737   Casey Schaufler   Smack: Simplified...
1168
  	}
e114e4737   Casey Schaufler   Smack: Simplified...
1169
1170
1171
1172
1173
1174
1175
  	return rc;
  }
  
  /**
   * smack_inode_permission - Smack version of permission()
   * @inode: the inode in question
   * @mask: the access requested
e114e4737   Casey Schaufler   Smack: Simplified...
1176
1177
1178
1179
1180
   *
   * This is the important Smack hook.
   *
   * Returns 0 if access is permitted, -EACCES otherwise
   */
e74f71eb7   Al Viro   ->permission() sa...
1181
  static int smack_inode_permission(struct inode *inode, int mask)
e114e4737   Casey Schaufler   Smack: Simplified...
1182
  {
9f50eda2a   Seth Forshee   Smack: Add suppor...
1183
  	struct superblock_smack *sbsp = inode->i_sb->s_security;
ecfcc53fe   Etienne Basset   smack: implement ...
1184
  	struct smk_audit_info ad;
e74f71eb7   Al Viro   ->permission() sa...
1185
  	int no_block = mask & MAY_NOT_BLOCK;
d166c8024   Casey Schaufler   Smack: Bring-up a...
1186
  	int rc;
d09ca7397   Eric Paris   security: make LS...
1187
1188
  
  	mask &= (MAY_READ|MAY_WRITE|MAY_EXEC|MAY_APPEND);
e114e4737   Casey Schaufler   Smack: Simplified...
1189
1190
1191
1192
1193
  	/*
  	 * No permission to check. Existence test. Yup, it's there.
  	 */
  	if (mask == 0)
  		return 0;
8c9e80ed2   Andi Kleen   SECURITY: Move ex...
1194

9f50eda2a   Seth Forshee   Smack: Add suppor...
1195
1196
1197
1198
  	if (sbsp->smk_flags & SMK_SB_UNTRUSTED) {
  		if (smk_of_inode(inode) != sbsp->smk_root)
  			return -EACCES;
  	}
8c9e80ed2   Andi Kleen   SECURITY: Move ex...
1199
  	/* May be droppable after audit */
e74f71eb7   Al Viro   ->permission() sa...
1200
  	if (no_block)
8c9e80ed2   Andi Kleen   SECURITY: Move ex...
1201
  		return -ECHILD;
f48b73998   Eric Paris   LSM: split LSM_AU...
1202
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_INODE);
ecfcc53fe   Etienne Basset   smack: implement ...
1203
  	smk_ad_setfield_u_fs_inode(&ad, inode);
d166c8024   Casey Schaufler   Smack: Bring-up a...
1204
1205
1206
  	rc = smk_curacc(smk_of_inode(inode), mask, &ad);
  	rc = smk_bu_inode(inode, mask, rc);
  	return rc;
e114e4737   Casey Schaufler   Smack: Simplified...
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
  }
  
  /**
   * 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 ...
1218
  	struct smk_audit_info ad;
d166c8024   Casey Schaufler   Smack: Bring-up a...
1219
  	int rc;
e114e4737   Casey Schaufler   Smack: Simplified...
1220
1221
1222
1223
1224
  	/*
  	 * Need to allow for clearing the setuid bit.
  	 */
  	if (iattr->ia_valid & ATTR_FORCE)
  		return 0;
a269434d2   Eric Paris   LSM: separate LSM...
1225
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
ecfcc53fe   Etienne Basset   smack: implement ...
1226
  	smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
e114e4737   Casey Schaufler   Smack: Simplified...
1227

c6f493d63   David Howells   VFS: security/: d...
1228
1229
  	rc = smk_curacc(smk_of_inode(d_backing_inode(dentry)), MAY_WRITE, &ad);
  	rc = smk_bu_inode(d_backing_inode(dentry), MAY_WRITE, rc);
d166c8024   Casey Schaufler   Smack: Bring-up a...
1230
  	return rc;
e114e4737   Casey Schaufler   Smack: Simplified...
1231
1232
1233
1234
  }
  
  /**
   * smack_inode_getattr - Smack check for getting attributes
e95ef49b7   Lukasz Pawelczyk   Small fixes in co...
1235
   * @mnt: vfsmount of the object
e114e4737   Casey Schaufler   Smack: Simplified...
1236
1237
1238
1239
   * @dentry: the object
   *
   * Returns 0 if access is permitted, an error code otherwise
   */
3f7036a07   Al Viro   switch security_i...
1240
  static int smack_inode_getattr(const struct path *path)
e114e4737   Casey Schaufler   Smack: Simplified...
1241
  {
ecfcc53fe   Etienne Basset   smack: implement ...
1242
  	struct smk_audit_info ad;
c6f493d63   David Howells   VFS: security/: d...
1243
  	struct inode *inode = d_backing_inode(path->dentry);
d166c8024   Casey Schaufler   Smack: Bring-up a...
1244
  	int rc;
ecfcc53fe   Etienne Basset   smack: implement ...
1245

f48b73998   Eric Paris   LSM: split LSM_AU...
1246
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
3f7036a07   Al Viro   switch security_i...
1247
1248
1249
  	smk_ad_setfield_u_fs_path(&ad, *path);
  	rc = smk_curacc(smk_of_inode(inode), MAY_READ, &ad);
  	rc = smk_bu_inode(inode, MAY_READ, rc);
d166c8024   Casey Schaufler   Smack: Bring-up a...
1250
  	return rc;
e114e4737   Casey Schaufler   Smack: Simplified...
1251
1252
1253
1254
1255
1256
  }
  
  /**
   * smack_inode_setxattr - Smack check for setting xattrs
   * @dentry: the object
   * @name: name of the attribute
e95ef49b7   Lukasz Pawelczyk   Small fixes in co...
1257
1258
   * @value: value of the attribute
   * @size: size of the value
e114e4737   Casey Schaufler   Smack: Simplified...
1259
1260
1261
1262
1263
1264
   * @flags: unused
   *
   * This protects the Smack attribute explicitly.
   *
   * Returns 0 if access is permitted, an error code otherwise
   */
8f0cfa52a   David Howells   xattr: add missin...
1265
1266
  static int smack_inode_setxattr(struct dentry *dentry, const char *name,
  				const void *value, size_t size, int flags)
e114e4737   Casey Schaufler   Smack: Simplified...
1267
  {
ecfcc53fe   Etienne Basset   smack: implement ...
1268
  	struct smk_audit_info ad;
19760ad03   Casey Schaufler   Smack: Prevent th...
1269
1270
1271
1272
  	struct smack_known *skp;
  	int check_priv = 0;
  	int check_import = 0;
  	int check_star = 0;
bcdca225b   Casey Schaufler   Smack: update for...
1273
  	int rc = 0;
e114e4737   Casey Schaufler   Smack: Simplified...
1274

19760ad03   Casey Schaufler   Smack: Prevent th...
1275
1276
1277
  	/*
  	 * Check label validity here so import won't fail in post_setxattr
  	 */
bcdca225b   Casey Schaufler   Smack: update for...
1278
1279
  	if (strcmp(name, XATTR_NAME_SMACK) == 0 ||
  	    strcmp(name, XATTR_NAME_SMACKIPIN) == 0 ||
19760ad03   Casey Schaufler   Smack: Prevent th...
1280
1281
1282
1283
1284
1285
1286
1287
  	    strcmp(name, XATTR_NAME_SMACKIPOUT) == 0) {
  		check_priv = 1;
  		check_import = 1;
  	} else if (strcmp(name, XATTR_NAME_SMACKEXEC) == 0 ||
  		   strcmp(name, XATTR_NAME_SMACKMMAP) == 0) {
  		check_priv = 1;
  		check_import = 1;
  		check_star = 1;
5c6d1125f   Jarkko Sakkinen   Smack: Transmute ...
1288
  	} else if (strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0) {
19760ad03   Casey Schaufler   Smack: Prevent th...
1289
  		check_priv = 1;
5c6d1125f   Jarkko Sakkinen   Smack: Transmute ...
1290
1291
1292
  		if (size != TRANS_TRUE_SIZE ||
  		    strncmp(value, TRANS_TRUE, TRANS_TRUE_SIZE) != 0)
  			rc = -EINVAL;
bcdca225b   Casey Schaufler   Smack: update for...
1293
1294
  	} else
  		rc = cap_inode_setxattr(dentry, name, value, size, flags);
19760ad03   Casey Schaufler   Smack: Prevent th...
1295
1296
1297
1298
  	if (check_priv && !smack_privileged(CAP_MAC_ADMIN))
  		rc = -EPERM;
  
  	if (rc == 0 && check_import) {
b862e561b   Konstantin Khlebnikov   Smack: handle zer...
1299
  		skp = size ? smk_import_entry(value, size) : NULL;
e774ad683   Lukasz Pawelczyk   smack: pass error...
1300
1301
1302
  		if (IS_ERR(skp))
  			rc = PTR_ERR(skp);
  		else if (skp == NULL || (check_star &&
19760ad03   Casey Schaufler   Smack: Prevent th...
1303
1304
1305
  		    (skp == &smack_known_star || skp == &smack_known_web)))
  			rc = -EINVAL;
  	}
a269434d2   Eric Paris   LSM: separate LSM...
1306
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
ecfcc53fe   Etienne Basset   smack: implement ...
1307
  	smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
d166c8024   Casey Schaufler   Smack: Bring-up a...
1308
  	if (rc == 0) {
c6f493d63   David Howells   VFS: security/: d...
1309
1310
  		rc = smk_curacc(smk_of_inode(d_backing_inode(dentry)), MAY_WRITE, &ad);
  		rc = smk_bu_inode(d_backing_inode(dentry), MAY_WRITE, rc);
d166c8024   Casey Schaufler   Smack: Bring-up a...
1311
  	}
bcdca225b   Casey Schaufler   Smack: update for...
1312
1313
  
  	return rc;
e114e4737   Casey Schaufler   Smack: Simplified...
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
  }
  
  /**
   * 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...
1327
1328
  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...
1329
  {
2f823ff8b   Casey Schaufler   Smack: Improve ac...
1330
  	struct smack_known *skp;
c6f493d63   David Howells   VFS: security/: d...
1331
  	struct inode_smack *isp = d_backing_inode(dentry)->i_security;
676dac4b1   Casey Schaufler   This patch adds a...
1332

2f823ff8b   Casey Schaufler   Smack: Improve ac...
1333
1334
1335
1336
  	if (strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0) {
  		isp->smk_flags |= SMK_INODE_TRANSMUTE;
  		return;
  	}
676dac4b1   Casey Schaufler   This patch adds a...
1337
  	if (strcmp(name, XATTR_NAME_SMACK) == 0) {
9598f4c9e   José Bollo   SMACK: Fix handli...
1338
  		skp = smk_import_entry(value, size);
e774ad683   Lukasz Pawelczyk   smack: pass error...
1339
  		if (!IS_ERR(skp))
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
1340
  			isp->smk_inode = skp;
5c6d1125f   Jarkko Sakkinen   Smack: Transmute ...
1341
  	} else if (strcmp(name, XATTR_NAME_SMACKEXEC) == 0) {
9598f4c9e   José Bollo   SMACK: Fix handli...
1342
  		skp = smk_import_entry(value, size);
e774ad683   Lukasz Pawelczyk   smack: pass error...
1343
  		if (!IS_ERR(skp))
2f823ff8b   Casey Schaufler   Smack: Improve ac...
1344
  			isp->smk_task = skp;
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1345
  	} else if (strcmp(name, XATTR_NAME_SMACKMMAP) == 0) {
9598f4c9e   José Bollo   SMACK: Fix handli...
1346
  		skp = smk_import_entry(value, size);
e774ad683   Lukasz Pawelczyk   smack: pass error...
1347
  		if (!IS_ERR(skp))
2f823ff8b   Casey Schaufler   Smack: Improve ac...
1348
  			isp->smk_mmap = skp;
2f823ff8b   Casey Schaufler   Smack: Improve ac...
1349
  	}
e114e4737   Casey Schaufler   Smack: Simplified...
1350
1351
1352
  
  	return;
  }
ce8a43219   Casey Schaufler   Smack: Clean up c...
1353
  /**
e114e4737   Casey Schaufler   Smack: Simplified...
1354
1355
1356
1357
1358
1359
   * 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...
1360
  static int smack_inode_getxattr(struct dentry *dentry, const char *name)
e114e4737   Casey Schaufler   Smack: Simplified...
1361
  {
ecfcc53fe   Etienne Basset   smack: implement ...
1362
  	struct smk_audit_info ad;
d166c8024   Casey Schaufler   Smack: Bring-up a...
1363
  	int rc;
ecfcc53fe   Etienne Basset   smack: implement ...
1364

a269434d2   Eric Paris   LSM: separate LSM...
1365
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
ecfcc53fe   Etienne Basset   smack: implement ...
1366
  	smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
c6f493d63   David Howells   VFS: security/: d...
1367
1368
  	rc = smk_curacc(smk_of_inode(d_backing_inode(dentry)), MAY_READ, &ad);
  	rc = smk_bu_inode(d_backing_inode(dentry), MAY_READ, rc);
d166c8024   Casey Schaufler   Smack: Bring-up a...
1369
  	return rc;
e114e4737   Casey Schaufler   Smack: Simplified...
1370
  }
ce8a43219   Casey Schaufler   Smack: Clean up c...
1371
  /**
e114e4737   Casey Schaufler   Smack: Simplified...
1372
1373
1374
1375
1376
1377
1378
1379
   * 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...
1380
  static int smack_inode_removexattr(struct dentry *dentry, const char *name)
e114e4737   Casey Schaufler   Smack: Simplified...
1381
  {
676dac4b1   Casey Schaufler   This patch adds a...
1382
  	struct inode_smack *isp;
ecfcc53fe   Etienne Basset   smack: implement ...
1383
  	struct smk_audit_info ad;
bcdca225b   Casey Schaufler   Smack: update for...
1384
  	int rc = 0;
e114e4737   Casey Schaufler   Smack: Simplified...
1385

bcdca225b   Casey Schaufler   Smack: update for...
1386
1387
  	if (strcmp(name, XATTR_NAME_SMACK) == 0 ||
  	    strcmp(name, XATTR_NAME_SMACKIPIN) == 0 ||
676dac4b1   Casey Schaufler   This patch adds a...
1388
  	    strcmp(name, XATTR_NAME_SMACKIPOUT) == 0 ||
5c6d1125f   Jarkko Sakkinen   Smack: Transmute ...
1389
  	    strcmp(name, XATTR_NAME_SMACKEXEC) == 0 ||
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1390
  	    strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0 ||
5e9ab593c   Pankaj Kumar   bugfix patch for ...
1391
  	    strcmp(name, XATTR_NAME_SMACKMMAP) == 0) {
1880eff77   Casey Schaufler   Smack: onlycap li...
1392
  		if (!smack_privileged(CAP_MAC_ADMIN))
bcdca225b   Casey Schaufler   Smack: update for...
1393
1394
1395
  			rc = -EPERM;
  	} else
  		rc = cap_inode_removexattr(dentry, name);
f59bdfba3   Casey Schaufler   Smack: Correctly ...
1396
1397
  	if (rc != 0)
  		return rc;
a269434d2   Eric Paris   LSM: separate LSM...
1398
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
ecfcc53fe   Etienne Basset   smack: implement ...
1399
  	smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
bcdca225b   Casey Schaufler   Smack: update for...
1400

c6f493d63   David Howells   VFS: security/: d...
1401
1402
  	rc = smk_curacc(smk_of_inode(d_backing_inode(dentry)), MAY_WRITE, &ad);
  	rc = smk_bu_inode(d_backing_inode(dentry), MAY_WRITE, rc);
f59bdfba3   Casey Schaufler   Smack: Correctly ...
1403
1404
  	if (rc != 0)
  		return rc;
c6f493d63   David Howells   VFS: security/: d...
1405
  	isp = d_backing_inode(dentry)->i_security;
f59bdfba3   Casey Schaufler   Smack: Correctly ...
1406
1407
1408
1409
  	/*
  	 * Don't do anything special for these.
  	 *	XATTR_NAME_SMACKIPIN
  	 *	XATTR_NAME_SMACKIPOUT
f59bdfba3   Casey Schaufler   Smack: Correctly ...
1410
  	 */
8012495e1   José Bollo   smack: fix cache ...
1411
  	if (strcmp(name, XATTR_NAME_SMACK) == 0) {
fc64005c9   Al Viro   don't bother with...
1412
  		struct super_block *sbp = dentry->d_sb;
8012495e1   José Bollo   smack: fix cache ...
1413
1414
1415
1416
  		struct superblock_smack *sbsp = sbp->s_security;
  
  		isp->smk_inode = sbsp->smk_default;
  	} else if (strcmp(name, XATTR_NAME_SMACKEXEC) == 0)
676dac4b1   Casey Schaufler   This patch adds a...
1417
  		isp->smk_task = NULL;
f59bdfba3   Casey Schaufler   Smack: Correctly ...
1418
  	else if (strcmp(name, XATTR_NAME_SMACKMMAP) == 0)
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1419
  		isp->smk_mmap = NULL;
f59bdfba3   Casey Schaufler   Smack: Correctly ...
1420
1421
  	else if (strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0)
  		isp->smk_flags &= ~SMK_INODE_TRANSMUTE;
676dac4b1   Casey Schaufler   This patch adds a...
1422

f59bdfba3   Casey Schaufler   Smack: Correctly ...
1423
  	return 0;
e114e4737   Casey Schaufler   Smack: Simplified...
1424
1425
1426
1427
1428
1429
1430
  }
  
  /**
   * smack_inode_getsecurity - get smack xattrs
   * @inode: the object
   * @name: attribute name
   * @buffer: where to put the result
57e7ba04d   Casey Schaufler   lsm: fix smack_in...
1431
   * @alloc: duplicate memory
e114e4737   Casey Schaufler   Smack: Simplified...
1432
1433
1434
   *
   * Returns the size of the attribute or an error code
   */
ea861dfd9   Andreas Gruenbacher   security: Make in...
1435
  static int smack_inode_getsecurity(struct inode *inode,
e114e4737   Casey Schaufler   Smack: Simplified...
1436
1437
1438
1439
1440
1441
1442
  				   const char *name, void **buffer,
  				   bool alloc)
  {
  	struct socket_smack *ssp;
  	struct socket *sock;
  	struct super_block *sbp;
  	struct inode *ip = (struct inode *)inode;
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
1443
  	struct smack_known *isp;
e114e4737   Casey Schaufler   Smack: Simplified...
1444

57e7ba04d   Casey Schaufler   lsm: fix smack_in...
1445
  	if (strcmp(name, XATTR_SMACK_SUFFIX) == 0)
e114e4737   Casey Schaufler   Smack: Simplified...
1446
  		isp = smk_of_inode(inode);
57e7ba04d   Casey Schaufler   lsm: fix smack_in...
1447
1448
1449
1450
1451
1452
1453
  	else {
  		/*
  		 * The rest of the Smack xattrs are only on sockets.
  		 */
  		sbp = ip->i_sb;
  		if (sbp->s_magic != SOCKFS_MAGIC)
  			return -EOPNOTSUPP;
e114e4737   Casey Schaufler   Smack: Simplified...
1454

57e7ba04d   Casey Schaufler   lsm: fix smack_in...
1455
1456
1457
  		sock = SOCKET_I(ip);
  		if (sock == NULL || sock->sk == NULL)
  			return -EOPNOTSUPP;
e114e4737   Casey Schaufler   Smack: Simplified...
1458

57e7ba04d   Casey Schaufler   lsm: fix smack_in...
1459
  		ssp = sock->sk->sk_security;
e114e4737   Casey Schaufler   Smack: Simplified...
1460

57e7ba04d   Casey Schaufler   lsm: fix smack_in...
1461
1462
1463
1464
1465
1466
1467
  		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;
  	}
e114e4737   Casey Schaufler   Smack: Simplified...
1468

57e7ba04d   Casey Schaufler   lsm: fix smack_in...
1469
1470
1471
1472
  	if (alloc) {
  		*buffer = kstrdup(isp->smk_known, GFP_KERNEL);
  		if (*buffer == NULL)
  			return -ENOMEM;
e114e4737   Casey Schaufler   Smack: Simplified...
1473
  	}
57e7ba04d   Casey Schaufler   lsm: fix smack_in...
1474
  	return strlen(isp->smk_known);
e114e4737   Casey Schaufler   Smack: Simplified...
1475
1476
1477
1478
1479
1480
1481
1482
  }
  
  
  /**
   * smack_inode_listsecurity - list the Smack attributes
   * @inode: the object
   * @buffer: where they go
   * @buffer_size: size of buffer
e114e4737   Casey Schaufler   Smack: Simplified...
1483
1484
1485
1486
   */
  static int smack_inode_listsecurity(struct inode *inode, char *buffer,
  				    size_t buffer_size)
  {
fd5c9d230   Konstantin Khlebnikov   Smack: fix behavi...
1487
  	int len = sizeof(XATTR_NAME_SMACK);
e114e4737   Casey Schaufler   Smack: Simplified...
1488

fd5c9d230   Konstantin Khlebnikov   Smack: fix behavi...
1489
  	if (buffer != NULL && len <= buffer_size)
e114e4737   Casey Schaufler   Smack: Simplified...
1490
  		memcpy(buffer, XATTR_NAME_SMACK, len);
fd5c9d230   Konstantin Khlebnikov   Smack: fix behavi...
1491
1492
  
  	return len;
e114e4737   Casey Schaufler   Smack: Simplified...
1493
  }
d20bdda6d   Ahmed S. Darwish   Smack: Integrate ...
1494
1495
1496
1497
1498
  /**
   * smack_inode_getsecid - Extract inode's security id
   * @inode: inode to extract the info from
   * @secid: where result will be saved
   */
d6335d77a   Andreas Gruenbacher   security: Make in...
1499
  static void smack_inode_getsecid(struct inode *inode, u32 *secid)
d20bdda6d   Ahmed S. Darwish   Smack: Integrate ...
1500
1501
  {
  	struct inode_smack *isp = inode->i_security;
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
1502
  	*secid = isp->smk_inode->smk_secid;
d20bdda6d   Ahmed S. Darwish   Smack: Integrate ...
1503
  }
e114e4737   Casey Schaufler   Smack: Simplified...
1504
1505
1506
  /*
   * File Hooks
   */
491a0b08d   Casey Schaufler   Smack: Remove poi...
1507
1508
  /*
   * There is no smack_file_permission hook
e114e4737   Casey Schaufler   Smack: Simplified...
1509
1510
1511
1512
1513
1514
1515
1516
   *
   * 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.
   */
e114e4737   Casey Schaufler   Smack: Simplified...
1517
1518
1519
1520
1521
1522
1523
1524
  
  /**
   * 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.
   *
5e7270a6d   Casey Schaufler   Smack: Rework fil...
1525
1526
1527
   * f_security is the owner security information. It
   * isn't used on file access checks, it's for send_sigio.
   *
e114e4737   Casey Schaufler   Smack: Simplified...
1528
1529
1530
1531
   * Returns 0
   */
  static int smack_file_alloc_security(struct file *file)
  {
2f823ff8b   Casey Schaufler   Smack: Improve ac...
1532
  	struct smack_known *skp = smk_of_current();
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
1533
  	file->f_security = skp;
e114e4737   Casey Schaufler   Smack: Simplified...
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
  	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 ...
1563
  	struct smk_audit_info ad;
5e7270a6d   Casey Schaufler   Smack: Rework fil...
1564
  	struct inode *inode = file_inode(file);
ecfcc53fe   Etienne Basset   smack: implement ...
1565

83a1e53f3   Seung-Woo Kim   Smack: ignore pri...
1566
1567
  	if (unlikely(IS_PRIVATE(inode)))
  		return 0;
f48b73998   Eric Paris   LSM: split LSM_AU...
1568
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
ecfcc53fe   Etienne Basset   smack: implement ...
1569
  	smk_ad_setfield_u_fs_path(&ad, file->f_path);
e114e4737   Casey Schaufler   Smack: Simplified...
1570

d166c8024   Casey Schaufler   Smack: Bring-up a...
1571
  	if (_IOC_DIR(cmd) & _IOC_WRITE) {
5e7270a6d   Casey Schaufler   Smack: Rework fil...
1572
  		rc = smk_curacc(smk_of_inode(inode), MAY_WRITE, &ad);
d166c8024   Casey Schaufler   Smack: Bring-up a...
1573
1574
  		rc = smk_bu_file(file, MAY_WRITE, rc);
  	}
e114e4737   Casey Schaufler   Smack: Simplified...
1575

d166c8024   Casey Schaufler   Smack: Bring-up a...
1576
  	if (rc == 0 && (_IOC_DIR(cmd) & _IOC_READ)) {
5e7270a6d   Casey Schaufler   Smack: Rework fil...
1577
  		rc = smk_curacc(smk_of_inode(inode), MAY_READ, &ad);
d166c8024   Casey Schaufler   Smack: Bring-up a...
1578
1579
  		rc = smk_bu_file(file, MAY_READ, rc);
  	}
e114e4737   Casey Schaufler   Smack: Simplified...
1580
1581
1582
1583
1584
1585
1586
  
  	return rc;
  }
  
  /**
   * smack_file_lock - Smack check on file locking
   * @file: the object
251a2a958   Randy Dunlap   smack: fix lots o...
1587
   * @cmd: unused
e114e4737   Casey Schaufler   Smack: Simplified...
1588
   *
c0ab6e56d   Casey Schaufler   Smack: Implement ...
1589
   * Returns 0 if current has lock access, error code otherwise
e114e4737   Casey Schaufler   Smack: Simplified...
1590
1591
1592
   */
  static int smack_file_lock(struct file *file, unsigned int cmd)
  {
ecfcc53fe   Etienne Basset   smack: implement ...
1593
  	struct smk_audit_info ad;
d166c8024   Casey Schaufler   Smack: Bring-up a...
1594
  	int rc;
5e7270a6d   Casey Schaufler   Smack: Rework fil...
1595
  	struct inode *inode = file_inode(file);
ecfcc53fe   Etienne Basset   smack: implement ...
1596

83a1e53f3   Seung-Woo Kim   Smack: ignore pri...
1597
1598
  	if (unlikely(IS_PRIVATE(inode)))
  		return 0;
92f425090   Eric Paris   SMACK: smack_file...
1599
1600
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
  	smk_ad_setfield_u_fs_path(&ad, file->f_path);
5e7270a6d   Casey Schaufler   Smack: Rework fil...
1601
  	rc = smk_curacc(smk_of_inode(inode), MAY_LOCK, &ad);
d166c8024   Casey Schaufler   Smack: Bring-up a...
1602
1603
  	rc = smk_bu_file(file, MAY_LOCK, rc);
  	return rc;
e114e4737   Casey Schaufler   Smack: Simplified...
1604
1605
1606
1607
1608
1609
1610
1611
  }
  
  /**
   * smack_file_fcntl - Smack check on fcntl
   * @file: the object
   * @cmd: what action to check
   * @arg: unused
   *
531f1d453   Casey Schaufler   Smack: Repair pro...
1612
1613
1614
1615
   * 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...
1616
1617
1618
1619
1620
   * 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 ...
1621
  	struct smk_audit_info ad;
531f1d453   Casey Schaufler   Smack: Repair pro...
1622
  	int rc = 0;
5e7270a6d   Casey Schaufler   Smack: Rework fil...
1623
  	struct inode *inode = file_inode(file);
ecfcc53fe   Etienne Basset   smack: implement ...
1624

83a1e53f3   Seung-Woo Kim   Smack: ignore pri...
1625
1626
  	if (unlikely(IS_PRIVATE(inode)))
  		return 0;
e114e4737   Casey Schaufler   Smack: Simplified...
1627
  	switch (cmd) {
e114e4737   Casey Schaufler   Smack: Simplified...
1628
  	case F_GETLK:
c0ab6e56d   Casey Schaufler   Smack: Implement ...
1629
  		break;
e114e4737   Casey Schaufler   Smack: Simplified...
1630
1631
  	case F_SETLK:
  	case F_SETLKW:
c0ab6e56d   Casey Schaufler   Smack: Implement ...
1632
1633
  		smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
  		smk_ad_setfield_u_fs_path(&ad, file->f_path);
5e7270a6d   Casey Schaufler   Smack: Rework fil...
1634
  		rc = smk_curacc(smk_of_inode(inode), MAY_LOCK, &ad);
d166c8024   Casey Schaufler   Smack: Bring-up a...
1635
  		rc = smk_bu_file(file, MAY_LOCK, rc);
c0ab6e56d   Casey Schaufler   Smack: Implement ...
1636
  		break;
e114e4737   Casey Schaufler   Smack: Simplified...
1637
1638
  	case F_SETOWN:
  	case F_SETSIG:
531f1d453   Casey Schaufler   Smack: Repair pro...
1639
1640
  		smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
  		smk_ad_setfield_u_fs_path(&ad, file->f_path);
5e7270a6d   Casey Schaufler   Smack: Rework fil...
1641
  		rc = smk_curacc(smk_of_inode(inode), MAY_WRITE, &ad);
d166c8024   Casey Schaufler   Smack: Bring-up a...
1642
  		rc = smk_bu_file(file, MAY_WRITE, rc);
e114e4737   Casey Schaufler   Smack: Simplified...
1643
1644
  		break;
  	default:
531f1d453   Casey Schaufler   Smack: Repair pro...
1645
  		break;
e114e4737   Casey Schaufler   Smack: Simplified...
1646
1647
1648
1649
1650
1651
  	}
  
  	return rc;
  }
  
  /**
e5467859f   Al Viro   split ->file_mmap...
1652
   * smack_mmap_file :
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1653
1654
1655
1656
1657
1658
1659
1660
   * 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.
   */
e5467859f   Al Viro   split ->file_mmap...
1661
  static int smack_mmap_file(struct file *file,
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1662
  			   unsigned long reqprot, unsigned long prot,
e5467859f   Al Viro   split ->file_mmap...
1663
  			   unsigned long flags)
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1664
  {
272cd7a8c   Casey Schaufler   Smack: Rule list ...
1665
  	struct smack_known *skp;
2f823ff8b   Casey Schaufler   Smack: Improve ac...
1666
  	struct smack_known *mkp;
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1667
1668
  	struct smack_rule *srp;
  	struct task_smack *tsp;
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
1669
  	struct smack_known *okp;
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1670
  	struct inode_smack *isp;
809c02e09   Seth Forshee   Smack: Handle lab...
1671
  	struct superblock_smack *sbsp;
0e0a070d3   Casey Schaufler   Smack: correct be...
1672
1673
1674
  	int may;
  	int mmay;
  	int tmay;
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1675
  	int rc;
496ad9aa8   Al Viro   new helper: file_...
1676
  	if (file == NULL)
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1677
  		return 0;
83a1e53f3   Seung-Woo Kim   Smack: ignore pri...
1678
1679
  	if (unlikely(IS_PRIVATE(file_inode(file))))
  		return 0;
496ad9aa8   Al Viro   new helper: file_...
1680
  	isp = file_inode(file)->i_security;
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1681
1682
  	if (isp->smk_mmap == NULL)
  		return 0;
809c02e09   Seth Forshee   Smack: Handle lab...
1683
1684
1685
1686
  	sbsp = file_inode(file)->i_sb->s_security;
  	if (sbsp->smk_flags & SMK_SB_UNTRUSTED &&
  	    isp->smk_mmap != sbsp->smk_root)
  		return -EACCES;
2f823ff8b   Casey Schaufler   Smack: Improve ac...
1687
  	mkp = isp->smk_mmap;
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1688
1689
  
  	tsp = current_security();
2f823ff8b   Casey Schaufler   Smack: Improve ac...
1690
  	skp = smk_of_current();
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1691
1692
1693
1694
1695
1696
1697
  	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] ...
1698
  	 */
272cd7a8c   Casey Schaufler   Smack: Rule list ...
1699
  	list_for_each_entry_rcu(srp, &skp->smk_rules, list) {
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
1700
  		okp = srp->smk_object;
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1701
1702
1703
  		/*
  		 * Matching labels always allows access.
  		 */
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
1704
  		if (mkp->smk_known == okp->smk_known)
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1705
  			continue;
0e0a070d3   Casey Schaufler   Smack: correct be...
1706
1707
1708
1709
  		/*
  		 * If there is a matching local rule take
  		 * that into account as well.
  		 */
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
1710
1711
1712
  		may = smk_access_entry(srp->smk_subject->smk_known,
  				       okp->smk_known,
  				       &tsp->smk_rules);
0e0a070d3   Casey Schaufler   Smack: correct be...
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
  		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.
  		 */
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
1729
1730
  		mmay = smk_access_entry(mkp->smk_known, okp->smk_known,
  					&mkp->smk_rules);
0e0a070d3   Casey Schaufler   Smack: correct be...
1731
1732
1733
1734
1735
1736
1737
1738
  		if (mmay == -ENOENT) {
  			rc = -EACCES;
  			break;
  		}
  		/*
  		 * If there is a local entry it modifies the
  		 * potential access, too.
  		 */
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
1739
1740
  		tmay = smk_access_entry(mkp->smk_known, okp->smk_known,
  					&tsp->smk_rules);
0e0a070d3   Casey Schaufler   Smack: correct be...
1741
1742
  		if (tmay != -ENOENT)
  			mmay &= tmay;
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1743

0e0a070d3   Casey Schaufler   Smack: correct be...
1744
1745
1746
1747
1748
  		/*
  		 * If there is any access available to current that is
  		 * not available to a SMACK64MMAP subject
  		 * deny access.
  		 */
75a25637b   Casey Schaufler   Smack: correct fi...
1749
  		if ((may | mmay) != mmay) {
0e0a070d3   Casey Schaufler   Smack: correct be...
1750
  			rc = -EACCES;
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1751
  			break;
0e0a070d3   Casey Schaufler   Smack: correct be...
1752
  		}
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1753
1754
1755
1756
1757
1758
1759
1760
  	}
  
  	rcu_read_unlock();
  
  	return rc;
  }
  
  /**
e114e4737   Casey Schaufler   Smack: Simplified...
1761
1762
1763
   * smack_file_set_fowner - set the file security blob value
   * @file: object in question
   *
e114e4737   Casey Schaufler   Smack: Simplified...
1764
   */
e0b93eddf   Jeff Layton   security: make se...
1765
  static void smack_file_set_fowner(struct file *file)
e114e4737   Casey Schaufler   Smack: Simplified...
1766
  {
5e7270a6d   Casey Schaufler   Smack: Rework fil...
1767
  	file->f_security = smk_of_current();
e114e4737   Casey Schaufler   Smack: Simplified...
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
  }
  
  /**
   * 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)
  {
2f823ff8b   Casey Schaufler   Smack: Improve ac...
1784
1785
  	struct smack_known *skp;
  	struct smack_known *tkp = smk_of_task(tsk->cred->security);
e114e4737   Casey Schaufler   Smack: Simplified...
1786
1787
  	struct file *file;
  	int rc;
ecfcc53fe   Etienne Basset   smack: implement ...
1788
  	struct smk_audit_info ad;
e114e4737   Casey Schaufler   Smack: Simplified...
1789
1790
1791
1792
1793
  
  	/*
  	 * 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] ...
1794

ecfcc53fe   Etienne Basset   smack: implement ...
1795
  	/* we don't log here as rc can be overriden */
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
1796
  	skp = file->f_security;
c60b90667   Casey Schaufler   Smack: Signal del...
1797
1798
  	rc = smk_access(skp, tkp, MAY_DELIVER, NULL);
  	rc = smk_bu_note("sigiotask", skp, tkp, MAY_DELIVER, rc);
5cd9c58fb   David Howells   security: Fix set...
1799
  	if (rc != 0 && has_capability(tsk, CAP_MAC_OVERRIDE))
ecfcc53fe   Etienne Basset   smack: implement ...
1800
1801
1802
1803
  		rc = 0;
  
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK);
  	smk_ad_setfield_u_tsk(&ad, tsk);
c60b90667   Casey Schaufler   Smack: Signal del...
1804
  	smack_log(skp->smk_known, tkp->smk_known, MAY_DELIVER, rc, &ad);
e114e4737   Casey Schaufler   Smack: Simplified...
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
  	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)
  {
d166c8024   Casey Schaufler   Smack: Bring-up a...
1816
  	int rc;
e114e4737   Casey Schaufler   Smack: Simplified...
1817
  	int may = 0;
ecfcc53fe   Etienne Basset   smack: implement ...
1818
  	struct smk_audit_info ad;
5e7270a6d   Casey Schaufler   Smack: Rework fil...
1819
  	struct inode *inode = file_inode(file);
79be09350   Casey Schaufler   Smack: File recei...
1820
1821
1822
  	struct socket *sock;
  	struct task_smack *tsp;
  	struct socket_smack *ssp;
e114e4737   Casey Schaufler   Smack: Simplified...
1823

9777582e8   Seung-Woo Kim   Smack: ignore pri...
1824
1825
  	if (unlikely(IS_PRIVATE(inode)))
  		return 0;
4482a44f6   Casey Schaufler   Smack: File recei...
1826
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
ecfcc53fe   Etienne Basset   smack: implement ...
1827
  	smk_ad_setfield_u_fs_path(&ad, file->f_path);
79be09350   Casey Schaufler   Smack: File recei...
1828

51d59af26   Casey Schaufler   Smack: Safer chec...
1829
  	if (inode->i_sb->s_magic == SOCKFS_MAGIC) {
79be09350   Casey Schaufler   Smack: File recei...
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
  		sock = SOCKET_I(inode);
  		ssp = sock->sk->sk_security;
  		tsp = current_security();
  		/*
  		 * If the receiving process can't write to the
  		 * passed socket or if the passed socket can't
  		 * write to the receiving process don't accept
  		 * the passed socket.
  		 */
  		rc = smk_access(tsp->smk_task, ssp->smk_out, MAY_WRITE, &ad);
  		rc = smk_bu_file(file, may, rc);
  		if (rc < 0)
  			return rc;
  		rc = smk_access(ssp->smk_in, tsp->smk_task, MAY_WRITE, &ad);
  		rc = smk_bu_file(file, may, rc);
  		return rc;
  	}
e114e4737   Casey Schaufler   Smack: Simplified...
1847
1848
1849
1850
1851
1852
1853
  	/*
  	 * This code relies on bitmasks.
  	 */
  	if (file->f_mode & FMODE_READ)
  		may = MAY_READ;
  	if (file->f_mode & FMODE_WRITE)
  		may |= MAY_WRITE;
5e7270a6d   Casey Schaufler   Smack: Rework fil...
1854
  	rc = smk_curacc(smk_of_inode(inode), may, &ad);
d166c8024   Casey Schaufler   Smack: Bring-up a...
1855
1856
  	rc = smk_bu_file(file, may, rc);
  	return rc;
e114e4737   Casey Schaufler   Smack: Simplified...
1857
  }
531f1d453   Casey Schaufler   Smack: Repair pro...
1858
  /**
83d498569   Eric Paris   SELinux: rename d...
1859
   * smack_file_open - Smack dentry open processing
531f1d453   Casey Schaufler   Smack: Repair pro...
1860
   * @file: the object
a6834c0b9   Casey Schaufler   Smack: Verify rea...
1861
   * @cred: task credential
531f1d453   Casey Schaufler   Smack: Repair pro...
1862
1863
   *
   * Set the security blob in the file structure.
a6834c0b9   Casey Schaufler   Smack: Verify rea...
1864
1865
1866
   * Allow the open only if the task has read access. There are
   * many read operations (e.g. fstat) that you can do with an
   * fd even if you have the file open write-only.
531f1d453   Casey Schaufler   Smack: Repair pro...
1867
1868
1869
   *
   * Returns 0
   */
83d498569   Eric Paris   SELinux: rename d...
1870
  static int smack_file_open(struct file *file, const struct cred *cred)
531f1d453   Casey Schaufler   Smack: Repair pro...
1871
  {
a6834c0b9   Casey Schaufler   Smack: Verify rea...
1872
  	struct task_smack *tsp = cred->security;
5e7270a6d   Casey Schaufler   Smack: Rework fil...
1873
  	struct inode *inode = file_inode(file);
a6834c0b9   Casey Schaufler   Smack: Verify rea...
1874
1875
  	struct smk_audit_info ad;
  	int rc;
531f1d453   Casey Schaufler   Smack: Repair pro...
1876

a6834c0b9   Casey Schaufler   Smack: Verify rea...
1877
1878
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
  	smk_ad_setfield_u_fs_path(&ad, file->f_path);
c9d238a18   Himanshu Shukla   SMACK: Use smk_ts...
1879
  	rc = smk_tskacc(tsp, smk_of_inode(inode), MAY_READ, &ad);
d166c8024   Casey Schaufler   Smack: Bring-up a...
1880
  	rc = smk_bu_credfile(cred, file, MAY_READ, rc);
a6834c0b9   Casey Schaufler   Smack: Verify rea...
1881
1882
  
  	return rc;
531f1d453   Casey Schaufler   Smack: Repair pro...
1883
  }
e114e4737   Casey Schaufler   Smack: Simplified...
1884
1885
1886
1887
1888
  /*
   * Task hooks
   */
  
  /**
ee18d64c1   David Howells   KEYS: Add a keyct...
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
   * 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] ...
1899
1900
1901
1902
  	struct task_smack *tsp;
  
  	tsp = new_task_smack(NULL, NULL, gfp);
  	if (tsp == NULL)
676dac4b1   Casey Schaufler   This patch adds a...
1903
  		return -ENOMEM;
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1904
1905
  
  	cred->security = tsp;
ee18d64c1   David Howells   KEYS: Add a keyct...
1906
1907
1908
1909
1910
  	return 0;
  }
  
  
  /**
f1752eec6   David Howells   CRED: Detach the ...
1911
1912
   * smack_cred_free - "free" task-level security credentials
   * @cred: the credentials in question
e114e4737   Casey Schaufler   Smack: Simplified...
1913
   *
e114e4737   Casey Schaufler   Smack: Simplified...
1914
   */
f1752eec6   David Howells   CRED: Detach the ...
1915
  static void smack_cred_free(struct cred *cred)
e114e4737   Casey Schaufler   Smack: Simplified...
1916
  {
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1917
1918
1919
1920
1921
1922
1923
1924
  	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;
38416e539   Zbigniew Jasinski   Smack: limited ca...
1925
  	smk_destroy_label_list(&tsp->smk_relabel);
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1926
1927
1928
1929
1930
1931
  	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...
1932
1933
1934
  }
  
  /**
d84f4f992   David Howells   CRED: Inaugurate ...
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
   * 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...
1945
1946
  	struct task_smack *old_tsp = old->security;
  	struct task_smack *new_tsp;
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1947
  	int rc;
676dac4b1   Casey Schaufler   This patch adds a...
1948

7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1949
  	new_tsp = new_task_smack(old_tsp->smk_task, old_tsp->smk_task, gfp);
676dac4b1   Casey Schaufler   This patch adds a...
1950
1951
  	if (new_tsp == NULL)
  		return -ENOMEM;
b437aba85   Himanshu Shukla   SMACK: Fix the me...
1952
  	new->security = new_tsp;
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1953
1954
1955
  	rc = smk_copy_rules(&new_tsp->smk_rules, &old_tsp->smk_rules, gfp);
  	if (rc != 0)
  		return rc;
38416e539   Zbigniew Jasinski   Smack: limited ca...
1956
1957
1958
1959
  	rc = smk_copy_relabel(&new_tsp->smk_relabel, &old_tsp->smk_relabel,
  				gfp);
  	if (rc != 0)
  		return rc;
d84f4f992   David Howells   CRED: Inaugurate ...
1960
1961
  	return 0;
  }
251a2a958   Randy Dunlap   smack: fix lots o...
1962
  /**
ee18d64c1   David Howells   KEYS: Add a keyct...
1963
1964
1965
1966
1967
1968
1969
1970
   * 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...
1971
1972
1973
1974
1975
  	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] ...
1976
1977
1978
1979
1980
  	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...
1981
1982
1983
  }
  
  /**
3a3b7ce93   David Howells   CRED: Allow kerne...
1984
   * smack_kernel_act_as - Set the subjective context in a set of credentials
251a2a958   Randy Dunlap   smack: fix lots o...
1985
1986
   * @new: points to the set of credentials to be modified.
   * @secid: specifies the security ID to be set
3a3b7ce93   David Howells   CRED: Allow kerne...
1987
1988
1989
1990
1991
   *
   * 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...
1992
  	struct task_smack *new_tsp = new->security;
3a3b7ce93   David Howells   CRED: Allow kerne...
1993

152f91d4d   Casey Schaufler   Smack: Remove unn...
1994
  	new_tsp->smk_task = smack_from_secid(secid);
3a3b7ce93   David Howells   CRED: Allow kerne...
1995
1996
1997
1998
1999
  	return 0;
  }
  
  /**
   * smack_kernel_create_files_as - Set the file creation label in a set of creds
251a2a958   Randy Dunlap   smack: fix lots o...
2000
2001
   * @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...
2002
2003
2004
2005
2006
2007
2008
2009
   *
   * 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...
2010
  	struct task_smack *tsp = new->security;
3a3b7ce93   David Howells   CRED: Allow kerne...
2011

21c7eae21   Lukasz Pawelczyk   Make Smack operat...
2012
  	tsp->smk_forked = isp->smk_inode;
2f823ff8b   Casey Schaufler   Smack: Improve ac...
2013
  	tsp->smk_task = tsp->smk_forked;
3a3b7ce93   David Howells   CRED: Allow kerne...
2014
2015
2016
2017
  	return 0;
  }
  
  /**
ecfcc53fe   Etienne Basset   smack: implement ...
2018
2019
   * smk_curacc_on_task - helper to log task related access
   * @p: the task object
531f1d453   Casey Schaufler   Smack: Repair pro...
2020
2021
   * @access: the access requested
   * @caller: name of the calling function for audit
ecfcc53fe   Etienne Basset   smack: implement ...
2022
2023
2024
   *
   * Return 0 if access is permitted
   */
531f1d453   Casey Schaufler   Smack: Repair pro...
2025
2026
  static int smk_curacc_on_task(struct task_struct *p, int access,
  				const char *caller)
ecfcc53fe   Etienne Basset   smack: implement ...
2027
2028
  {
  	struct smk_audit_info ad;
6d1cff2a8   Andrey Ryabinin   smack: fix possib...
2029
  	struct smack_known *skp = smk_of_task_struct(p);
d166c8024   Casey Schaufler   Smack: Bring-up a...
2030
  	int rc;
ecfcc53fe   Etienne Basset   smack: implement ...
2031

531f1d453   Casey Schaufler   Smack: Repair pro...
2032
  	smk_ad_init(&ad, caller, LSM_AUDIT_DATA_TASK);
ecfcc53fe   Etienne Basset   smack: implement ...
2033
  	smk_ad_setfield_u_tsk(&ad, p);
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
2034
  	rc = smk_curacc(skp, access, &ad);
d166c8024   Casey Schaufler   Smack: Bring-up a...
2035
2036
  	rc = smk_bu_task(p, access, rc);
  	return rc;
ecfcc53fe   Etienne Basset   smack: implement ...
2037
2038
2039
  }
  
  /**
e114e4737   Casey Schaufler   Smack: Simplified...
2040
2041
2042
2043
2044
2045
2046
2047
   * 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...
2048
  	return smk_curacc_on_task(p, MAY_WRITE, __func__);
e114e4737   Casey Schaufler   Smack: Simplified...
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
  }
  
  /**
   * 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...
2059
  	return smk_curacc_on_task(p, MAY_READ, __func__);
e114e4737   Casey Schaufler   Smack: Simplified...
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
  }
  
  /**
   * 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...
2070
  	return smk_curacc_on_task(p, MAY_READ, __func__);
e114e4737   Casey Schaufler   Smack: Simplified...
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
  }
  
  /**
   * 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)
  {
6d1cff2a8   Andrey Ryabinin   smack: fix possib...
2082
  	struct smack_known *skp = smk_of_task_struct(p);
2f823ff8b   Casey Schaufler   Smack: Improve ac...
2083
2084
  
  	*secid = skp->smk_secid;
e114e4737   Casey Schaufler   Smack: Simplified...
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
  }
  
  /**
   * 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)
  {
b1d9e6b06   Casey Schaufler   LSM: Switch to li...
2096
  	return smk_curacc_on_task(p, MAY_WRITE, __func__);
e114e4737   Casey Schaufler   Smack: Simplified...
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
  }
  
  /**
   * 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)
  {
b1d9e6b06   Casey Schaufler   LSM: Switch to li...
2108
  	return smk_curacc_on_task(p, MAY_WRITE, __func__);
e114e4737   Casey Schaufler   Smack: Simplified...
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
  }
  
  /**
   * 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...
2119
  	return smk_curacc_on_task(p, MAY_READ, __func__);
e114e4737   Casey Schaufler   Smack: Simplified...
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
  }
  
  /**
   * 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 ...
2130
  static int smack_task_setscheduler(struct task_struct *p)
e114e4737   Casey Schaufler   Smack: Simplified...
2131
  {
b1d9e6b06   Casey Schaufler   LSM: Switch to li...
2132
  	return smk_curacc_on_task(p, MAY_WRITE, __func__);
e114e4737   Casey Schaufler   Smack: Simplified...
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
  }
  
  /**
   * 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...
2143
  	return smk_curacc_on_task(p, MAY_READ, __func__);
e114e4737   Casey Schaufler   Smack: Simplified...
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
  }
  
  /**
   * 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...
2154
  	return smk_curacc_on_task(p, MAY_WRITE, __func__);
e114e4737   Casey Schaufler   Smack: Simplified...
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
  }
  
  /**
   * 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 ...
2172
  	struct smk_audit_info ad;
2f823ff8b   Casey Schaufler   Smack: Improve ac...
2173
  	struct smack_known *skp;
6d1cff2a8   Andrey Ryabinin   smack: fix possib...
2174
  	struct smack_known *tkp = smk_of_task_struct(p);
d166c8024   Casey Schaufler   Smack: Bring-up a...
2175
  	int rc;
ecfcc53fe   Etienne Basset   smack: implement ...
2176

18d872f77   Rafal Krypa   Smack: ignore nul...
2177
2178
  	if (!sig)
  		return 0; /* null signal; existence test */
ecfcc53fe   Etienne Basset   smack: implement ...
2179
2180
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK);
  	smk_ad_setfield_u_tsk(&ad, p);
e114e4737   Casey Schaufler   Smack: Simplified...
2181
  	/*
e114e4737   Casey Schaufler   Smack: Simplified...
2182
2183
2184
  	 * Sending a signal requires that the sender
  	 * can write the receiver.
  	 */
d166c8024   Casey Schaufler   Smack: Bring-up a...
2185
  	if (secid == 0) {
c60b90667   Casey Schaufler   Smack: Signal del...
2186
2187
  		rc = smk_curacc(tkp, MAY_DELIVER, &ad);
  		rc = smk_bu_task(p, MAY_DELIVER, rc);
d166c8024   Casey Schaufler   Smack: Bring-up a...
2188
2189
  		return rc;
  	}
e114e4737   Casey Schaufler   Smack: Simplified...
2190
2191
2192
2193
2194
  	/*
  	 * 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.
  	 */
2f823ff8b   Casey Schaufler   Smack: Improve ac...
2195
  	skp = smack_from_secid(secid);
c60b90667   Casey Schaufler   Smack: Signal del...
2196
2197
  	rc = smk_access(skp, tkp, MAY_DELIVER, &ad);
  	rc = smk_bu_note("USB signal", skp, tkp, MAY_DELIVER, rc);
d166c8024   Casey Schaufler   Smack: Bring-up a...
2198
  	return rc;
e114e4737   Casey Schaufler   Smack: Simplified...
2199
2200
2201
  }
  
  /**
e114e4737   Casey Schaufler   Smack: Simplified...
2202
2203
   * smack_task_to_inode - copy task smack into the inode blob
   * @p: task to copy from
251a2a958   Randy Dunlap   smack: fix lots o...
2204
   * @inode: inode to copy to
e114e4737   Casey Schaufler   Smack: Simplified...
2205
2206
2207
2208
2209
2210
   *
   * 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;
6d1cff2a8   Andrey Ryabinin   smack: fix possib...
2211
  	struct smack_known *skp = smk_of_task_struct(p);
2f823ff8b   Casey Schaufler   Smack: Improve ac...
2212

21c7eae21   Lukasz Pawelczyk   Make Smack operat...
2213
  	isp->smk_inode = skp;
4545cfb00   Casey Schaufler   Smack: Mark inode...
2214
  	isp->smk_flags |= SMK_INODE_INSTANT;
e114e4737   Casey Schaufler   Smack: Simplified...
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
  }
  
  /*
   * Socket hooks.
   */
  
  /**
   * smack_sk_alloc_security - Allocate a socket blob
   * @sk: the socket
   * @family: unused
251a2a958   Randy Dunlap   smack: fix lots o...
2225
   * @gfp_flags: memory allocation flags
e114e4737   Casey Schaufler   Smack: Simplified...
2226
2227
2228
2229
2230
2231
2232
   *
   * 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)
  {
2f823ff8b   Casey Schaufler   Smack: Improve ac...
2233
  	struct smack_known *skp = smk_of_current();
e114e4737   Casey Schaufler   Smack: Simplified...
2234
2235
2236
2237
2238
  	struct socket_smack *ssp;
  
  	ssp = kzalloc(sizeof(struct socket_smack), gfp_flags);
  	if (ssp == NULL)
  		return -ENOMEM;
08382c9f6   jooseong lee   Smack: Assign sma...
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
  	/*
  	 * Sockets created by kernel threads receive web label.
  	 */
  	if (unlikely(current->flags & PF_KTHREAD)) {
  		ssp->smk_in = &smack_known_web;
  		ssp->smk_out = &smack_known_web;
  	} else {
  		ssp->smk_in = skp;
  		ssp->smk_out = skp;
  	}
272cd7a8c   Casey Schaufler   Smack: Rule list ...
2249
  	ssp->smk_packet = NULL;
e114e4737   Casey Schaufler   Smack: Simplified...
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
  
  	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)
  {
0c96d1f53   Vishal Goel   Smack: Fix the is...
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
  #ifdef SMACK_IPV6_PORT_LABELING
  	struct smk_port_label *spp;
  
  	if (sk->sk_family == PF_INET6) {
  		rcu_read_lock();
  		list_for_each_entry_rcu(spp, &smk_ipv6_port_list, list) {
  			if (spp->smk_sock != sk)
  				continue;
  			spp->smk_can_reuse = 1;
  			break;
  		}
  		rcu_read_unlock();
  	}
  #endif
e114e4737   Casey Schaufler   Smack: Simplified...
2278
2279
2280
2281
  	kfree(sk->sk_security);
  }
  
  /**
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
2282
  * smack_ipv4host_label - check host based restrictions
07feee8f8   Paul Moore   netlabel: Cleanup...
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
  * @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.
  */
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
2293
  static struct smack_known *smack_ipv4host_label(struct sockaddr_in *sip)
07feee8f8   Paul Moore   netlabel: Cleanup...
2294
  {
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
2295
  	struct smk_net4addr *snp;
07feee8f8   Paul Moore   netlabel: Cleanup...
2296
2297
2298
2299
  	struct in_addr *siap = &sip->sin_addr;
  
  	if (siap->s_addr == 0)
  		return NULL;
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
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
2352
2353
2354
2355
2356
  	list_for_each_entry_rcu(snp, &smk_net4addr_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.s_addr ==
  		    (siap->s_addr & snp->smk_mask.s_addr))
  			return snp->smk_label;
  
  	return NULL;
  }
  
  #if IS_ENABLED(CONFIG_IPV6)
  /*
   * smk_ipv6_localhost - Check for local ipv6 host address
   * @sip: the address
   *
   * Returns boolean true if this is the localhost address
   */
  static bool smk_ipv6_localhost(struct sockaddr_in6 *sip)
  {
  	__be16 *be16p = (__be16 *)&sip->sin6_addr;
  	__be32 *be32p = (__be32 *)&sip->sin6_addr;
  
  	if (be32p[0] == 0 && be32p[1] == 0 && be32p[2] == 0 && be16p[6] == 0 &&
  	    ntohs(be16p[7]) == 1)
  		return true;
  	return false;
  }
  
  /**
  * smack_ipv6host_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 struct smack_known *smack_ipv6host_label(struct sockaddr_in6 *sip)
  {
  	struct smk_net6addr *snp;
  	struct in6_addr *sap = &sip->sin6_addr;
  	int i;
  	int found = 0;
  
  	/*
  	 * It's local. Don't look for a host label.
  	 */
  	if (smk_ipv6_localhost(sip))
  		return NULL;
  
  	list_for_each_entry_rcu(snp, &smk_net6addr_list, list) {
07feee8f8   Paul Moore   netlabel: Cleanup...
2357
  		/*
2e4939f70   Casey Schaufler   Smack: ipv6 label...
2358
2359
2360
2361
2362
2363
  		 * If the label is NULL the entry has
  		 * been renounced. Ignore it.
  		 */
  		if (snp->smk_label == NULL)
  			continue;
  		/*
07feee8f8   Paul Moore   netlabel: Cleanup...
2364
2365
2366
2367
  		* 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
  		*/
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
2368
  		for (found = 1, i = 0; i < 8; i++) {
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
2369
2370
2371
2372
2373
  			if ((sap->s6_addr16[i] & snp->smk_mask.s6_addr16[i]) !=
  			    snp->smk_host.s6_addr16[i]) {
  				found = 0;
  				break;
  			}
4303154e8   Etienne Basset   smack: Add a new ...
2374
  		}
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
2375
2376
2377
  		if (found)
  			return snp->smk_label;
  	}
07feee8f8   Paul Moore   netlabel: Cleanup...
2378
2379
2380
  
  	return NULL;
  }
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
2381
  #endif /* CONFIG_IPV6 */
07feee8f8   Paul Moore   netlabel: Cleanup...
2382
2383
  
  /**
e114e4737   Casey Schaufler   Smack: Simplified...
2384
2385
   * smack_netlabel - Set the secattr on a socket
   * @sk: the socket
6d3dc07cb   Casey Schaufler   smack: Add suppor...
2386
   * @labeled: socket label scheme
e114e4737   Casey Schaufler   Smack: Simplified...
2387
2388
2389
2390
2391
2392
   *
   * 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...
2393
  static int smack_netlabel(struct sock *sk, int labeled)
e114e4737   Casey Schaufler   Smack: Simplified...
2394
  {
f7112e6c9   Casey Schaufler   Smack: allow for ...
2395
  	struct smack_known *skp;
07feee8f8   Paul Moore   netlabel: Cleanup...
2396
  	struct socket_smack *ssp = sk->sk_security;
6d3dc07cb   Casey Schaufler   smack: Add suppor...
2397
  	int rc = 0;
e114e4737   Casey Schaufler   Smack: Simplified...
2398

6d3dc07cb   Casey Schaufler   smack: Add suppor...
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
  	/*
  	 * 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 {
2f823ff8b   Casey Schaufler   Smack: Improve ac...
2414
  		skp = ssp->smk_out;
f7112e6c9   Casey Schaufler   Smack: allow for ...
2415
  		rc = netlbl_sock_setattr(sk, sk->sk_family, &skp->smk_netlabel);
6d3dc07cb   Casey Schaufler   smack: Add suppor...
2416
2417
2418
2419
  	}
  
  	bh_unlock_sock(sk);
  	local_bh_enable();
4bc87e627   Casey Schaufler   Smack: unlabeled ...
2420

e114e4737   Casey Schaufler   Smack: Simplified...
2421
2422
2423
2424
  	return rc;
  }
  
  /**
07feee8f8   Paul Moore   netlabel: Cleanup...
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
   * 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)
  {
2f823ff8b   Casey Schaufler   Smack: Improve ac...
2437
  	struct smack_known *skp;
07feee8f8   Paul Moore   netlabel: Cleanup...
2438
2439
  	int rc;
  	int sk_lbl;
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
2440
  	struct smack_known *hkp;
07feee8f8   Paul Moore   netlabel: Cleanup...
2441
  	struct socket_smack *ssp = sk->sk_security;
ecfcc53fe   Etienne Basset   smack: implement ...
2442
  	struct smk_audit_info ad;
07feee8f8   Paul Moore   netlabel: Cleanup...
2443
2444
  
  	rcu_read_lock();
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
2445
  	hkp = smack_ipv4host_label(sap);
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
2446
  	if (hkp != NULL) {
ecfcc53fe   Etienne Basset   smack: implement ...
2447
  #ifdef CONFIG_AUDIT
923e9a139   Kees Cook   Smack: build when...
2448
  		struct lsm_network_audit net;
48c62af68   Eric Paris   LSM: shrink the c...
2449
2450
2451
2452
  		smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &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;
ecfcc53fe   Etienne Basset   smack: implement ...
2453
  #endif
923e9a139   Kees Cook   Smack: build when...
2454
  		sk_lbl = SMACK_UNLABELED_SOCKET;
2f823ff8b   Casey Schaufler   Smack: Improve ac...
2455
  		skp = ssp->smk_out;
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
2456
2457
  		rc = smk_access(skp, hkp, MAY_WRITE, &ad);
  		rc = smk_bu_note("IPv4 host check", skp, hkp, MAY_WRITE, rc);
07feee8f8   Paul Moore   netlabel: Cleanup...
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
  	} else {
  		sk_lbl = SMACK_CIPSO_SOCKET;
  		rc = 0;
  	}
  	rcu_read_unlock();
  	if (rc != 0)
  		return rc;
  
  	return smack_netlabel(sk, sk_lbl);
  }
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
  #if IS_ENABLED(CONFIG_IPV6)
  /**
   * smk_ipv6_check - check Smack access
   * @subject: subject Smack label
   * @object: object Smack label
   * @address: address
   * @act: the action being taken
   *
   * Check an IPv6 access
   */
  static int smk_ipv6_check(struct smack_known *subject,
  				struct smack_known *object,
  				struct sockaddr_in6 *address, int act)
  {
  #ifdef CONFIG_AUDIT
  	struct lsm_network_audit net;
  #endif
  	struct smk_audit_info ad;
  	int rc;
  
  #ifdef CONFIG_AUDIT
  	smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net);
  	ad.a.u.net->family = PF_INET6;
  	ad.a.u.net->dport = ntohs(address->sin6_port);
  	if (act == SMK_RECEIVING)
  		ad.a.u.net->v6info.saddr = address->sin6_addr;
  	else
  		ad.a.u.net->v6info.daddr = address->sin6_addr;
  #endif
  	rc = smk_access(subject, object, MAY_WRITE, &ad);
  	rc = smk_bu_note("IPv6 check", subject, object, MAY_WRITE, rc);
  	return rc;
  }
  #endif /* CONFIG_IPV6 */
  
  #ifdef SMACK_IPV6_PORT_LABELING
07feee8f8   Paul Moore   netlabel: Cleanup...
2504
  /**
c67394434   Casey Schaufler   Smack: Local IPv6...
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
   * smk_ipv6_port_label - Smack port access table management
   * @sock: socket
   * @address: address
   *
   * Create or update the port list entry
   */
  static void smk_ipv6_port_label(struct socket *sock, struct sockaddr *address)
  {
  	struct sock *sk = sock->sk;
  	struct sockaddr_in6 *addr6;
  	struct socket_smack *ssp = sock->sk->sk_security;
  	struct smk_port_label *spp;
  	unsigned short port = 0;
  
  	if (address == NULL) {
  		/*
  		 * This operation is changing the Smack information
  		 * on the bound socket. Take the changes to the port
  		 * as well.
  		 */
3c7ce3427   Vishal Goel   SMACK: Add the rc...
2525
2526
  		rcu_read_lock();
  		list_for_each_entry_rcu(spp, &smk_ipv6_port_list, list) {
c67394434   Casey Schaufler   Smack: Local IPv6...
2527
2528
2529
2530
  			if (sk != spp->smk_sock)
  				continue;
  			spp->smk_in = ssp->smk_in;
  			spp->smk_out = ssp->smk_out;
3c7ce3427   Vishal Goel   SMACK: Add the rc...
2531
  			rcu_read_unlock();
c67394434   Casey Schaufler   Smack: Local IPv6...
2532
2533
2534
2535
2536
2537
  			return;
  		}
  		/*
  		 * A NULL address is only used for updating existing
  		 * bound entries. If there isn't one, it's OK.
  		 */
3c7ce3427   Vishal Goel   SMACK: Add the rc...
2538
  		rcu_read_unlock();
c67394434   Casey Schaufler   Smack: Local IPv6...
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
  		return;
  	}
  
  	addr6 = (struct sockaddr_in6 *)address;
  	port = ntohs(addr6->sin6_port);
  	/*
  	 * This is a special case that is safely ignored.
  	 */
  	if (port == 0)
  		return;
  
  	/*
  	 * Look for an existing port list entry.
  	 * This is an indication that a port is getting reused.
  	 */
3c7ce3427   Vishal Goel   SMACK: Add the rc...
2554
2555
  	rcu_read_lock();
  	list_for_each_entry_rcu(spp, &smk_ipv6_port_list, list) {
9d44c9738   Vishal Goel   Smack: Fix the is...
2556
  		if (spp->smk_port != port || spp->smk_sock_type != sock->type)
c67394434   Casey Schaufler   Smack: Local IPv6...
2557
  			continue;
0c96d1f53   Vishal Goel   Smack: Fix the is...
2558
2559
2560
2561
  		if (spp->smk_can_reuse != 1) {
  			rcu_read_unlock();
  			return;
  		}
c67394434   Casey Schaufler   Smack: Local IPv6...
2562
2563
2564
2565
  		spp->smk_port = port;
  		spp->smk_sock = sk;
  		spp->smk_in = ssp->smk_in;
  		spp->smk_out = ssp->smk_out;
0c96d1f53   Vishal Goel   Smack: Fix the is...
2566
  		spp->smk_can_reuse = 0;
3c7ce3427   Vishal Goel   SMACK: Add the rc...
2567
  		rcu_read_unlock();
c67394434   Casey Schaufler   Smack: Local IPv6...
2568
2569
  		return;
  	}
3c7ce3427   Vishal Goel   SMACK: Add the rc...
2570
  	rcu_read_unlock();
c67394434   Casey Schaufler   Smack: Local IPv6...
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
  	/*
  	 * A new port entry is required.
  	 */
  	spp = kzalloc(sizeof(*spp), GFP_KERNEL);
  	if (spp == NULL)
  		return;
  
  	spp->smk_port = port;
  	spp->smk_sock = sk;
  	spp->smk_in = ssp->smk_in;
  	spp->smk_out = ssp->smk_out;
9d44c9738   Vishal Goel   Smack: Fix the is...
2582
  	spp->smk_sock_type = sock->type;
0c96d1f53   Vishal Goel   Smack: Fix the is...
2583
  	spp->smk_can_reuse = 0;
c67394434   Casey Schaufler   Smack: Local IPv6...
2584

3c7ce3427   Vishal Goel   SMACK: Add the rc...
2585
2586
2587
  	mutex_lock(&smack_ipv6_lock);
  	list_add_rcu(&spp->list, &smk_ipv6_port_list);
  	mutex_unlock(&smack_ipv6_lock);
c67394434   Casey Schaufler   Smack: Local IPv6...
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
  	return;
  }
  
  /**
   * smk_ipv6_port_check - check Smack port access
   * @sock: socket
   * @address: address
   *
   * Create or update the port list entry
   */
6ea062475   Casey Schaufler   Smack: IPv6 casti...
2598
  static int smk_ipv6_port_check(struct sock *sk, struct sockaddr_in6 *address,
c67394434   Casey Schaufler   Smack: Local IPv6...
2599
2600
  				int act)
  {
c67394434   Casey Schaufler   Smack: Local IPv6...
2601
2602
  	struct smk_port_label *spp;
  	struct socket_smack *ssp = sk->sk_security;
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
2603
2604
  	struct smack_known *skp = NULL;
  	unsigned short port;
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
2605
  	struct smack_known *object;
c67394434   Casey Schaufler   Smack: Local IPv6...
2606
2607
  
  	if (act == SMK_RECEIVING) {
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
2608
  		skp = smack_ipv6host_label(address);
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
2609
  		object = ssp->smk_in;
c67394434   Casey Schaufler   Smack: Local IPv6...
2610
  	} else {
2f823ff8b   Casey Schaufler   Smack: Improve ac...
2611
  		skp = ssp->smk_out;
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
2612
  		object = smack_ipv6host_label(address);
c67394434   Casey Schaufler   Smack: Local IPv6...
2613
2614
2615
  	}
  
  	/*
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
2616
  	 * The other end is a single label host.
c67394434   Casey Schaufler   Smack: Local IPv6...
2617
  	 */
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
2618
2619
2620
2621
2622
2623
  	if (skp != NULL && object != NULL)
  		return smk_ipv6_check(skp, object, address, act);
  	if (skp == NULL)
  		skp = smack_net_ambient;
  	if (object == NULL)
  		object = smack_net_ambient;
c67394434   Casey Schaufler   Smack: Local IPv6...
2624
2625
2626
2627
  
  	/*
  	 * It's remote, so port lookup does no good.
  	 */
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
2628
2629
  	if (!smk_ipv6_localhost(address))
  		return smk_ipv6_check(skp, object, address, act);
c67394434   Casey Schaufler   Smack: Local IPv6...
2630
2631
2632
2633
  
  	/*
  	 * It's local so the send check has to have passed.
  	 */
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
2634
2635
  	if (act == SMK_RECEIVING)
  		return 0;
c67394434   Casey Schaufler   Smack: Local IPv6...
2636

21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
2637
  	port = ntohs(address->sin6_port);
3c7ce3427   Vishal Goel   SMACK: Add the rc...
2638
2639
  	rcu_read_lock();
  	list_for_each_entry_rcu(spp, &smk_ipv6_port_list, list) {
9d44c9738   Vishal Goel   Smack: Fix the is...
2640
  		if (spp->smk_port != port || spp->smk_sock_type != sk->sk_type)
c67394434   Casey Schaufler   Smack: Local IPv6...
2641
  			continue;
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
2642
  		object = spp->smk_in;
c67394434   Casey Schaufler   Smack: Local IPv6...
2643
  		if (act == SMK_CONNECTING)
54e70ec5e   Casey Schaufler   Smack: bidirectio...
2644
  			ssp->smk_packet = spp->smk_out;
c67394434   Casey Schaufler   Smack: Local IPv6...
2645
2646
  		break;
  	}
3c7ce3427   Vishal Goel   SMACK: Add the rc...
2647
  	rcu_read_unlock();
c67394434   Casey Schaufler   Smack: Local IPv6...
2648

21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
2649
  	return smk_ipv6_check(skp, object, address, act);
c67394434   Casey Schaufler   Smack: Local IPv6...
2650
  }
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
2651
  #endif /* SMACK_IPV6_PORT_LABELING */
c67394434   Casey Schaufler   Smack: Local IPv6...
2652
2653
  
  /**
e114e4737   Casey Schaufler   Smack: Simplified...
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
   * 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)
  {
2f823ff8b   Casey Schaufler   Smack: Improve ac...
2668
  	struct smack_known *skp;
e114e4737   Casey Schaufler   Smack: Simplified...
2669
2670
2671
  	struct inode_smack *nsp = inode->i_security;
  	struct socket_smack *ssp;
  	struct socket *sock;
4bc87e627   Casey Schaufler   Smack: unlabeled ...
2672
  	int rc = 0;
e114e4737   Casey Schaufler   Smack: Simplified...
2673

f7112e6c9   Casey Schaufler   Smack: allow for ...
2674
  	if (value == NULL || size > SMK_LONGLABEL || size == 0)
5e9ab593c   Pankaj Kumar   bugfix patch for ...
2675
  		return -EINVAL;
e114e4737   Casey Schaufler   Smack: Simplified...
2676

2f823ff8b   Casey Schaufler   Smack: Improve ac...
2677
  	skp = smk_import_entry(value, size);
e774ad683   Lukasz Pawelczyk   smack: pass error...
2678
2679
  	if (IS_ERR(skp))
  		return PTR_ERR(skp);
e114e4737   Casey Schaufler   Smack: Simplified...
2680
2681
  
  	if (strcmp(name, XATTR_SMACK_SUFFIX) == 0) {
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
2682
  		nsp->smk_inode = skp;
ddd29ec65   David P. Quigley   sysfs: Add labeli...
2683
  		nsp->smk_flags |= SMK_INODE_INSTANT;
e114e4737   Casey Schaufler   Smack: Simplified...
2684
2685
2686
2687
2688
2689
2690
2691
2692
  		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 ...
2693
  	if (sock == NULL || sock->sk == NULL)
e114e4737   Casey Schaufler   Smack: Simplified...
2694
2695
2696
2697
2698
  		return -EOPNOTSUPP;
  
  	ssp = sock->sk->sk_security;
  
  	if (strcmp(name, XATTR_SMACK_IPIN) == 0)
54e70ec5e   Casey Schaufler   Smack: bidirectio...
2699
  		ssp->smk_in = skp;
e114e4737   Casey Schaufler   Smack: Simplified...
2700
  	else if (strcmp(name, XATTR_SMACK_IPOUT) == 0) {
2f823ff8b   Casey Schaufler   Smack: Improve ac...
2701
  		ssp->smk_out = skp;
c67394434   Casey Schaufler   Smack: Local IPv6...
2702
  		if (sock->sk->sk_family == PF_INET) {
b4e0d5f07   Casey Schaufler   Smack: UDS revision
2703
2704
2705
2706
2707
2708
2709
  			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...
2710
2711
  	} else
  		return -EOPNOTSUPP;
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
2712
  #ifdef SMACK_IPV6_PORT_LABELING
c67394434   Casey Schaufler   Smack: Local IPv6...
2713
2714
  	if (sock->sk->sk_family == PF_INET6)
  		smk_ipv6_port_label(sock, NULL);
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
2715
  #endif
c67394434   Casey Schaufler   Smack: Local IPv6...
2716

e114e4737   Casey Schaufler   Smack: Simplified...
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
  	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)
  {
7412301b7   Marcin Lis   Smack: Assign sma...
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
  	struct socket_smack *ssp;
  
  	if (sock->sk == NULL)
  		return 0;
  
  	/*
  	 * Sockets created by kernel threads receive web label.
  	 */
  	if (unlikely(current->flags & PF_KTHREAD)) {
  		ssp = sock->sk->sk_security;
  		ssp->smk_in = &smack_known_web;
  		ssp->smk_out = &smack_known_web;
  	}
  
  	if (family != PF_INET)
e114e4737   Casey Schaufler   Smack: Simplified...
2750
2751
2752
2753
  		return 0;
  	/*
  	 * Set the outbound netlbl.
  	 */
6d3dc07cb   Casey Schaufler   smack: Add suppor...
2754
2755
  	return smack_netlabel(sock->sk, SMACK_CIPSO_SOCKET);
  }
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
2756
  #ifdef SMACK_IPV6_PORT_LABELING
6d3dc07cb   Casey Schaufler   smack: Add suppor...
2757
  /**
c67394434   Casey Schaufler   Smack: Local IPv6...
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
   * smack_socket_bind - record port binding information.
   * @sock: the socket
   * @address: the port address
   * @addrlen: size of the address
   *
   * Records the label bound to a port.
   *
   * Returns 0
   */
  static int smack_socket_bind(struct socket *sock, struct sockaddr *address,
  				int addrlen)
  {
  	if (sock->sk != NULL && sock->sk->sk_family == PF_INET6)
  		smk_ipv6_port_label(sock, address);
c67394434   Casey Schaufler   Smack: Local IPv6...
2772
2773
  	return 0;
  }
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
2774
  #endif /* SMACK_IPV6_PORT_LABELING */
c67394434   Casey Schaufler   Smack: Local IPv6...
2775
2776
  
  /**
6d3dc07cb   Casey Schaufler   smack: Add suppor...
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
   * 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)
  {
c67394434   Casey Schaufler   Smack: Local IPv6...
2789
  	int rc = 0;
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
2790
2791
2792
2793
2794
2795
2796
  #if IS_ENABLED(CONFIG_IPV6)
  	struct sockaddr_in6 *sip = (struct sockaddr_in6 *)sap;
  #endif
  #ifdef SMACK_IPV6_SECMARK_LABELING
  	struct smack_known *rsp;
  	struct socket_smack *ssp = sock->sk->sk_security;
  #endif
c67394434   Casey Schaufler   Smack: Local IPv6...
2797
2798
  
  	if (sock->sk == NULL)
6d3dc07cb   Casey Schaufler   smack: Add suppor...
2799
  		return 0;
6d3dc07cb   Casey Schaufler   smack: Add suppor...
2800

c67394434   Casey Schaufler   Smack: Local IPv6...
2801
2802
2803
2804
2805
2806
2807
2808
2809
  	switch (sock->sk->sk_family) {
  	case PF_INET:
  		if (addrlen < sizeof(struct sockaddr_in))
  			return -EINVAL;
  		rc = smack_netlabel_send(sock->sk, (struct sockaddr_in *)sap);
  		break;
  	case PF_INET6:
  		if (addrlen < sizeof(struct sockaddr_in6))
  			return -EINVAL;
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
2810
2811
2812
2813
  #ifdef SMACK_IPV6_SECMARK_LABELING
  		rsp = smack_ipv6host_label(sip);
  		if (rsp != NULL)
  			rc = smk_ipv6_check(ssp->smk_out, rsp, sip,
6ea062475   Casey Schaufler   Smack: IPv6 casti...
2814
  						SMK_CONNECTING);
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
2815
2816
2817
2818
  #endif
  #ifdef SMACK_IPV6_PORT_LABELING
  		rc = smk_ipv6_port_check(sock->sk, sip, SMK_CONNECTING);
  #endif
c67394434   Casey Schaufler   Smack: Local IPv6...
2819
2820
2821
  		break;
  	}
  	return rc;
e114e4737   Casey Schaufler   Smack: Simplified...
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
  }
  
  /**
   * 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)
  {
2f823ff8b   Casey Schaufler   Smack: Improve ac...
2852
  	struct smack_known *skp = smk_of_current();
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
2853
  	msg->security = skp;
e114e4737   Casey Schaufler   Smack: Simplified...
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
  	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
   */
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
2874
  static struct smack_known *smack_of_shm(struct shmid_kernel *shp)
e114e4737   Casey Schaufler   Smack: Simplified...
2875
  {
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
2876
  	return (struct smack_known *)shp->shm_perm.security;
e114e4737   Casey Schaufler   Smack: Simplified...
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
  }
  
  /**
   * 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;
2f823ff8b   Casey Schaufler   Smack: Improve ac...
2888
  	struct smack_known *skp = smk_of_current();
e114e4737   Casey Schaufler   Smack: Simplified...
2889

21c7eae21   Lukasz Pawelczyk   Make Smack operat...
2890
  	isp->security = skp;
e114e4737   Casey Schaufler   Smack: Simplified...
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
  	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 ...
2908
2909
2910
2911
2912
2913
2914
2915
   * 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)
  {
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
2916
  	struct smack_known *ssp = smack_of_shm(shp);
ecfcc53fe   Etienne Basset   smack: implement ...
2917
  	struct smk_audit_info ad;
d166c8024   Casey Schaufler   Smack: Bring-up a...
2918
  	int rc;
ecfcc53fe   Etienne Basset   smack: implement ...
2919
2920
2921
2922
2923
  
  #ifdef CONFIG_AUDIT
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_IPC);
  	ad.a.u.ipc_id = shp->shm_perm.id;
  #endif
d166c8024   Casey Schaufler   Smack: Bring-up a...
2924
2925
2926
  	rc = smk_curacc(ssp, access, &ad);
  	rc = smk_bu_current("shm", ssp, access, rc);
  	return rc;
ecfcc53fe   Etienne Basset   smack: implement ...
2927
2928
2929
  }
  
  /**
e114e4737   Casey Schaufler   Smack: Simplified...
2930
2931
2932
2933
2934
2935
2936
2937
   * 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...
2938
2939
2940
  	int may;
  
  	may = smack_flags_to_may(shmflg);
ecfcc53fe   Etienne Basset   smack: implement ...
2941
  	return smk_curacc_shm(shp, may);
e114e4737   Casey Schaufler   Smack: Simplified...
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
  }
  
  /**
   * 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...
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
  	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 ...
2975
  	return smk_curacc_shm(shp, may);
e114e4737   Casey Schaufler   Smack: Simplified...
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
  }
  
  /**
   * 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...
2989
2990
2991
  	int may;
  
  	may = smack_flags_to_may(shmflg);
ecfcc53fe   Etienne Basset   smack: implement ...
2992
  	return smk_curacc_shm(shp, may);
e114e4737   Casey Schaufler   Smack: Simplified...
2993
2994
2995
2996
2997
2998
2999
3000
  }
  
  /**
   * smack_of_sem - the smack pointer for the sem
   * @sma: the object
   *
   * Returns a pointer to the smack value
   */
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
3001
  static struct smack_known *smack_of_sem(struct sem_array *sma)
e114e4737   Casey Schaufler   Smack: Simplified...
3002
  {
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
3003
  	return (struct smack_known *)sma->sem_perm.security;
e114e4737   Casey Schaufler   Smack: Simplified...
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
  }
  
  /**
   * 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;
2f823ff8b   Casey Schaufler   Smack: Improve ac...
3015
  	struct smack_known *skp = smk_of_current();
e114e4737   Casey Schaufler   Smack: Simplified...
3016

21c7eae21   Lukasz Pawelczyk   Make Smack operat...
3017
  	isp->security = skp;
e114e4737   Casey Schaufler   Smack: Simplified...
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
  	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 ...
3035
3036
3037
3038
3039
3040
3041
3042
   * 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)
  {
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
3043
  	struct smack_known *ssp = smack_of_sem(sma);
ecfcc53fe   Etienne Basset   smack: implement ...
3044
  	struct smk_audit_info ad;
d166c8024   Casey Schaufler   Smack: Bring-up a...
3045
  	int rc;
ecfcc53fe   Etienne Basset   smack: implement ...
3046
3047
3048
3049
3050
  
  #ifdef CONFIG_AUDIT
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_IPC);
  	ad.a.u.ipc_id = sma->sem_perm.id;
  #endif
d166c8024   Casey Schaufler   Smack: Bring-up a...
3051
3052
3053
  	rc = smk_curacc(ssp, access, &ad);
  	rc = smk_bu_current("sem", ssp, access, rc);
  	return rc;
ecfcc53fe   Etienne Basset   smack: implement ...
3054
3055
3056
  }
  
  /**
e114e4737   Casey Schaufler   Smack: Simplified...
3057
3058
3059
3060
3061
3062
3063
3064
   * 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...
3065
3066
3067
  	int may;
  
  	may = smack_flags_to_may(semflg);
ecfcc53fe   Etienne Basset   smack: implement ...
3068
  	return smk_curacc_sem(sma, may);
e114e4737   Casey Schaufler   Smack: Simplified...
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
  }
  
  /**
   * 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...
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
  	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 ...
3107
  	return smk_curacc_sem(sma, may);
e114e4737   Casey Schaufler   Smack: Simplified...
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
  }
  
  /**
   * 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 ...
3124
  	return smk_curacc_sem(sma, MAY_READWRITE);
e114e4737   Casey Schaufler   Smack: Simplified...
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
  }
  
  /**
   * 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;
2f823ff8b   Casey Schaufler   Smack: Improve ac...
3136
  	struct smack_known *skp = smk_of_current();
e114e4737   Casey Schaufler   Smack: Simplified...
3137

21c7eae21   Lukasz Pawelczyk   Make Smack operat...
3138
  	kisp->security = skp;
e114e4737   Casey Schaufler   Smack: Simplified...
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
  	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
   *
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
3159
   * Returns a pointer to the smack label entry
e114e4737   Casey Schaufler   Smack: Simplified...
3160
   */
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
3161
  static struct smack_known *smack_of_msq(struct msg_queue *msq)
e114e4737   Casey Schaufler   Smack: Simplified...
3162
  {
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
3163
  	return (struct smack_known *)msq->q_perm.security;
e114e4737   Casey Schaufler   Smack: Simplified...
3164
3165
3166
  }
  
  /**
ecfcc53fe   Etienne Basset   smack: implement ...
3167
3168
3169
3170
3171
3172
3173
3174
   * 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)
  {
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
3175
  	struct smack_known *msp = smack_of_msq(msq);
ecfcc53fe   Etienne Basset   smack: implement ...
3176
  	struct smk_audit_info ad;
d166c8024   Casey Schaufler   Smack: Bring-up a...
3177
  	int rc;
ecfcc53fe   Etienne Basset   smack: implement ...
3178
3179
3180
3181
3182
  
  #ifdef CONFIG_AUDIT
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_IPC);
  	ad.a.u.ipc_id = msq->q_perm.id;
  #endif
d166c8024   Casey Schaufler   Smack: Bring-up a...
3183
3184
3185
  	rc = smk_curacc(msp, access, &ad);
  	rc = smk_bu_current("msq", msp, access, rc);
  	return rc;
ecfcc53fe   Etienne Basset   smack: implement ...
3186
3187
3188
  }
  
  /**
e114e4737   Casey Schaufler   Smack: Simplified...
3189
3190
3191
3192
3193
3194
3195
3196
   * 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...
3197
3198
3199
  	int may;
  
  	may = smack_flags_to_may(msqflg);
ecfcc53fe   Etienne Basset   smack: implement ...
3200
  	return smk_curacc_msq(msq, may);
e114e4737   Casey Schaufler   Smack: Simplified...
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
  }
  
  /**
   * 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...
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
  	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 ...
3232
  	return smk_curacc_msq(msq, may);
e114e4737   Casey Schaufler   Smack: Simplified...
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
  }
  
  /**
   * 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 ...
3246
  	int may;
e114e4737   Casey Schaufler   Smack: Simplified...
3247

ecfcc53fe   Etienne Basset   smack: implement ...
3248
3249
  	may = smack_flags_to_may(msqflg);
  	return smk_curacc_msq(msq, may);
e114e4737   Casey Schaufler   Smack: Simplified...
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
  }
  
  /**
   * 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 ...
3265
  	return smk_curacc_msq(msq, MAY_READWRITE);
e114e4737   Casey Schaufler   Smack: Simplified...
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
  }
  
  /**
   * 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)
  {
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
3277
  	struct smack_known *iskp = ipp->security;
ecfcc53fe   Etienne Basset   smack: implement ...
3278
3279
  	int may = smack_flags_to_may(flag);
  	struct smk_audit_info ad;
d166c8024   Casey Schaufler   Smack: Bring-up a...
3280
  	int rc;
e114e4737   Casey Schaufler   Smack: Simplified...
3281

ecfcc53fe   Etienne Basset   smack: implement ...
3282
3283
3284
3285
  #ifdef CONFIG_AUDIT
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_IPC);
  	ad.a.u.ipc_id = ipp->id;
  #endif
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
3286
3287
  	rc = smk_curacc(iskp, may, &ad);
  	rc = smk_bu_current("svipc", iskp, may, rc);
d166c8024   Casey Schaufler   Smack: Bring-up a...
3288
  	return rc;
e114e4737   Casey Schaufler   Smack: Simplified...
3289
  }
d20bdda6d   Ahmed S. Darwish   Smack: Integrate ...
3290
3291
  /**
   * smack_ipc_getsecid - Extract smack security id
251a2a958   Randy Dunlap   smack: fix lots o...
3292
   * @ipp: the object permissions
d20bdda6d   Ahmed S. Darwish   Smack: Integrate ...
3293
3294
3295
3296
   * @secid: where result will be saved
   */
  static void smack_ipc_getsecid(struct kern_ipc_perm *ipp, u32 *secid)
  {
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
3297
  	struct smack_known *iskp = ipp->security;
d20bdda6d   Ahmed S. Darwish   Smack: Integrate ...
3298

21c7eae21   Lukasz Pawelczyk   Make Smack operat...
3299
  	*secid = iskp->smk_secid;
d20bdda6d   Ahmed S. Darwish   Smack: Integrate ...
3300
  }
e114e4737   Casey Schaufler   Smack: Simplified...
3301
3302
  /**
   * smack_d_instantiate - Make sure the blob is correct on an inode
3e62cbb84   Dan Carpenter   smack: opt_dentry...
3303
   * @opt_dentry: dentry where inode will be attached
e114e4737   Casey Schaufler   Smack: Simplified...
3304
3305
3306
3307
3308
3309
3310
3311
3312
   * @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;
2f823ff8b   Casey Schaufler   Smack: Improve ac...
3313
3314
  	struct smack_known *skp;
  	struct smack_known *ckp = smk_of_current();
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
3315
  	struct smack_known *final;
5c6d1125f   Jarkko Sakkinen   Smack: Transmute ...
3316
3317
  	char trattr[TRANS_TRUE_SIZE];
  	int transflag = 0;
2267b13a7   Casey Schaufler   Smack: recursive ...
3318
  	int rc;
e114e4737   Casey Schaufler   Smack: Simplified...
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
  	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...
3343
3344
3345
3346
3347
3348
  	 * 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) {
1d8c2326a   Łukasz Stelmach   smack: introduce ...
3349
3350
  		switch (sbp->s_magic) {
  		case CGROUP_SUPER_MAGIC:
36ea735b5   Casey Schaufler   Smack: Label cgro...
3351
3352
3353
3354
3355
  			/*
  			 * The cgroup filesystem is never mounted,
  			 * so there's no opportunity to set the mount
  			 * options.
  			 */
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
3356
3357
  			sbsp->smk_root = &smack_known_star;
  			sbsp->smk_default = &smack_known_star;
1d8c2326a   Łukasz Stelmach   smack: introduce ...
3358
3359
3360
3361
3362
3363
3364
3365
3366
  			isp->smk_inode = sbsp->smk_root;
  			break;
  		case TMPFS_MAGIC:
  			/*
  			 * What about shmem/tmpfs anonymous files with dentry
  			 * obtained from d_alloc_pseudo()?
  			 */
  			isp->smk_inode = smk_of_current();
  			break;
8da4aba5b   Roman Kubiak   Smack: pipefs fix...
3367
3368
3369
  		case PIPEFS_MAGIC:
  			isp->smk_inode = smk_of_current();
  			break;
805b65a80   Rafal Krypa   Smack: fix d_inst...
3370
3371
3372
3373
3374
3375
3376
  		case SOCKFS_MAGIC:
  			/*
  			 * Socket access is controlled by the socket
  			 * structures associated with the task involved.
  			 */
  			isp->smk_inode = &smack_known_star;
  			break;
1d8c2326a   Łukasz Stelmach   smack: introduce ...
3377
3378
3379
  		default:
  			isp->smk_inode = sbsp->smk_root;
  			break;
36ea735b5   Casey Schaufler   Smack: Label cgro...
3380
  		}
e97dcb0ea   Casey Schaufler   Smack: fuse mount...
3381
3382
3383
3384
3385
  		isp->smk_flags |= SMK_INODE_INSTANT;
  		goto unlockandout;
  	}
  
  	/*
e114e4737   Casey Schaufler   Smack: Simplified...
3386
3387
3388
3389
3390
3391
3392
  	 * 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:
36ea735b5   Casey Schaufler   Smack: Label cgro...
3393
  	case CGROUP_SUPER_MAGIC:
e114e4737   Casey Schaufler   Smack: Simplified...
3394
  		/*
25985edce   Lucas De Marchi   Fix common misspe...
3395
  		 * Casey says that it's a little embarrassing
e114e4737   Casey Schaufler   Smack: Simplified...
3396
3397
  		 * that the smack file system doesn't do
  		 * extended attributes.
36ea735b5   Casey Schaufler   Smack: Label cgro...
3398
  		 *
36ea735b5   Casey Schaufler   Smack: Label cgro...
3399
  		 * Cgroupfs is special
e114e4737   Casey Schaufler   Smack: Simplified...
3400
  		 */
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
3401
  		final = &smack_known_star;
e114e4737   Casey Schaufler   Smack: Simplified...
3402
3403
3404
3405
3406
3407
3408
  		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.
  		 */
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
3409
  		final = ckp;
e114e4737   Casey Schaufler   Smack: Simplified...
3410
  		break;
e114e4737   Casey Schaufler   Smack: Simplified...
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
  	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.
  		 */
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
3423
  		final = &smack_known_star;
e114e4737   Casey Schaufler   Smack: Simplified...
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
  		/*
  		 * 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
3436
3437
3438
3439
3440
3441
  		 */
  
  		/*
  		 * UNIX domain sockets use lower level socket data.
  		 */
  		if (S_ISSOCK(inode->i_mode)) {
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
3442
  			final = &smack_known_star;
b4e0d5f07   Casey Schaufler   Smack: UDS revision
3443
3444
3445
  			break;
  		}
  		/*
e114e4737   Casey Schaufler   Smack: Simplified...
3446
3447
3448
3449
3450
  		 * 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.
  		 */
5d6c31910   Andreas Gruenbacher   xattr: Add __vfs_...
3451
3452
  		if (!(inode->i_opflags & IOP_XATTR))
  		        break;
e114e4737   Casey Schaufler   Smack: Simplified...
3453
3454
3455
  		/*
  		 * Get the dentry for xattr.
  		 */
3e62cbb84   Dan Carpenter   smack: opt_dentry...
3456
  		dp = dget(opt_dentry);
2f823ff8b   Casey Schaufler   Smack: Improve ac...
3457
  		skp = smk_fetch(XATTR_NAME_SMACK, inode, dp);
e774ad683   Lukasz Pawelczyk   smack: pass error...
3458
  		if (!IS_ERR_OR_NULL(skp))
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
3459
  			final = skp;
2267b13a7   Casey Schaufler   Smack: recursive ...
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
  
  		/*
  		 * Transmuting directory
  		 */
  		if (S_ISDIR(inode->i_mode)) {
  			/*
  			 * If this is a new directory and the label was
  			 * transmuted when the inode was initialized
  			 * set the transmute attribute on the directory
  			 * and mark the inode.
  			 *
  			 * If there is a transmute attribute on the
  			 * directory mark the inode.
  			 */
  			if (isp->smk_flags & SMK_INODE_CHANGED) {
  				isp->smk_flags &= ~SMK_INODE_CHANGED;
5d6c31910   Andreas Gruenbacher   xattr: Add __vfs_...
3476
  				rc = __vfs_setxattr(dp, inode,
5c6d1125f   Jarkko Sakkinen   Smack: Transmute ...
3477
  					XATTR_NAME_SMACKTRANSMUTE,
2267b13a7   Casey Schaufler   Smack: recursive ...
3478
3479
3480
  					TRANS_TRUE, TRANS_TRUE_SIZE,
  					0);
  			} else {
5d6c31910   Andreas Gruenbacher   xattr: Add __vfs_...
3481
  				rc = __vfs_getxattr(dp, inode,
2267b13a7   Casey Schaufler   Smack: recursive ...
3482
3483
3484
3485
3486
  					XATTR_NAME_SMACKTRANSMUTE, trattr,
  					TRANS_TRUE_SIZE);
  				if (rc >= 0 && strncmp(trattr, TRANS_TRUE,
  						       TRANS_TRUE_SIZE) != 0)
  					rc = -EINVAL;
5c6d1125f   Jarkko Sakkinen   Smack: Transmute ...
3487
  			}
2267b13a7   Casey Schaufler   Smack: recursive ...
3488
3489
  			if (rc >= 0)
  				transflag = SMK_INODE_TRANSMUTE;
5c6d1125f   Jarkko Sakkinen   Smack: Transmute ...
3490
  		}
809c02e09   Seth Forshee   Smack: Handle lab...
3491
3492
3493
3494
3495
3496
3497
3498
  		/*
  		 * Don't let the exec or mmap label be "*" or "@".
  		 */
  		skp = smk_fetch(XATTR_NAME_SMACKEXEC, inode, dp);
  		if (IS_ERR(skp) || skp == &smack_known_star ||
  		    skp == &smack_known_web)
  			skp = NULL;
  		isp->smk_task = skp;
e774ad683   Lukasz Pawelczyk   smack: pass error...
3499

19760ad03   Casey Schaufler   Smack: Prevent th...
3500
  		skp = smk_fetch(XATTR_NAME_SMACKMMAP, inode, dp);
e774ad683   Lukasz Pawelczyk   smack: pass error...
3501
3502
  		if (IS_ERR(skp) || skp == &smack_known_star ||
  		    skp == &smack_known_web)
19760ad03   Casey Schaufler   Smack: Prevent th...
3503
3504
  			skp = NULL;
  		isp->smk_mmap = skp;
676dac4b1   Casey Schaufler   This patch adds a...
3505

e114e4737   Casey Schaufler   Smack: Simplified...
3506
3507
3508
3509
3510
  		dput(dp);
  		break;
  	}
  
  	if (final == NULL)
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
3511
  		isp->smk_inode = ckp;
e114e4737   Casey Schaufler   Smack: Simplified...
3512
3513
  	else
  		isp->smk_inode = final;
5c6d1125f   Jarkko Sakkinen   Smack: Transmute ...
3514
  	isp->smk_flags |= (SMK_INODE_INSTANT | transflag);
e114e4737   Casey Schaufler   Smack: Simplified...
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
  
  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)
  {
6d1cff2a8   Andrey Ryabinin   smack: fix possib...
3533
  	struct smack_known *skp = smk_of_task_struct(p);
e114e4737   Casey Schaufler   Smack: Simplified...
3534
3535
3536
3537
3538
  	char *cp;
  	int slen;
  
  	if (strcmp(name, "current") != 0)
  		return -EINVAL;
2f823ff8b   Casey Schaufler   Smack: Improve ac...
3539
  	cp = kstrdup(skp->smk_known, GFP_KERNEL);
e114e4737   Casey Schaufler   Smack: Simplified...
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
  	if (cp == NULL)
  		return -ENOMEM;
  
  	slen = strlen(cp);
  	*value = cp;
  	return slen;
  }
  
  /**
   * smack_setprocattr - Smack process attribute setting
e114e4737   Casey Schaufler   Smack: Simplified...
3550
3551
3552
3553
3554
3555
3556
3557
3558
   * @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
   */
b21507e27   Stephen Smalley   proc,security: mo...
3559
  static int smack_setprocattr(const char *name, void *value, size_t size)
e114e4737   Casey Schaufler   Smack: Simplified...
3560
  {
38416e539   Zbigniew Jasinski   Smack: limited ca...
3561
  	struct task_smack *tsp = current_security();
d84f4f992   David Howells   CRED: Inaugurate ...
3562
  	struct cred *new;
2f823ff8b   Casey Schaufler   Smack: Improve ac...
3563
  	struct smack_known *skp;
38416e539   Zbigniew Jasinski   Smack: limited ca...
3564
3565
  	struct smack_known_list_elem *sklep;
  	int rc;
e114e4737   Casey Schaufler   Smack: Simplified...
3566

38416e539   Zbigniew Jasinski   Smack: limited ca...
3567
  	if (!smack_privileged(CAP_MAC_ADMIN) && list_empty(&tsp->smk_relabel))
5cd9c58fb   David Howells   security: Fix set...
3568
  		return -EPERM;
f7112e6c9   Casey Schaufler   Smack: allow for ...
3569
  	if (value == NULL || size == 0 || size >= SMK_LONGLABEL)
e114e4737   Casey Schaufler   Smack: Simplified...
3570
3571
3572
3573
  		return -EINVAL;
  
  	if (strcmp(name, "current") != 0)
  		return -EINVAL;
2f823ff8b   Casey Schaufler   Smack: Improve ac...
3574
  	skp = smk_import_entry(value, size);
e774ad683   Lukasz Pawelczyk   smack: pass error...
3575
3576
  	if (IS_ERR(skp))
  		return PTR_ERR(skp);
e114e4737   Casey Schaufler   Smack: Simplified...
3577

6d3dc07cb   Casey Schaufler   smack: Add suppor...
3578
  	/*
7128ea159   Himanshu Shukla   SMACK: Do not app...
3579
3580
  	 * No process is ever allowed the web ("@") label
  	 * and the star ("*") label.
6d3dc07cb   Casey Schaufler   smack: Add suppor...
3581
  	 */
7128ea159   Himanshu Shukla   SMACK: Do not app...
3582
3583
  	if (skp == &smack_known_web || skp == &smack_known_star)
  		return -EINVAL;
6d3dc07cb   Casey Schaufler   smack: Add suppor...
3584

38416e539   Zbigniew Jasinski   Smack: limited ca...
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
  	if (!smack_privileged(CAP_MAC_ADMIN)) {
  		rc = -EPERM;
  		list_for_each_entry(sklep, &tsp->smk_relabel, list)
  			if (sklep->smk_label == skp) {
  				rc = 0;
  				break;
  			}
  		if (rc)
  			return rc;
  	}
d84f4f992   David Howells   CRED: Inaugurate ...
3595
  	new = prepare_creds();
6d3dc07cb   Casey Schaufler   smack: Add suppor...
3596
  	if (new == NULL)
d84f4f992   David Howells   CRED: Inaugurate ...
3597
  		return -ENOMEM;
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
3598

46a2f3b9e   Casey Schaufler   Smack: setprocatt...
3599
  	tsp = new->security;
2f823ff8b   Casey Schaufler   Smack: Improve ac...
3600
  	tsp->smk_task = skp;
38416e539   Zbigniew Jasinski   Smack: limited ca...
3601
3602
3603
3604
  	/*
  	 * process can change its label only once
  	 */
  	smk_destroy_label_list(&tsp->smk_relabel);
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
3605

d84f4f992   David Howells   CRED: Inaugurate ...
3606
  	commit_creds(new);
e114e4737   Casey Schaufler   Smack: Simplified...
3607
3608
3609
3610
3611
  	return size;
  }
  
  /**
   * smack_unix_stream_connect - Smack access on UDS
3610cda53   David S. Miller   af_unix: Avoid so...
3612
3613
   * @sock: one sock
   * @other: the other sock
e114e4737   Casey Schaufler   Smack: Simplified...
3614
3615
3616
3617
3618
   * @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...
3619
3620
  static int smack_unix_stream_connect(struct sock *sock,
  				     struct sock *other, struct sock *newsk)
e114e4737   Casey Schaufler   Smack: Simplified...
3621
  {
2f823ff8b   Casey Schaufler   Smack: Improve ac...
3622
  	struct smack_known *skp;
54e70ec5e   Casey Schaufler   Smack: bidirectio...
3623
  	struct smack_known *okp;
d2e7ad192   James Morris   Merge branch 'mas...
3624
3625
  	struct socket_smack *ssp = sock->sk_security;
  	struct socket_smack *osp = other->sk_security;
975d5e55c   Casey Schaufler   Smack: Provide in...
3626
  	struct socket_smack *nsp = newsk->sk_security;
ecfcc53fe   Etienne Basset   smack: implement ...
3627
  	struct smk_audit_info ad;
b4e0d5f07   Casey Schaufler   Smack: UDS revision
3628
  	int rc = 0;
923e9a139   Kees Cook   Smack: build when...
3629
3630
  #ifdef CONFIG_AUDIT
  	struct lsm_network_audit net;
923e9a139   Kees Cook   Smack: build when...
3631
  #endif
b4e0d5f07   Casey Schaufler   Smack: UDS revision
3632

2f823ff8b   Casey Schaufler   Smack: Improve ac...
3633
3634
  	if (!smack_privileged(CAP_MAC_OVERRIDE)) {
  		skp = ssp->smk_out;
96be7b542   Zbigniew Jasinski   smack: Fix a bidi...
3635
  		okp = osp->smk_in;
54e70ec5e   Casey Schaufler   Smack: bidirectio...
3636
3637
3638
3639
  #ifdef CONFIG_AUDIT
  		smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net);
  		smk_ad_setfield_u_net_sk(&ad, other);
  #endif
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
3640
3641
  		rc = smk_access(skp, okp, MAY_WRITE, &ad);
  		rc = smk_bu_note("UDS connect", skp, okp, MAY_WRITE, rc);
d166c8024   Casey Schaufler   Smack: Bring-up a...
3642
  		if (rc == 0) {
96be7b542   Zbigniew Jasinski   smack: Fix a bidi...
3643
3644
  			okp = osp->smk_out;
  			skp = ssp->smk_in;
138a868f0   Rafal Krypa   smack: Add missin...
3645
  			rc = smk_access(okp, skp, MAY_WRITE, &ad);
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
3646
  			rc = smk_bu_note("UDS connect", okp, skp,
d166c8024   Casey Schaufler   Smack: Bring-up a...
3647
3648
  						MAY_WRITE, rc);
  		}
2f823ff8b   Casey Schaufler   Smack: Improve ac...
3649
  	}
b4e0d5f07   Casey Schaufler   Smack: UDS revision
3650

975d5e55c   Casey Schaufler   Smack: Provide in...
3651
3652
3653
3654
  	/*
  	 * Cross reference the peer labels for SO_PEERSEC.
  	 */
  	if (rc == 0) {
54e70ec5e   Casey Schaufler   Smack: bidirectio...
3655
3656
  		nsp->smk_packet = ssp->smk_out;
  		ssp->smk_packet = osp->smk_out;
975d5e55c   Casey Schaufler   Smack: Provide in...
3657
  	}
b4e0d5f07   Casey Schaufler   Smack: UDS revision
3658
  	return rc;
e114e4737   Casey Schaufler   Smack: Simplified...
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
  }
  
  /**
   * 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
3671
3672
  	struct socket_smack *ssp = sock->sk->sk_security;
  	struct socket_smack *osp = other->sk->sk_security;
ecfcc53fe   Etienne Basset   smack: implement ...
3673
  	struct smk_audit_info ad;
d166c8024   Casey Schaufler   Smack: Bring-up a...
3674
  	int rc;
e114e4737   Casey Schaufler   Smack: Simplified...
3675

923e9a139   Kees Cook   Smack: build when...
3676
3677
  #ifdef CONFIG_AUDIT
  	struct lsm_network_audit net;
48c62af68   Eric Paris   LSM: shrink the c...
3678
  	smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net);
ecfcc53fe   Etienne Basset   smack: implement ...
3679
  	smk_ad_setfield_u_net_sk(&ad, other->sk);
923e9a139   Kees Cook   Smack: build when...
3680
  #endif
b4e0d5f07   Casey Schaufler   Smack: UDS revision
3681

2f823ff8b   Casey Schaufler   Smack: Improve ac...
3682
3683
  	if (smack_privileged(CAP_MAC_OVERRIDE))
  		return 0;
b4e0d5f07   Casey Schaufler   Smack: UDS revision
3684

21c7eae21   Lukasz Pawelczyk   Make Smack operat...
3685
3686
  	rc = smk_access(ssp->smk_out, osp->smk_in, MAY_WRITE, &ad);
  	rc = smk_bu_note("UDS send", ssp->smk_out, osp->smk_in, MAY_WRITE, rc);
d166c8024   Casey Schaufler   Smack: Bring-up a...
3687
  	return rc;
e114e4737   Casey Schaufler   Smack: Simplified...
3688
3689
3690
  }
  
  /**
6d3dc07cb   Casey Schaufler   smack: Add suppor...
3691
3692
   * smack_socket_sendmsg - Smack check based on destination host
   * @sock: the socket
251a2a958   Randy Dunlap   smack: fix lots o...
3693
   * @msg: the message
6d3dc07cb   Casey Schaufler   smack: Add suppor...
3694
3695
   * @size: the size of the message
   *
c67394434   Casey Schaufler   Smack: Local IPv6...
3696
3697
3698
   * Return 0 if the current subject can write to the destination host.
   * For IPv4 this is only a question if the destination is a single label host.
   * For IPv6 this is a check against the label of the port.
6d3dc07cb   Casey Schaufler   smack: Add suppor...
3699
3700
3701
3702
3703
   */
  static int smack_socket_sendmsg(struct socket *sock, struct msghdr *msg,
  				int size)
  {
  	struct sockaddr_in *sip = (struct sockaddr_in *) msg->msg_name;
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
3704
  #if IS_ENABLED(CONFIG_IPV6)
6ea062475   Casey Schaufler   Smack: IPv6 casti...
3705
  	struct sockaddr_in6 *sap = (struct sockaddr_in6 *) msg->msg_name;
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
3706
3707
3708
3709
3710
  #endif
  #ifdef SMACK_IPV6_SECMARK_LABELING
  	struct socket_smack *ssp = sock->sk->sk_security;
  	struct smack_known *rsp;
  #endif
c67394434   Casey Schaufler   Smack: Local IPv6...
3711
  	int rc = 0;
6d3dc07cb   Casey Schaufler   smack: Add suppor...
3712
3713
3714
3715
  
  	/*
  	 * Perfectly reasonable for this to be NULL
  	 */
c67394434   Casey Schaufler   Smack: Local IPv6...
3716
  	if (sip == NULL)
6d3dc07cb   Casey Schaufler   smack: Add suppor...
3717
  		return 0;
81bd0d562   Roman Kubiak   Smack: type confu...
3718
  	switch (sock->sk->sk_family) {
c67394434   Casey Schaufler   Smack: Local IPv6...
3719
3720
3721
3722
  	case AF_INET:
  		rc = smack_netlabel_send(sock->sk, sip);
  		break;
  	case AF_INET6:
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
3723
3724
3725
3726
3727
3728
3729
  #ifdef SMACK_IPV6_SECMARK_LABELING
  		rsp = smack_ipv6host_label(sap);
  		if (rsp != NULL)
  			rc = smk_ipv6_check(ssp->smk_out, rsp, sap,
  						SMK_CONNECTING);
  #endif
  #ifdef SMACK_IPV6_PORT_LABELING
c67394434   Casey Schaufler   Smack: Local IPv6...
3730
  		rc = smk_ipv6_port_check(sock->sk, sap, SMK_SENDING);
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
3731
  #endif
c67394434   Casey Schaufler   Smack: Local IPv6...
3732
3733
3734
  		break;
  	}
  	return rc;
6d3dc07cb   Casey Schaufler   smack: Add suppor...
3735
  }
6d3dc07cb   Casey Schaufler   smack: Add suppor...
3736
  /**
251a2a958   Randy Dunlap   smack: fix lots o...
3737
   * smack_from_secattr - Convert a netlabel attr.mls.lvl/attr.mls.cat pair to smack
e114e4737   Casey Schaufler   Smack: Simplified...
3738
   * @sap: netlabel secattr
272cd7a8c   Casey Schaufler   Smack: Rule list ...
3739
   * @ssp: socket security information
e114e4737   Casey Schaufler   Smack: Simplified...
3740
   *
2f823ff8b   Casey Schaufler   Smack: Improve ac...
3741
   * Returns a pointer to a Smack label entry found on the label list.
e114e4737   Casey Schaufler   Smack: Simplified...
3742
   */
2f823ff8b   Casey Schaufler   Smack: Improve ac...
3743
3744
  static struct smack_known *smack_from_secattr(struct netlbl_lsm_secattr *sap,
  						struct socket_smack *ssp)
e114e4737   Casey Schaufler   Smack: Simplified...
3745
  {
2f823ff8b   Casey Schaufler   Smack: Improve ac...
3746
  	struct smack_known *skp;
f7112e6c9   Casey Schaufler   Smack: allow for ...
3747
  	int found = 0;
677264e8f   Casey Schaufler   Smack: network la...
3748
3749
  	int acat;
  	int kcat;
e114e4737   Casey Schaufler   Smack: Simplified...
3750

6d3dc07cb   Casey Schaufler   smack: Add suppor...
3751
  	if ((sap->flags & NETLBL_SECATTR_MLS_LVL) != 0) {
e114e4737   Casey Schaufler   Smack: Simplified...
3752
  		/*
6d3dc07cb   Casey Schaufler   smack: Add suppor...
3753
  		 * Looks like a CIPSO packet.
e114e4737   Casey Schaufler   Smack: Simplified...
3754
3755
3756
  		 * If there are flags but no level netlabel isn't
  		 * behaving the way we expect it to.
  		 *
f7112e6c9   Casey Schaufler   Smack: allow for ...
3757
  		 * Look it up in the label table
e114e4737   Casey Schaufler   Smack: Simplified...
3758
3759
3760
3761
  		 * Without guidance regarding the smack value
  		 * for the packet fall back on the network
  		 * ambient value.
  		 */
f7112e6c9   Casey Schaufler   Smack: allow for ...
3762
  		rcu_read_lock();
348dc288d   Vishal Goel   Smack: Traverse t...
3763
  		list_for_each_entry_rcu(skp, &smack_known_list, list) {
2f823ff8b   Casey Schaufler   Smack: Improve ac...
3764
  			if (sap->attr.mls.lvl != skp->smk_netlabel.attr.mls.lvl)
f7112e6c9   Casey Schaufler   Smack: allow for ...
3765
  				continue;
677264e8f   Casey Schaufler   Smack: network la...
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
  			/*
  			 * Compare the catsets. Use the netlbl APIs.
  			 */
  			if ((sap->flags & NETLBL_SECATTR_MLS_CAT) == 0) {
  				if ((skp->smk_netlabel.flags &
  				     NETLBL_SECATTR_MLS_CAT) == 0)
  					found = 1;
  				break;
  			}
  			for (acat = -1, kcat = -1; acat == kcat; ) {
4fbe63d1c   Paul Moore   netlabel: shorter...
3776
3777
3778
  				acat = netlbl_catmap_walk(sap->attr.mls.cat,
  							  acat + 1);
  				kcat = netlbl_catmap_walk(
677264e8f   Casey Schaufler   Smack: network la...
3779
3780
3781
3782
3783
3784
3785
3786
3787
  					skp->smk_netlabel.attr.mls.cat,
  					kcat + 1);
  				if (acat < 0 || kcat < 0)
  					break;
  			}
  			if (acat == kcat) {
  				found = 1;
  				break;
  			}
6d3dc07cb   Casey Schaufler   smack: Add suppor...
3788
  		}
f7112e6c9   Casey Schaufler   Smack: allow for ...
3789
3790
3791
  		rcu_read_unlock();
  
  		if (found)
2f823ff8b   Casey Schaufler   Smack: Improve ac...
3792
  			return skp;
f7112e6c9   Casey Schaufler   Smack: allow for ...
3793

54e70ec5e   Casey Schaufler   Smack: bidirectio...
3794
  		if (ssp != NULL && ssp->smk_in == &smack_known_star)
2f823ff8b   Casey Schaufler   Smack: Improve ac...
3795
3796
  			return &smack_known_web;
  		return &smack_known_star;
e114e4737   Casey Schaufler   Smack: Simplified...
3797
  	}
152f91d4d   Casey Schaufler   Smack: Remove unn...
3798
  	if ((sap->flags & NETLBL_SECATTR_SECID) != 0)
6d3dc07cb   Casey Schaufler   smack: Add suppor...
3799
3800
3801
  		/*
  		 * Looks like a fallback, which gives us a secid.
  		 */
152f91d4d   Casey Schaufler   Smack: Remove unn...
3802
  		return smack_from_secid(sap->attr.secid);
e114e4737   Casey Schaufler   Smack: Simplified...
3803
  	/*
6d3dc07cb   Casey Schaufler   smack: Add suppor...
3804
3805
3806
  	 * Without guidance regarding the smack value
  	 * for the packet fall back on the network
  	 * ambient value.
e114e4737   Casey Schaufler   Smack: Simplified...
3807
  	 */
272cd7a8c   Casey Schaufler   Smack: Rule list ...
3808
  	return smack_net_ambient;
e114e4737   Casey Schaufler   Smack: Simplified...
3809
  }
69f287ae6   Casey Schaufler   Smack: secmark su...
3810
  #if IS_ENABLED(CONFIG_IPV6)
6ea062475   Casey Schaufler   Smack: IPv6 casti...
3811
  static int smk_skb_to_addr_ipv6(struct sk_buff *skb, struct sockaddr_in6 *sip)
c67394434   Casey Schaufler   Smack: Local IPv6...
3812
  {
c67394434   Casey Schaufler   Smack: Local IPv6...
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
  	u8 nexthdr;
  	int offset;
  	int proto = -EINVAL;
  	struct ipv6hdr _ipv6h;
  	struct ipv6hdr *ip6;
  	__be16 frag_off;
  	struct tcphdr _tcph, *th;
  	struct udphdr _udph, *uh;
  	struct dccp_hdr _dccph, *dh;
  
  	sip->sin6_port = 0;
  
  	offset = skb_network_offset(skb);
  	ip6 = skb_header_pointer(skb, offset, sizeof(_ipv6h), &_ipv6h);
  	if (ip6 == NULL)
  		return -EINVAL;
  	sip->sin6_addr = ip6->saddr;
  
  	nexthdr = ip6->nexthdr;
  	offset += sizeof(_ipv6h);
  	offset = ipv6_skip_exthdr(skb, offset, &nexthdr, &frag_off);
  	if (offset < 0)
  		return -EINVAL;
  
  	proto = nexthdr;
  	switch (proto) {
  	case IPPROTO_TCP:
  		th = skb_header_pointer(skb, offset, sizeof(_tcph), &_tcph);
  		if (th != NULL)
  			sip->sin6_port = th->source;
  		break;
  	case IPPROTO_UDP:
  		uh = skb_header_pointer(skb, offset, sizeof(_udph), &_udph);
  		if (uh != NULL)
  			sip->sin6_port = uh->source;
  		break;
  	case IPPROTO_DCCP:
  		dh = skb_header_pointer(skb, offset, sizeof(_dccph), &_dccph);
  		if (dh != NULL)
  			sip->sin6_port = dh->dccph_sport;
  		break;
  	}
  	return proto;
  }
69f287ae6   Casey Schaufler   Smack: secmark su...
3857
  #endif /* CONFIG_IPV6 */
c67394434   Casey Schaufler   Smack: Local IPv6...
3858

e114e4737   Casey Schaufler   Smack: Simplified...
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
  /**
   * 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;
69f287ae6   Casey Schaufler   Smack: secmark su...
3870
  	struct smack_known *skp = NULL;
c67394434   Casey Schaufler   Smack: Local IPv6...
3871
  	int rc = 0;
ecfcc53fe   Etienne Basset   smack: implement ...
3872
  	struct smk_audit_info ad;
bff663136   Piotr Sawicki   Smack: Fix handli...
3873
  	u16 family = sk->sk_family;
923e9a139   Kees Cook   Smack: build when...
3874
  #ifdef CONFIG_AUDIT
48c62af68   Eric Paris   LSM: shrink the c...
3875
  	struct lsm_network_audit net;
923e9a139   Kees Cook   Smack: build when...
3876
  #endif
69f287ae6   Casey Schaufler   Smack: secmark su...
3877
3878
3879
  #if IS_ENABLED(CONFIG_IPV6)
  	struct sockaddr_in6 sadd;
  	int proto;
bff663136   Piotr Sawicki   Smack: Fix handli...
3880
3881
3882
  
  	if (family == PF_INET6 && skb->protocol == htons(ETH_P_IP))
  		family = PF_INET;
69f287ae6   Casey Schaufler   Smack: secmark su...
3883
  #endif /* CONFIG_IPV6 */
bff663136   Piotr Sawicki   Smack: Fix handli...
3884
  	switch (family) {
c67394434   Casey Schaufler   Smack: Local IPv6...
3885
  	case PF_INET:
69f287ae6   Casey Schaufler   Smack: secmark su...
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
  #ifdef CONFIG_SECURITY_SMACK_NETFILTER
  		/*
  		 * If there is a secmark use it rather than the CIPSO label.
  		 * If there is no secmark fall back to CIPSO.
  		 * The secmark is assumed to reflect policy better.
  		 */
  		if (skb && skb->secmark != 0) {
  			skp = smack_from_secid(skb->secmark);
  			goto access_check;
  		}
  #endif /* CONFIG_SECURITY_SMACK_NETFILTER */
c67394434   Casey Schaufler   Smack: Local IPv6...
3897
3898
3899
3900
  		/*
  		 * Translate what netlabel gave us.
  		 */
  		netlbl_secattr_init(&secattr);
6d3dc07cb   Casey Schaufler   smack: Add suppor...
3901

bff663136   Piotr Sawicki   Smack: Fix handli...
3902
  		rc = netlbl_skbuff_getattr(skb, family, &secattr);
c67394434   Casey Schaufler   Smack: Local IPv6...
3903
  		if (rc == 0)
2f823ff8b   Casey Schaufler   Smack: Improve ac...
3904
  			skp = smack_from_secattr(&secattr, ssp);
c67394434   Casey Schaufler   Smack: Local IPv6...
3905
  		else
2f823ff8b   Casey Schaufler   Smack: Improve ac...
3906
  			skp = smack_net_ambient;
6d3dc07cb   Casey Schaufler   smack: Add suppor...
3907

c67394434   Casey Schaufler   Smack: Local IPv6...
3908
  		netlbl_secattr_destroy(&secattr);
6d3dc07cb   Casey Schaufler   smack: Add suppor...
3909

69f287ae6   Casey Schaufler   Smack: secmark su...
3910
3911
3912
  #ifdef CONFIG_SECURITY_SMACK_NETFILTER
  access_check:
  #endif
ecfcc53fe   Etienne Basset   smack: implement ...
3913
  #ifdef CONFIG_AUDIT
c67394434   Casey Schaufler   Smack: Local IPv6...
3914
  		smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net);
bff663136   Piotr Sawicki   Smack: Fix handli...
3915
  		ad.a.u.net->family = family;
c67394434   Casey Schaufler   Smack: Local IPv6...
3916
3917
  		ad.a.u.net->netif = skb->skb_iif;
  		ipv4_skb_to_auditdata(skb, &ad.a, NULL);
ecfcc53fe   Etienne Basset   smack: implement ...
3918
  #endif
c67394434   Casey Schaufler   Smack: Local IPv6...
3919
3920
3921
3922
3923
3924
  		/*
  		 * 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.
  		 */
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
3925
3926
  		rc = smk_access(skp, ssp->smk_in, MAY_WRITE, &ad);
  		rc = smk_bu_note("IPv4 delivery", skp, ssp->smk_in,
d166c8024   Casey Schaufler   Smack: Bring-up a...
3927
  					MAY_WRITE, rc);
c67394434   Casey Schaufler   Smack: Local IPv6...
3928
  		if (rc != 0)
bff663136   Piotr Sawicki   Smack: Fix handli...
3929
  			netlbl_skbuff_err(skb, family, rc, 0);
c67394434   Casey Schaufler   Smack: Local IPv6...
3930
  		break;
69f287ae6   Casey Schaufler   Smack: secmark su...
3931
  #if IS_ENABLED(CONFIG_IPV6)
c67394434   Casey Schaufler   Smack: Local IPv6...
3932
  	case PF_INET6:
69f287ae6   Casey Schaufler   Smack: secmark su...
3933
3934
3935
  		proto = smk_skb_to_addr_ipv6(skb, &sadd);
  		if (proto != IPPROTO_UDP && proto != IPPROTO_TCP)
  			break;
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
3936
  #ifdef SMACK_IPV6_SECMARK_LABELING
69f287ae6   Casey Schaufler   Smack: secmark su...
3937
3938
  		if (skb && skb->secmark != 0)
  			skp = smack_from_secid(skb->secmark);
c67394434   Casey Schaufler   Smack: Local IPv6...
3939
  		else
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
3940
3941
  			skp = smack_ipv6host_label(&sadd);
  		if (skp == NULL)
69f287ae6   Casey Schaufler   Smack: secmark su...
3942
3943
3944
  			skp = smack_net_ambient;
  #ifdef CONFIG_AUDIT
  		smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net);
bff663136   Piotr Sawicki   Smack: Fix handli...
3945
  		ad.a.u.net->family = family;
69f287ae6   Casey Schaufler   Smack: secmark su...
3946
3947
3948
3949
3950
3951
  		ad.a.u.net->netif = skb->skb_iif;
  		ipv6_skb_to_auditdata(skb, &ad.a, NULL);
  #endif /* CONFIG_AUDIT */
  		rc = smk_access(skp, ssp->smk_in, MAY_WRITE, &ad);
  		rc = smk_bu_note("IPv6 delivery", skp, ssp->smk_in,
  					MAY_WRITE, rc);
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
3952
3953
  #endif /* SMACK_IPV6_SECMARK_LABELING */
  #ifdef SMACK_IPV6_PORT_LABELING
69f287ae6   Casey Schaufler   Smack: secmark su...
3954
  		rc = smk_ipv6_port_check(sk, &sadd, SMK_RECEIVING);
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
3955
  #endif /* SMACK_IPV6_PORT_LABELING */
c67394434   Casey Schaufler   Smack: Local IPv6...
3956
  		break;
69f287ae6   Casey Schaufler   Smack: secmark su...
3957
  #endif /* CONFIG_IPV6 */
c67394434   Casey Schaufler   Smack: Local IPv6...
3958
  	}
69f287ae6   Casey Schaufler   Smack: secmark su...
3959

a8134296b   Paul Moore   smack: Fix missin...
3960
  	return rc;
e114e4737   Casey Schaufler   Smack: Simplified...
3961
3962
3963
3964
3965
3966
3967
  }
  
  /**
   * 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...
3968
   * @len: max thereof
e114e4737   Casey Schaufler   Smack: Simplified...
3969
3970
3971
3972
3973
3974
3975
3976
   *
   * 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 ...
3977
3978
  	char *rcp = "";
  	int slen = 1;
e114e4737   Casey Schaufler   Smack: Simplified...
3979
3980
3981
  	int rc = 0;
  
  	ssp = sock->sk->sk_security;
272cd7a8c   Casey Schaufler   Smack: Rule list ...
3982
  	if (ssp->smk_packet != NULL) {
54e70ec5e   Casey Schaufler   Smack: bidirectio...
3983
  		rcp = ssp->smk_packet->smk_known;
272cd7a8c   Casey Schaufler   Smack: Rule list ...
3984
3985
  		slen = strlen(rcp) + 1;
  	}
e114e4737   Casey Schaufler   Smack: Simplified...
3986
3987
3988
  
  	if (slen > len)
  		rc = -ERANGE;
272cd7a8c   Casey Schaufler   Smack: Rule list ...
3989
  	else if (copy_to_user(optval, rcp, slen) != 0)
e114e4737   Casey Schaufler   Smack: Simplified...
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
  		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
4001
   * @sock: the peer socket
e114e4737   Casey Schaufler   Smack: Simplified...
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
   * @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 ...
4012
  	struct socket_smack *ssp = NULL;
2f823ff8b   Casey Schaufler   Smack: Improve ac...
4013
  	struct smack_known *skp;
b4e0d5f07   Casey Schaufler   Smack: UDS revision
4014
4015
  	int family = PF_UNSPEC;
  	u32 s = 0;	/* 0 is the invalid secid */
e114e4737   Casey Schaufler   Smack: Simplified...
4016
  	int rc;
b4e0d5f07   Casey Schaufler   Smack: UDS revision
4017
4018
4019
  	if (skb != NULL) {
  		if (skb->protocol == htons(ETH_P_IP))
  			family = PF_INET;
69f287ae6   Casey Schaufler   Smack: secmark su...
4020
  #if IS_ENABLED(CONFIG_IPV6)
b4e0d5f07   Casey Schaufler   Smack: UDS revision
4021
4022
  		else if (skb->protocol == htons(ETH_P_IPV6))
  			family = PF_INET6;
69f287ae6   Casey Schaufler   Smack: secmark su...
4023
  #endif /* CONFIG_IPV6 */
e114e4737   Casey Schaufler   Smack: Simplified...
4024
  	}
b4e0d5f07   Casey Schaufler   Smack: UDS revision
4025
4026
  	if (family == PF_UNSPEC && sock != NULL)
  		family = sock->sk->sk_family;
e114e4737   Casey Schaufler   Smack: Simplified...
4027

69f287ae6   Casey Schaufler   Smack: secmark su...
4028
4029
  	switch (family) {
  	case PF_UNIX:
272cd7a8c   Casey Schaufler   Smack: Rule list ...
4030
  		ssp = sock->sk->sk_security;
2f823ff8b   Casey Schaufler   Smack: Improve ac...
4031
  		s = ssp->smk_out->smk_secid;
69f287ae6   Casey Schaufler   Smack: secmark su...
4032
4033
4034
4035
4036
4037
4038
  		break;
  	case PF_INET:
  #ifdef CONFIG_SECURITY_SMACK_NETFILTER
  		s = skb->secmark;
  		if (s != 0)
  			break;
  #endif
b4e0d5f07   Casey Schaufler   Smack: UDS revision
4039
4040
4041
  		/*
  		 * Translate what netlabel gave us.
  		 */
272cd7a8c   Casey Schaufler   Smack: Rule list ...
4042
4043
  		if (sock != NULL && sock->sk != NULL)
  			ssp = sock->sk->sk_security;
b4e0d5f07   Casey Schaufler   Smack: UDS revision
4044
4045
4046
  		netlbl_secattr_init(&secattr);
  		rc = netlbl_skbuff_getattr(skb, family, &secattr);
  		if (rc == 0) {
2f823ff8b   Casey Schaufler   Smack: Improve ac...
4047
4048
  			skp = smack_from_secattr(&secattr, ssp);
  			s = skp->smk_secid;
b4e0d5f07   Casey Schaufler   Smack: UDS revision
4049
4050
  		}
  		netlbl_secattr_destroy(&secattr);
69f287ae6   Casey Schaufler   Smack: secmark su...
4051
  		break;
69f287ae6   Casey Schaufler   Smack: secmark su...
4052
  	case PF_INET6:
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
4053
  #ifdef SMACK_IPV6_SECMARK_LABELING
69f287ae6   Casey Schaufler   Smack: secmark su...
4054
  		s = skb->secmark;
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
4055
  #endif
69f287ae6   Casey Schaufler   Smack: secmark su...
4056
  		break;
b4e0d5f07   Casey Schaufler   Smack: UDS revision
4057
4058
  	}
  	*secid = s;
e114e4737   Casey Schaufler   Smack: Simplified...
4059
4060
  	if (s == 0)
  		return -EINVAL;
e114e4737   Casey Schaufler   Smack: Simplified...
4061
4062
4063
4064
  	return 0;
  }
  
  /**
07feee8f8   Paul Moore   netlabel: Cleanup...
4065
4066
4067
   * smack_sock_graft - Initialize a newly created socket with an existing sock
   * @sk: child sock
   * @parent: parent socket
e114e4737   Casey Schaufler   Smack: Simplified...
4068
   *
07feee8f8   Paul Moore   netlabel: Cleanup...
4069
4070
   * 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...
4071
4072
4073
4074
   */
  static void smack_sock_graft(struct sock *sk, struct socket *parent)
  {
  	struct socket_smack *ssp;
2f823ff8b   Casey Schaufler   Smack: Improve ac...
4075
  	struct smack_known *skp = smk_of_current();
e114e4737   Casey Schaufler   Smack: Simplified...
4076

07feee8f8   Paul Moore   netlabel: Cleanup...
4077
4078
  	if (sk == NULL ||
  	    (sk->sk_family != PF_INET && sk->sk_family != PF_INET6))
e114e4737   Casey Schaufler   Smack: Simplified...
4079
4080
4081
  		return;
  
  	ssp = sk->sk_security;
54e70ec5e   Casey Schaufler   Smack: bidirectio...
4082
  	ssp->smk_in = skp;
2f823ff8b   Casey Schaufler   Smack: Improve ac...
4083
  	ssp->smk_out = skp;
07feee8f8   Paul Moore   netlabel: Cleanup...
4084
  	/* cssp->smk_packet is already set in smack_inet_csk_clone() */
e114e4737   Casey Schaufler   Smack: Simplified...
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
  }
  
  /**
   * 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...
4099
  	u16 family = sk->sk_family;
f7112e6c9   Casey Schaufler   Smack: allow for ...
4100
  	struct smack_known *skp;
e114e4737   Casey Schaufler   Smack: Simplified...
4101
  	struct socket_smack *ssp = sk->sk_security;
07feee8f8   Paul Moore   netlabel: Cleanup...
4102
4103
4104
  	struct netlbl_lsm_secattr secattr;
  	struct sockaddr_in addr;
  	struct iphdr *hdr;
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
4105
  	struct smack_known *hskp;
e114e4737   Casey Schaufler   Smack: Simplified...
4106
  	int rc;
ecfcc53fe   Etienne Basset   smack: implement ...
4107
  	struct smk_audit_info ad;
923e9a139   Kees Cook   Smack: build when...
4108
  #ifdef CONFIG_AUDIT
48c62af68   Eric Paris   LSM: shrink the c...
4109
  	struct lsm_network_audit net;
923e9a139   Kees Cook   Smack: build when...
4110
  #endif
e114e4737   Casey Schaufler   Smack: Simplified...
4111

69f287ae6   Casey Schaufler   Smack: secmark su...
4112
  #if IS_ENABLED(CONFIG_IPV6)
c67394434   Casey Schaufler   Smack: Local IPv6...
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
  	if (family == PF_INET6) {
  		/*
  		 * Handle mapped IPv4 packets arriving
  		 * via IPv6 sockets. Don't set up netlabel
  		 * processing on IPv6.
  		 */
  		if (skb->protocol == htons(ETH_P_IP))
  			family = PF_INET;
  		else
  			return 0;
  	}
69f287ae6   Casey Schaufler   Smack: secmark su...
4124
  #endif /* CONFIG_IPV6 */
e114e4737   Casey Schaufler   Smack: Simplified...
4125

7f368ad34   Casey Schaufler   Smack: secmark co...
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
  #ifdef CONFIG_SECURITY_SMACK_NETFILTER
  	/*
  	 * If there is a secmark use it rather than the CIPSO label.
  	 * If there is no secmark fall back to CIPSO.
  	 * The secmark is assumed to reflect policy better.
  	 */
  	if (skb && skb->secmark != 0) {
  		skp = smack_from_secid(skb->secmark);
  		goto access_check;
  	}
  #endif /* CONFIG_SECURITY_SMACK_NETFILTER */
07feee8f8   Paul Moore   netlabel: Cleanup...
4137
4138
  	netlbl_secattr_init(&secattr);
  	rc = netlbl_skbuff_getattr(skb, family, &secattr);
e114e4737   Casey Schaufler   Smack: Simplified...
4139
  	if (rc == 0)
2f823ff8b   Casey Schaufler   Smack: Improve ac...
4140
  		skp = smack_from_secattr(&secattr, ssp);
e114e4737   Casey Schaufler   Smack: Simplified...
4141
  	else
2f823ff8b   Casey Schaufler   Smack: Improve ac...
4142
  		skp = &smack_known_huh;
07feee8f8   Paul Moore   netlabel: Cleanup...
4143
  	netlbl_secattr_destroy(&secattr);
7f368ad34   Casey Schaufler   Smack: secmark co...
4144
4145
4146
  #ifdef CONFIG_SECURITY_SMACK_NETFILTER
  access_check:
  #endif
ecfcc53fe   Etienne Basset   smack: implement ...
4147
  #ifdef CONFIG_AUDIT
48c62af68   Eric Paris   LSM: shrink the c...
4148
4149
4150
  	smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net);
  	ad.a.u.net->family = family;
  	ad.a.u.net->netif = skb->skb_iif;
ecfcc53fe   Etienne Basset   smack: implement ...
4151
4152
  	ipv4_skb_to_auditdata(skb, &ad.a, NULL);
  #endif
e114e4737   Casey Schaufler   Smack: Simplified...
4153
  	/*
07feee8f8   Paul Moore   netlabel: Cleanup...
4154
4155
  	 * Receiving a packet requires that the other end be able to write
  	 * here. Read access is not required.
e114e4737   Casey Schaufler   Smack: Simplified...
4156
  	 */
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
4157
4158
  	rc = smk_access(skp, ssp->smk_in, MAY_WRITE, &ad);
  	rc = smk_bu_note("IPv4 connect", skp, ssp->smk_in, MAY_WRITE, rc);
07feee8f8   Paul Moore   netlabel: Cleanup...
4159
4160
4161
4162
4163
4164
4165
  	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.
  	 */
2f823ff8b   Casey Schaufler   Smack: Improve ac...
4166
  	req->peer_secid = skp->smk_secid;
07feee8f8   Paul Moore   netlabel: Cleanup...
4167
4168
4169
4170
  
  	/*
  	 * 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...
4171
  	 * propagate the wire-label to the sock when it is created.
07feee8f8   Paul Moore   netlabel: Cleanup...
4172
4173
4174
4175
  	 */
  	hdr = ip_hdr(skb);
  	addr.sin_addr.s_addr = hdr->saddr;
  	rcu_read_lock();
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
4176
  	hskp = smack_ipv4host_label(&addr);
f7112e6c9   Casey Schaufler   Smack: allow for ...
4177
  	rcu_read_unlock();
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
4178
  	if (hskp == NULL)
f7112e6c9   Casey Schaufler   Smack: allow for ...
4179
  		rc = netlbl_req_setattr(req, &skp->smk_netlabel);
2f823ff8b   Casey Schaufler   Smack: Improve ac...
4180
  	else
07feee8f8   Paul Moore   netlabel: Cleanup...
4181
  		netlbl_req_delattr(req);
e114e4737   Casey Schaufler   Smack: Simplified...
4182
4183
4184
  
  	return rc;
  }
07feee8f8   Paul Moore   netlabel: Cleanup...
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
  /**
   * 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;
2f823ff8b   Casey Schaufler   Smack: Improve ac...
4196
  	struct smack_known *skp;
07feee8f8   Paul Moore   netlabel: Cleanup...
4197

2f823ff8b   Casey Schaufler   Smack: Improve ac...
4198
4199
  	if (req->peer_secid != 0) {
  		skp = smack_from_secid(req->peer_secid);
54e70ec5e   Casey Schaufler   Smack: bidirectio...
4200
  		ssp->smk_packet = skp;
2f823ff8b   Casey Schaufler   Smack: Improve ac...
4201
  	} else
272cd7a8c   Casey Schaufler   Smack: Rule list ...
4202
  		ssp->smk_packet = NULL;
07feee8f8   Paul Moore   netlabel: Cleanup...
4203
  }
e114e4737   Casey Schaufler   Smack: Simplified...
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
  /*
   * 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 ...
4216
   * @cred: the credentials to use
e114e4737   Casey Schaufler   Smack: Simplified...
4217
4218
4219
4220
4221
4222
   * @flags: unused
   *
   * No allocation required
   *
   * Returns 0
   */
d84f4f992   David Howells   CRED: Inaugurate ...
4223
  static int smack_key_alloc(struct key *key, const struct cred *cred,
e114e4737   Casey Schaufler   Smack: Simplified...
4224
4225
  			   unsigned long flags)
  {
2f823ff8b   Casey Schaufler   Smack: Improve ac...
4226
  	struct smack_known *skp = smk_of_task(cred->security);
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
4227
  	key->security = skp;
e114e4737   Casey Schaufler   Smack: Simplified...
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
  	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;
  }
1a28979b3   Lukasz Pawelczyk   smack: miscellane...
4241
  /**
e114e4737   Casey Schaufler   Smack: Simplified...
4242
4243
   * smack_key_permission - Smack access on a key
   * @key_ref: gets to the object
d84f4f992   David Howells   CRED: Inaugurate ...
4244
   * @cred: the credentials to use
1a28979b3   Lukasz Pawelczyk   smack: miscellane...
4245
   * @perm: requested key permissions
e114e4737   Casey Schaufler   Smack: Simplified...
4246
4247
4248
4249
4250
   *
   * 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,
f5895943d   David Howells   KEYS: Move the fl...
4251
  				const struct cred *cred, unsigned perm)
e114e4737   Casey Schaufler   Smack: Simplified...
4252
4253
  {
  	struct key *keyp;
ecfcc53fe   Etienne Basset   smack: implement ...
4254
  	struct smk_audit_info ad;
2f823ff8b   Casey Schaufler   Smack: Improve ac...
4255
  	struct smack_known *tkp = smk_of_task(cred->security);
fffea214a   Dmitry Kasatkin   smack: fix key pe...
4256
  	int request = 0;
d166c8024   Casey Schaufler   Smack: Bring-up a...
4257
  	int rc;
e114e4737   Casey Schaufler   Smack: Simplified...
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
  
  	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
  	 */
2f823ff8b   Casey Schaufler   Smack: Improve ac...
4271
  	if (tkp == NULL)
e114e4737   Casey Schaufler   Smack: Simplified...
4272
  		return -EACCES;
ecfcc53fe   Etienne Basset   smack: implement ...
4273
4274
4275
4276
4277
  #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
fffea214a   Dmitry Kasatkin   smack: fix key pe...
4278
4279
4280
4281
  	if (perm & KEY_NEED_READ)
  		request = MAY_READ;
  	if (perm & (KEY_NEED_WRITE | KEY_NEED_LINK | KEY_NEED_SETATTR))
  		request = MAY_WRITE;
d166c8024   Casey Schaufler   Smack: Bring-up a...
4282
4283
4284
  	rc = smk_access(tkp, keyp->security, request, &ad);
  	rc = smk_bu_note("key access", tkp, keyp->security, request, rc);
  	return rc;
e114e4737   Casey Schaufler   Smack: Simplified...
4285
  }
7fc5f36e9   José Bollo   Smack: getting th...
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
4300
4301
4302
4303
4304
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314
  
  /*
   * smack_key_getsecurity - Smack label tagging the key
   * @key points to the key to be queried
   * @_buffer points to a pointer that should be set to point to the
   * resulting string (if no label or an error occurs).
   * Return the length of the string (including terminating NUL) or -ve if
   * an error.
   * May also return 0 (and a NULL buffer pointer) if there is no label.
   */
  static int smack_key_getsecurity(struct key *key, char **_buffer)
  {
  	struct smack_known *skp = key->security;
  	size_t length;
  	char *copy;
  
  	if (key->security == NULL) {
  		*_buffer = NULL;
  		return 0;
  	}
  
  	copy = kstrdup(skp->smk_known, GFP_KERNEL);
  	if (copy == NULL)
  		return -ENOMEM;
  	length = strlen(copy) + 1;
  
  	*_buffer = copy;
  	return length;
  }
e114e4737   Casey Schaufler   Smack: Simplified...
4315
4316
4317
  #endif /* CONFIG_KEYS */
  
  /*
d20bdda6d   Ahmed S. Darwish   Smack: Integrate ...
4318
4319
4320
4321
4322
4323
4324
4325
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
   * 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)
  {
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
4344
  	struct smack_known *skp;
d20bdda6d   Ahmed S. Darwish   Smack: Integrate ...
4345
4346
4347
4348
4349
  	char **rule = (char **)vrule;
  	*rule = NULL;
  
  	if (field != AUDIT_SUBJ_USER && field != AUDIT_OBJ_USER)
  		return -EINVAL;
5af75d8d5   Al Viro   audit: validate c...
4350
  	if (op != Audit_equal && op != Audit_not_equal)
d20bdda6d   Ahmed S. Darwish   Smack: Integrate ...
4351
  		return -EINVAL;
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
4352
  	skp = smk_import_entry(rulestr, 0);
e774ad683   Lukasz Pawelczyk   smack: pass error...
4353
4354
4355
4356
  	if (IS_ERR(skp))
  		return PTR_ERR(skp);
  
  	*rule = skp->smk_known;
d20bdda6d   Ahmed S. Darwish   Smack: Integrate ...
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
  
  	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)
  {
2f823ff8b   Casey Schaufler   Smack: Improve ac...
4398
  	struct smack_known *skp;
d20bdda6d   Ahmed S. Darwish   Smack: Integrate ...
4399
  	char *rule = vrule;
4eb0f4abf   Richard Guy Briggs   smack: call WARN_...
4400
4401
4402
  	if (unlikely(!rule)) {
  		WARN_ONCE(1, "Smack: missing rule
  ");
d20bdda6d   Ahmed S. Darwish   Smack: Integrate ...
4403
4404
4405
4406
4407
  		return -ENOENT;
  	}
  
  	if (field != AUDIT_SUBJ_USER && field != AUDIT_OBJ_USER)
  		return 0;
2f823ff8b   Casey Schaufler   Smack: Improve ac...
4408
  	skp = smack_from_secid(secid);
d20bdda6d   Ahmed S. Darwish   Smack: Integrate ...
4409
4410
4411
4412
4413
4414
  
  	/*
  	 * 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...
4415
  	if (op == Audit_equal)
2f823ff8b   Casey Schaufler   Smack: Improve ac...
4416
  		return (rule == skp->smk_known);
5af75d8d5   Al Viro   audit: validate c...
4417
  	if (op == Audit_not_equal)
2f823ff8b   Casey Schaufler   Smack: Improve ac...
4418
  		return (rule != skp->smk_known);
d20bdda6d   Ahmed S. Darwish   Smack: Integrate ...
4419
4420
4421
  
  	return 0;
  }
491a0b08d   Casey Schaufler   Smack: Remove poi...
4422
4423
  /*
   * There is no need for a smack_audit_rule_free hook.
d20bdda6d   Ahmed S. Darwish   Smack: Integrate ...
4424
4425
   * No memory was allocated.
   */
d20bdda6d   Ahmed S. Darwish   Smack: Integrate ...
4426
4427
  
  #endif /* CONFIG_AUDIT */
251a2a958   Randy Dunlap   smack: fix lots o...
4428
  /**
746df9b59   David Quigley   Security: Add Hoo...
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
   * smack_ismaclabel - check if xattr @name references a smack MAC label
   * @name: Full xattr name to check.
   */
  static int smack_ismaclabel(const char *name)
  {
  	return (strcmp(name, XATTR_SMACK_SUFFIX) == 0);
  }
  
  
  /**
e114e4737   Casey Schaufler   Smack: Simplified...
4439
4440
4441
4442
4443
4444
4445
4446
4447
   * 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)
  {
2f823ff8b   Casey Schaufler   Smack: Improve ac...
4448
  	struct smack_known *skp = smack_from_secid(secid);
e114e4737   Casey Schaufler   Smack: Simplified...
4449

d5630b9d2   Eric Paris   security: secid_t...
4450
  	if (secdata)
2f823ff8b   Casey Schaufler   Smack: Improve ac...
4451
4452
  		*secdata = skp->smk_known;
  	*seclen = strlen(skp->smk_known);
e114e4737   Casey Schaufler   Smack: Simplified...
4453
4454
  	return 0;
  }
251a2a958   Randy Dunlap   smack: fix lots o...
4455
  /**
4bc87e627   Casey Schaufler   Smack: unlabeled ...
4456
4457
4458
4459
4460
4461
4462
   * 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...
4463
  static int smack_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid)
4bc87e627   Casey Schaufler   Smack: unlabeled ...
4464
  {
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
4465
4466
4467
4468
4469
4470
  	struct smack_known *skp = smk_find_entry(secdata);
  
  	if (skp)
  		*secid = skp->smk_secid;
  	else
  		*secid = 0;
4bc87e627   Casey Schaufler   Smack: unlabeled ...
4471
4472
  	return 0;
  }
491a0b08d   Casey Schaufler   Smack: Remove poi...
4473
4474
4475
4476
  /*
   * There used to be a smack_release_secctx hook
   * that did nothing back when hooks were in a vector.
   * Now that there's a list such a hook adds cost.
e114e4737   Casey Schaufler   Smack: Simplified...
4477
   */
e114e4737   Casey Schaufler   Smack: Simplified...
4478

1ee65e37e   David P. Quigley   LSM/SELinux: inod...
4479
4480
4481
4482
4483
4484
4485
4486
4487
4488
4489
4490
4491
4492
4493
4494
4495
4496
4497
4498
  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;
  }
ca97d939d   James Morris   security: mark LS...
4499
  static struct security_hook_list smack_hooks[] __lsm_ro_after_init = {
e20b043a6   Casey Schaufler   LSM: Add security...
4500
4501
4502
4503
4504
4505
4506
4507
4508
  	LSM_HOOK_INIT(ptrace_access_check, smack_ptrace_access_check),
  	LSM_HOOK_INIT(ptrace_traceme, smack_ptrace_traceme),
  	LSM_HOOK_INIT(syslog, smack_syslog),
  
  	LSM_HOOK_INIT(sb_alloc_security, smack_sb_alloc_security),
  	LSM_HOOK_INIT(sb_free_security, smack_sb_free_security),
  	LSM_HOOK_INIT(sb_copy_data, smack_sb_copy_data),
  	LSM_HOOK_INIT(sb_kern_mount, smack_sb_kern_mount),
  	LSM_HOOK_INIT(sb_statfs, smack_sb_statfs),
3bf2789ca   Vivek Trivedi   smack: allow moun...
4509
4510
  	LSM_HOOK_INIT(sb_set_mnt_opts, smack_set_mnt_opts),
  	LSM_HOOK_INIT(sb_parse_opts_str, smack_parse_opts_str),
e20b043a6   Casey Schaufler   LSM: Add security...
4511
4512
  
  	LSM_HOOK_INIT(bprm_set_creds, smack_bprm_set_creds),
e20b043a6   Casey Schaufler   LSM: Add security...
4513
4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
4531
  
  	LSM_HOOK_INIT(inode_alloc_security, smack_inode_alloc_security),
  	LSM_HOOK_INIT(inode_free_security, smack_inode_free_security),
  	LSM_HOOK_INIT(inode_init_security, smack_inode_init_security),
  	LSM_HOOK_INIT(inode_link, smack_inode_link),
  	LSM_HOOK_INIT(inode_unlink, smack_inode_unlink),
  	LSM_HOOK_INIT(inode_rmdir, smack_inode_rmdir),
  	LSM_HOOK_INIT(inode_rename, smack_inode_rename),
  	LSM_HOOK_INIT(inode_permission, smack_inode_permission),
  	LSM_HOOK_INIT(inode_setattr, smack_inode_setattr),
  	LSM_HOOK_INIT(inode_getattr, smack_inode_getattr),
  	LSM_HOOK_INIT(inode_setxattr, smack_inode_setxattr),
  	LSM_HOOK_INIT(inode_post_setxattr, smack_inode_post_setxattr),
  	LSM_HOOK_INIT(inode_getxattr, smack_inode_getxattr),
  	LSM_HOOK_INIT(inode_removexattr, smack_inode_removexattr),
  	LSM_HOOK_INIT(inode_getsecurity, smack_inode_getsecurity),
  	LSM_HOOK_INIT(inode_setsecurity, smack_inode_setsecurity),
  	LSM_HOOK_INIT(inode_listsecurity, smack_inode_listsecurity),
  	LSM_HOOK_INIT(inode_getsecid, smack_inode_getsecid),
e20b043a6   Casey Schaufler   LSM: Add security...
4532
4533
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
4561
  	LSM_HOOK_INIT(file_alloc_security, smack_file_alloc_security),
  	LSM_HOOK_INIT(file_free_security, smack_file_free_security),
  	LSM_HOOK_INIT(file_ioctl, smack_file_ioctl),
  	LSM_HOOK_INIT(file_lock, smack_file_lock),
  	LSM_HOOK_INIT(file_fcntl, smack_file_fcntl),
  	LSM_HOOK_INIT(mmap_file, smack_mmap_file),
  	LSM_HOOK_INIT(mmap_addr, cap_mmap_addr),
  	LSM_HOOK_INIT(file_set_fowner, smack_file_set_fowner),
  	LSM_HOOK_INIT(file_send_sigiotask, smack_file_send_sigiotask),
  	LSM_HOOK_INIT(file_receive, smack_file_receive),
  
  	LSM_HOOK_INIT(file_open, smack_file_open),
  
  	LSM_HOOK_INIT(cred_alloc_blank, smack_cred_alloc_blank),
  	LSM_HOOK_INIT(cred_free, smack_cred_free),
  	LSM_HOOK_INIT(cred_prepare, smack_cred_prepare),
  	LSM_HOOK_INIT(cred_transfer, smack_cred_transfer),
  	LSM_HOOK_INIT(kernel_act_as, smack_kernel_act_as),
  	LSM_HOOK_INIT(kernel_create_files_as, smack_kernel_create_files_as),
  	LSM_HOOK_INIT(task_setpgid, smack_task_setpgid),
  	LSM_HOOK_INIT(task_getpgid, smack_task_getpgid),
  	LSM_HOOK_INIT(task_getsid, smack_task_getsid),
  	LSM_HOOK_INIT(task_getsecid, smack_task_getsecid),
  	LSM_HOOK_INIT(task_setnice, smack_task_setnice),
  	LSM_HOOK_INIT(task_setioprio, smack_task_setioprio),
  	LSM_HOOK_INIT(task_getioprio, smack_task_getioprio),
  	LSM_HOOK_INIT(task_setscheduler, smack_task_setscheduler),
  	LSM_HOOK_INIT(task_getscheduler, smack_task_getscheduler),
  	LSM_HOOK_INIT(task_movememory, smack_task_movememory),
  	LSM_HOOK_INIT(task_kill, smack_task_kill),
e20b043a6   Casey Schaufler   LSM: Add security...
4562
4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
4578
4579
4580
4581
4582
4583
4584
4585
4586
4587
4588
4589
4590
4591
4592
4593
4594
4595
4596
4597
  	LSM_HOOK_INIT(task_to_inode, smack_task_to_inode),
  
  	LSM_HOOK_INIT(ipc_permission, smack_ipc_permission),
  	LSM_HOOK_INIT(ipc_getsecid, smack_ipc_getsecid),
  
  	LSM_HOOK_INIT(msg_msg_alloc_security, smack_msg_msg_alloc_security),
  	LSM_HOOK_INIT(msg_msg_free_security, smack_msg_msg_free_security),
  
  	LSM_HOOK_INIT(msg_queue_alloc_security, smack_msg_queue_alloc_security),
  	LSM_HOOK_INIT(msg_queue_free_security, smack_msg_queue_free_security),
  	LSM_HOOK_INIT(msg_queue_associate, smack_msg_queue_associate),
  	LSM_HOOK_INIT(msg_queue_msgctl, smack_msg_queue_msgctl),
  	LSM_HOOK_INIT(msg_queue_msgsnd, smack_msg_queue_msgsnd),
  	LSM_HOOK_INIT(msg_queue_msgrcv, smack_msg_queue_msgrcv),
  
  	LSM_HOOK_INIT(shm_alloc_security, smack_shm_alloc_security),
  	LSM_HOOK_INIT(shm_free_security, smack_shm_free_security),
  	LSM_HOOK_INIT(shm_associate, smack_shm_associate),
  	LSM_HOOK_INIT(shm_shmctl, smack_shm_shmctl),
  	LSM_HOOK_INIT(shm_shmat, smack_shm_shmat),
  
  	LSM_HOOK_INIT(sem_alloc_security, smack_sem_alloc_security),
  	LSM_HOOK_INIT(sem_free_security, smack_sem_free_security),
  	LSM_HOOK_INIT(sem_associate, smack_sem_associate),
  	LSM_HOOK_INIT(sem_semctl, smack_sem_semctl),
  	LSM_HOOK_INIT(sem_semop, smack_sem_semop),
  
  	LSM_HOOK_INIT(d_instantiate, smack_d_instantiate),
  
  	LSM_HOOK_INIT(getprocattr, smack_getprocattr),
  	LSM_HOOK_INIT(setprocattr, smack_setprocattr),
  
  	LSM_HOOK_INIT(unix_stream_connect, smack_unix_stream_connect),
  	LSM_HOOK_INIT(unix_may_send, smack_unix_may_send),
  
  	LSM_HOOK_INIT(socket_post_create, smack_socket_post_create),
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
4598
  #ifdef SMACK_IPV6_PORT_LABELING
e20b043a6   Casey Schaufler   LSM: Add security...
4599
  	LSM_HOOK_INIT(socket_bind, smack_socket_bind),
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
4600
  #endif
e20b043a6   Casey Schaufler   LSM: Add security...
4601
4602
4603
4604
4605
4606
4607
4608
4609
4610
  	LSM_HOOK_INIT(socket_connect, smack_socket_connect),
  	LSM_HOOK_INIT(socket_sendmsg, smack_socket_sendmsg),
  	LSM_HOOK_INIT(socket_sock_rcv_skb, smack_socket_sock_rcv_skb),
  	LSM_HOOK_INIT(socket_getpeersec_stream, smack_socket_getpeersec_stream),
  	LSM_HOOK_INIT(socket_getpeersec_dgram, smack_socket_getpeersec_dgram),
  	LSM_HOOK_INIT(sk_alloc_security, smack_sk_alloc_security),
  	LSM_HOOK_INIT(sk_free_security, smack_sk_free_security),
  	LSM_HOOK_INIT(sock_graft, smack_sock_graft),
  	LSM_HOOK_INIT(inet_conn_request, smack_inet_conn_request),
  	LSM_HOOK_INIT(inet_csk_clone, smack_inet_csk_clone),
d20bdda6d   Ahmed S. Darwish   Smack: Integrate ...
4611

e114e4737   Casey Schaufler   Smack: Simplified...
4612
4613
   /* key management security hooks */
  #ifdef CONFIG_KEYS
e20b043a6   Casey Schaufler   LSM: Add security...
4614
4615
4616
4617
  	LSM_HOOK_INIT(key_alloc, smack_key_alloc),
  	LSM_HOOK_INIT(key_free, smack_key_free),
  	LSM_HOOK_INIT(key_permission, smack_key_permission),
  	LSM_HOOK_INIT(key_getsecurity, smack_key_getsecurity),
e114e4737   Casey Schaufler   Smack: Simplified...
4618
  #endif /* CONFIG_KEYS */
d20bdda6d   Ahmed S. Darwish   Smack: Integrate ...
4619
4620
4621
  
   /* Audit hooks */
  #ifdef CONFIG_AUDIT
e20b043a6   Casey Schaufler   LSM: Add security...
4622
4623
4624
  	LSM_HOOK_INIT(audit_rule_init, smack_audit_rule_init),
  	LSM_HOOK_INIT(audit_rule_known, smack_audit_rule_known),
  	LSM_HOOK_INIT(audit_rule_match, smack_audit_rule_match),
d20bdda6d   Ahmed S. Darwish   Smack: Integrate ...
4625
  #endif /* CONFIG_AUDIT */
e20b043a6   Casey Schaufler   LSM: Add security...
4626
4627
4628
  	LSM_HOOK_INIT(ismaclabel, smack_ismaclabel),
  	LSM_HOOK_INIT(secid_to_secctx, smack_secid_to_secctx),
  	LSM_HOOK_INIT(secctx_to_secid, smack_secctx_to_secid),
e20b043a6   Casey Schaufler   LSM: Add security...
4629
4630
4631
  	LSM_HOOK_INIT(inode_notifysecctx, smack_inode_notifysecctx),
  	LSM_HOOK_INIT(inode_setsecctx, smack_inode_setsecctx),
  	LSM_HOOK_INIT(inode_getsecctx, smack_inode_getsecctx),
e114e4737   Casey Schaufler   Smack: Simplified...
4632
  };
7198e2eeb   Etienne Basset   smack: convert sm...
4633

86812bb0d   Casey Schaufler   Smack: move label...
4634
  static __init void init_smack_known_list(void)
7198e2eeb   Etienne Basset   smack: convert sm...
4635
  {
86812bb0d   Casey Schaufler   Smack: move label...
4636
  	/*
86812bb0d   Casey Schaufler   Smack: move label...
4637
4638
4639
4640
4641
4642
  	 * Initialize rule list locks
  	 */
  	mutex_init(&smack_known_huh.smk_rules_lock);
  	mutex_init(&smack_known_hat.smk_rules_lock);
  	mutex_init(&smack_known_floor.smk_rules_lock);
  	mutex_init(&smack_known_star.smk_rules_lock);
86812bb0d   Casey Schaufler   Smack: move label...
4643
4644
4645
4646
4647
4648
4649
4650
  	mutex_init(&smack_known_web.smk_rules_lock);
  	/*
  	 * Initialize rule lists
  	 */
  	INIT_LIST_HEAD(&smack_known_huh.smk_rules);
  	INIT_LIST_HEAD(&smack_known_hat.smk_rules);
  	INIT_LIST_HEAD(&smack_known_star.smk_rules);
  	INIT_LIST_HEAD(&smack_known_floor.smk_rules);
86812bb0d   Casey Schaufler   Smack: move label...
4651
4652
4653
4654
  	INIT_LIST_HEAD(&smack_known_web.smk_rules);
  	/*
  	 * Create the known labels list
  	 */
4d7cf4a1f   Tomasz Stanislawski   security: smack: ...
4655
4656
4657
4658
  	smk_insert_entry(&smack_known_huh);
  	smk_insert_entry(&smack_known_hat);
  	smk_insert_entry(&smack_known_star);
  	smk_insert_entry(&smack_known_floor);
4d7cf4a1f   Tomasz Stanislawski   security: smack: ...
4659
  	smk_insert_entry(&smack_known_web);
7198e2eeb   Etienne Basset   smack: convert sm...
4660
  }
e114e4737   Casey Schaufler   Smack: Simplified...
4661
4662
4663
4664
4665
4666
4667
  /**
   * smack_init - initialize the smack system
   *
   * Returns 0
   */
  static __init int smack_init(void)
  {
d84f4f992   David Howells   CRED: Inaugurate ...
4668
  	struct cred *cred;
676dac4b1   Casey Schaufler   This patch adds a...
4669
  	struct task_smack *tsp;
d84f4f992   David Howells   CRED: Inaugurate ...
4670

b1d9e6b06   Casey Schaufler   LSM: Switch to li...
4671
  	if (!security_module_enable("smack"))
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
4672
  		return 0;
1a5b472bd   Rohit   Security: smack: ...
4673
4674
4675
  	smack_inode_cache = KMEM_CACHE(inode_smack, 0);
  	if (!smack_inode_cache)
  		return -ENOMEM;
2f823ff8b   Casey Schaufler   Smack: Improve ac...
4676
4677
  	tsp = new_task_smack(&smack_known_floor, &smack_known_floor,
  				GFP_KERNEL);
1a5b472bd   Rohit   Security: smack: ...
4678
4679
  	if (tsp == NULL) {
  		kmem_cache_destroy(smack_inode_cache);
676dac4b1   Casey Schaufler   This patch adds a...
4680
  		return -ENOMEM;
1a5b472bd   Rohit   Security: smack: ...
4681
  	}
676dac4b1   Casey Schaufler   This patch adds a...
4682

d21b7b049   José Bollo   Smack: Minor init...
4683
  	smack_enabled = 1;
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
4684
4685
4686
4687
4688
4689
4690
4691
4692
4693
4694
4695
4696
4697
  	pr_info("Smack:  Initializing.
  ");
  #ifdef CONFIG_SECURITY_SMACK_NETFILTER
  	pr_info("Smack:  Netfilter enabled.
  ");
  #endif
  #ifdef SMACK_IPV6_PORT_LABELING
  	pr_info("Smack:  IPv6 port labeling enabled.
  ");
  #endif
  #ifdef SMACK_IPV6_SECMARK_LABELING
  	pr_info("Smack:  IPv6 Netfilter enabled.
  ");
  #endif
e114e4737   Casey Schaufler   Smack: Simplified...
4698
4699
4700
4701
  
  	/*
  	 * Set the security state for the initial task.
  	 */
d84f4f992   David Howells   CRED: Inaugurate ...
4702
  	cred = (struct cred *) current->cred;
676dac4b1   Casey Schaufler   This patch adds a...
4703
  	cred->security = tsp;
e114e4737   Casey Schaufler   Smack: Simplified...
4704

86812bb0d   Casey Schaufler   Smack: move label...
4705
4706
  	/* initialize the smack_known_list */
  	init_smack_known_list();
e114e4737   Casey Schaufler   Smack: Simplified...
4707
4708
4709
4710
  
  	/*
  	 * Register with LSM
  	 */
d69dece5f   Casey Schaufler   LSM: Add /sys/ker...
4711
  	security_add_hooks(smack_hooks, ARRAY_SIZE(smack_hooks), "smack");
e114e4737   Casey Schaufler   Smack: Simplified...
4712
4713
4714
4715
4716
4717
4718
4719
4720
  
  	return 0;
  }
  
  /*
   * Smack requires early initialization in order to label
   * all processes and objects when they are created.
   */
  security_initcall(smack_init);