blob: 14bf2f4aea3bc3aa0a52cc8b6bf8ca2e59926f36 [file] [log] [blame]
Thomas Gleixnerd2912cb2019-06-04 10:11:33 +02001// SPDX-License-Identifier: GPL-2.0-only
Casey Schauflere114e472008-02-04 22:29:50 -08002/*
3 * Simplified MAC Kernel (smack) security module
4 *
5 * This file contains the smack hook function implementations.
6 *
Jarkko Sakkinen5c6d1122010-12-07 13:34:01 +02007 * Authors:
Casey Schauflere114e472008-02-04 22:29:50 -08008 * Casey Schaufler <casey@schaufler-ca.com>
Jarkko Sakkinen84088ba2011-10-07 09:27:53 +03009 * Jarkko Sakkinen <jarkko.sakkinen@intel.com>
Casey Schauflere114e472008-02-04 22:29:50 -080010 *
11 * Copyright (C) 2007 Casey Schaufler <casey@schaufler-ca.com>
Paul Moore07feee82009-03-27 17:10:54 -040012 * Copyright (C) 2009 Hewlett-Packard Development Company, L.P.
Paul Moore82c21bf2011-08-01 11:10:33 +000013 * Paul Moore <paul@paul-moore.com>
Jarkko Sakkinen5c6d1122010-12-07 13:34:01 +020014 * Copyright (C) 2010 Nokia Corporation
Jarkko Sakkinen84088ba2011-10-07 09:27:53 +030015 * Copyright (C) 2011 Intel Corporation.
Casey Schauflere114e472008-02-04 22:29:50 -080016 */
17
18#include <linux/xattr.h>
19#include <linux/pagemap.h>
20#include <linux/mount.h>
21#include <linux/stat.h>
Casey Schauflere114e472008-02-04 22:29:50 -080022#include <linux/kd.h>
23#include <asm/ioctls.h>
Paul Moore07feee82009-03-27 17:10:54 -040024#include <linux/ip.h>
Casey Schauflere114e472008-02-04 22:29:50 -080025#include <linux/tcp.h>
26#include <linux/udp.h>
Casey Schauflerc6739442013-05-22 18:42:56 -070027#include <linux/dccp.h>
Piotr Sawickid66a8ac2018-07-19 11:47:31 +020028#include <linux/icmpv6.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090029#include <linux/slab.h>
Casey Schauflere114e472008-02-04 22:29:50 -080030#include <linux/mutex.h>
Casey Schauflere114e472008-02-04 22:29:50 -080031#include <net/cipso_ipv4.h>
Casey Schauflerc6739442013-05-22 18:42:56 -070032#include <net/ip.h>
33#include <net/ipv6.h>
Ahmed S. Darwishd20bdda2008-04-30 08:34:10 +100034#include <linux/audit.h>
Nick Black1fd7317d2009-09-22 16:43:33 -070035#include <linux/magic.h>
Eric Paris2a7dba32011-02-01 11:05:39 -050036#include <linux/dcache.h>
Jarkko Sakkinen16014d82011-10-14 13:16:24 +030037#include <linux/personality.h>
Al Viro40401532012-02-13 03:58:52 +000038#include <linux/msg.h>
39#include <linux/shm.h>
40#include <linux/binfmts.h>
Vivek Trivedi3bf27892015-06-22 15:36:06 +053041#include <linux/parser.h>
David Howells2febd252018-11-01 23:07:24 +000042#include <linux/fs_context.h>
43#include <linux/fs_parser.h>
Casey Schauflere114e472008-02-04 22:29:50 -080044#include "smack.h"
45
Jarkko Sakkinen5c6d1122010-12-07 13:34:01 +020046#define TRANS_TRUE "TRUE"
47#define TRANS_TRUE_SIZE 4
48
Casey Schauflerc6739442013-05-22 18:42:56 -070049#define SMK_CONNECTING 0
50#define SMK_RECEIVING 1
51#define SMK_SENDING 2
52
Arnd Bergmann00720f02020-04-08 21:04:31 +020053static DEFINE_MUTEX(smack_ipv6_lock);
Geliang Tang8b549ef2015-09-27 23:10:25 +080054static LIST_HEAD(smk_ipv6_port_list);
Rohit1a5b4722014-10-15 17:40:41 +053055static struct kmem_cache *smack_inode_cache;
Casey Schaufler4e328b02019-04-02 11:37:12 -070056struct kmem_cache *smack_rule_cache;
Casey Schaufler69f287a2014-12-12 17:08:40 -080057int smack_enabled;
Casey Schauflerc6739442013-05-22 18:42:56 -070058
Al Viroc3300aa2018-12-16 01:52:24 -050059#define A(s) {"smack"#s, sizeof("smack"#s) - 1, Opt_##s}
60static struct {
61 const char *name;
62 int len;
63 int opt;
64} smk_mount_opts[] = {
Casey Schaufler6e7739f2019-05-31 11:53:33 +010065 {"smackfsdef", sizeof("smackfsdef") - 1, Opt_fsdefault},
Al Viroc3300aa2018-12-16 01:52:24 -050066 A(fsdefault), A(fsfloor), A(fshat), A(fsroot), A(fstransmute)
Vivek Trivedi3bf27892015-06-22 15:36:06 +053067};
Al Viroc3300aa2018-12-16 01:52:24 -050068#undef A
69
70static int match_opt_prefix(char *s, int l, char **arg)
71{
72 int i;
73
74 for (i = 0; i < ARRAY_SIZE(smk_mount_opts); i++) {
75 size_t len = smk_mount_opts[i].len;
76 if (len > l || memcmp(s, smk_mount_opts[i].name, len))
77 continue;
78 if (len == l || s[len] != '=')
79 continue;
80 *arg = s + len + 1;
81 return smk_mount_opts[i].opt;
82 }
83 return Opt_error;
84}
Vivek Trivedi3bf27892015-06-22 15:36:06 +053085
Casey Schaufler3d04c922015-08-12 11:56:02 -070086#ifdef CONFIG_SECURITY_SMACK_BRINGUP
87static char *smk_bu_mess[] = {
88 "Bringup Error", /* Unused */
89 "Bringup", /* SMACK_BRINGUP_ALLOW */
90 "Unconfined Subject", /* SMACK_UNCONFINED_SUBJECT */
91 "Unconfined Object", /* SMACK_UNCONFINED_OBJECT */
92};
93
Casey Schauflerd166c802014-08-27 14:51:27 -070094static void smk_bu_mode(int mode, char *s)
95{
96 int i = 0;
97
98 if (mode & MAY_READ)
99 s[i++] = 'r';
100 if (mode & MAY_WRITE)
101 s[i++] = 'w';
102 if (mode & MAY_EXEC)
103 s[i++] = 'x';
104 if (mode & MAY_APPEND)
105 s[i++] = 'a';
106 if (mode & MAY_TRANSMUTE)
107 s[i++] = 't';
108 if (mode & MAY_LOCK)
109 s[i++] = 'l';
110 if (i == 0)
111 s[i++] = '-';
112 s[i] = '\0';
113}
114#endif
115
116#ifdef CONFIG_SECURITY_SMACK_BRINGUP
Lukasz Pawelczyk21c7eae2014-08-29 17:02:55 +0200117static int smk_bu_note(char *note, struct smack_known *sskp,
118 struct smack_known *oskp, int mode, int rc)
Casey Schauflerd166c802014-08-27 14:51:27 -0700119{
120 char acc[SMK_NUM_ACCESS_TYPE + 1];
121
122 if (rc <= 0)
123 return rc;
Casey Schauflerbf4b2fe2015-03-21 18:26:40 -0700124 if (rc > SMACK_UNCONFINED_OBJECT)
125 rc = 0;
Casey Schauflerd166c802014-08-27 14:51:27 -0700126
127 smk_bu_mode(mode, acc);
Casey Schauflerbf4b2fe2015-03-21 18:26:40 -0700128 pr_info("Smack %s: (%s %s %s) %s\n", smk_bu_mess[rc],
Lukasz Pawelczyk21c7eae2014-08-29 17:02:55 +0200129 sskp->smk_known, oskp->smk_known, acc, note);
Casey Schauflerd166c802014-08-27 14:51:27 -0700130 return 0;
131}
132#else
Lukasz Pawelczyk21c7eae2014-08-29 17:02:55 +0200133#define smk_bu_note(note, sskp, oskp, mode, RC) (RC)
Casey Schauflerd166c802014-08-27 14:51:27 -0700134#endif
135
136#ifdef CONFIG_SECURITY_SMACK_BRINGUP
Lukasz Pawelczyk21c7eae2014-08-29 17:02:55 +0200137static int smk_bu_current(char *note, struct smack_known *oskp,
138 int mode, int rc)
Casey Schauflerd166c802014-08-27 14:51:27 -0700139{
Casey Schauflerb17103a2018-11-09 16:12:56 -0800140 struct task_smack *tsp = smack_cred(current_cred());
Casey Schauflerd166c802014-08-27 14:51:27 -0700141 char acc[SMK_NUM_ACCESS_TYPE + 1];
142
143 if (rc <= 0)
144 return rc;
Casey Schauflerbf4b2fe2015-03-21 18:26:40 -0700145 if (rc > SMACK_UNCONFINED_OBJECT)
146 rc = 0;
Casey Schauflerd166c802014-08-27 14:51:27 -0700147
148 smk_bu_mode(mode, acc);
Casey Schauflerbf4b2fe2015-03-21 18:26:40 -0700149 pr_info("Smack %s: (%s %s %s) %s %s\n", smk_bu_mess[rc],
Lukasz Pawelczyk21c7eae2014-08-29 17:02:55 +0200150 tsp->smk_task->smk_known, oskp->smk_known,
151 acc, current->comm, note);
Casey Schauflerd166c802014-08-27 14:51:27 -0700152 return 0;
153}
154#else
Lukasz Pawelczyk21c7eae2014-08-29 17:02:55 +0200155#define smk_bu_current(note, oskp, mode, RC) (RC)
Casey Schauflerd166c802014-08-27 14:51:27 -0700156#endif
157
158#ifdef CONFIG_SECURITY_SMACK_BRINGUP
159static int smk_bu_task(struct task_struct *otp, int mode, int rc)
160{
Casey Schauflerb17103a2018-11-09 16:12:56 -0800161 struct task_smack *tsp = smack_cred(current_cred());
Andrey Ryabinin6d1cff22015-01-13 18:52:40 +0300162 struct smack_known *smk_task = smk_of_task_struct(otp);
Casey Schauflerd166c802014-08-27 14:51:27 -0700163 char acc[SMK_NUM_ACCESS_TYPE + 1];
164
165 if (rc <= 0)
166 return rc;
Casey Schauflerbf4b2fe2015-03-21 18:26:40 -0700167 if (rc > SMACK_UNCONFINED_OBJECT)
168 rc = 0;
Casey Schauflerd166c802014-08-27 14:51:27 -0700169
170 smk_bu_mode(mode, acc);
Casey Schauflerbf4b2fe2015-03-21 18:26:40 -0700171 pr_info("Smack %s: (%s %s %s) %s to %s\n", smk_bu_mess[rc],
Andrey Ryabinin6d1cff22015-01-13 18:52:40 +0300172 tsp->smk_task->smk_known, smk_task->smk_known, acc,
Casey Schauflerd166c802014-08-27 14:51:27 -0700173 current->comm, otp->comm);
174 return 0;
175}
176#else
177#define smk_bu_task(otp, mode, RC) (RC)
178#endif
179
180#ifdef CONFIG_SECURITY_SMACK_BRINGUP
181static int smk_bu_inode(struct inode *inode, int mode, int rc)
182{
Casey Schauflerb17103a2018-11-09 16:12:56 -0800183 struct task_smack *tsp = smack_cred(current_cred());
Casey Schauflerfb4021b2018-11-12 12:43:01 -0800184 struct inode_smack *isp = smack_inode(inode);
Casey Schauflerd166c802014-08-27 14:51:27 -0700185 char acc[SMK_NUM_ACCESS_TYPE + 1];
186
Casey Schauflerbf4b2fe2015-03-21 18:26:40 -0700187 if (isp->smk_flags & SMK_INODE_IMPURE)
188 pr_info("Smack Unconfined Corruption: inode=(%s %ld) %s\n",
189 inode->i_sb->s_id, inode->i_ino, current->comm);
190
Casey Schauflerd166c802014-08-27 14:51:27 -0700191 if (rc <= 0)
192 return rc;
Casey Schauflerbf4b2fe2015-03-21 18:26:40 -0700193 if (rc > SMACK_UNCONFINED_OBJECT)
194 rc = 0;
195 if (rc == SMACK_UNCONFINED_SUBJECT &&
196 (mode & (MAY_WRITE | MAY_APPEND)))
197 isp->smk_flags |= SMK_INODE_IMPURE;
Casey Schauflerd166c802014-08-27 14:51:27 -0700198
199 smk_bu_mode(mode, acc);
Casey Schauflerbf4b2fe2015-03-21 18:26:40 -0700200
201 pr_info("Smack %s: (%s %s %s) inode=(%s %ld) %s\n", smk_bu_mess[rc],
202 tsp->smk_task->smk_known, isp->smk_inode->smk_known, acc,
Casey Schauflerd166c802014-08-27 14:51:27 -0700203 inode->i_sb->s_id, inode->i_ino, current->comm);
204 return 0;
205}
206#else
207#define smk_bu_inode(inode, mode, RC) (RC)
208#endif
209
210#ifdef CONFIG_SECURITY_SMACK_BRINGUP
211static int smk_bu_file(struct file *file, int mode, int rc)
212{
Casey Schauflerb17103a2018-11-09 16:12:56 -0800213 struct task_smack *tsp = smack_cred(current_cred());
Casey Schauflerd166c802014-08-27 14:51:27 -0700214 struct smack_known *sskp = tsp->smk_task;
Casey Schaufler5e7270a2014-12-12 17:19:19 -0800215 struct inode *inode = file_inode(file);
Casey Schauflerfb4021b2018-11-12 12:43:01 -0800216 struct inode_smack *isp = smack_inode(inode);
Casey Schauflerd166c802014-08-27 14:51:27 -0700217 char acc[SMK_NUM_ACCESS_TYPE + 1];
218
Casey Schauflerbf4b2fe2015-03-21 18:26:40 -0700219 if (isp->smk_flags & SMK_INODE_IMPURE)
220 pr_info("Smack Unconfined Corruption: inode=(%s %ld) %s\n",
221 inode->i_sb->s_id, inode->i_ino, current->comm);
222
Casey Schauflerd166c802014-08-27 14:51:27 -0700223 if (rc <= 0)
224 return rc;
Casey Schauflerbf4b2fe2015-03-21 18:26:40 -0700225 if (rc > SMACK_UNCONFINED_OBJECT)
226 rc = 0;
Casey Schauflerd166c802014-08-27 14:51:27 -0700227
228 smk_bu_mode(mode, acc);
Casey Schauflerbf4b2fe2015-03-21 18:26:40 -0700229 pr_info("Smack %s: (%s %s %s) file=(%s %ld %pD) %s\n", smk_bu_mess[rc],
Casey Schaufler5e7270a2014-12-12 17:19:19 -0800230 sskp->smk_known, smk_of_inode(inode)->smk_known, acc,
Al Viroa4555892014-10-21 20:11:25 -0400231 inode->i_sb->s_id, inode->i_ino, file,
Casey Schauflerd166c802014-08-27 14:51:27 -0700232 current->comm);
233 return 0;
234}
235#else
236#define smk_bu_file(file, mode, RC) (RC)
237#endif
238
239#ifdef CONFIG_SECURITY_SMACK_BRINGUP
240static int smk_bu_credfile(const struct cred *cred, struct file *file,
241 int mode, int rc)
242{
Casey Schauflerb17103a2018-11-09 16:12:56 -0800243 struct task_smack *tsp = smack_cred(cred);
Casey Schauflerd166c802014-08-27 14:51:27 -0700244 struct smack_known *sskp = tsp->smk_task;
Al Viro45063092016-12-04 18:24:56 -0500245 struct inode *inode = file_inode(file);
Casey Schauflerfb4021b2018-11-12 12:43:01 -0800246 struct inode_smack *isp = smack_inode(inode);
Casey Schauflerd166c802014-08-27 14:51:27 -0700247 char acc[SMK_NUM_ACCESS_TYPE + 1];
248
Casey Schauflerbf4b2fe2015-03-21 18:26:40 -0700249 if (isp->smk_flags & SMK_INODE_IMPURE)
250 pr_info("Smack Unconfined Corruption: inode=(%s %ld) %s\n",
251 inode->i_sb->s_id, inode->i_ino, current->comm);
252
Casey Schauflerd166c802014-08-27 14:51:27 -0700253 if (rc <= 0)
254 return rc;
Casey Schauflerbf4b2fe2015-03-21 18:26:40 -0700255 if (rc > SMACK_UNCONFINED_OBJECT)
256 rc = 0;
Casey Schauflerd166c802014-08-27 14:51:27 -0700257
258 smk_bu_mode(mode, acc);
Casey Schauflerbf4b2fe2015-03-21 18:26:40 -0700259 pr_info("Smack %s: (%s %s %s) file=(%s %ld %pD) %s\n", smk_bu_mess[rc],
Lukasz Pawelczyk21c7eae2014-08-29 17:02:55 +0200260 sskp->smk_known, smk_of_inode(inode)->smk_known, acc,
Al Viroa4555892014-10-21 20:11:25 -0400261 inode->i_sb->s_id, inode->i_ino, file,
Casey Schauflerd166c802014-08-27 14:51:27 -0700262 current->comm);
263 return 0;
264}
265#else
266#define smk_bu_credfile(cred, file, mode, RC) (RC)
267#endif
268
Casey Schauflere114e472008-02-04 22:29:50 -0800269/**
270 * smk_fetch - Fetch the smack label from a file.
Lukasz Pawelczyk1a289792014-11-26 15:31:06 +0100271 * @name: type of the label (attribute)
Casey Schauflere114e472008-02-04 22:29:50 -0800272 * @ip: a pointer to the inode
273 * @dp: a pointer to the dentry
274 *
Lukasz Pawelczyke774ad62015-04-20 17:12:54 +0200275 * Returns a pointer to the master list entry for the Smack label,
276 * NULL if there was no label to fetch, or an error code.
Casey Schauflere114e472008-02-04 22:29:50 -0800277 */
Casey Schaufler2f823ff2013-05-22 18:43:03 -0700278static struct smack_known *smk_fetch(const char *name, struct inode *ip,
279 struct dentry *dp)
Casey Schauflere114e472008-02-04 22:29:50 -0800280{
281 int rc;
Casey Schauflerf7112e62012-05-06 15:22:02 -0700282 char *buffer;
Casey Schaufler2f823ff2013-05-22 18:43:03 -0700283 struct smack_known *skp = NULL;
Casey Schauflere114e472008-02-04 22:29:50 -0800284
Andreas Gruenbacher5d6c3192016-09-29 17:48:42 +0200285 if (!(ip->i_opflags & IOP_XATTR))
Lukasz Pawelczyke774ad62015-04-20 17:12:54 +0200286 return ERR_PTR(-EOPNOTSUPP);
Casey Schauflere114e472008-02-04 22:29:50 -0800287
Eric Biggerse5bfad32019-08-21 22:54:41 -0700288 buffer = kzalloc(SMK_LONGLABEL, GFP_NOFS);
Casey Schauflerf7112e62012-05-06 15:22:02 -0700289 if (buffer == NULL)
Lukasz Pawelczyke774ad62015-04-20 17:12:54 +0200290 return ERR_PTR(-ENOMEM);
Casey Schauflere114e472008-02-04 22:29:50 -0800291
Andreas Gruenbacher5d6c3192016-09-29 17:48:42 +0200292 rc = __vfs_getxattr(dp, ip, name, buffer, SMK_LONGLABEL);
Lukasz Pawelczyke774ad62015-04-20 17:12:54 +0200293 if (rc < 0)
294 skp = ERR_PTR(rc);
295 else if (rc == 0)
296 skp = NULL;
297 else
Casey Schaufler2f823ff2013-05-22 18:43:03 -0700298 skp = smk_import_entry(buffer, rc);
Casey Schauflerf7112e62012-05-06 15:22:02 -0700299
300 kfree(buffer);
301
Casey Schaufler2f823ff2013-05-22 18:43:03 -0700302 return skp;
Casey Schauflere114e472008-02-04 22:29:50 -0800303}
304
305/**
Casey Schauflerafb1cbe32018-09-21 17:19:29 -0700306 * init_inode_smack - initialize an inode security blob
luanshia1a07f22019-07-05 10:35:20 +0800307 * @inode: inode to extract the info from
Lukasz Pawelczyk21c7eae2014-08-29 17:02:55 +0200308 * @skp: a pointer to the Smack label entry to use in the blob
Casey Schauflere114e472008-02-04 22:29:50 -0800309 *
Casey Schauflere114e472008-02-04 22:29:50 -0800310 */
Casey Schauflerafb1cbe32018-09-21 17:19:29 -0700311static void init_inode_smack(struct inode *inode, struct smack_known *skp)
Casey Schauflere114e472008-02-04 22:29:50 -0800312{
Casey Schauflerafb1cbe32018-09-21 17:19:29 -0700313 struct inode_smack *isp = smack_inode(inode);
Casey Schauflere114e472008-02-04 22:29:50 -0800314
Lukasz Pawelczyk21c7eae2014-08-29 17:02:55 +0200315 isp->smk_inode = skp;
Casey Schauflere114e472008-02-04 22:29:50 -0800316 isp->smk_flags = 0;
317 mutex_init(&isp->smk_lock);
Casey Schauflere114e472008-02-04 22:29:50 -0800318}
319
Casey Schaufler7898e1f2011-01-17 08:05:27 -0800320/**
Casey Schauflerbbd36622018-11-12 09:30:56 -0800321 * init_task_smack - initialize a task security blob
322 * @tsp: blob to initialize
Lukasz Pawelczyk1a289792014-11-26 15:31:06 +0100323 * @task: a pointer to the Smack label for the running task
324 * @forked: a pointer to the Smack label for the forked task
Casey Schaufler7898e1f2011-01-17 08:05:27 -0800325 *
Casey Schaufler7898e1f2011-01-17 08:05:27 -0800326 */
Casey Schauflerbbd36622018-11-12 09:30:56 -0800327static void init_task_smack(struct task_smack *tsp, struct smack_known *task,
328 struct smack_known *forked)
Casey Schaufler7898e1f2011-01-17 08:05:27 -0800329{
Casey Schaufler7898e1f2011-01-17 08:05:27 -0800330 tsp->smk_task = task;
331 tsp->smk_forked = forked;
332 INIT_LIST_HEAD(&tsp->smk_rules);
Zbigniew Jasinski38416e52015-10-19 18:23:53 +0200333 INIT_LIST_HEAD(&tsp->smk_relabel);
Casey Schaufler7898e1f2011-01-17 08:05:27 -0800334 mutex_init(&tsp->smk_rules_lock);
Casey Schaufler7898e1f2011-01-17 08:05:27 -0800335}
336
337/**
338 * smk_copy_rules - copy a rule set
Lukasz Pawelczyk1a289792014-11-26 15:31:06 +0100339 * @nhead: new rules header pointer
340 * @ohead: old rules header pointer
341 * @gfp: type of the memory for the allocation
Casey Schaufler7898e1f2011-01-17 08:05:27 -0800342 *
343 * Returns 0 on success, -ENOMEM on error
344 */
345static int smk_copy_rules(struct list_head *nhead, struct list_head *ohead,
346 gfp_t gfp)
347{
348 struct smack_rule *nrp;
349 struct smack_rule *orp;
350 int rc = 0;
351
Casey Schaufler7898e1f2011-01-17 08:05:27 -0800352 list_for_each_entry_rcu(orp, ohead, list) {
Casey Schaufler4e328b02019-04-02 11:37:12 -0700353 nrp = kmem_cache_zalloc(smack_rule_cache, gfp);
Casey Schaufler7898e1f2011-01-17 08:05:27 -0800354 if (nrp == NULL) {
355 rc = -ENOMEM;
356 break;
357 }
358 *nrp = *orp;
359 list_add_rcu(&nrp->list, nhead);
360 }
361 return rc;
362}
363
Lukasz Pawelczyk56638842014-03-11 17:07:05 +0100364/**
Zbigniew Jasinski38416e52015-10-19 18:23:53 +0200365 * smk_copy_relabel - copy smk_relabel labels list
366 * @nhead: new rules header pointer
367 * @ohead: old rules header pointer
368 * @gfp: type of the memory for the allocation
369 *
370 * Returns 0 on success, -ENOMEM on error
371 */
372static int smk_copy_relabel(struct list_head *nhead, struct list_head *ohead,
373 gfp_t gfp)
374{
375 struct smack_known_list_elem *nklep;
376 struct smack_known_list_elem *oklep;
377
Zbigniew Jasinski38416e52015-10-19 18:23:53 +0200378 list_for_each_entry(oklep, ohead, list) {
379 nklep = kzalloc(sizeof(struct smack_known_list_elem), gfp);
380 if (nklep == NULL) {
381 smk_destroy_label_list(nhead);
382 return -ENOMEM;
383 }
384 nklep->smk_label = oklep->smk_label;
385 list_add(&nklep->list, nhead);
386 }
387
388 return 0;
389}
390
391/**
Lukasz Pawelczyk56638842014-03-11 17:07:05 +0100392 * smk_ptrace_mode - helper function for converting PTRACE_MODE_* into MAY_*
393 * @mode - input mode in form of PTRACE_MODE_*
394 *
395 * Returns a converted MAY_* mode usable by smack rules
396 */
397static inline unsigned int smk_ptrace_mode(unsigned int mode)
398{
Jann Horn3dfb7d82016-01-20 15:00:01 -0800399 if (mode & PTRACE_MODE_ATTACH)
Lukasz Pawelczyk56638842014-03-11 17:07:05 +0100400 return MAY_READWRITE;
Jann Horn3dfb7d82016-01-20 15:00:01 -0800401 if (mode & PTRACE_MODE_READ)
402 return MAY_READ;
Lukasz Pawelczyk56638842014-03-11 17:07:05 +0100403
404 return 0;
405}
406
407/**
408 * smk_ptrace_rule_check - helper for ptrace access
409 * @tracer: tracer process
Lukasz Pawelczyk21c7eae2014-08-29 17:02:55 +0200410 * @tracee_known: label entry of the process that's about to be traced
Lukasz Pawelczyk56638842014-03-11 17:07:05 +0100411 * @mode: ptrace attachment mode (PTRACE_MODE_*)
412 * @func: name of the function that called us, used for audit
413 *
414 * Returns 0 on access granted, -error on error
415 */
Lukasz Pawelczyk21c7eae2014-08-29 17:02:55 +0200416static int smk_ptrace_rule_check(struct task_struct *tracer,
417 struct smack_known *tracee_known,
Lukasz Pawelczyk56638842014-03-11 17:07:05 +0100418 unsigned int mode, const char *func)
419{
420 int rc;
421 struct smk_audit_info ad, *saip = NULL;
422 struct task_smack *tsp;
Lukasz Pawelczyk21c7eae2014-08-29 17:02:55 +0200423 struct smack_known *tracer_known;
Casey Schauflerdcb569c2018-09-18 16:09:16 -0700424 const struct cred *tracercred;
Lukasz Pawelczyk56638842014-03-11 17:07:05 +0100425
426 if ((mode & PTRACE_MODE_NOAUDIT) == 0) {
427 smk_ad_init(&ad, func, LSM_AUDIT_DATA_TASK);
428 smk_ad_setfield_u_tsk(&ad, tracer);
429 saip = &ad;
430 }
431
Andrey Ryabinin6d1cff22015-01-13 18:52:40 +0300432 rcu_read_lock();
Casey Schauflerdcb569c2018-09-18 16:09:16 -0700433 tracercred = __task_cred(tracer);
Casey Schauflerb17103a2018-11-09 16:12:56 -0800434 tsp = smack_cred(tracercred);
Lukasz Pawelczyk21c7eae2014-08-29 17:02:55 +0200435 tracer_known = smk_of_task(tsp);
Lukasz Pawelczyk56638842014-03-11 17:07:05 +0100436
Lukasz Pawelczyk66867812014-03-11 17:07:06 +0100437 if ((mode & PTRACE_MODE_ATTACH) &&
438 (smack_ptrace_rule == SMACK_PTRACE_EXACT ||
439 smack_ptrace_rule == SMACK_PTRACE_DRACONIAN)) {
Lukasz Pawelczyk21c7eae2014-08-29 17:02:55 +0200440 if (tracer_known->smk_known == tracee_known->smk_known)
Lukasz Pawelczyk66867812014-03-11 17:07:06 +0100441 rc = 0;
442 else if (smack_ptrace_rule == SMACK_PTRACE_DRACONIAN)
443 rc = -EACCES;
Casey Schauflerdcb569c2018-09-18 16:09:16 -0700444 else if (smack_privileged_cred(CAP_SYS_PTRACE, tracercred))
Lukasz Pawelczyk66867812014-03-11 17:07:06 +0100445 rc = 0;
446 else
447 rc = -EACCES;
448
449 if (saip)
Lukasz Pawelczyk21c7eae2014-08-29 17:02:55 +0200450 smack_log(tracer_known->smk_known,
451 tracee_known->smk_known,
452 0, rc, saip);
Lukasz Pawelczyk66867812014-03-11 17:07:06 +0100453
Andrey Ryabinin6d1cff22015-01-13 18:52:40 +0300454 rcu_read_unlock();
Lukasz Pawelczyk66867812014-03-11 17:07:06 +0100455 return rc;
456 }
457
458 /* In case of rule==SMACK_PTRACE_DEFAULT or mode==PTRACE_MODE_READ */
Lukasz Pawelczyk21c7eae2014-08-29 17:02:55 +0200459 rc = smk_tskacc(tsp, tracee_known, smk_ptrace_mode(mode), saip);
Andrey Ryabinin6d1cff22015-01-13 18:52:40 +0300460
461 rcu_read_unlock();
Lukasz Pawelczyk56638842014-03-11 17:07:05 +0100462 return rc;
463}
464
Casey Schauflere114e472008-02-04 22:29:50 -0800465/*
466 * LSM hooks.
467 * We he, that is fun!
468 */
469
470/**
Ingo Molnar9e488582009-05-07 19:26:19 +1000471 * smack_ptrace_access_check - Smack approval on PTRACE_ATTACH
Casey Schauflere114e472008-02-04 22:29:50 -0800472 * @ctp: child task pointer
Lukasz Pawelczyk56638842014-03-11 17:07:05 +0100473 * @mode: ptrace attachment mode (PTRACE_MODE_*)
Casey Schauflere114e472008-02-04 22:29:50 -0800474 *
475 * Returns 0 if access is OK, an error code otherwise
476 *
Lukasz Pawelczyk56638842014-03-11 17:07:05 +0100477 * Do the capability checks.
Casey Schauflere114e472008-02-04 22:29:50 -0800478 */
Ingo Molnar9e488582009-05-07 19:26:19 +1000479static int smack_ptrace_access_check(struct task_struct *ctp, unsigned int mode)
Casey Schauflere114e472008-02-04 22:29:50 -0800480{
Casey Schaufler2f823ff2013-05-22 18:43:03 -0700481 struct smack_known *skp;
Casey Schauflere114e472008-02-04 22:29:50 -0800482
Andrey Ryabinin6d1cff22015-01-13 18:52:40 +0300483 skp = smk_of_task_struct(ctp);
Etienne Bassetecfcc532009-04-08 20:40:06 +0200484
Casey Schauflerb1d9e6b2015-05-02 15:11:42 -0700485 return smk_ptrace_rule_check(current, skp, mode, __func__);
David Howells5cd9c582008-08-14 11:37:28 +0100486}
Casey Schauflere114e472008-02-04 22:29:50 -0800487
David Howells5cd9c582008-08-14 11:37:28 +0100488/**
489 * smack_ptrace_traceme - Smack approval on PTRACE_TRACEME
490 * @ptp: parent task pointer
491 *
492 * Returns 0 if access is OK, an error code otherwise
493 *
Lukasz Pawelczyk56638842014-03-11 17:07:05 +0100494 * Do the capability checks, and require PTRACE_MODE_ATTACH.
David Howells5cd9c582008-08-14 11:37:28 +0100495 */
496static int smack_ptrace_traceme(struct task_struct *ptp)
497{
498 int rc;
Casey Schaufler2f823ff2013-05-22 18:43:03 -0700499 struct smack_known *skp;
David Howells5cd9c582008-08-14 11:37:28 +0100500
Casey Schauflerb17103a2018-11-09 16:12:56 -0800501 skp = smk_of_task(smack_cred(current_cred()));
Etienne Bassetecfcc532009-04-08 20:40:06 +0200502
Lukasz Pawelczyk21c7eae2014-08-29 17:02:55 +0200503 rc = smk_ptrace_rule_check(ptp, skp, PTRACE_MODE_ATTACH, __func__);
Casey Schauflere114e472008-02-04 22:29:50 -0800504 return rc;
505}
506
507/**
508 * smack_syslog - Smack approval on syslog
luanshia1a07f22019-07-05 10:35:20 +0800509 * @typefrom_file: unused
Casey Schauflere114e472008-02-04 22:29:50 -0800510 *
Casey Schauflere114e472008-02-04 22:29:50 -0800511 * Returns 0 on success, error code otherwise.
512 */
Eric Paris12b30522010-11-15 18:36:29 -0500513static int smack_syslog(int typefrom_file)
Casey Schauflere114e472008-02-04 22:29:50 -0800514{
Eric Paris12b30522010-11-15 18:36:29 -0500515 int rc = 0;
Casey Schaufler2f823ff2013-05-22 18:43:03 -0700516 struct smack_known *skp = smk_of_current();
Casey Schauflere114e472008-02-04 22:29:50 -0800517
Casey Schaufler1880eff2012-06-05 15:28:30 -0700518 if (smack_privileged(CAP_MAC_OVERRIDE))
Casey Schauflere114e472008-02-04 22:29:50 -0800519 return 0;
520
Casey Schaufler24ea1b62013-12-30 09:38:00 -0800521 if (smack_syslog_label != NULL && smack_syslog_label != skp)
Casey Schauflere114e472008-02-04 22:29:50 -0800522 rc = -EACCES;
523
524 return rc;
525}
526
Casey Schauflere114e472008-02-04 22:29:50 -0800527/*
528 * Superblock Hooks.
529 */
530
531/**
532 * smack_sb_alloc_security - allocate a superblock blob
533 * @sb: the superblock getting the blob
534 *
535 * Returns 0 on success or -ENOMEM on error.
536 */
537static int smack_sb_alloc_security(struct super_block *sb)
538{
539 struct superblock_smack *sbsp;
540
541 sbsp = kzalloc(sizeof(struct superblock_smack), GFP_KERNEL);
542
543 if (sbsp == NULL)
544 return -ENOMEM;
545
Lukasz Pawelczyk21c7eae2014-08-29 17:02:55 +0200546 sbsp->smk_root = &smack_known_floor;
547 sbsp->smk_default = &smack_known_floor;
548 sbsp->smk_floor = &smack_known_floor;
549 sbsp->smk_hat = &smack_known_hat;
Casey Schauflere830b392013-05-22 18:43:07 -0700550 /*
Seth Forshee9f50eda2015-09-23 15:16:06 -0500551 * SMK_SB_INITIALIZED will be zero from kzalloc.
Casey Schauflere830b392013-05-22 18:43:07 -0700552 */
Casey Schauflere114e472008-02-04 22:29:50 -0800553 sb->s_security = sbsp;
554
555 return 0;
556}
557
558/**
559 * smack_sb_free_security - free a superblock blob
560 * @sb: the superblock getting the blob
561 *
562 */
563static void smack_sb_free_security(struct super_block *sb)
564{
565 kfree(sb->s_security);
566 sb->s_security = NULL;
567}
568
Al Viro12085b12018-12-13 15:18:05 -0500569struct smack_mnt_opts {
570 const char *fsdefault, *fsfloor, *fshat, *fsroot, *fstransmute;
571};
572
Al Viro204cc0c2018-12-13 13:41:47 -0500573static void smack_free_mnt_opts(void *mnt_opts)
Casey Schauflere114e472008-02-04 22:29:50 -0800574{
Al Viro12085b12018-12-13 15:18:05 -0500575 struct smack_mnt_opts *opts = mnt_opts;
576 kfree(opts->fsdefault);
577 kfree(opts->fsfloor);
578 kfree(opts->fshat);
579 kfree(opts->fsroot);
580 kfree(opts->fstransmute);
Al Viro204cc0c2018-12-13 13:41:47 -0500581 kfree(opts);
Casey Schauflere114e472008-02-04 22:29:50 -0800582}
583
Al Viro55c0e5b2018-12-16 01:09:45 -0500584static int smack_add_opt(int token, const char *s, void **mnt_opts)
Vivek Trivedi3bf27892015-06-22 15:36:06 +0530585{
Al Viro55c0e5b2018-12-16 01:09:45 -0500586 struct smack_mnt_opts *opts = *mnt_opts;
Vivek Trivedi3bf27892015-06-22 15:36:06 +0530587
Al Viro55c0e5b2018-12-16 01:09:45 -0500588 if (!opts) {
589 opts = kzalloc(sizeof(struct smack_mnt_opts), GFP_KERNEL);
590 if (!opts)
591 return -ENOMEM;
592 *mnt_opts = opts;
Vivek Trivedi3bf27892015-06-22 15:36:06 +0530593 }
Al Viro55c0e5b2018-12-16 01:09:45 -0500594 if (!s)
595 return -ENOMEM;
Vivek Trivedi3bf27892015-06-22 15:36:06 +0530596
Al Viro55c0e5b2018-12-16 01:09:45 -0500597 switch (token) {
598 case Opt_fsdefault:
599 if (opts->fsdefault)
600 goto out_opt_err;
601 opts->fsdefault = s;
602 break;
603 case Opt_fsfloor:
604 if (opts->fsfloor)
605 goto out_opt_err;
606 opts->fsfloor = s;
607 break;
608 case Opt_fshat:
609 if (opts->fshat)
610 goto out_opt_err;
611 opts->fshat = s;
612 break;
613 case Opt_fsroot:
614 if (opts->fsroot)
615 goto out_opt_err;
616 opts->fsroot = s;
617 break;
618 case Opt_fstransmute:
619 if (opts->fstransmute)
620 goto out_opt_err;
621 opts->fstransmute = s;
622 break;
Vivek Trivedi3bf27892015-06-22 15:36:06 +0530623 }
Vivek Trivedi3bf27892015-06-22 15:36:06 +0530624 return 0;
625
626out_opt_err:
Vivek Trivedi3bf27892015-06-22 15:36:06 +0530627 pr_warn("Smack: duplicate mount options\n");
Al Viro55c0e5b2018-12-16 01:09:45 -0500628 return -EINVAL;
629}
Vivek Trivedi3bf27892015-06-22 15:36:06 +0530630
Al Viro0b520752018-12-23 16:02:47 -0500631/**
632 * smack_fs_context_dup - Duplicate the security data on fs_context duplication
633 * @fc: The new filesystem context.
634 * @src_fc: The source filesystem context being duplicated.
635 *
636 * Returns 0 on success or -ENOMEM on error.
637 */
638static int smack_fs_context_dup(struct fs_context *fc,
639 struct fs_context *src_fc)
640{
641 struct smack_mnt_opts *dst, *src = src_fc->security;
642
643 if (!src)
644 return 0;
645
646 fc->security = kzalloc(sizeof(struct smack_mnt_opts), GFP_KERNEL);
647 if (!fc->security)
648 return -ENOMEM;
649 dst = fc->security;
650
651 if (src->fsdefault) {
652 dst->fsdefault = kstrdup(src->fsdefault, GFP_KERNEL);
653 if (!dst->fsdefault)
654 return -ENOMEM;
655 }
656 if (src->fsfloor) {
657 dst->fsfloor = kstrdup(src->fsfloor, GFP_KERNEL);
658 if (!dst->fsfloor)
659 return -ENOMEM;
660 }
661 if (src->fshat) {
662 dst->fshat = kstrdup(src->fshat, GFP_KERNEL);
663 if (!dst->fshat)
664 return -ENOMEM;
665 }
666 if (src->fsroot) {
667 dst->fsroot = kstrdup(src->fsroot, GFP_KERNEL);
668 if (!dst->fsroot)
669 return -ENOMEM;
670 }
671 if (src->fstransmute) {
672 dst->fstransmute = kstrdup(src->fstransmute, GFP_KERNEL);
673 if (!dst->fstransmute)
674 return -ENOMEM;
675 }
676 return 0;
677}
678
Al Virod7167b12019-09-07 07:23:15 -0400679static const struct fs_parameter_spec smack_fs_parameters[] = {
Casey Schaufler6e7739f2019-05-31 11:53:33 +0100680 fsparam_string("smackfsdef", Opt_fsdefault),
681 fsparam_string("smackfsdefault", Opt_fsdefault),
682 fsparam_string("smackfsfloor", Opt_fsfloor),
683 fsparam_string("smackfshat", Opt_fshat),
684 fsparam_string("smackfsroot", Opt_fsroot),
685 fsparam_string("smackfstransmute", Opt_fstransmute),
David Howells2febd252018-11-01 23:07:24 +0000686 {}
687};
688
David Howells2febd252018-11-01 23:07:24 +0000689/**
690 * smack_fs_context_parse_param - Parse a single mount parameter
691 * @fc: The new filesystem context being constructed.
692 * @param: The parameter.
693 *
694 * Returns 0 on success, -ENOPARAM to pass the parameter on or anything else on
695 * error.
696 */
697static int smack_fs_context_parse_param(struct fs_context *fc,
698 struct fs_parameter *param)
699{
700 struct fs_parse_result result;
701 int opt, rc;
702
Al Virod7167b12019-09-07 07:23:15 -0400703 opt = fs_parse(fc, smack_fs_parameters, param, &result);
David Howells2febd252018-11-01 23:07:24 +0000704 if (opt < 0)
705 return opt;
706
707 rc = smack_add_opt(opt, param->string, &fc->security);
708 if (!rc)
709 param->string = NULL;
710 return rc;
711}
712
Al Virod2497e12018-12-16 01:37:06 -0500713static int smack_sb_eat_lsm_opts(char *options, void **mnt_opts)
Vivek Trivedi3bf27892015-06-22 15:36:06 +0530714{
Al Virod2497e12018-12-16 01:37:06 -0500715 char *from = options, *to = options;
716 bool first = true;
Vivek Trivedi3bf27892015-06-22 15:36:06 +0530717
Al Viroc3300aa2018-12-16 01:52:24 -0500718 while (1) {
719 char *next = strchr(from, ',');
720 int token, len, rc;
721 char *arg = NULL;
Vivek Trivedi3bf27892015-06-22 15:36:06 +0530722
Al Viroc3300aa2018-12-16 01:52:24 -0500723 if (next)
724 len = next - from;
725 else
726 len = strlen(from);
Vivek Trivedi3bf27892015-06-22 15:36:06 +0530727
Al Viroc3300aa2018-12-16 01:52:24 -0500728 token = match_opt_prefix(from, len, &arg);
Al Virod2497e12018-12-16 01:37:06 -0500729 if (token != Opt_error) {
730 arg = kmemdup_nul(arg, from + len - arg, GFP_KERNEL);
731 rc = smack_add_opt(token, arg, mnt_opts);
732 if (unlikely(rc)) {
733 kfree(arg);
734 if (*mnt_opts)
735 smack_free_mnt_opts(*mnt_opts);
736 *mnt_opts = NULL;
737 return rc;
738 }
739 } else {
740 if (!first) { // copy with preceding comma
741 from--;
742 len++;
743 }
744 if (to != from)
745 memmove(to, from, len);
746 to += len;
747 first = false;
Vivek Trivedi3bf27892015-06-22 15:36:06 +0530748 }
Al Viroc3300aa2018-12-16 01:52:24 -0500749 if (!from[len])
750 break;
751 from += len + 1;
Vivek Trivedi3bf27892015-06-22 15:36:06 +0530752 }
Al Virod2497e12018-12-16 01:37:06 -0500753 *to = '\0';
Vivek Trivedi3bf27892015-06-22 15:36:06 +0530754 return 0;
Vivek Trivedi3bf27892015-06-22 15:36:06 +0530755}
756
757/**
758 * smack_set_mnt_opts - set Smack specific mount options
Casey Schauflere114e472008-02-04 22:29:50 -0800759 * @sb: the file system superblock
luanshia1a07f22019-07-05 10:35:20 +0800760 * @mnt_opts: Smack mount options
Vivek Trivedi3bf27892015-06-22 15:36:06 +0530761 * @kern_flags: mount option from kernel space or user space
762 * @set_kern_flags: where to store converted mount opts
Casey Schauflere114e472008-02-04 22:29:50 -0800763 *
764 * Returns 0 on success, an error code on failure
Vivek Trivedi3bf27892015-06-22 15:36:06 +0530765 *
766 * Allow filesystems with binary mount data to explicitly set Smack mount
767 * labels.
Casey Schauflere114e472008-02-04 22:29:50 -0800768 */
Vivek Trivedi3bf27892015-06-22 15:36:06 +0530769static int smack_set_mnt_opts(struct super_block *sb,
Al Viro204cc0c2018-12-13 13:41:47 -0500770 void *mnt_opts,
Vivek Trivedi3bf27892015-06-22 15:36:06 +0530771 unsigned long kern_flags,
772 unsigned long *set_kern_flags)
Casey Schauflere114e472008-02-04 22:29:50 -0800773{
774 struct dentry *root = sb->s_root;
David Howellsc6f493d2015-03-17 22:26:22 +0000775 struct inode *inode = d_backing_inode(root);
Casey Schauflere114e472008-02-04 22:29:50 -0800776 struct superblock_smack *sp = sb->s_security;
777 struct inode_smack *isp;
Casey Schaufler24ea1b62013-12-30 09:38:00 -0800778 struct smack_known *skp;
Al Viro12085b12018-12-13 15:18:05 -0500779 struct smack_mnt_opts *opts = mnt_opts;
780 bool transmute = false;
Casey Schauflere114e472008-02-04 22:29:50 -0800781
Seth Forshee9f50eda2015-09-23 15:16:06 -0500782 if (sp->smk_flags & SMK_SB_INITIALIZED)
Casey Schauflere114e472008-02-04 22:29:50 -0800783 return 0;
Casey Schauflereb982cb2012-05-23 17:46:58 -0700784
Casey Schauflerafb1cbe32018-09-21 17:19:29 -0700785 if (inode->i_security == NULL) {
786 int rc = lsm_inode_alloc(inode);
787
788 if (rc)
789 return rc;
790 }
791
Himanshu Shukla2097f592016-11-10 16:19:52 +0530792 if (!smack_privileged(CAP_MAC_ADMIN)) {
793 /*
794 * Unprivileged mounts don't get to specify Smack values.
795 */
Al Viro12085b12018-12-13 15:18:05 -0500796 if (opts)
Himanshu Shukla2097f592016-11-10 16:19:52 +0530797 return -EPERM;
798 /*
799 * Unprivileged mounts get root and default from the caller.
800 */
801 skp = smk_of_current();
802 sp->smk_root = skp;
803 sp->smk_default = skp;
804 /*
805 * For a handful of fs types with no user-controlled
806 * backing store it's okay to trust security labels
807 * in the filesystem. The rest are untrusted.
808 */
809 if (sb->s_user_ns != &init_user_ns &&
810 sb->s_magic != SYSFS_MAGIC && sb->s_magic != TMPFS_MAGIC &&
811 sb->s_magic != RAMFS_MAGIC) {
Al Viro12085b12018-12-13 15:18:05 -0500812 transmute = true;
Himanshu Shukla2097f592016-11-10 16:19:52 +0530813 sp->smk_flags |= SMK_SB_UNTRUSTED;
814 }
815 }
816
Seth Forshee9f50eda2015-09-23 15:16:06 -0500817 sp->smk_flags |= SMK_SB_INITIALIZED;
Casey Schauflere114e472008-02-04 22:29:50 -0800818
Al Viro12085b12018-12-13 15:18:05 -0500819 if (opts) {
820 if (opts->fsdefault) {
821 skp = smk_import_entry(opts->fsdefault, 0);
Lukasz Pawelczyke774ad62015-04-20 17:12:54 +0200822 if (IS_ERR(skp))
823 return PTR_ERR(skp);
824 sp->smk_default = skp;
Al Viro12085b12018-12-13 15:18:05 -0500825 }
826 if (opts->fsfloor) {
827 skp = smk_import_entry(opts->fsfloor, 0);
Vivek Trivedi3bf27892015-06-22 15:36:06 +0530828 if (IS_ERR(skp))
829 return PTR_ERR(skp);
830 sp->smk_floor = skp;
Al Viro12085b12018-12-13 15:18:05 -0500831 }
832 if (opts->fshat) {
833 skp = smk_import_entry(opts->fshat, 0);
Vivek Trivedi3bf27892015-06-22 15:36:06 +0530834 if (IS_ERR(skp))
835 return PTR_ERR(skp);
836 sp->smk_hat = skp;
Al Viro12085b12018-12-13 15:18:05 -0500837 }
838 if (opts->fsroot) {
839 skp = smk_import_entry(opts->fsroot, 0);
Lukasz Pawelczyke774ad62015-04-20 17:12:54 +0200840 if (IS_ERR(skp))
841 return PTR_ERR(skp);
842 sp->smk_root = skp;
Al Viro12085b12018-12-13 15:18:05 -0500843 }
844 if (opts->fstransmute) {
845 skp = smk_import_entry(opts->fstransmute, 0);
Lukasz Pawelczyke774ad62015-04-20 17:12:54 +0200846 if (IS_ERR(skp))
847 return PTR_ERR(skp);
848 sp->smk_root = skp;
Al Viro12085b12018-12-13 15:18:05 -0500849 transmute = true;
Casey Schauflere114e472008-02-04 22:29:50 -0800850 }
851 }
852
853 /*
854 * Initialize the root inode.
855 */
Casey Schauflerafb1cbe32018-09-21 17:19:29 -0700856 init_inode_smack(inode, sp->smk_root);
Casey Schauflere114e472008-02-04 22:29:50 -0800857
Casey Schauflerafb1cbe32018-09-21 17:19:29 -0700858 if (transmute) {
859 isp = smack_inode(inode);
Casey Schauflere830b392013-05-22 18:43:07 -0700860 isp->smk_flags |= SMK_INODE_TRANSMUTE;
Casey Schauflerafb1cbe32018-09-21 17:19:29 -0700861 }
Casey Schauflere830b392013-05-22 18:43:07 -0700862
Casey Schauflere114e472008-02-04 22:29:50 -0800863 return 0;
864}
865
866/**
867 * smack_sb_statfs - Smack check on statfs
868 * @dentry: identifies the file system in question
869 *
870 * Returns 0 if current can read the floor of the filesystem,
871 * and error code otherwise
872 */
873static int smack_sb_statfs(struct dentry *dentry)
874{
875 struct superblock_smack *sbp = dentry->d_sb->s_security;
Etienne Bassetecfcc532009-04-08 20:40:06 +0200876 int rc;
877 struct smk_audit_info ad;
Casey Schauflere114e472008-02-04 22:29:50 -0800878
Eric Parisa2694342011-04-25 13:10:27 -0400879 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
Etienne Bassetecfcc532009-04-08 20:40:06 +0200880 smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
881
882 rc = smk_curacc(sbp->smk_floor, MAY_READ, &ad);
Casey Schauflerd166c802014-08-27 14:51:27 -0700883 rc = smk_bu_current("statfs", sbp->smk_floor, MAY_READ, rc);
Etienne Bassetecfcc532009-04-08 20:40:06 +0200884 return rc;
Casey Schauflere114e472008-02-04 22:29:50 -0800885}
886
Casey Schauflere114e472008-02-04 22:29:50 -0800887/*
Casey Schaufler676dac42010-12-02 06:43:39 -0800888 * BPRM hooks
889 */
890
Casey Schauflerce8a4322011-09-29 18:21:01 -0700891/**
892 * smack_bprm_set_creds - set creds for exec
893 * @bprm: the exec information
894 *
Lukasz Pawelczyk56638842014-03-11 17:07:05 +0100895 * Returns 0 if it gets a blob, -EPERM if exec forbidden and -ENOMEM otherwise
Casey Schauflerce8a4322011-09-29 18:21:01 -0700896 */
Casey Schaufler676dac42010-12-02 06:43:39 -0800897static int smack_bprm_set_creds(struct linux_binprm *bprm)
898{
Al Viro496ad9a2013-01-23 17:07:38 -0500899 struct inode *inode = file_inode(bprm->file);
Casey Schauflerb17103a2018-11-09 16:12:56 -0800900 struct task_smack *bsp = smack_cred(bprm->cred);
Casey Schaufler676dac42010-12-02 06:43:39 -0800901 struct inode_smack *isp;
Seth Forshee809c02e2016-04-26 14:36:22 -0500902 struct superblock_smack *sbsp;
Casey Schaufler676dac42010-12-02 06:43:39 -0800903 int rc;
904
Kees Cookddb4a142017-07-18 15:25:23 -0700905 if (bprm->called_set_creds)
Casey Schaufler676dac42010-12-02 06:43:39 -0800906 return 0;
907
Casey Schauflerfb4021b2018-11-12 12:43:01 -0800908 isp = smack_inode(inode);
Jarkko Sakkinen84088ba2011-10-07 09:27:53 +0300909 if (isp->smk_task == NULL || isp->smk_task == bsp->smk_task)
Casey Schaufler676dac42010-12-02 06:43:39 -0800910 return 0;
911
Seth Forshee809c02e2016-04-26 14:36:22 -0500912 sbsp = inode->i_sb->s_security;
913 if ((sbsp->smk_flags & SMK_SB_UNTRUSTED) &&
914 isp->smk_task != sbsp->smk_root)
915 return 0;
916
Eric W. Biederman9227dd22017-01-23 17:26:31 +1300917 if (bprm->unsafe & LSM_UNSAFE_PTRACE) {
Lukasz Pawelczyk56638842014-03-11 17:07:05 +0100918 struct task_struct *tracer;
919 rc = 0;
920
921 rcu_read_lock();
922 tracer = ptrace_parent(current);
923 if (likely(tracer != NULL))
924 rc = smk_ptrace_rule_check(tracer,
Lukasz Pawelczyk21c7eae2014-08-29 17:02:55 +0200925 isp->smk_task,
Lukasz Pawelczyk56638842014-03-11 17:07:05 +0100926 PTRACE_MODE_ATTACH,
927 __func__);
928 rcu_read_unlock();
929
930 if (rc != 0)
931 return rc;
Jann Horn3675f052019-07-04 20:44:44 +0200932 }
933 if (bprm->unsafe & ~LSM_UNSAFE_PTRACE)
Jarkko Sakkinen84088ba2011-10-07 09:27:53 +0300934 return -EPERM;
Casey Schaufler676dac42010-12-02 06:43:39 -0800935
Jarkko Sakkinen84088ba2011-10-07 09:27:53 +0300936 bsp->smk_task = isp->smk_task;
937 bprm->per_clear |= PER_CLEAR_ON_SETID;
Casey Schaufler676dac42010-12-02 06:43:39 -0800938
Kees Cookccbb6e12017-07-18 15:25:26 -0700939 /* Decide if this is a secure exec. */
940 if (bsp->smk_task != bsp->smk_forked)
941 bprm->secureexec = 1;
942
Casey Schaufler676dac42010-12-02 06:43:39 -0800943 return 0;
944}
945
946/*
Casey Schauflere114e472008-02-04 22:29:50 -0800947 * Inode hooks
948 */
949
950/**
951 * smack_inode_alloc_security - allocate an inode blob
Randy Dunlap251a2a92009-02-18 11:42:33 -0800952 * @inode: the inode in need of a blob
Casey Schauflere114e472008-02-04 22:29:50 -0800953 *
luanshia1a07f22019-07-05 10:35:20 +0800954 * Returns 0
Casey Schauflere114e472008-02-04 22:29:50 -0800955 */
956static int smack_inode_alloc_security(struct inode *inode)
957{
Casey Schaufler2f823ff2013-05-22 18:43:03 -0700958 struct smack_known *skp = smk_of_current();
959
Casey Schauflerafb1cbe32018-09-21 17:19:29 -0700960 init_inode_smack(inode, skp);
Casey Schauflere114e472008-02-04 22:29:50 -0800961 return 0;
962}
963
964/**
Casey Schauflere114e472008-02-04 22:29:50 -0800965 * smack_inode_init_security - copy out the smack from an inode
Lukasz Pawelczyke95ef492014-08-29 17:02:53 +0200966 * @inode: the newly created inode
967 * @dir: containing directory object
Eric Paris2a7dba32011-02-01 11:05:39 -0500968 * @qstr: unused
Casey Schauflere114e472008-02-04 22:29:50 -0800969 * @name: where to put the attribute name
970 * @value: where to put the attribute value
971 * @len: where to put the length of the attribute
972 *
973 * Returns 0 if it all works out, -ENOMEM if there's no memory
974 */
975static int smack_inode_init_security(struct inode *inode, struct inode *dir,
Tetsuo Handa95489062013-07-25 05:44:02 +0900976 const struct qstr *qstr, const char **name,
Eric Paris2a7dba32011-02-01 11:05:39 -0500977 void **value, size_t *len)
Casey Schauflere114e472008-02-04 22:29:50 -0800978{
Casey Schauflerfb4021b2018-11-12 12:43:01 -0800979 struct inode_smack *issp = smack_inode(inode);
Casey Schaufler2f823ff2013-05-22 18:43:03 -0700980 struct smack_known *skp = smk_of_current();
Lukasz Pawelczyk21c7eae2014-08-29 17:02:55 +0200981 struct smack_known *isp = smk_of_inode(inode);
982 struct smack_known *dsp = smk_of_inode(dir);
Casey Schaufler7898e1f2011-01-17 08:05:27 -0800983 int may;
Casey Schauflere114e472008-02-04 22:29:50 -0800984
Tetsuo Handa95489062013-07-25 05:44:02 +0900985 if (name)
986 *name = XATTR_SMACK_SUFFIX;
Casey Schauflere114e472008-02-04 22:29:50 -0800987
Lukasz Pawelczyk68390cc2014-11-26 15:31:07 +0100988 if (value && len) {
Casey Schaufler7898e1f2011-01-17 08:05:27 -0800989 rcu_read_lock();
Lukasz Pawelczyk21c7eae2014-08-29 17:02:55 +0200990 may = smk_access_entry(skp->smk_known, dsp->smk_known,
991 &skp->smk_rules);
Casey Schaufler7898e1f2011-01-17 08:05:27 -0800992 rcu_read_unlock();
Jarkko Sakkinen5c6d1122010-12-07 13:34:01 +0200993
994 /*
995 * If the access rule allows transmutation and
996 * the directory requests transmutation then
997 * by all means transmute.
Casey Schaufler2267b132012-03-13 19:14:19 -0700998 * Mark the inode as changed.
Jarkko Sakkinen5c6d1122010-12-07 13:34:01 +0200999 */
Casey Schaufler7898e1f2011-01-17 08:05:27 -08001000 if (may > 0 && ((may & MAY_TRANSMUTE) != 0) &&
Casey Schaufler2267b132012-03-13 19:14:19 -07001001 smk_inode_transmutable(dir)) {
Jarkko Sakkinen5c6d1122010-12-07 13:34:01 +02001002 isp = dsp;
Casey Schaufler2267b132012-03-13 19:14:19 -07001003 issp->smk_flags |= SMK_INODE_CHANGED;
1004 }
Jarkko Sakkinen5c6d1122010-12-07 13:34:01 +02001005
Lukasz Pawelczyk21c7eae2014-08-29 17:02:55 +02001006 *value = kstrdup(isp->smk_known, GFP_NOFS);
Casey Schauflere114e472008-02-04 22:29:50 -08001007 if (*value == NULL)
1008 return -ENOMEM;
Casey Schauflere114e472008-02-04 22:29:50 -08001009
Lukasz Pawelczyk21c7eae2014-08-29 17:02:55 +02001010 *len = strlen(isp->smk_known);
Lukasz Pawelczyk68390cc2014-11-26 15:31:07 +01001011 }
Casey Schauflere114e472008-02-04 22:29:50 -08001012
1013 return 0;
1014}
1015
1016/**
1017 * smack_inode_link - Smack check on link
1018 * @old_dentry: the existing object
1019 * @dir: unused
1020 * @new_dentry: the new object
1021 *
1022 * Returns 0 if access is permitted, an error code otherwise
1023 */
1024static int smack_inode_link(struct dentry *old_dentry, struct inode *dir,
1025 struct dentry *new_dentry)
1026{
Lukasz Pawelczyk21c7eae2014-08-29 17:02:55 +02001027 struct smack_known *isp;
Etienne Bassetecfcc532009-04-08 20:40:06 +02001028 struct smk_audit_info ad;
1029 int rc;
1030
Eric Parisa2694342011-04-25 13:10:27 -04001031 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
Etienne Bassetecfcc532009-04-08 20:40:06 +02001032 smk_ad_setfield_u_fs_path_dentry(&ad, old_dentry);
Casey Schauflere114e472008-02-04 22:29:50 -08001033
David Howellsc6f493d2015-03-17 22:26:22 +00001034 isp = smk_of_inode(d_backing_inode(old_dentry));
Etienne Bassetecfcc532009-04-08 20:40:06 +02001035 rc = smk_curacc(isp, MAY_WRITE, &ad);
David Howellsc6f493d2015-03-17 22:26:22 +00001036 rc = smk_bu_inode(d_backing_inode(old_dentry), MAY_WRITE, rc);
Casey Schauflere114e472008-02-04 22:29:50 -08001037
David Howells88025652015-01-29 12:02:32 +00001038 if (rc == 0 && d_is_positive(new_dentry)) {
David Howellsc6f493d2015-03-17 22:26:22 +00001039 isp = smk_of_inode(d_backing_inode(new_dentry));
Etienne Bassetecfcc532009-04-08 20:40:06 +02001040 smk_ad_setfield_u_fs_path_dentry(&ad, new_dentry);
1041 rc = smk_curacc(isp, MAY_WRITE, &ad);
David Howellsc6f493d2015-03-17 22:26:22 +00001042 rc = smk_bu_inode(d_backing_inode(new_dentry), MAY_WRITE, rc);
Casey Schauflere114e472008-02-04 22:29:50 -08001043 }
1044
1045 return rc;
1046}
1047
1048/**
1049 * smack_inode_unlink - Smack check on inode deletion
1050 * @dir: containing directory object
1051 * @dentry: file to unlink
1052 *
1053 * Returns 0 if current can write the containing directory
1054 * and the object, error code otherwise
1055 */
1056static int smack_inode_unlink(struct inode *dir, struct dentry *dentry)
1057{
David Howellsc6f493d2015-03-17 22:26:22 +00001058 struct inode *ip = d_backing_inode(dentry);
Etienne Bassetecfcc532009-04-08 20:40:06 +02001059 struct smk_audit_info ad;
Casey Schauflere114e472008-02-04 22:29:50 -08001060 int rc;
1061
Eric Parisa2694342011-04-25 13:10:27 -04001062 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
Etienne Bassetecfcc532009-04-08 20:40:06 +02001063 smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
1064
Casey Schauflere114e472008-02-04 22:29:50 -08001065 /*
1066 * You need write access to the thing you're unlinking
1067 */
Etienne Bassetecfcc532009-04-08 20:40:06 +02001068 rc = smk_curacc(smk_of_inode(ip), MAY_WRITE, &ad);
Casey Schauflerd166c802014-08-27 14:51:27 -07001069 rc = smk_bu_inode(ip, MAY_WRITE, rc);
Etienne Bassetecfcc532009-04-08 20:40:06 +02001070 if (rc == 0) {
Casey Schauflere114e472008-02-04 22:29:50 -08001071 /*
1072 * You also need write access to the containing directory
1073 */
Igor Zhbanovcdb56b62013-03-19 13:49:47 +04001074 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_INODE);
Etienne Bassetecfcc532009-04-08 20:40:06 +02001075 smk_ad_setfield_u_fs_inode(&ad, dir);
1076 rc = smk_curacc(smk_of_inode(dir), MAY_WRITE, &ad);
Casey Schauflerd166c802014-08-27 14:51:27 -07001077 rc = smk_bu_inode(dir, MAY_WRITE, rc);
Etienne Bassetecfcc532009-04-08 20:40:06 +02001078 }
Casey Schauflere114e472008-02-04 22:29:50 -08001079 return rc;
1080}
1081
1082/**
1083 * smack_inode_rmdir - Smack check on directory deletion
1084 * @dir: containing directory object
1085 * @dentry: directory to unlink
1086 *
1087 * Returns 0 if current can write the containing directory
1088 * and the directory, error code otherwise
1089 */
1090static int smack_inode_rmdir(struct inode *dir, struct dentry *dentry)
1091{
Etienne Bassetecfcc532009-04-08 20:40:06 +02001092 struct smk_audit_info ad;
Casey Schauflere114e472008-02-04 22:29:50 -08001093 int rc;
1094
Eric Parisa2694342011-04-25 13:10:27 -04001095 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
Etienne Bassetecfcc532009-04-08 20:40:06 +02001096 smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
1097
Casey Schauflere114e472008-02-04 22:29:50 -08001098 /*
1099 * You need write access to the thing you're removing
1100 */
David Howellsc6f493d2015-03-17 22:26:22 +00001101 rc = smk_curacc(smk_of_inode(d_backing_inode(dentry)), MAY_WRITE, &ad);
1102 rc = smk_bu_inode(d_backing_inode(dentry), MAY_WRITE, rc);
Etienne Bassetecfcc532009-04-08 20:40:06 +02001103 if (rc == 0) {
Casey Schauflere114e472008-02-04 22:29:50 -08001104 /*
1105 * You also need write access to the containing directory
1106 */
Igor Zhbanovcdb56b62013-03-19 13:49:47 +04001107 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_INODE);
Etienne Bassetecfcc532009-04-08 20:40:06 +02001108 smk_ad_setfield_u_fs_inode(&ad, dir);
1109 rc = smk_curacc(smk_of_inode(dir), MAY_WRITE, &ad);
Casey Schauflerd166c802014-08-27 14:51:27 -07001110 rc = smk_bu_inode(dir, MAY_WRITE, rc);
Etienne Bassetecfcc532009-04-08 20:40:06 +02001111 }
Casey Schauflere114e472008-02-04 22:29:50 -08001112
1113 return rc;
1114}
1115
1116/**
1117 * smack_inode_rename - Smack check on rename
Lukasz Pawelczyke95ef492014-08-29 17:02:53 +02001118 * @old_inode: unused
1119 * @old_dentry: the old object
1120 * @new_inode: unused
1121 * @new_dentry: the new object
Casey Schauflere114e472008-02-04 22:29:50 -08001122 *
1123 * Read and write access is required on both the old and
1124 * new directories.
1125 *
1126 * Returns 0 if access is permitted, an error code otherwise
1127 */
1128static int smack_inode_rename(struct inode *old_inode,
1129 struct dentry *old_dentry,
1130 struct inode *new_inode,
1131 struct dentry *new_dentry)
1132{
1133 int rc;
Lukasz Pawelczyk21c7eae2014-08-29 17:02:55 +02001134 struct smack_known *isp;
Etienne Bassetecfcc532009-04-08 20:40:06 +02001135 struct smk_audit_info ad;
1136
Eric Parisa2694342011-04-25 13:10:27 -04001137 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
Etienne Bassetecfcc532009-04-08 20:40:06 +02001138 smk_ad_setfield_u_fs_path_dentry(&ad, old_dentry);
Casey Schauflere114e472008-02-04 22:29:50 -08001139
David Howellsc6f493d2015-03-17 22:26:22 +00001140 isp = smk_of_inode(d_backing_inode(old_dentry));
Etienne Bassetecfcc532009-04-08 20:40:06 +02001141 rc = smk_curacc(isp, MAY_READWRITE, &ad);
David Howellsc6f493d2015-03-17 22:26:22 +00001142 rc = smk_bu_inode(d_backing_inode(old_dentry), MAY_READWRITE, rc);
Casey Schauflere114e472008-02-04 22:29:50 -08001143
David Howells88025652015-01-29 12:02:32 +00001144 if (rc == 0 && d_is_positive(new_dentry)) {
David Howellsc6f493d2015-03-17 22:26:22 +00001145 isp = smk_of_inode(d_backing_inode(new_dentry));
Etienne Bassetecfcc532009-04-08 20:40:06 +02001146 smk_ad_setfield_u_fs_path_dentry(&ad, new_dentry);
1147 rc = smk_curacc(isp, MAY_READWRITE, &ad);
David Howellsc6f493d2015-03-17 22:26:22 +00001148 rc = smk_bu_inode(d_backing_inode(new_dentry), MAY_READWRITE, rc);
Casey Schauflere114e472008-02-04 22:29:50 -08001149 }
Casey Schauflere114e472008-02-04 22:29:50 -08001150 return rc;
1151}
1152
1153/**
1154 * smack_inode_permission - Smack version of permission()
1155 * @inode: the inode in question
1156 * @mask: the access requested
Casey Schauflere114e472008-02-04 22:29:50 -08001157 *
1158 * This is the important Smack hook.
1159 *
luanshia1a07f22019-07-05 10:35:20 +08001160 * Returns 0 if access is permitted, an error code otherwise
Casey Schauflere114e472008-02-04 22:29:50 -08001161 */
Al Viroe74f71e2011-06-20 19:38:15 -04001162static int smack_inode_permission(struct inode *inode, int mask)
Casey Schauflere114e472008-02-04 22:29:50 -08001163{
Seth Forshee9f50eda2015-09-23 15:16:06 -05001164 struct superblock_smack *sbsp = inode->i_sb->s_security;
Etienne Bassetecfcc532009-04-08 20:40:06 +02001165 struct smk_audit_info ad;
Al Viroe74f71e2011-06-20 19:38:15 -04001166 int no_block = mask & MAY_NOT_BLOCK;
Casey Schauflerd166c802014-08-27 14:51:27 -07001167 int rc;
Eric Parisd09ca732010-07-23 11:43:57 -04001168
1169 mask &= (MAY_READ|MAY_WRITE|MAY_EXEC|MAY_APPEND);
Casey Schauflere114e472008-02-04 22:29:50 -08001170 /*
1171 * No permission to check. Existence test. Yup, it's there.
1172 */
1173 if (mask == 0)
1174 return 0;
Andi Kleen8c9e80e2011-04-21 17:23:19 -07001175
Seth Forshee9f50eda2015-09-23 15:16:06 -05001176 if (sbsp->smk_flags & SMK_SB_UNTRUSTED) {
1177 if (smk_of_inode(inode) != sbsp->smk_root)
1178 return -EACCES;
1179 }
1180
Andi Kleen8c9e80e2011-04-21 17:23:19 -07001181 /* May be droppable after audit */
Al Viroe74f71e2011-06-20 19:38:15 -04001182 if (no_block)
Andi Kleen8c9e80e2011-04-21 17:23:19 -07001183 return -ECHILD;
Eric Parisf48b7392011-04-25 12:54:27 -04001184 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_INODE);
Etienne Bassetecfcc532009-04-08 20:40:06 +02001185 smk_ad_setfield_u_fs_inode(&ad, inode);
Casey Schauflerd166c802014-08-27 14:51:27 -07001186 rc = smk_curacc(smk_of_inode(inode), mask, &ad);
1187 rc = smk_bu_inode(inode, mask, rc);
1188 return rc;
Casey Schauflere114e472008-02-04 22:29:50 -08001189}
1190
1191/**
1192 * smack_inode_setattr - Smack check for setting attributes
1193 * @dentry: the object
1194 * @iattr: for the force flag
1195 *
1196 * Returns 0 if access is permitted, an error code otherwise
1197 */
1198static int smack_inode_setattr(struct dentry *dentry, struct iattr *iattr)
1199{
Etienne Bassetecfcc532009-04-08 20:40:06 +02001200 struct smk_audit_info ad;
Casey Schauflerd166c802014-08-27 14:51:27 -07001201 int rc;
1202
Casey Schauflere114e472008-02-04 22:29:50 -08001203 /*
1204 * Need to allow for clearing the setuid bit.
1205 */
1206 if (iattr->ia_valid & ATTR_FORCE)
1207 return 0;
Eric Parisa2694342011-04-25 13:10:27 -04001208 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
Etienne Bassetecfcc532009-04-08 20:40:06 +02001209 smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
Casey Schauflere114e472008-02-04 22:29:50 -08001210
David Howellsc6f493d2015-03-17 22:26:22 +00001211 rc = smk_curacc(smk_of_inode(d_backing_inode(dentry)), MAY_WRITE, &ad);
1212 rc = smk_bu_inode(d_backing_inode(dentry), MAY_WRITE, rc);
Casey Schauflerd166c802014-08-27 14:51:27 -07001213 return rc;
Casey Schauflere114e472008-02-04 22:29:50 -08001214}
1215
1216/**
1217 * smack_inode_getattr - Smack check for getting attributes
luanshia1a07f22019-07-05 10:35:20 +08001218 * @path: path to extract the info from
Casey Schauflere114e472008-02-04 22:29:50 -08001219 *
1220 * Returns 0 if access is permitted, an error code otherwise
1221 */
Al Viro3f7036a2015-03-08 19:28:30 -04001222static int smack_inode_getattr(const struct path *path)
Casey Schauflere114e472008-02-04 22:29:50 -08001223{
Etienne Bassetecfcc532009-04-08 20:40:06 +02001224 struct smk_audit_info ad;
David Howellsc6f493d2015-03-17 22:26:22 +00001225 struct inode *inode = d_backing_inode(path->dentry);
Casey Schauflerd166c802014-08-27 14:51:27 -07001226 int rc;
Etienne Bassetecfcc532009-04-08 20:40:06 +02001227
Eric Parisf48b7392011-04-25 12:54:27 -04001228 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
Al Viro3f7036a2015-03-08 19:28:30 -04001229 smk_ad_setfield_u_fs_path(&ad, *path);
1230 rc = smk_curacc(smk_of_inode(inode), MAY_READ, &ad);
1231 rc = smk_bu_inode(inode, MAY_READ, rc);
Casey Schauflerd166c802014-08-27 14:51:27 -07001232 return rc;
Casey Schauflere114e472008-02-04 22:29:50 -08001233}
1234
1235/**
1236 * smack_inode_setxattr - Smack check for setting xattrs
1237 * @dentry: the object
1238 * @name: name of the attribute
Lukasz Pawelczyke95ef492014-08-29 17:02:53 +02001239 * @value: value of the attribute
1240 * @size: size of the value
Casey Schauflere114e472008-02-04 22:29:50 -08001241 * @flags: unused
1242 *
1243 * This protects the Smack attribute explicitly.
1244 *
1245 * Returns 0 if access is permitted, an error code otherwise
1246 */
David Howells8f0cfa52008-04-29 00:59:41 -07001247static int smack_inode_setxattr(struct dentry *dentry, const char *name,
1248 const void *value, size_t size, int flags)
Casey Schauflere114e472008-02-04 22:29:50 -08001249{
Etienne Bassetecfcc532009-04-08 20:40:06 +02001250 struct smk_audit_info ad;
Casey Schaufler19760ad2013-12-16 16:27:26 -08001251 struct smack_known *skp;
1252 int check_priv = 0;
1253 int check_import = 0;
1254 int check_star = 0;
Casey Schauflerbcdca222008-02-23 15:24:04 -08001255 int rc = 0;
Casey Schauflere114e472008-02-04 22:29:50 -08001256
Casey Schaufler19760ad2013-12-16 16:27:26 -08001257 /*
1258 * Check label validity here so import won't fail in post_setxattr
1259 */
Casey Schauflerbcdca222008-02-23 15:24:04 -08001260 if (strcmp(name, XATTR_NAME_SMACK) == 0 ||
1261 strcmp(name, XATTR_NAME_SMACKIPIN) == 0 ||
Casey Schaufler19760ad2013-12-16 16:27:26 -08001262 strcmp(name, XATTR_NAME_SMACKIPOUT) == 0) {
1263 check_priv = 1;
1264 check_import = 1;
1265 } else if (strcmp(name, XATTR_NAME_SMACKEXEC) == 0 ||
1266 strcmp(name, XATTR_NAME_SMACKMMAP) == 0) {
1267 check_priv = 1;
1268 check_import = 1;
1269 check_star = 1;
Jarkko Sakkinen5c6d1122010-12-07 13:34:01 +02001270 } else if (strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0) {
Casey Schaufler19760ad2013-12-16 16:27:26 -08001271 check_priv = 1;
Jarkko Sakkinen5c6d1122010-12-07 13:34:01 +02001272 if (size != TRANS_TRUE_SIZE ||
1273 strncmp(value, TRANS_TRUE, TRANS_TRUE_SIZE) != 0)
1274 rc = -EINVAL;
Casey Schauflerbcdca222008-02-23 15:24:04 -08001275 } else
1276 rc = cap_inode_setxattr(dentry, name, value, size, flags);
1277
Casey Schaufler19760ad2013-12-16 16:27:26 -08001278 if (check_priv && !smack_privileged(CAP_MAC_ADMIN))
1279 rc = -EPERM;
1280
1281 if (rc == 0 && check_import) {
Konstantin Khlebnikovb862e562014-08-07 20:52:43 +04001282 skp = size ? smk_import_entry(value, size) : NULL;
Lukasz Pawelczyke774ad62015-04-20 17:12:54 +02001283 if (IS_ERR(skp))
1284 rc = PTR_ERR(skp);
1285 else if (skp == NULL || (check_star &&
Casey Schaufler19760ad2013-12-16 16:27:26 -08001286 (skp == &smack_known_star || skp == &smack_known_web)))
1287 rc = -EINVAL;
1288 }
1289
Eric Parisa2694342011-04-25 13:10:27 -04001290 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
Etienne Bassetecfcc532009-04-08 20:40:06 +02001291 smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
1292
Casey Schauflerd166c802014-08-27 14:51:27 -07001293 if (rc == 0) {
David Howellsc6f493d2015-03-17 22:26:22 +00001294 rc = smk_curacc(smk_of_inode(d_backing_inode(dentry)), MAY_WRITE, &ad);
1295 rc = smk_bu_inode(d_backing_inode(dentry), MAY_WRITE, rc);
Casey Schauflerd166c802014-08-27 14:51:27 -07001296 }
Casey Schauflerbcdca222008-02-23 15:24:04 -08001297
1298 return rc;
Casey Schauflere114e472008-02-04 22:29:50 -08001299}
1300
1301/**
1302 * smack_inode_post_setxattr - Apply the Smack update approved above
1303 * @dentry: object
1304 * @name: attribute name
1305 * @value: attribute value
1306 * @size: attribute size
1307 * @flags: unused
1308 *
1309 * Set the pointer in the inode blob to the entry found
1310 * in the master label list.
1311 */
David Howells8f0cfa52008-04-29 00:59:41 -07001312static void smack_inode_post_setxattr(struct dentry *dentry, const char *name,
1313 const void *value, size_t size, int flags)
Casey Schauflere114e472008-02-04 22:29:50 -08001314{
Casey Schaufler2f823ff2013-05-22 18:43:03 -07001315 struct smack_known *skp;
Casey Schauflerfb4021b2018-11-12 12:43:01 -08001316 struct inode_smack *isp = smack_inode(d_backing_inode(dentry));
Casey Schaufler676dac42010-12-02 06:43:39 -08001317
Casey Schaufler2f823ff2013-05-22 18:43:03 -07001318 if (strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0) {
1319 isp->smk_flags |= SMK_INODE_TRANSMUTE;
1320 return;
1321 }
1322
Casey Schaufler676dac42010-12-02 06:43:39 -08001323 if (strcmp(name, XATTR_NAME_SMACK) == 0) {
José Bollo9598f4c2014-04-03 13:48:41 +02001324 skp = smk_import_entry(value, size);
Lukasz Pawelczyke774ad62015-04-20 17:12:54 +02001325 if (!IS_ERR(skp))
Lukasz Pawelczyk21c7eae2014-08-29 17:02:55 +02001326 isp->smk_inode = skp;
Jarkko Sakkinen5c6d1122010-12-07 13:34:01 +02001327 } else if (strcmp(name, XATTR_NAME_SMACKEXEC) == 0) {
José Bollo9598f4c2014-04-03 13:48:41 +02001328 skp = smk_import_entry(value, size);
Lukasz Pawelczyke774ad62015-04-20 17:12:54 +02001329 if (!IS_ERR(skp))
Casey Schaufler2f823ff2013-05-22 18:43:03 -07001330 isp->smk_task = skp;
Casey Schaufler7898e1f2011-01-17 08:05:27 -08001331 } else if (strcmp(name, XATTR_NAME_SMACKMMAP) == 0) {
José Bollo9598f4c2014-04-03 13:48:41 +02001332 skp = smk_import_entry(value, size);
Lukasz Pawelczyke774ad62015-04-20 17:12:54 +02001333 if (!IS_ERR(skp))
Casey Schaufler2f823ff2013-05-22 18:43:03 -07001334 isp->smk_mmap = skp;
Casey Schaufler2f823ff2013-05-22 18:43:03 -07001335 }
Casey Schauflere114e472008-02-04 22:29:50 -08001336
1337 return;
1338}
1339
Casey Schauflerce8a4322011-09-29 18:21:01 -07001340/**
Casey Schauflere114e472008-02-04 22:29:50 -08001341 * smack_inode_getxattr - Smack check on getxattr
1342 * @dentry: the object
1343 * @name: unused
1344 *
1345 * Returns 0 if access is permitted, an error code otherwise
1346 */
David Howells8f0cfa52008-04-29 00:59:41 -07001347static int smack_inode_getxattr(struct dentry *dentry, const char *name)
Casey Schauflere114e472008-02-04 22:29:50 -08001348{
Etienne Bassetecfcc532009-04-08 20:40:06 +02001349 struct smk_audit_info ad;
Casey Schauflerd166c802014-08-27 14:51:27 -07001350 int rc;
Etienne Bassetecfcc532009-04-08 20:40:06 +02001351
Eric Parisa2694342011-04-25 13:10:27 -04001352 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
Etienne Bassetecfcc532009-04-08 20:40:06 +02001353 smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
1354
David Howellsc6f493d2015-03-17 22:26:22 +00001355 rc = smk_curacc(smk_of_inode(d_backing_inode(dentry)), MAY_READ, &ad);
1356 rc = smk_bu_inode(d_backing_inode(dentry), MAY_READ, rc);
Casey Schauflerd166c802014-08-27 14:51:27 -07001357 return rc;
Casey Schauflere114e472008-02-04 22:29:50 -08001358}
1359
Casey Schauflerce8a4322011-09-29 18:21:01 -07001360/**
Casey Schauflere114e472008-02-04 22:29:50 -08001361 * smack_inode_removexattr - Smack check on removexattr
1362 * @dentry: the object
1363 * @name: name of the attribute
1364 *
1365 * Removing the Smack attribute requires CAP_MAC_ADMIN
1366 *
1367 * Returns 0 if access is permitted, an error code otherwise
1368 */
David Howells8f0cfa52008-04-29 00:59:41 -07001369static int smack_inode_removexattr(struct dentry *dentry, const char *name)
Casey Schauflere114e472008-02-04 22:29:50 -08001370{
Casey Schaufler676dac42010-12-02 06:43:39 -08001371 struct inode_smack *isp;
Etienne Bassetecfcc532009-04-08 20:40:06 +02001372 struct smk_audit_info ad;
Casey Schauflerbcdca222008-02-23 15:24:04 -08001373 int rc = 0;
Casey Schauflere114e472008-02-04 22:29:50 -08001374
Casey Schauflerbcdca222008-02-23 15:24:04 -08001375 if (strcmp(name, XATTR_NAME_SMACK) == 0 ||
1376 strcmp(name, XATTR_NAME_SMACKIPIN) == 0 ||
Casey Schaufler676dac42010-12-02 06:43:39 -08001377 strcmp(name, XATTR_NAME_SMACKIPOUT) == 0 ||
Jarkko Sakkinen5c6d1122010-12-07 13:34:01 +02001378 strcmp(name, XATTR_NAME_SMACKEXEC) == 0 ||
Casey Schaufler7898e1f2011-01-17 08:05:27 -08001379 strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0 ||
Pankaj Kumar5e9ab592013-12-13 15:12:22 +05301380 strcmp(name, XATTR_NAME_SMACKMMAP) == 0) {
Casey Schaufler1880eff2012-06-05 15:28:30 -07001381 if (!smack_privileged(CAP_MAC_ADMIN))
Casey Schauflerbcdca222008-02-23 15:24:04 -08001382 rc = -EPERM;
1383 } else
1384 rc = cap_inode_removexattr(dentry, name);
1385
Casey Schauflerf59bdfb2014-04-10 16:35:36 -07001386 if (rc != 0)
1387 return rc;
1388
Eric Parisa2694342011-04-25 13:10:27 -04001389 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
Etienne Bassetecfcc532009-04-08 20:40:06 +02001390 smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
Casey Schauflerbcdca222008-02-23 15:24:04 -08001391
David Howellsc6f493d2015-03-17 22:26:22 +00001392 rc = smk_curacc(smk_of_inode(d_backing_inode(dentry)), MAY_WRITE, &ad);
1393 rc = smk_bu_inode(d_backing_inode(dentry), MAY_WRITE, rc);
Casey Schauflerf59bdfb2014-04-10 16:35:36 -07001394 if (rc != 0)
1395 return rc;
1396
Casey Schauflerfb4021b2018-11-12 12:43:01 -08001397 isp = smack_inode(d_backing_inode(dentry));
Casey Schauflerf59bdfb2014-04-10 16:35:36 -07001398 /*
1399 * Don't do anything special for these.
1400 * XATTR_NAME_SMACKIPIN
1401 * XATTR_NAME_SMACKIPOUT
Casey Schauflerf59bdfb2014-04-10 16:35:36 -07001402 */
José Bollo80124952016-01-12 21:23:40 +01001403 if (strcmp(name, XATTR_NAME_SMACK) == 0) {
Al Virofc640052016-04-10 01:33:30 -04001404 struct super_block *sbp = dentry->d_sb;
José Bollo80124952016-01-12 21:23:40 +01001405 struct superblock_smack *sbsp = sbp->s_security;
1406
1407 isp->smk_inode = sbsp->smk_default;
1408 } else if (strcmp(name, XATTR_NAME_SMACKEXEC) == 0)
Casey Schaufler676dac42010-12-02 06:43:39 -08001409 isp->smk_task = NULL;
Casey Schauflerf59bdfb2014-04-10 16:35:36 -07001410 else if (strcmp(name, XATTR_NAME_SMACKMMAP) == 0)
Casey Schaufler7898e1f2011-01-17 08:05:27 -08001411 isp->smk_mmap = NULL;
Casey Schauflerf59bdfb2014-04-10 16:35:36 -07001412 else if (strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0)
1413 isp->smk_flags &= ~SMK_INODE_TRANSMUTE;
Casey Schaufler676dac42010-12-02 06:43:39 -08001414
Casey Schauflerf59bdfb2014-04-10 16:35:36 -07001415 return 0;
Casey Schauflere114e472008-02-04 22:29:50 -08001416}
1417
1418/**
1419 * smack_inode_getsecurity - get smack xattrs
1420 * @inode: the object
1421 * @name: attribute name
1422 * @buffer: where to put the result
Casey Schaufler57e7ba02017-09-19 09:39:08 -07001423 * @alloc: duplicate memory
Casey Schauflere114e472008-02-04 22:29:50 -08001424 *
1425 * Returns the size of the attribute or an error code
1426 */
Andreas Gruenbacherea861df2015-12-24 11:09:39 -05001427static int smack_inode_getsecurity(struct inode *inode,
Casey Schauflere114e472008-02-04 22:29:50 -08001428 const char *name, void **buffer,
1429 bool alloc)
1430{
1431 struct socket_smack *ssp;
1432 struct socket *sock;
1433 struct super_block *sbp;
1434 struct inode *ip = (struct inode *)inode;
Lukasz Pawelczyk21c7eae2014-08-29 17:02:55 +02001435 struct smack_known *isp;
Casey Schauflere114e472008-02-04 22:29:50 -08001436
Casey Schaufler57e7ba02017-09-19 09:39:08 -07001437 if (strcmp(name, XATTR_SMACK_SUFFIX) == 0)
Casey Schauflere114e472008-02-04 22:29:50 -08001438 isp = smk_of_inode(inode);
Casey Schaufler57e7ba02017-09-19 09:39:08 -07001439 else {
1440 /*
1441 * The rest of the Smack xattrs are only on sockets.
1442 */
1443 sbp = ip->i_sb;
1444 if (sbp->s_magic != SOCKFS_MAGIC)
1445 return -EOPNOTSUPP;
1446
1447 sock = SOCKET_I(ip);
1448 if (sock == NULL || sock->sk == NULL)
1449 return -EOPNOTSUPP;
1450
1451 ssp = sock->sk->sk_security;
1452
1453 if (strcmp(name, XATTR_SMACK_IPIN) == 0)
1454 isp = ssp->smk_in;
1455 else if (strcmp(name, XATTR_SMACK_IPOUT) == 0)
1456 isp = ssp->smk_out;
1457 else
1458 return -EOPNOTSUPP;
Casey Schauflere114e472008-02-04 22:29:50 -08001459 }
1460
Casey Schaufler57e7ba02017-09-19 09:39:08 -07001461 if (alloc) {
1462 *buffer = kstrdup(isp->smk_known, GFP_KERNEL);
1463 if (*buffer == NULL)
1464 return -ENOMEM;
Casey Schauflere114e472008-02-04 22:29:50 -08001465 }
1466
Casey Schaufler57e7ba02017-09-19 09:39:08 -07001467 return strlen(isp->smk_known);
Casey Schauflere114e472008-02-04 22:29:50 -08001468}
1469
1470
1471/**
1472 * smack_inode_listsecurity - list the Smack attributes
1473 * @inode: the object
1474 * @buffer: where they go
1475 * @buffer_size: size of buffer
Casey Schauflere114e472008-02-04 22:29:50 -08001476 */
1477static int smack_inode_listsecurity(struct inode *inode, char *buffer,
1478 size_t buffer_size)
1479{
Konstantin Khlebnikovfd5c9d22014-08-07 20:52:33 +04001480 int len = sizeof(XATTR_NAME_SMACK);
Casey Schauflere114e472008-02-04 22:29:50 -08001481
Konstantin Khlebnikovfd5c9d22014-08-07 20:52:33 +04001482 if (buffer != NULL && len <= buffer_size)
Casey Schauflere114e472008-02-04 22:29:50 -08001483 memcpy(buffer, XATTR_NAME_SMACK, len);
Konstantin Khlebnikovfd5c9d22014-08-07 20:52:33 +04001484
1485 return len;
Casey Schauflere114e472008-02-04 22:29:50 -08001486}
1487
Ahmed S. Darwishd20bdda2008-04-30 08:34:10 +10001488/**
1489 * smack_inode_getsecid - Extract inode's security id
1490 * @inode: inode to extract the info from
1491 * @secid: where result will be saved
1492 */
Andreas Gruenbacherd6335d72015-12-24 11:09:39 -05001493static void smack_inode_getsecid(struct inode *inode, u32 *secid)
Ahmed S. Darwishd20bdda2008-04-30 08:34:10 +10001494{
Casey Schaufler0f8983c2018-06-01 10:45:12 -07001495 struct smack_known *skp = smk_of_inode(inode);
Ahmed S. Darwishd20bdda2008-04-30 08:34:10 +10001496
Casey Schaufler0f8983c2018-06-01 10:45:12 -07001497 *secid = skp->smk_secid;
Ahmed S. Darwishd20bdda2008-04-30 08:34:10 +10001498}
1499
Casey Schauflere114e472008-02-04 22:29:50 -08001500/*
1501 * File Hooks
1502 */
1503
Casey Schaufler491a0b02016-01-26 15:08:35 -08001504/*
1505 * There is no smack_file_permission hook
Casey Schauflere114e472008-02-04 22:29:50 -08001506 *
1507 * Should access checks be done on each read or write?
1508 * UNICOS and SELinux say yes.
1509 * Trusted Solaris, Trusted Irix, and just about everyone else says no.
1510 *
1511 * I'll say no for now. Smack does not do the frequent
1512 * label changing that SELinux does.
1513 */
Casey Schauflere114e472008-02-04 22:29:50 -08001514
1515/**
1516 * smack_file_alloc_security - assign a file security blob
1517 * @file: the object
1518 *
1519 * The security blob for a file is a pointer to the master
1520 * label list, so no allocation is done.
1521 *
Casey Schaufler5e7270a2014-12-12 17:19:19 -08001522 * f_security is the owner security information. It
1523 * isn't used on file access checks, it's for send_sigio.
1524 *
Casey Schauflere114e472008-02-04 22:29:50 -08001525 * Returns 0
1526 */
1527static int smack_file_alloc_security(struct file *file)
1528{
Casey Schauflerf28952a2018-11-12 09:38:53 -08001529 struct smack_known **blob = smack_file(file);
Casey Schaufler2f823ff2013-05-22 18:43:03 -07001530
Casey Schauflerf28952a2018-11-12 09:38:53 -08001531 *blob = smk_of_current();
Casey Schauflere114e472008-02-04 22:29:50 -08001532 return 0;
1533}
1534
1535/**
Casey Schauflere114e472008-02-04 22:29:50 -08001536 * smack_file_ioctl - Smack check on ioctls
1537 * @file: the object
1538 * @cmd: what to do
1539 * @arg: unused
1540 *
1541 * Relies heavily on the correct use of the ioctl command conventions.
1542 *
1543 * Returns 0 if allowed, error code otherwise
1544 */
1545static int smack_file_ioctl(struct file *file, unsigned int cmd,
1546 unsigned long arg)
1547{
1548 int rc = 0;
Etienne Bassetecfcc532009-04-08 20:40:06 +02001549 struct smk_audit_info ad;
Casey Schaufler5e7270a2014-12-12 17:19:19 -08001550 struct inode *inode = file_inode(file);
Etienne Bassetecfcc532009-04-08 20:40:06 +02001551
Seung-Woo Kim83a1e532016-12-12 17:35:26 +09001552 if (unlikely(IS_PRIVATE(inode)))
1553 return 0;
1554
Eric Parisf48b7392011-04-25 12:54:27 -04001555 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
Etienne Bassetecfcc532009-04-08 20:40:06 +02001556 smk_ad_setfield_u_fs_path(&ad, file->f_path);
Casey Schauflere114e472008-02-04 22:29:50 -08001557
Casey Schauflerd166c802014-08-27 14:51:27 -07001558 if (_IOC_DIR(cmd) & _IOC_WRITE) {
Casey Schaufler5e7270a2014-12-12 17:19:19 -08001559 rc = smk_curacc(smk_of_inode(inode), MAY_WRITE, &ad);
Casey Schauflerd166c802014-08-27 14:51:27 -07001560 rc = smk_bu_file(file, MAY_WRITE, rc);
1561 }
Casey Schauflere114e472008-02-04 22:29:50 -08001562
Casey Schauflerd166c802014-08-27 14:51:27 -07001563 if (rc == 0 && (_IOC_DIR(cmd) & _IOC_READ)) {
Casey Schaufler5e7270a2014-12-12 17:19:19 -08001564 rc = smk_curacc(smk_of_inode(inode), MAY_READ, &ad);
Casey Schauflerd166c802014-08-27 14:51:27 -07001565 rc = smk_bu_file(file, MAY_READ, rc);
1566 }
Casey Schauflere114e472008-02-04 22:29:50 -08001567
1568 return rc;
1569}
1570
1571/**
1572 * smack_file_lock - Smack check on file locking
1573 * @file: the object
Randy Dunlap251a2a92009-02-18 11:42:33 -08001574 * @cmd: unused
Casey Schauflere114e472008-02-04 22:29:50 -08001575 *
Casey Schauflerc0ab6e52013-10-11 18:06:39 -07001576 * Returns 0 if current has lock access, error code otherwise
Casey Schauflere114e472008-02-04 22:29:50 -08001577 */
1578static int smack_file_lock(struct file *file, unsigned int cmd)
1579{
Etienne Bassetecfcc532009-04-08 20:40:06 +02001580 struct smk_audit_info ad;
Casey Schauflerd166c802014-08-27 14:51:27 -07001581 int rc;
Casey Schaufler5e7270a2014-12-12 17:19:19 -08001582 struct inode *inode = file_inode(file);
Etienne Bassetecfcc532009-04-08 20:40:06 +02001583
Seung-Woo Kim83a1e532016-12-12 17:35:26 +09001584 if (unlikely(IS_PRIVATE(inode)))
1585 return 0;
1586
Eric Paris92f42502011-04-25 13:15:55 -04001587 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
1588 smk_ad_setfield_u_fs_path(&ad, file->f_path);
Casey Schaufler5e7270a2014-12-12 17:19:19 -08001589 rc = smk_curacc(smk_of_inode(inode), MAY_LOCK, &ad);
Casey Schauflerd166c802014-08-27 14:51:27 -07001590 rc = smk_bu_file(file, MAY_LOCK, rc);
1591 return rc;
Casey Schauflere114e472008-02-04 22:29:50 -08001592}
1593
1594/**
1595 * smack_file_fcntl - Smack check on fcntl
1596 * @file: the object
1597 * @cmd: what action to check
1598 * @arg: unused
1599 *
Casey Schaufler531f1d42011-09-19 12:41:42 -07001600 * Generally these operations are harmless.
1601 * File locking operations present an obvious mechanism
1602 * for passing information, so they require write access.
1603 *
Casey Schauflere114e472008-02-04 22:29:50 -08001604 * Returns 0 if current has access, error code otherwise
1605 */
1606static int smack_file_fcntl(struct file *file, unsigned int cmd,
1607 unsigned long arg)
1608{
Etienne Bassetecfcc532009-04-08 20:40:06 +02001609 struct smk_audit_info ad;
Casey Schaufler531f1d42011-09-19 12:41:42 -07001610 int rc = 0;
Casey Schaufler5e7270a2014-12-12 17:19:19 -08001611 struct inode *inode = file_inode(file);
Etienne Bassetecfcc532009-04-08 20:40:06 +02001612
Seung-Woo Kim83a1e532016-12-12 17:35:26 +09001613 if (unlikely(IS_PRIVATE(inode)))
1614 return 0;
1615
Casey Schauflere114e472008-02-04 22:29:50 -08001616 switch (cmd) {
Casey Schauflere114e472008-02-04 22:29:50 -08001617 case F_GETLK:
Casey Schauflerc0ab6e52013-10-11 18:06:39 -07001618 break;
Casey Schauflere114e472008-02-04 22:29:50 -08001619 case F_SETLK:
1620 case F_SETLKW:
Casey Schauflerc0ab6e52013-10-11 18:06:39 -07001621 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
1622 smk_ad_setfield_u_fs_path(&ad, file->f_path);
Casey Schaufler5e7270a2014-12-12 17:19:19 -08001623 rc = smk_curacc(smk_of_inode(inode), MAY_LOCK, &ad);
Casey Schauflerd166c802014-08-27 14:51:27 -07001624 rc = smk_bu_file(file, MAY_LOCK, rc);
Casey Schauflerc0ab6e52013-10-11 18:06:39 -07001625 break;
Casey Schauflere114e472008-02-04 22:29:50 -08001626 case F_SETOWN:
1627 case F_SETSIG:
Casey Schaufler531f1d42011-09-19 12:41:42 -07001628 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
1629 smk_ad_setfield_u_fs_path(&ad, file->f_path);
Casey Schaufler5e7270a2014-12-12 17:19:19 -08001630 rc = smk_curacc(smk_of_inode(inode), MAY_WRITE, &ad);
Casey Schauflerd166c802014-08-27 14:51:27 -07001631 rc = smk_bu_file(file, MAY_WRITE, rc);
Casey Schauflere114e472008-02-04 22:29:50 -08001632 break;
1633 default:
Casey Schaufler531f1d42011-09-19 12:41:42 -07001634 break;
Casey Schauflere114e472008-02-04 22:29:50 -08001635 }
1636
1637 return rc;
1638}
1639
1640/**
Al Viroe5467852012-05-30 13:30:51 -04001641 * smack_mmap_file :
Casey Schaufler7898e1f2011-01-17 08:05:27 -08001642 * Check permissions for a mmap operation. The @file may be NULL, e.g.
1643 * if mapping anonymous memory.
1644 * @file contains the file structure for file to map (may be NULL).
1645 * @reqprot contains the protection requested by the application.
1646 * @prot contains the protection that will be applied by the kernel.
1647 * @flags contains the operational flags.
1648 * Return 0 if permission is granted.
1649 */
Al Viroe5467852012-05-30 13:30:51 -04001650static int smack_mmap_file(struct file *file,
Casey Schaufler7898e1f2011-01-17 08:05:27 -08001651 unsigned long reqprot, unsigned long prot,
Al Viroe5467852012-05-30 13:30:51 -04001652 unsigned long flags)
Casey Schaufler7898e1f2011-01-17 08:05:27 -08001653{
Casey Schaufler272cd7a2011-09-20 12:24:36 -07001654 struct smack_known *skp;
Casey Schaufler2f823ff2013-05-22 18:43:03 -07001655 struct smack_known *mkp;
Casey Schaufler7898e1f2011-01-17 08:05:27 -08001656 struct smack_rule *srp;
1657 struct task_smack *tsp;
Lukasz Pawelczyk21c7eae2014-08-29 17:02:55 +02001658 struct smack_known *okp;
Casey Schaufler7898e1f2011-01-17 08:05:27 -08001659 struct inode_smack *isp;
Seth Forshee809c02e2016-04-26 14:36:22 -05001660 struct superblock_smack *sbsp;
Casey Schaufler0e0a0702011-02-08 16:36:24 -08001661 int may;
1662 int mmay;
1663 int tmay;
Casey Schaufler7898e1f2011-01-17 08:05:27 -08001664 int rc;
1665
Al Viro496ad9a2013-01-23 17:07:38 -05001666 if (file == NULL)
Casey Schaufler7898e1f2011-01-17 08:05:27 -08001667 return 0;
1668
Seung-Woo Kim83a1e532016-12-12 17:35:26 +09001669 if (unlikely(IS_PRIVATE(file_inode(file))))
1670 return 0;
1671
Casey Schauflerfb4021b2018-11-12 12:43:01 -08001672 isp = smack_inode(file_inode(file));
Casey Schaufler7898e1f2011-01-17 08:05:27 -08001673 if (isp->smk_mmap == NULL)
1674 return 0;
Seth Forshee809c02e2016-04-26 14:36:22 -05001675 sbsp = file_inode(file)->i_sb->s_security;
1676 if (sbsp->smk_flags & SMK_SB_UNTRUSTED &&
1677 isp->smk_mmap != sbsp->smk_root)
1678 return -EACCES;
Casey Schaufler2f823ff2013-05-22 18:43:03 -07001679 mkp = isp->smk_mmap;
Casey Schaufler7898e1f2011-01-17 08:05:27 -08001680
Casey Schauflerb17103a2018-11-09 16:12:56 -08001681 tsp = smack_cred(current_cred());
Casey Schaufler2f823ff2013-05-22 18:43:03 -07001682 skp = smk_of_current();
Casey Schaufler7898e1f2011-01-17 08:05:27 -08001683 rc = 0;
1684
1685 rcu_read_lock();
1686 /*
1687 * For each Smack rule associated with the subject
1688 * label verify that the SMACK64MMAP also has access
1689 * to that rule's object label.
Casey Schaufler7898e1f2011-01-17 08:05:27 -08001690 */
Casey Schaufler272cd7a2011-09-20 12:24:36 -07001691 list_for_each_entry_rcu(srp, &skp->smk_rules, list) {
Lukasz Pawelczyk21c7eae2014-08-29 17:02:55 +02001692 okp = srp->smk_object;
Casey Schaufler7898e1f2011-01-17 08:05:27 -08001693 /*
1694 * Matching labels always allows access.
1695 */
Lukasz Pawelczyk21c7eae2014-08-29 17:02:55 +02001696 if (mkp->smk_known == okp->smk_known)
Casey Schaufler0e0a0702011-02-08 16:36:24 -08001697 continue;
1698 /*
1699 * If there is a matching local rule take
1700 * that into account as well.
1701 */
Lukasz Pawelczyk21c7eae2014-08-29 17:02:55 +02001702 may = smk_access_entry(srp->smk_subject->smk_known,
1703 okp->smk_known,
1704 &tsp->smk_rules);
Casey Schaufler0e0a0702011-02-08 16:36:24 -08001705 if (may == -ENOENT)
1706 may = srp->smk_access;
1707 else
1708 may &= srp->smk_access;
1709 /*
1710 * If may is zero the SMACK64MMAP subject can't
1711 * possibly have less access.
1712 */
1713 if (may == 0)
Casey Schaufler7898e1f2011-01-17 08:05:27 -08001714 continue;
1715
Casey Schaufler0e0a0702011-02-08 16:36:24 -08001716 /*
1717 * Fetch the global list entry.
1718 * If there isn't one a SMACK64MMAP subject
1719 * can't have as much access as current.
1720 */
Lukasz Pawelczyk21c7eae2014-08-29 17:02:55 +02001721 mmay = smk_access_entry(mkp->smk_known, okp->smk_known,
1722 &mkp->smk_rules);
Casey Schaufler0e0a0702011-02-08 16:36:24 -08001723 if (mmay == -ENOENT) {
1724 rc = -EACCES;
Casey Schaufler7898e1f2011-01-17 08:05:27 -08001725 break;
Casey Schaufler0e0a0702011-02-08 16:36:24 -08001726 }
1727 /*
1728 * If there is a local entry it modifies the
1729 * potential access, too.
1730 */
Lukasz Pawelczyk21c7eae2014-08-29 17:02:55 +02001731 tmay = smk_access_entry(mkp->smk_known, okp->smk_known,
1732 &tsp->smk_rules);
Casey Schaufler0e0a0702011-02-08 16:36:24 -08001733 if (tmay != -ENOENT)
1734 mmay &= tmay;
1735
1736 /*
1737 * If there is any access available to current that is
1738 * not available to a SMACK64MMAP subject
1739 * deny access.
1740 */
Casey Schaufler75a25632011-02-09 19:58:42 -08001741 if ((may | mmay) != mmay) {
Casey Schaufler0e0a0702011-02-08 16:36:24 -08001742 rc = -EACCES;
1743 break;
1744 }
Casey Schaufler7898e1f2011-01-17 08:05:27 -08001745 }
1746
1747 rcu_read_unlock();
1748
1749 return rc;
1750}
1751
1752/**
Casey Schauflere114e472008-02-04 22:29:50 -08001753 * smack_file_set_fowner - set the file security blob value
1754 * @file: object in question
1755 *
Casey Schauflere114e472008-02-04 22:29:50 -08001756 */
Jeff Laytone0b93ed2014-08-22 11:27:32 -04001757static void smack_file_set_fowner(struct file *file)
Casey Schauflere114e472008-02-04 22:29:50 -08001758{
Casey Schauflerf28952a2018-11-12 09:38:53 -08001759 struct smack_known **blob = smack_file(file);
1760
1761 *blob = smk_of_current();
Casey Schauflere114e472008-02-04 22:29:50 -08001762}
1763
1764/**
1765 * smack_file_send_sigiotask - Smack on sigio
1766 * @tsk: The target task
1767 * @fown: the object the signal come from
1768 * @signum: unused
1769 *
1770 * Allow a privileged task to get signals even if it shouldn't
1771 *
1772 * Returns 0 if a subject with the object's smack could
1773 * write to the task, an error code otherwise.
1774 */
1775static int smack_file_send_sigiotask(struct task_struct *tsk,
1776 struct fown_struct *fown, int signum)
1777{
Casey Schauflerf28952a2018-11-12 09:38:53 -08001778 struct smack_known **blob;
Casey Schaufler2f823ff2013-05-22 18:43:03 -07001779 struct smack_known *skp;
Casey Schauflerb17103a2018-11-09 16:12:56 -08001780 struct smack_known *tkp = smk_of_task(smack_cred(tsk->cred));
Casey Schauflerdcb569c2018-09-18 16:09:16 -07001781 const struct cred *tcred;
Casey Schauflere114e472008-02-04 22:29:50 -08001782 struct file *file;
1783 int rc;
Etienne Bassetecfcc532009-04-08 20:40:06 +02001784 struct smk_audit_info ad;
Casey Schauflere114e472008-02-04 22:29:50 -08001785
1786 /*
1787 * struct fown_struct is never outside the context of a struct file
1788 */
1789 file = container_of(fown, struct file, f_owner);
Casey Schaufler7898e1f2011-01-17 08:05:27 -08001790
Etienne Bassetecfcc532009-04-08 20:40:06 +02001791 /* we don't log here as rc can be overriden */
Casey Schauflerf28952a2018-11-12 09:38:53 -08001792 blob = smack_file(file);
1793 skp = *blob;
Casey Schauflerc60b9062016-08-30 10:31:39 -07001794 rc = smk_access(skp, tkp, MAY_DELIVER, NULL);
1795 rc = smk_bu_note("sigiotask", skp, tkp, MAY_DELIVER, rc);
Casey Schauflerdcb569c2018-09-18 16:09:16 -07001796
1797 rcu_read_lock();
1798 tcred = __task_cred(tsk);
1799 if (rc != 0 && smack_privileged_cred(CAP_MAC_OVERRIDE, tcred))
Etienne Bassetecfcc532009-04-08 20:40:06 +02001800 rc = 0;
Casey Schauflerdcb569c2018-09-18 16:09:16 -07001801 rcu_read_unlock();
Etienne Bassetecfcc532009-04-08 20:40:06 +02001802
1803 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK);
1804 smk_ad_setfield_u_tsk(&ad, tsk);
Casey Schauflerc60b9062016-08-30 10:31:39 -07001805 smack_log(skp->smk_known, tkp->smk_known, MAY_DELIVER, rc, &ad);
Casey Schauflere114e472008-02-04 22:29:50 -08001806 return rc;
1807}
1808
1809/**
1810 * smack_file_receive - Smack file receive check
1811 * @file: the object
1812 *
1813 * Returns 0 if current has access, error code otherwise
1814 */
1815static int smack_file_receive(struct file *file)
1816{
Casey Schauflerd166c802014-08-27 14:51:27 -07001817 int rc;
Casey Schauflere114e472008-02-04 22:29:50 -08001818 int may = 0;
Etienne Bassetecfcc532009-04-08 20:40:06 +02001819 struct smk_audit_info ad;
Casey Schaufler5e7270a2014-12-12 17:19:19 -08001820 struct inode *inode = file_inode(file);
Casey Schaufler79be0932015-12-07 14:34:32 -08001821 struct socket *sock;
1822 struct task_smack *tsp;
1823 struct socket_smack *ssp;
Casey Schauflere114e472008-02-04 22:29:50 -08001824
Seung-Woo Kim97775822015-04-17 15:25:04 +09001825 if (unlikely(IS_PRIVATE(inode)))
1826 return 0;
1827
Casey Schaufler4482a442013-12-30 17:37:45 -08001828 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
Etienne Bassetecfcc532009-04-08 20:40:06 +02001829 smk_ad_setfield_u_fs_path(&ad, file->f_path);
Casey Schaufler79be0932015-12-07 14:34:32 -08001830
Casey Schaufler51d59af2017-05-31 08:53:42 -07001831 if (inode->i_sb->s_magic == SOCKFS_MAGIC) {
Casey Schaufler79be0932015-12-07 14:34:32 -08001832 sock = SOCKET_I(inode);
1833 ssp = sock->sk->sk_security;
Casey Schauflerb17103a2018-11-09 16:12:56 -08001834 tsp = smack_cred(current_cred());
Casey Schaufler79be0932015-12-07 14:34:32 -08001835 /*
1836 * If the receiving process can't write to the
1837 * passed socket or if the passed socket can't
1838 * write to the receiving process don't accept
1839 * the passed socket.
1840 */
1841 rc = smk_access(tsp->smk_task, ssp->smk_out, MAY_WRITE, &ad);
1842 rc = smk_bu_file(file, may, rc);
1843 if (rc < 0)
1844 return rc;
1845 rc = smk_access(ssp->smk_in, tsp->smk_task, MAY_WRITE, &ad);
1846 rc = smk_bu_file(file, may, rc);
1847 return rc;
1848 }
Casey Schauflere114e472008-02-04 22:29:50 -08001849 /*
1850 * This code relies on bitmasks.
1851 */
1852 if (file->f_mode & FMODE_READ)
1853 may = MAY_READ;
1854 if (file->f_mode & FMODE_WRITE)
1855 may |= MAY_WRITE;
1856
Casey Schaufler5e7270a2014-12-12 17:19:19 -08001857 rc = smk_curacc(smk_of_inode(inode), may, &ad);
Casey Schauflerd166c802014-08-27 14:51:27 -07001858 rc = smk_bu_file(file, may, rc);
1859 return rc;
Casey Schauflere114e472008-02-04 22:29:50 -08001860}
1861
Casey Schaufler531f1d42011-09-19 12:41:42 -07001862/**
Eric Paris83d49852012-04-04 13:45:40 -04001863 * smack_file_open - Smack dentry open processing
Casey Schaufler531f1d42011-09-19 12:41:42 -07001864 * @file: the object
Casey Schaufler531f1d42011-09-19 12:41:42 -07001865 *
1866 * Set the security blob in the file structure.
Casey Schauflera6834c02014-04-21 11:10:26 -07001867 * Allow the open only if the task has read access. There are
1868 * many read operations (e.g. fstat) that you can do with an
1869 * fd even if you have the file open write-only.
Casey Schaufler531f1d42011-09-19 12:41:42 -07001870 *
luanshia1a07f22019-07-05 10:35:20 +08001871 * Returns 0 if current has access, error code otherwise
Casey Schaufler531f1d42011-09-19 12:41:42 -07001872 */
Al Viro94817692018-07-10 14:13:18 -04001873static int smack_file_open(struct file *file)
Casey Schaufler531f1d42011-09-19 12:41:42 -07001874{
Casey Schauflerb17103a2018-11-09 16:12:56 -08001875 struct task_smack *tsp = smack_cred(file->f_cred);
Casey Schaufler5e7270a2014-12-12 17:19:19 -08001876 struct inode *inode = file_inode(file);
Casey Schauflera6834c02014-04-21 11:10:26 -07001877 struct smk_audit_info ad;
1878 int rc;
Casey Schaufler531f1d42011-09-19 12:41:42 -07001879
Casey Schauflera6834c02014-04-21 11:10:26 -07001880 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
1881 smk_ad_setfield_u_fs_path(&ad, file->f_path);
Himanshu Shuklac9d238a2016-11-23 11:59:45 +05301882 rc = smk_tskacc(tsp, smk_of_inode(inode), MAY_READ, &ad);
Al Viro94817692018-07-10 14:13:18 -04001883 rc = smk_bu_credfile(file->f_cred, file, MAY_READ, rc);
Casey Schauflera6834c02014-04-21 11:10:26 -07001884
1885 return rc;
Casey Schaufler531f1d42011-09-19 12:41:42 -07001886}
1887
Casey Schauflere114e472008-02-04 22:29:50 -08001888/*
1889 * Task hooks
1890 */
1891
1892/**
David Howellsee18d642009-09-02 09:14:21 +01001893 * smack_cred_alloc_blank - "allocate" blank task-level security credentials
luanshia1a07f22019-07-05 10:35:20 +08001894 * @cred: the new credentials
David Howellsee18d642009-09-02 09:14:21 +01001895 * @gfp: the atomicity of any memory allocations
1896 *
1897 * Prepare a blank set of credentials for modification. This must allocate all
1898 * the memory the LSM module might require such that cred_transfer() can
1899 * complete without error.
1900 */
1901static int smack_cred_alloc_blank(struct cred *cred, gfp_t gfp)
1902{
Casey Schauflerbbd36622018-11-12 09:30:56 -08001903 init_task_smack(smack_cred(cred), NULL, NULL);
David Howellsee18d642009-09-02 09:14:21 +01001904 return 0;
1905}
1906
1907
1908/**
David Howellsf1752ee2008-11-14 10:39:17 +11001909 * smack_cred_free - "free" task-level security credentials
1910 * @cred: the credentials in question
Casey Schauflere114e472008-02-04 22:29:50 -08001911 *
Casey Schauflere114e472008-02-04 22:29:50 -08001912 */
David Howellsf1752ee2008-11-14 10:39:17 +11001913static void smack_cred_free(struct cred *cred)
Casey Schauflere114e472008-02-04 22:29:50 -08001914{
Casey Schauflerb17103a2018-11-09 16:12:56 -08001915 struct task_smack *tsp = smack_cred(cred);
Casey Schaufler7898e1f2011-01-17 08:05:27 -08001916 struct smack_rule *rp;
1917 struct list_head *l;
1918 struct list_head *n;
1919
Zbigniew Jasinski38416e52015-10-19 18:23:53 +02001920 smk_destroy_label_list(&tsp->smk_relabel);
1921
Casey Schaufler7898e1f2011-01-17 08:05:27 -08001922 list_for_each_safe(l, n, &tsp->smk_rules) {
1923 rp = list_entry(l, struct smack_rule, list);
1924 list_del(&rp->list);
Casey Schaufler4e328b02019-04-02 11:37:12 -07001925 kmem_cache_free(smack_rule_cache, rp);
Casey Schaufler7898e1f2011-01-17 08:05:27 -08001926 }
Casey Schauflere114e472008-02-04 22:29:50 -08001927}
1928
1929/**
David Howellsd84f4f92008-11-14 10:39:23 +11001930 * smack_cred_prepare - prepare new set of credentials for modification
1931 * @new: the new credentials
1932 * @old: the original credentials
1933 * @gfp: the atomicity of any memory allocations
1934 *
1935 * Prepare a new set of credentials for modification.
1936 */
1937static int smack_cred_prepare(struct cred *new, const struct cred *old,
1938 gfp_t gfp)
1939{
Casey Schauflerb17103a2018-11-09 16:12:56 -08001940 struct task_smack *old_tsp = smack_cred(old);
Casey Schauflerbbd36622018-11-12 09:30:56 -08001941 struct task_smack *new_tsp = smack_cred(new);
Casey Schaufler7898e1f2011-01-17 08:05:27 -08001942 int rc;
Casey Schaufler676dac42010-12-02 06:43:39 -08001943
Casey Schauflerbbd36622018-11-12 09:30:56 -08001944 init_task_smack(new_tsp, old_tsp->smk_task, old_tsp->smk_task);
Himanshu Shuklab437aba2016-11-10 16:17:02 +05301945
Casey Schaufler7898e1f2011-01-17 08:05:27 -08001946 rc = smk_copy_rules(&new_tsp->smk_rules, &old_tsp->smk_rules, gfp);
1947 if (rc != 0)
1948 return rc;
1949
Zbigniew Jasinski38416e52015-10-19 18:23:53 +02001950 rc = smk_copy_relabel(&new_tsp->smk_relabel, &old_tsp->smk_relabel,
1951 gfp);
Casey Schauflerbbd36622018-11-12 09:30:56 -08001952 return rc;
David Howellsd84f4f92008-11-14 10:39:23 +11001953}
1954
Randy Dunlap251a2a92009-02-18 11:42:33 -08001955/**
David Howellsee18d642009-09-02 09:14:21 +01001956 * smack_cred_transfer - Transfer the old credentials to the new credentials
1957 * @new: the new credentials
1958 * @old: the original credentials
1959 *
1960 * Fill in a set of blank credentials from another set of credentials.
1961 */
1962static void smack_cred_transfer(struct cred *new, const struct cred *old)
1963{
Casey Schauflerb17103a2018-11-09 16:12:56 -08001964 struct task_smack *old_tsp = smack_cred(old);
1965 struct task_smack *new_tsp = smack_cred(new);
Casey Schaufler676dac42010-12-02 06:43:39 -08001966
1967 new_tsp->smk_task = old_tsp->smk_task;
1968 new_tsp->smk_forked = old_tsp->smk_task;
Casey Schaufler7898e1f2011-01-17 08:05:27 -08001969 mutex_init(&new_tsp->smk_rules_lock);
1970 INIT_LIST_HEAD(&new_tsp->smk_rules);
1971
Casey Schaufler7898e1f2011-01-17 08:05:27 -08001972 /* cbs copy rule list */
David Howellsee18d642009-09-02 09:14:21 +01001973}
1974
1975/**
Matthew Garrett3ec30112018-01-08 13:36:19 -08001976 * smack_cred_getsecid - get the secid corresponding to a creds structure
luanshia1a07f22019-07-05 10:35:20 +08001977 * @cred: the object creds
Matthew Garrett3ec30112018-01-08 13:36:19 -08001978 * @secid: where to put the result
1979 *
1980 * Sets the secid to contain a u32 version of the smack label.
1981 */
Casey Schauflerb17103a2018-11-09 16:12:56 -08001982static void smack_cred_getsecid(const struct cred *cred, u32 *secid)
Matthew Garrett3ec30112018-01-08 13:36:19 -08001983{
1984 struct smack_known *skp;
1985
1986 rcu_read_lock();
Casey Schauflerb17103a2018-11-09 16:12:56 -08001987 skp = smk_of_task(smack_cred(cred));
Matthew Garrett3ec30112018-01-08 13:36:19 -08001988 *secid = skp->smk_secid;
1989 rcu_read_unlock();
1990}
1991
1992/**
David Howells3a3b7ce2008-11-14 10:39:28 +11001993 * smack_kernel_act_as - Set the subjective context in a set of credentials
Randy Dunlap251a2a92009-02-18 11:42:33 -08001994 * @new: points to the set of credentials to be modified.
1995 * @secid: specifies the security ID to be set
David Howells3a3b7ce2008-11-14 10:39:28 +11001996 *
1997 * Set the security data for a kernel service.
1998 */
1999static int smack_kernel_act_as(struct cred *new, u32 secid)
2000{
Casey Schauflerb17103a2018-11-09 16:12:56 -08002001 struct task_smack *new_tsp = smack_cred(new);
David Howells3a3b7ce2008-11-14 10:39:28 +11002002
Casey Schaufler152f91d2016-11-14 09:38:15 -08002003 new_tsp->smk_task = smack_from_secid(secid);
David Howells3a3b7ce2008-11-14 10:39:28 +11002004 return 0;
2005}
2006
2007/**
2008 * smack_kernel_create_files_as - Set the file creation label in a set of creds
Randy Dunlap251a2a92009-02-18 11:42:33 -08002009 * @new: points to the set of credentials to be modified
2010 * @inode: points to the inode to use as a reference
David Howells3a3b7ce2008-11-14 10:39:28 +11002011 *
2012 * Set the file creation context in a set of credentials to the same
2013 * as the objective context of the specified inode
2014 */
2015static int smack_kernel_create_files_as(struct cred *new,
2016 struct inode *inode)
2017{
Casey Schauflerfb4021b2018-11-12 12:43:01 -08002018 struct inode_smack *isp = smack_inode(inode);
Casey Schauflerb17103a2018-11-09 16:12:56 -08002019 struct task_smack *tsp = smack_cred(new);
David Howells3a3b7ce2008-11-14 10:39:28 +11002020
Lukasz Pawelczyk21c7eae2014-08-29 17:02:55 +02002021 tsp->smk_forked = isp->smk_inode;
Casey Schaufler2f823ff2013-05-22 18:43:03 -07002022 tsp->smk_task = tsp->smk_forked;
David Howells3a3b7ce2008-11-14 10:39:28 +11002023 return 0;
2024}
2025
2026/**
Etienne Bassetecfcc532009-04-08 20:40:06 +02002027 * smk_curacc_on_task - helper to log task related access
2028 * @p: the task object
Casey Schaufler531f1d42011-09-19 12:41:42 -07002029 * @access: the access requested
2030 * @caller: name of the calling function for audit
Etienne Bassetecfcc532009-04-08 20:40:06 +02002031 *
2032 * Return 0 if access is permitted
2033 */
Casey Schaufler531f1d42011-09-19 12:41:42 -07002034static int smk_curacc_on_task(struct task_struct *p, int access,
2035 const char *caller)
Etienne Bassetecfcc532009-04-08 20:40:06 +02002036{
2037 struct smk_audit_info ad;
Andrey Ryabinin6d1cff22015-01-13 18:52:40 +03002038 struct smack_known *skp = smk_of_task_struct(p);
Casey Schauflerd166c802014-08-27 14:51:27 -07002039 int rc;
Etienne Bassetecfcc532009-04-08 20:40:06 +02002040
Casey Schaufler531f1d42011-09-19 12:41:42 -07002041 smk_ad_init(&ad, caller, LSM_AUDIT_DATA_TASK);
Etienne Bassetecfcc532009-04-08 20:40:06 +02002042 smk_ad_setfield_u_tsk(&ad, p);
Lukasz Pawelczyk21c7eae2014-08-29 17:02:55 +02002043 rc = smk_curacc(skp, access, &ad);
Casey Schauflerd166c802014-08-27 14:51:27 -07002044 rc = smk_bu_task(p, access, rc);
2045 return rc;
Etienne Bassetecfcc532009-04-08 20:40:06 +02002046}
2047
2048/**
Casey Schauflere114e472008-02-04 22:29:50 -08002049 * smack_task_setpgid - Smack check on setting pgid
2050 * @p: the task object
2051 * @pgid: unused
2052 *
2053 * Return 0 if write access is permitted
2054 */
2055static int smack_task_setpgid(struct task_struct *p, pid_t pgid)
2056{
Casey Schaufler531f1d42011-09-19 12:41:42 -07002057 return smk_curacc_on_task(p, MAY_WRITE, __func__);
Casey Schauflere114e472008-02-04 22:29:50 -08002058}
2059
2060/**
2061 * smack_task_getpgid - Smack access check for getpgid
2062 * @p: the object task
2063 *
2064 * Returns 0 if current can read the object task, error code otherwise
2065 */
2066static int smack_task_getpgid(struct task_struct *p)
2067{
Casey Schaufler531f1d42011-09-19 12:41:42 -07002068 return smk_curacc_on_task(p, MAY_READ, __func__);
Casey Schauflere114e472008-02-04 22:29:50 -08002069}
2070
2071/**
2072 * smack_task_getsid - Smack access check for getsid
2073 * @p: the object task
2074 *
2075 * Returns 0 if current can read the object task, error code otherwise
2076 */
2077static int smack_task_getsid(struct task_struct *p)
2078{
Casey Schaufler531f1d42011-09-19 12:41:42 -07002079 return smk_curacc_on_task(p, MAY_READ, __func__);
Casey Schauflere114e472008-02-04 22:29:50 -08002080}
2081
2082/**
2083 * smack_task_getsecid - get the secid of the task
2084 * @p: the object task
2085 * @secid: where to put the result
2086 *
2087 * Sets the secid to contain a u32 version of the smack label.
2088 */
2089static void smack_task_getsecid(struct task_struct *p, u32 *secid)
2090{
Andrey Ryabinin6d1cff22015-01-13 18:52:40 +03002091 struct smack_known *skp = smk_of_task_struct(p);
Casey Schaufler2f823ff2013-05-22 18:43:03 -07002092
2093 *secid = skp->smk_secid;
Casey Schauflere114e472008-02-04 22:29:50 -08002094}
2095
2096/**
2097 * smack_task_setnice - Smack check on setting nice
2098 * @p: the task object
2099 * @nice: unused
2100 *
2101 * Return 0 if write access is permitted
2102 */
2103static int smack_task_setnice(struct task_struct *p, int nice)
2104{
Casey Schauflerb1d9e6b2015-05-02 15:11:42 -07002105 return smk_curacc_on_task(p, MAY_WRITE, __func__);
Casey Schauflere114e472008-02-04 22:29:50 -08002106}
2107
2108/**
2109 * smack_task_setioprio - Smack check on setting ioprio
2110 * @p: the task object
2111 * @ioprio: unused
2112 *
2113 * Return 0 if write access is permitted
2114 */
2115static int smack_task_setioprio(struct task_struct *p, int ioprio)
2116{
Casey Schauflerb1d9e6b2015-05-02 15:11:42 -07002117 return smk_curacc_on_task(p, MAY_WRITE, __func__);
Casey Schauflere114e472008-02-04 22:29:50 -08002118}
2119
2120/**
2121 * smack_task_getioprio - Smack check on reading ioprio
2122 * @p: the task object
2123 *
2124 * Return 0 if read access is permitted
2125 */
2126static int smack_task_getioprio(struct task_struct *p)
2127{
Casey Schaufler531f1d42011-09-19 12:41:42 -07002128 return smk_curacc_on_task(p, MAY_READ, __func__);
Casey Schauflere114e472008-02-04 22:29:50 -08002129}
2130
2131/**
2132 * smack_task_setscheduler - Smack check on setting scheduler
2133 * @p: the task object
Casey Schauflere114e472008-02-04 22:29:50 -08002134 *
2135 * Return 0 if read access is permitted
2136 */
KOSAKI Motohirob0ae1982010-10-15 04:21:18 +09002137static int smack_task_setscheduler(struct task_struct *p)
Casey Schauflere114e472008-02-04 22:29:50 -08002138{
Casey Schauflerb1d9e6b2015-05-02 15:11:42 -07002139 return smk_curacc_on_task(p, MAY_WRITE, __func__);
Casey Schauflere114e472008-02-04 22:29:50 -08002140}
2141
2142/**
2143 * smack_task_getscheduler - Smack check on reading scheduler
2144 * @p: the task object
2145 *
2146 * Return 0 if read access is permitted
2147 */
2148static int smack_task_getscheduler(struct task_struct *p)
2149{
Casey Schaufler531f1d42011-09-19 12:41:42 -07002150 return smk_curacc_on_task(p, MAY_READ, __func__);
Casey Schauflere114e472008-02-04 22:29:50 -08002151}
2152
2153/**
2154 * smack_task_movememory - Smack check on moving memory
2155 * @p: the task object
2156 *
2157 * Return 0 if write access is permitted
2158 */
2159static int smack_task_movememory(struct task_struct *p)
2160{
Casey Schaufler531f1d42011-09-19 12:41:42 -07002161 return smk_curacc_on_task(p, MAY_WRITE, __func__);
Casey Schauflere114e472008-02-04 22:29:50 -08002162}
2163
2164/**
2165 * smack_task_kill - Smack check on signal delivery
2166 * @p: the task object
2167 * @info: unused
2168 * @sig: unused
Stephen Smalley6b4f3d02017-09-08 12:40:01 -04002169 * @cred: identifies the cred to use in lieu of current's
Casey Schauflere114e472008-02-04 22:29:50 -08002170 *
2171 * Return 0 if write access is permitted
2172 *
Casey Schauflere114e472008-02-04 22:29:50 -08002173 */
Eric W. Biedermanae7795b2018-09-25 11:27:20 +02002174static int smack_task_kill(struct task_struct *p, struct kernel_siginfo *info,
Stephen Smalley6b4f3d02017-09-08 12:40:01 -04002175 int sig, const struct cred *cred)
Casey Schauflere114e472008-02-04 22:29:50 -08002176{
Etienne Bassetecfcc532009-04-08 20:40:06 +02002177 struct smk_audit_info ad;
Casey Schaufler2f823ff2013-05-22 18:43:03 -07002178 struct smack_known *skp;
Andrey Ryabinin6d1cff22015-01-13 18:52:40 +03002179 struct smack_known *tkp = smk_of_task_struct(p);
Casey Schauflerd166c802014-08-27 14:51:27 -07002180 int rc;
Etienne Bassetecfcc532009-04-08 20:40:06 +02002181
Rafal Krypa18d872f2016-04-04 11:14:53 +02002182 if (!sig)
2183 return 0; /* null signal; existence test */
2184
Etienne Bassetecfcc532009-04-08 20:40:06 +02002185 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK);
2186 smk_ad_setfield_u_tsk(&ad, p);
Casey Schauflere114e472008-02-04 22:29:50 -08002187 /*
Casey Schauflere114e472008-02-04 22:29:50 -08002188 * Sending a signal requires that the sender
2189 * can write the receiver.
2190 */
Stephen Smalley6b4f3d02017-09-08 12:40:01 -04002191 if (cred == NULL) {
Casey Schauflerc60b9062016-08-30 10:31:39 -07002192 rc = smk_curacc(tkp, MAY_DELIVER, &ad);
2193 rc = smk_bu_task(p, MAY_DELIVER, rc);
Casey Schauflerd166c802014-08-27 14:51:27 -07002194 return rc;
2195 }
Casey Schauflere114e472008-02-04 22:29:50 -08002196 /*
Stephen Smalley6b4f3d02017-09-08 12:40:01 -04002197 * If the cred isn't NULL we're dealing with some USB IO
Casey Schauflere114e472008-02-04 22:29:50 -08002198 * specific behavior. This is not clean. For one thing
2199 * we can't take privilege into account.
2200 */
Casey Schauflerb17103a2018-11-09 16:12:56 -08002201 skp = smk_of_task(smack_cred(cred));
Casey Schauflerc60b9062016-08-30 10:31:39 -07002202 rc = smk_access(skp, tkp, MAY_DELIVER, &ad);
2203 rc = smk_bu_note("USB signal", skp, tkp, MAY_DELIVER, rc);
Casey Schauflerd166c802014-08-27 14:51:27 -07002204 return rc;
Casey Schauflere114e472008-02-04 22:29:50 -08002205}
2206
2207/**
Casey Schauflere114e472008-02-04 22:29:50 -08002208 * smack_task_to_inode - copy task smack into the inode blob
2209 * @p: task to copy from
Randy Dunlap251a2a92009-02-18 11:42:33 -08002210 * @inode: inode to copy to
Casey Schauflere114e472008-02-04 22:29:50 -08002211 *
2212 * Sets the smack pointer in the inode security blob
2213 */
2214static void smack_task_to_inode(struct task_struct *p, struct inode *inode)
2215{
Casey Schauflerfb4021b2018-11-12 12:43:01 -08002216 struct inode_smack *isp = smack_inode(inode);
Andrey Ryabinin6d1cff22015-01-13 18:52:40 +03002217 struct smack_known *skp = smk_of_task_struct(p);
Casey Schaufler2f823ff2013-05-22 18:43:03 -07002218
Lukasz Pawelczyk21c7eae2014-08-29 17:02:55 +02002219 isp->smk_inode = skp;
Casey Schaufler7b4e8842018-06-22 10:54:45 -07002220 isp->smk_flags |= SMK_INODE_INSTANT;
Casey Schauflere114e472008-02-04 22:29:50 -08002221}
2222
2223/*
2224 * Socket hooks.
2225 */
2226
2227/**
2228 * smack_sk_alloc_security - Allocate a socket blob
2229 * @sk: the socket
2230 * @family: unused
Randy Dunlap251a2a92009-02-18 11:42:33 -08002231 * @gfp_flags: memory allocation flags
Casey Schauflere114e472008-02-04 22:29:50 -08002232 *
2233 * Assign Smack pointers to current
2234 *
2235 * Returns 0 on success, -ENOMEM is there's no memory
2236 */
2237static int smack_sk_alloc_security(struct sock *sk, int family, gfp_t gfp_flags)
2238{
Casey Schaufler2f823ff2013-05-22 18:43:03 -07002239 struct smack_known *skp = smk_of_current();
Casey Schauflere114e472008-02-04 22:29:50 -08002240 struct socket_smack *ssp;
2241
2242 ssp = kzalloc(sizeof(struct socket_smack), gfp_flags);
2243 if (ssp == NULL)
2244 return -ENOMEM;
2245
jooseong lee08382c92016-11-03 11:54:39 +01002246 /*
2247 * Sockets created by kernel threads receive web label.
2248 */
2249 if (unlikely(current->flags & PF_KTHREAD)) {
2250 ssp->smk_in = &smack_known_web;
2251 ssp->smk_out = &smack_known_web;
2252 } else {
2253 ssp->smk_in = skp;
2254 ssp->smk_out = skp;
2255 }
Casey Schaufler272cd7a2011-09-20 12:24:36 -07002256 ssp->smk_packet = NULL;
Casey Schauflere114e472008-02-04 22:29:50 -08002257
2258 sk->sk_security = ssp;
2259
2260 return 0;
2261}
2262
2263/**
2264 * smack_sk_free_security - Free a socket blob
2265 * @sk: the socket
2266 *
2267 * Clears the blob pointer
2268 */
2269static void smack_sk_free_security(struct sock *sk)
2270{
Vishal Goel0c96d1f2016-11-23 10:32:54 +05302271#ifdef SMACK_IPV6_PORT_LABELING
2272 struct smk_port_label *spp;
2273
2274 if (sk->sk_family == PF_INET6) {
2275 rcu_read_lock();
2276 list_for_each_entry_rcu(spp, &smk_ipv6_port_list, list) {
2277 if (spp->smk_sock != sk)
2278 continue;
2279 spp->smk_can_reuse = 1;
2280 break;
2281 }
2282 rcu_read_unlock();
2283 }
2284#endif
Casey Schauflere114e472008-02-04 22:29:50 -08002285 kfree(sk->sk_security);
2286}
2287
2288/**
Casey Schaufler21abb1e2015-07-22 14:25:31 -07002289* smack_ipv4host_label - check host based restrictions
Paul Moore07feee82009-03-27 17:10:54 -04002290* @sip: the object end
2291*
2292* looks for host based access restrictions
2293*
2294* This version will only be appropriate for really small sets of single label
2295* hosts. The caller is responsible for ensuring that the RCU read lock is
2296* taken before calling this function.
2297*
2298* Returns the label of the far end or NULL if it's not special.
2299*/
Casey Schaufler21abb1e2015-07-22 14:25:31 -07002300static struct smack_known *smack_ipv4host_label(struct sockaddr_in *sip)
Paul Moore07feee82009-03-27 17:10:54 -04002301{
Casey Schaufler21abb1e2015-07-22 14:25:31 -07002302 struct smk_net4addr *snp;
Paul Moore07feee82009-03-27 17:10:54 -04002303 struct in_addr *siap = &sip->sin_addr;
2304
2305 if (siap->s_addr == 0)
2306 return NULL;
2307
Casey Schaufler21abb1e2015-07-22 14:25:31 -07002308 list_for_each_entry_rcu(snp, &smk_net4addr_list, list)
2309 /*
2310 * we break after finding the first match because
2311 * the list is sorted from longest to shortest mask
2312 * so we have found the most specific match
2313 */
2314 if (snp->smk_host.s_addr ==
2315 (siap->s_addr & snp->smk_mask.s_addr))
2316 return snp->smk_label;
2317
2318 return NULL;
2319}
2320
Casey Schaufler21abb1e2015-07-22 14:25:31 -07002321/*
2322 * smk_ipv6_localhost - Check for local ipv6 host address
2323 * @sip: the address
2324 *
2325 * Returns boolean true if this is the localhost address
2326 */
2327static bool smk_ipv6_localhost(struct sockaddr_in6 *sip)
2328{
2329 __be16 *be16p = (__be16 *)&sip->sin6_addr;
2330 __be32 *be32p = (__be32 *)&sip->sin6_addr;
2331
2332 if (be32p[0] == 0 && be32p[1] == 0 && be32p[2] == 0 && be16p[6] == 0 &&
2333 ntohs(be16p[7]) == 1)
2334 return true;
2335 return false;
2336}
2337
2338/**
2339* smack_ipv6host_label - check host based restrictions
2340* @sip: the object end
2341*
2342* looks for host based access restrictions
2343*
2344* This version will only be appropriate for really small sets of single label
2345* hosts. The caller is responsible for ensuring that the RCU read lock is
2346* taken before calling this function.
2347*
2348* Returns the label of the far end or NULL if it's not special.
2349*/
2350static struct smack_known *smack_ipv6host_label(struct sockaddr_in6 *sip)
2351{
2352 struct smk_net6addr *snp;
2353 struct in6_addr *sap = &sip->sin6_addr;
2354 int i;
2355 int found = 0;
2356
2357 /*
2358 * It's local. Don't look for a host label.
2359 */
2360 if (smk_ipv6_localhost(sip))
2361 return NULL;
2362
2363 list_for_each_entry_rcu(snp, &smk_net6addr_list, list) {
Paul Moore07feee82009-03-27 17:10:54 -04002364 /*
Casey Schaufler2e4939f2016-11-07 19:01:09 -08002365 * If the label is NULL the entry has
2366 * been renounced. Ignore it.
2367 */
2368 if (snp->smk_label == NULL)
2369 continue;
2370 /*
Paul Moore07feee82009-03-27 17:10:54 -04002371 * we break after finding the first match because
2372 * the list is sorted from longest to shortest mask
2373 * so we have found the most specific match
2374 */
Casey Schaufler21abb1e2015-07-22 14:25:31 -07002375 for (found = 1, i = 0; i < 8; i++) {
Casey Schaufler21abb1e2015-07-22 14:25:31 -07002376 if ((sap->s6_addr16[i] & snp->smk_mask.s6_addr16[i]) !=
2377 snp->smk_host.s6_addr16[i]) {
2378 found = 0;
2379 break;
2380 }
Etienne Basset43031542009-03-27 17:11:01 -04002381 }
Casey Schaufler21abb1e2015-07-22 14:25:31 -07002382 if (found)
2383 return snp->smk_label;
2384 }
Paul Moore07feee82009-03-27 17:10:54 -04002385
2386 return NULL;
2387}
2388
2389/**
Casey Schauflere114e472008-02-04 22:29:50 -08002390 * smack_netlabel - Set the secattr on a socket
2391 * @sk: the socket
Casey Schaufler6d3dc072008-12-31 12:54:12 -05002392 * @labeled: socket label scheme
Casey Schauflere114e472008-02-04 22:29:50 -08002393 *
2394 * Convert the outbound smack value (smk_out) to a
2395 * secattr and attach it to the socket.
2396 *
2397 * Returns 0 on success or an error code
2398 */
Casey Schaufler6d3dc072008-12-31 12:54:12 -05002399static int smack_netlabel(struct sock *sk, int labeled)
Casey Schauflere114e472008-02-04 22:29:50 -08002400{
Casey Schauflerf7112e62012-05-06 15:22:02 -07002401 struct smack_known *skp;
Paul Moore07feee82009-03-27 17:10:54 -04002402 struct socket_smack *ssp = sk->sk_security;
Casey Schaufler6d3dc072008-12-31 12:54:12 -05002403 int rc = 0;
Casey Schauflere114e472008-02-04 22:29:50 -08002404
Casey Schaufler6d3dc072008-12-31 12:54:12 -05002405 /*
2406 * Usually the netlabel code will handle changing the
2407 * packet labeling based on the label.
2408 * The case of a single label host is different, because
2409 * a single label host should never get a labeled packet
2410 * even though the label is usually associated with a packet
2411 * label.
2412 */
2413 local_bh_disable();
2414 bh_lock_sock_nested(sk);
2415
2416 if (ssp->smk_out == smack_net_ambient ||
2417 labeled == SMACK_UNLABELED_SOCKET)
2418 netlbl_sock_delattr(sk);
2419 else {
Casey Schaufler2f823ff2013-05-22 18:43:03 -07002420 skp = ssp->smk_out;
Casey Schauflerf7112e62012-05-06 15:22:02 -07002421 rc = netlbl_sock_setattr(sk, sk->sk_family, &skp->smk_netlabel);
Casey Schaufler6d3dc072008-12-31 12:54:12 -05002422 }
2423
2424 bh_unlock_sock(sk);
2425 local_bh_enable();
Casey Schaufler4bc87e62008-02-15 15:24:25 -08002426
Casey Schauflere114e472008-02-04 22:29:50 -08002427 return rc;
2428}
2429
2430/**
Paul Moore07feee82009-03-27 17:10:54 -04002431 * smack_netlbel_send - Set the secattr on a socket and perform access checks
2432 * @sk: the socket
2433 * @sap: the destination address
2434 *
2435 * Set the correct secattr for the given socket based on the destination
2436 * address and perform any outbound access checks needed.
2437 *
2438 * Returns 0 on success or an error code.
2439 *
2440 */
2441static int smack_netlabel_send(struct sock *sk, struct sockaddr_in *sap)
2442{
Casey Schaufler2f823ff2013-05-22 18:43:03 -07002443 struct smack_known *skp;
Paul Moore07feee82009-03-27 17:10:54 -04002444 int rc;
2445 int sk_lbl;
Lukasz Pawelczyk21c7eae2014-08-29 17:02:55 +02002446 struct smack_known *hkp;
Paul Moore07feee82009-03-27 17:10:54 -04002447 struct socket_smack *ssp = sk->sk_security;
Etienne Bassetecfcc532009-04-08 20:40:06 +02002448 struct smk_audit_info ad;
Paul Moore07feee82009-03-27 17:10:54 -04002449
2450 rcu_read_lock();
Casey Schaufler21abb1e2015-07-22 14:25:31 -07002451 hkp = smack_ipv4host_label(sap);
Lukasz Pawelczyk21c7eae2014-08-29 17:02:55 +02002452 if (hkp != NULL) {
Etienne Bassetecfcc532009-04-08 20:40:06 +02002453#ifdef CONFIG_AUDIT
Kees Cook923e9a12012-04-10 13:26:44 -07002454 struct lsm_network_audit net;
2455
Eric Paris48c62af2012-04-02 13:15:44 -04002456 smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net);
2457 ad.a.u.net->family = sap->sin_family;
2458 ad.a.u.net->dport = sap->sin_port;
2459 ad.a.u.net->v4info.daddr = sap->sin_addr.s_addr;
Etienne Bassetecfcc532009-04-08 20:40:06 +02002460#endif
Kees Cook923e9a12012-04-10 13:26:44 -07002461 sk_lbl = SMACK_UNLABELED_SOCKET;
Casey Schaufler2f823ff2013-05-22 18:43:03 -07002462 skp = ssp->smk_out;
Lukasz Pawelczyk21c7eae2014-08-29 17:02:55 +02002463 rc = smk_access(skp, hkp, MAY_WRITE, &ad);
2464 rc = smk_bu_note("IPv4 host check", skp, hkp, MAY_WRITE, rc);
Paul Moore07feee82009-03-27 17:10:54 -04002465 } else {
2466 sk_lbl = SMACK_CIPSO_SOCKET;
2467 rc = 0;
2468 }
2469 rcu_read_unlock();
2470 if (rc != 0)
2471 return rc;
2472
2473 return smack_netlabel(sk, sk_lbl);
2474}
2475
Casey Schaufler21abb1e2015-07-22 14:25:31 -07002476/**
2477 * smk_ipv6_check - check Smack access
2478 * @subject: subject Smack label
2479 * @object: object Smack label
2480 * @address: address
2481 * @act: the action being taken
2482 *
2483 * Check an IPv6 access
2484 */
2485static int smk_ipv6_check(struct smack_known *subject,
2486 struct smack_known *object,
2487 struct sockaddr_in6 *address, int act)
2488{
2489#ifdef CONFIG_AUDIT
2490 struct lsm_network_audit net;
2491#endif
2492 struct smk_audit_info ad;
2493 int rc;
2494
2495#ifdef CONFIG_AUDIT
2496 smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net);
2497 ad.a.u.net->family = PF_INET6;
2498 ad.a.u.net->dport = ntohs(address->sin6_port);
2499 if (act == SMK_RECEIVING)
2500 ad.a.u.net->v6info.saddr = address->sin6_addr;
2501 else
2502 ad.a.u.net->v6info.daddr = address->sin6_addr;
2503#endif
2504 rc = smk_access(subject, object, MAY_WRITE, &ad);
2505 rc = smk_bu_note("IPv6 check", subject, object, MAY_WRITE, rc);
2506 return rc;
2507}
Casey Schaufler21abb1e2015-07-22 14:25:31 -07002508
2509#ifdef SMACK_IPV6_PORT_LABELING
Paul Moore07feee82009-03-27 17:10:54 -04002510/**
Casey Schauflerc6739442013-05-22 18:42:56 -07002511 * smk_ipv6_port_label - Smack port access table management
2512 * @sock: socket
2513 * @address: address
2514 *
2515 * Create or update the port list entry
2516 */
2517static void smk_ipv6_port_label(struct socket *sock, struct sockaddr *address)
2518{
2519 struct sock *sk = sock->sk;
2520 struct sockaddr_in6 *addr6;
2521 struct socket_smack *ssp = sock->sk->sk_security;
2522 struct smk_port_label *spp;
2523 unsigned short port = 0;
2524
2525 if (address == NULL) {
2526 /*
2527 * This operation is changing the Smack information
2528 * on the bound socket. Take the changes to the port
2529 * as well.
2530 */
Vishal Goel3c7ce342016-11-23 10:31:08 +05302531 rcu_read_lock();
2532 list_for_each_entry_rcu(spp, &smk_ipv6_port_list, list) {
Casey Schauflerc6739442013-05-22 18:42:56 -07002533 if (sk != spp->smk_sock)
2534 continue;
2535 spp->smk_in = ssp->smk_in;
2536 spp->smk_out = ssp->smk_out;
Vishal Goel3c7ce342016-11-23 10:31:08 +05302537 rcu_read_unlock();
Casey Schauflerc6739442013-05-22 18:42:56 -07002538 return;
2539 }
2540 /*
2541 * A NULL address is only used for updating existing
2542 * bound entries. If there isn't one, it's OK.
2543 */
Vishal Goel3c7ce342016-11-23 10:31:08 +05302544 rcu_read_unlock();
Casey Schauflerc6739442013-05-22 18:42:56 -07002545 return;
2546 }
2547
2548 addr6 = (struct sockaddr_in6 *)address;
2549 port = ntohs(addr6->sin6_port);
2550 /*
2551 * This is a special case that is safely ignored.
2552 */
2553 if (port == 0)
2554 return;
2555
2556 /*
2557 * Look for an existing port list entry.
2558 * This is an indication that a port is getting reused.
2559 */
Vishal Goel3c7ce342016-11-23 10:31:08 +05302560 rcu_read_lock();
2561 list_for_each_entry_rcu(spp, &smk_ipv6_port_list, list) {
Vishal Goel9d44c972016-11-23 10:31:59 +05302562 if (spp->smk_port != port || spp->smk_sock_type != sock->type)
Casey Schauflerc6739442013-05-22 18:42:56 -07002563 continue;
Vishal Goel0c96d1f2016-11-23 10:32:54 +05302564 if (spp->smk_can_reuse != 1) {
2565 rcu_read_unlock();
2566 return;
2567 }
Casey Schauflerc6739442013-05-22 18:42:56 -07002568 spp->smk_port = port;
2569 spp->smk_sock = sk;
2570 spp->smk_in = ssp->smk_in;
2571 spp->smk_out = ssp->smk_out;
Vishal Goel0c96d1f2016-11-23 10:32:54 +05302572 spp->smk_can_reuse = 0;
Vishal Goel3c7ce342016-11-23 10:31:08 +05302573 rcu_read_unlock();
Casey Schauflerc6739442013-05-22 18:42:56 -07002574 return;
2575 }
Vishal Goel3c7ce342016-11-23 10:31:08 +05302576 rcu_read_unlock();
Casey Schauflerc6739442013-05-22 18:42:56 -07002577 /*
2578 * A new port entry is required.
2579 */
2580 spp = kzalloc(sizeof(*spp), GFP_KERNEL);
2581 if (spp == NULL)
2582 return;
2583
2584 spp->smk_port = port;
2585 spp->smk_sock = sk;
2586 spp->smk_in = ssp->smk_in;
2587 spp->smk_out = ssp->smk_out;
Vishal Goel9d44c972016-11-23 10:31:59 +05302588 spp->smk_sock_type = sock->type;
Vishal Goel0c96d1f2016-11-23 10:32:54 +05302589 spp->smk_can_reuse = 0;
Casey Schauflerc6739442013-05-22 18:42:56 -07002590
Vishal Goel3c7ce342016-11-23 10:31:08 +05302591 mutex_lock(&smack_ipv6_lock);
2592 list_add_rcu(&spp->list, &smk_ipv6_port_list);
2593 mutex_unlock(&smack_ipv6_lock);
Casey Schauflerc6739442013-05-22 18:42:56 -07002594 return;
2595}
Arnd Bergmann00720f02020-04-08 21:04:31 +02002596#endif
Casey Schauflerc6739442013-05-22 18:42:56 -07002597
2598/**
2599 * smk_ipv6_port_check - check Smack port access
luanshia1a07f22019-07-05 10:35:20 +08002600 * @sk: socket
Casey Schauflerc6739442013-05-22 18:42:56 -07002601 * @address: address
luanshia1a07f22019-07-05 10:35:20 +08002602 * @act: the action being taken
Casey Schauflerc6739442013-05-22 18:42:56 -07002603 *
2604 * Create or update the port list entry
2605 */
Casey Schaufler6ea06242013-08-05 13:21:22 -07002606static int smk_ipv6_port_check(struct sock *sk, struct sockaddr_in6 *address,
Casey Schauflerc6739442013-05-22 18:42:56 -07002607 int act)
2608{
Casey Schauflerc6739442013-05-22 18:42:56 -07002609 struct smk_port_label *spp;
2610 struct socket_smack *ssp = sk->sk_security;
Casey Schaufler21abb1e2015-07-22 14:25:31 -07002611 struct smack_known *skp = NULL;
2612 unsigned short port;
Lukasz Pawelczyk21c7eae2014-08-29 17:02:55 +02002613 struct smack_known *object;
Casey Schauflerc6739442013-05-22 18:42:56 -07002614
2615 if (act == SMK_RECEIVING) {
Casey Schaufler21abb1e2015-07-22 14:25:31 -07002616 skp = smack_ipv6host_label(address);
Lukasz Pawelczyk21c7eae2014-08-29 17:02:55 +02002617 object = ssp->smk_in;
Casey Schauflerc6739442013-05-22 18:42:56 -07002618 } else {
Casey Schaufler2f823ff2013-05-22 18:43:03 -07002619 skp = ssp->smk_out;
Casey Schaufler21abb1e2015-07-22 14:25:31 -07002620 object = smack_ipv6host_label(address);
Casey Schauflerc6739442013-05-22 18:42:56 -07002621 }
2622
2623 /*
Casey Schaufler21abb1e2015-07-22 14:25:31 -07002624 * The other end is a single label host.
Casey Schauflerc6739442013-05-22 18:42:56 -07002625 */
Casey Schaufler21abb1e2015-07-22 14:25:31 -07002626 if (skp != NULL && object != NULL)
2627 return smk_ipv6_check(skp, object, address, act);
2628 if (skp == NULL)
2629 skp = smack_net_ambient;
2630 if (object == NULL)
2631 object = smack_net_ambient;
Casey Schauflerc6739442013-05-22 18:42:56 -07002632
2633 /*
2634 * It's remote, so port lookup does no good.
2635 */
Casey Schaufler21abb1e2015-07-22 14:25:31 -07002636 if (!smk_ipv6_localhost(address))
2637 return smk_ipv6_check(skp, object, address, act);
Casey Schauflerc6739442013-05-22 18:42:56 -07002638
2639 /*
2640 * It's local so the send check has to have passed.
2641 */
Casey Schaufler21abb1e2015-07-22 14:25:31 -07002642 if (act == SMK_RECEIVING)
2643 return 0;
Casey Schauflerc6739442013-05-22 18:42:56 -07002644
Casey Schaufler21abb1e2015-07-22 14:25:31 -07002645 port = ntohs(address->sin6_port);
Vishal Goel3c7ce342016-11-23 10:31:08 +05302646 rcu_read_lock();
2647 list_for_each_entry_rcu(spp, &smk_ipv6_port_list, list) {
Vishal Goel9d44c972016-11-23 10:31:59 +05302648 if (spp->smk_port != port || spp->smk_sock_type != sk->sk_type)
Casey Schauflerc6739442013-05-22 18:42:56 -07002649 continue;
Lukasz Pawelczyk21c7eae2014-08-29 17:02:55 +02002650 object = spp->smk_in;
Casey Schauflerc6739442013-05-22 18:42:56 -07002651 if (act == SMK_CONNECTING)
Casey Schaufler54e70ec2014-04-10 16:37:08 -07002652 ssp->smk_packet = spp->smk_out;
Casey Schauflerc6739442013-05-22 18:42:56 -07002653 break;
2654 }
Vishal Goel3c7ce342016-11-23 10:31:08 +05302655 rcu_read_unlock();
Casey Schauflerc6739442013-05-22 18:42:56 -07002656
Casey Schaufler21abb1e2015-07-22 14:25:31 -07002657 return smk_ipv6_check(skp, object, address, act);
Casey Schauflerc6739442013-05-22 18:42:56 -07002658}
2659
2660/**
Casey Schauflere114e472008-02-04 22:29:50 -08002661 * smack_inode_setsecurity - set smack xattrs
2662 * @inode: the object
2663 * @name: attribute name
2664 * @value: attribute value
2665 * @size: size of the attribute
2666 * @flags: unused
2667 *
2668 * Sets the named attribute in the appropriate blob
2669 *
2670 * Returns 0 on success, or an error code
2671 */
2672static int smack_inode_setsecurity(struct inode *inode, const char *name,
2673 const void *value, size_t size, int flags)
2674{
Casey Schaufler2f823ff2013-05-22 18:43:03 -07002675 struct smack_known *skp;
Casey Schauflerfb4021b2018-11-12 12:43:01 -08002676 struct inode_smack *nsp = smack_inode(inode);
Casey Schauflere114e472008-02-04 22:29:50 -08002677 struct socket_smack *ssp;
2678 struct socket *sock;
Casey Schaufler4bc87e62008-02-15 15:24:25 -08002679 int rc = 0;
Casey Schauflere114e472008-02-04 22:29:50 -08002680
Casey Schauflerf7112e62012-05-06 15:22:02 -07002681 if (value == NULL || size > SMK_LONGLABEL || size == 0)
Pankaj Kumar5e9ab592013-12-13 15:12:22 +05302682 return -EINVAL;
Casey Schauflere114e472008-02-04 22:29:50 -08002683
Casey Schaufler2f823ff2013-05-22 18:43:03 -07002684 skp = smk_import_entry(value, size);
Lukasz Pawelczyke774ad62015-04-20 17:12:54 +02002685 if (IS_ERR(skp))
2686 return PTR_ERR(skp);
Casey Schauflere114e472008-02-04 22:29:50 -08002687
2688 if (strcmp(name, XATTR_SMACK_SUFFIX) == 0) {
Lukasz Pawelczyk21c7eae2014-08-29 17:02:55 +02002689 nsp->smk_inode = skp;
David P. Quigleyddd29ec2009-09-09 14:25:37 -04002690 nsp->smk_flags |= SMK_INODE_INSTANT;
Casey Schauflere114e472008-02-04 22:29:50 -08002691 return 0;
2692 }
2693 /*
2694 * The rest of the Smack xattrs are only on sockets.
2695 */
2696 if (inode->i_sb->s_magic != SOCKFS_MAGIC)
2697 return -EOPNOTSUPP;
2698
2699 sock = SOCKET_I(inode);
Ahmed S. Darwish2e1d1462008-02-13 15:03:34 -08002700 if (sock == NULL || sock->sk == NULL)
Casey Schauflere114e472008-02-04 22:29:50 -08002701 return -EOPNOTSUPP;
2702
2703 ssp = sock->sk->sk_security;
2704
2705 if (strcmp(name, XATTR_SMACK_IPIN) == 0)
Casey Schaufler54e70ec2014-04-10 16:37:08 -07002706 ssp->smk_in = skp;
Casey Schauflere114e472008-02-04 22:29:50 -08002707 else if (strcmp(name, XATTR_SMACK_IPOUT) == 0) {
Casey Schaufler2f823ff2013-05-22 18:43:03 -07002708 ssp->smk_out = skp;
Casey Schauflerc6739442013-05-22 18:42:56 -07002709 if (sock->sk->sk_family == PF_INET) {
Casey Schauflerb4e0d5f2010-11-24 17:12:10 -08002710 rc = smack_netlabel(sock->sk, SMACK_CIPSO_SOCKET);
2711 if (rc != 0)
2712 printk(KERN_WARNING
2713 "Smack: \"%s\" netlbl error %d.\n",
2714 __func__, -rc);
2715 }
Casey Schauflere114e472008-02-04 22:29:50 -08002716 } else
2717 return -EOPNOTSUPP;
2718
Casey Schaufler21abb1e2015-07-22 14:25:31 -07002719#ifdef SMACK_IPV6_PORT_LABELING
Casey Schauflerc6739442013-05-22 18:42:56 -07002720 if (sock->sk->sk_family == PF_INET6)
2721 smk_ipv6_port_label(sock, NULL);
Casey Schaufler21abb1e2015-07-22 14:25:31 -07002722#endif
Casey Schauflerc6739442013-05-22 18:42:56 -07002723
Casey Schauflere114e472008-02-04 22:29:50 -08002724 return 0;
2725}
2726
2727/**
2728 * smack_socket_post_create - finish socket setup
2729 * @sock: the socket
2730 * @family: protocol family
2731 * @type: unused
2732 * @protocol: unused
2733 * @kern: unused
2734 *
2735 * Sets the netlabel information on the socket
2736 *
2737 * Returns 0 on success, and error code otherwise
2738 */
2739static int smack_socket_post_create(struct socket *sock, int family,
2740 int type, int protocol, int kern)
2741{
Marcin Lis74123012015-01-22 15:40:33 +01002742 struct socket_smack *ssp;
2743
2744 if (sock->sk == NULL)
2745 return 0;
2746
2747 /*
2748 * Sockets created by kernel threads receive web label.
2749 */
2750 if (unlikely(current->flags & PF_KTHREAD)) {
2751 ssp = sock->sk->sk_security;
2752 ssp->smk_in = &smack_known_web;
2753 ssp->smk_out = &smack_known_web;
2754 }
2755
2756 if (family != PF_INET)
Casey Schauflere114e472008-02-04 22:29:50 -08002757 return 0;
2758 /*
2759 * Set the outbound netlbl.
2760 */
Casey Schaufler6d3dc072008-12-31 12:54:12 -05002761 return smack_netlabel(sock->sk, SMACK_CIPSO_SOCKET);
2762}
2763
Tom Gundersen5859cdf2018-05-04 16:28:22 +02002764/**
2765 * smack_socket_socketpair - create socket pair
2766 * @socka: one socket
2767 * @sockb: another socket
2768 *
2769 * Cross reference the peer labels for SO_PEERSEC
2770 *
luanshia1a07f22019-07-05 10:35:20 +08002771 * Returns 0
Tom Gundersen5859cdf2018-05-04 16:28:22 +02002772 */
2773static int smack_socket_socketpair(struct socket *socka,
2774 struct socket *sockb)
2775{
2776 struct socket_smack *asp = socka->sk->sk_security;
2777 struct socket_smack *bsp = sockb->sk->sk_security;
2778
2779 asp->smk_packet = bsp->smk_out;
2780 bsp->smk_packet = asp->smk_out;
2781
2782 return 0;
2783}
2784
Casey Schaufler21abb1e2015-07-22 14:25:31 -07002785#ifdef SMACK_IPV6_PORT_LABELING
Casey Schaufler6d3dc072008-12-31 12:54:12 -05002786/**
Casey Schauflerc6739442013-05-22 18:42:56 -07002787 * smack_socket_bind - record port binding information.
2788 * @sock: the socket
2789 * @address: the port address
2790 * @addrlen: size of the address
2791 *
2792 * Records the label bound to a port.
2793 *
Tetsuo Handab9ef5512019-04-12 19:59:35 +09002794 * Returns 0 on success, and error code otherwise
Casey Schauflerc6739442013-05-22 18:42:56 -07002795 */
2796static int smack_socket_bind(struct socket *sock, struct sockaddr *address,
2797 int addrlen)
2798{
Tetsuo Handab9ef5512019-04-12 19:59:35 +09002799 if (sock->sk != NULL && sock->sk->sk_family == PF_INET6) {
2800 if (addrlen < SIN6_LEN_RFC2133 ||
2801 address->sa_family != AF_INET6)
2802 return -EINVAL;
Casey Schauflerc6739442013-05-22 18:42:56 -07002803 smk_ipv6_port_label(sock, address);
Tetsuo Handab9ef5512019-04-12 19:59:35 +09002804 }
Casey Schauflerc6739442013-05-22 18:42:56 -07002805 return 0;
2806}
Casey Schaufler21abb1e2015-07-22 14:25:31 -07002807#endif /* SMACK_IPV6_PORT_LABELING */
Casey Schauflerc6739442013-05-22 18:42:56 -07002808
2809/**
Casey Schaufler6d3dc072008-12-31 12:54:12 -05002810 * smack_socket_connect - connect access check
2811 * @sock: the socket
2812 * @sap: the other end
2813 * @addrlen: size of sap
2814 *
2815 * Verifies that a connection may be possible
2816 *
2817 * Returns 0 on success, and error code otherwise
2818 */
2819static int smack_socket_connect(struct socket *sock, struct sockaddr *sap,
2820 int addrlen)
2821{
Casey Schauflerc6739442013-05-22 18:42:56 -07002822 int rc = 0;
Casey Schaufler6d3dc072008-12-31 12:54:12 -05002823
Casey Schauflerc6739442013-05-22 18:42:56 -07002824 if (sock->sk == NULL)
2825 return 0;
Casey Schaufler87fbfff2020-02-03 09:15:00 -08002826 if (sock->sk->sk_family != PF_INET &&
2827 (!IS_ENABLED(CONFIG_IPV6) || sock->sk->sk_family != PF_INET6))
2828 return 0;
2829 if (addrlen < offsetofend(struct sockaddr, sa_family))
2830 return 0;
2831 if (IS_ENABLED(CONFIG_IPV6) && sap->sa_family == AF_INET6) {
2832 struct sockaddr_in6 *sip = (struct sockaddr_in6 *)sap;
Arnd Bergmann00720f02020-04-08 21:04:31 +02002833 struct smack_known *rsp = NULL;
Vasyl Gomonovychda49b5d2017-12-21 16:57:52 +01002834
Casey Schaufler87fbfff2020-02-03 09:15:00 -08002835 if (addrlen < SIN6_LEN_RFC2133)
2836 return 0;
Arnd Bergmann00720f02020-04-08 21:04:31 +02002837 if (__is_defined(SMACK_IPV6_SECMARK_LABELING))
2838 rsp = smack_ipv6host_label(sip);
Casey Schaufler87fbfff2020-02-03 09:15:00 -08002839 if (rsp != NULL) {
2840 struct socket_smack *ssp = sock->sk->sk_security;
2841
Casey Schaufler21abb1e2015-07-22 14:25:31 -07002842 rc = smk_ipv6_check(ssp->smk_out, rsp, sip,
Casey Schaufler87fbfff2020-02-03 09:15:00 -08002843 SMK_CONNECTING);
2844 }
Arnd Bergmann00720f02020-04-08 21:04:31 +02002845 if (__is_defined(SMACK_IPV6_PORT_LABELING))
2846 rc = smk_ipv6_port_check(sock->sk, sip, SMK_CONNECTING);
2847
Casey Schaufler87fbfff2020-02-03 09:15:00 -08002848 return rc;
Casey Schauflerc6739442013-05-22 18:42:56 -07002849 }
Casey Schaufler87fbfff2020-02-03 09:15:00 -08002850 if (sap->sa_family != AF_INET || addrlen < sizeof(struct sockaddr_in))
2851 return 0;
2852 rc = smack_netlabel_send(sock->sk, (struct sockaddr_in *)sap);
Casey Schauflerc6739442013-05-22 18:42:56 -07002853 return rc;
Casey Schauflere114e472008-02-04 22:29:50 -08002854}
2855
2856/**
2857 * smack_flags_to_may - convert S_ to MAY_ values
2858 * @flags: the S_ value
2859 *
2860 * Returns the equivalent MAY_ value
2861 */
2862static int smack_flags_to_may(int flags)
2863{
2864 int may = 0;
2865
2866 if (flags & S_IRUGO)
2867 may |= MAY_READ;
2868 if (flags & S_IWUGO)
2869 may |= MAY_WRITE;
2870 if (flags & S_IXUGO)
2871 may |= MAY_EXEC;
2872
2873 return may;
2874}
2875
2876/**
2877 * smack_msg_msg_alloc_security - Set the security blob for msg_msg
2878 * @msg: the object
2879 *
2880 * Returns 0
2881 */
2882static int smack_msg_msg_alloc_security(struct msg_msg *msg)
2883{
Casey Schauflerecd5f822018-11-20 11:55:02 -08002884 struct smack_known **blob = smack_msg_msg(msg);
Casey Schaufler2f823ff2013-05-22 18:43:03 -07002885
Casey Schauflerecd5f822018-11-20 11:55:02 -08002886 *blob = smk_of_current();
Casey Schauflere114e472008-02-04 22:29:50 -08002887 return 0;
2888}
2889
2890/**
Eric W. Biederman0d79cbf2018-03-23 23:56:19 -05002891 * smack_of_ipc - the smack pointer for the ipc
2892 * @isp: the object
Casey Schauflere114e472008-02-04 22:29:50 -08002893 *
2894 * Returns a pointer to the smack value
2895 */
Eric W. Biederman0d79cbf2018-03-23 23:56:19 -05002896static struct smack_known *smack_of_ipc(struct kern_ipc_perm *isp)
Casey Schauflere114e472008-02-04 22:29:50 -08002897{
Casey Schaufler019bcca2018-09-21 17:19:54 -07002898 struct smack_known **blob = smack_ipc(isp);
2899
2900 return *blob;
Casey Schauflere114e472008-02-04 22:29:50 -08002901}
2902
2903/**
Eric W. Biederman0d79cbf2018-03-23 23:56:19 -05002904 * smack_ipc_alloc_security - Set the security blob for ipc
2905 * @isp: the object
Casey Schauflere114e472008-02-04 22:29:50 -08002906 *
2907 * Returns 0
2908 */
Eric W. Biederman0d79cbf2018-03-23 23:56:19 -05002909static int smack_ipc_alloc_security(struct kern_ipc_perm *isp)
Casey Schauflere114e472008-02-04 22:29:50 -08002910{
Casey Schaufler019bcca2018-09-21 17:19:54 -07002911 struct smack_known **blob = smack_ipc(isp);
Casey Schauflere114e472008-02-04 22:29:50 -08002912
Casey Schaufler019bcca2018-09-21 17:19:54 -07002913 *blob = smk_of_current();
Casey Schauflere114e472008-02-04 22:29:50 -08002914 return 0;
2915}
2916
2917/**
Etienne Bassetecfcc532009-04-08 20:40:06 +02002918 * smk_curacc_shm : check if current has access on shm
Eric W. Biederman0d79cbf2018-03-23 23:56:19 -05002919 * @isp : the object
Etienne Bassetecfcc532009-04-08 20:40:06 +02002920 * @access : access requested
2921 *
2922 * Returns 0 if current has the requested access, error code otherwise
2923 */
Eric W. Biederman0d79cbf2018-03-23 23:56:19 -05002924static int smk_curacc_shm(struct kern_ipc_perm *isp, int access)
Etienne Bassetecfcc532009-04-08 20:40:06 +02002925{
Eric W. Biederman0d79cbf2018-03-23 23:56:19 -05002926 struct smack_known *ssp = smack_of_ipc(isp);
Etienne Bassetecfcc532009-04-08 20:40:06 +02002927 struct smk_audit_info ad;
Casey Schauflerd166c802014-08-27 14:51:27 -07002928 int rc;
Etienne Bassetecfcc532009-04-08 20:40:06 +02002929
2930#ifdef CONFIG_AUDIT
2931 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_IPC);
Eric W. Biederman0d79cbf2018-03-23 23:56:19 -05002932 ad.a.u.ipc_id = isp->id;
Etienne Bassetecfcc532009-04-08 20:40:06 +02002933#endif
Casey Schauflerd166c802014-08-27 14:51:27 -07002934 rc = smk_curacc(ssp, access, &ad);
2935 rc = smk_bu_current("shm", ssp, access, rc);
2936 return rc;
Etienne Bassetecfcc532009-04-08 20:40:06 +02002937}
2938
2939/**
Casey Schauflere114e472008-02-04 22:29:50 -08002940 * smack_shm_associate - Smack access check for shm
Eric W. Biederman0d79cbf2018-03-23 23:56:19 -05002941 * @isp: the object
Casey Schauflere114e472008-02-04 22:29:50 -08002942 * @shmflg: access requested
2943 *
2944 * Returns 0 if current has the requested access, error code otherwise
2945 */
Eric W. Biederman0d79cbf2018-03-23 23:56:19 -05002946static int smack_shm_associate(struct kern_ipc_perm *isp, int shmflg)
Casey Schauflere114e472008-02-04 22:29:50 -08002947{
Casey Schauflere114e472008-02-04 22:29:50 -08002948 int may;
2949
2950 may = smack_flags_to_may(shmflg);
Eric W. Biederman0d79cbf2018-03-23 23:56:19 -05002951 return smk_curacc_shm(isp, may);
Casey Schauflere114e472008-02-04 22:29:50 -08002952}
2953
2954/**
2955 * smack_shm_shmctl - Smack access check for shm
Eric W. Biederman0d79cbf2018-03-23 23:56:19 -05002956 * @isp: the object
Casey Schauflere114e472008-02-04 22:29:50 -08002957 * @cmd: what it wants to do
2958 *
2959 * Returns 0 if current has the requested access, error code otherwise
2960 */
Eric W. Biederman0d79cbf2018-03-23 23:56:19 -05002961static int smack_shm_shmctl(struct kern_ipc_perm *isp, int cmd)
Casey Schauflere114e472008-02-04 22:29:50 -08002962{
Casey Schauflere114e472008-02-04 22:29:50 -08002963 int may;
2964
2965 switch (cmd) {
2966 case IPC_STAT:
2967 case SHM_STAT:
Davidlohr Buesoc21a6972018-04-10 16:35:23 -07002968 case SHM_STAT_ANY:
Casey Schauflere114e472008-02-04 22:29:50 -08002969 may = MAY_READ;
2970 break;
2971 case IPC_SET:
2972 case SHM_LOCK:
2973 case SHM_UNLOCK:
2974 case IPC_RMID:
2975 may = MAY_READWRITE;
2976 break;
2977 case IPC_INFO:
2978 case SHM_INFO:
2979 /*
2980 * System level information.
2981 */
2982 return 0;
2983 default:
2984 return -EINVAL;
2985 }
Eric W. Biederman0d79cbf2018-03-23 23:56:19 -05002986 return smk_curacc_shm(isp, may);
Casey Schauflere114e472008-02-04 22:29:50 -08002987}
2988
2989/**
2990 * smack_shm_shmat - Smack access for shmat
Eric W. Biederman0d79cbf2018-03-23 23:56:19 -05002991 * @isp: the object
Casey Schauflere114e472008-02-04 22:29:50 -08002992 * @shmaddr: unused
2993 * @shmflg: access requested
2994 *
2995 * Returns 0 if current has the requested access, error code otherwise
2996 */
luanshia1a07f22019-07-05 10:35:20 +08002997static int smack_shm_shmat(struct kern_ipc_perm *isp, char __user *shmaddr,
Casey Schauflere114e472008-02-04 22:29:50 -08002998 int shmflg)
2999{
Casey Schauflere114e472008-02-04 22:29:50 -08003000 int may;
3001
3002 may = smack_flags_to_may(shmflg);
luanshia1a07f22019-07-05 10:35:20 +08003003 return smk_curacc_shm(isp, may);
Casey Schauflere114e472008-02-04 22:29:50 -08003004}
3005
3006/**
Etienne Bassetecfcc532009-04-08 20:40:06 +02003007 * smk_curacc_sem : check if current has access on sem
Eric W. Biederman0d79cbf2018-03-23 23:56:19 -05003008 * @isp : the object
Etienne Bassetecfcc532009-04-08 20:40:06 +02003009 * @access : access requested
3010 *
3011 * Returns 0 if current has the requested access, error code otherwise
3012 */
Eric W. Biederman0d79cbf2018-03-23 23:56:19 -05003013static int smk_curacc_sem(struct kern_ipc_perm *isp, int access)
Etienne Bassetecfcc532009-04-08 20:40:06 +02003014{
Eric W. Biederman0d79cbf2018-03-23 23:56:19 -05003015 struct smack_known *ssp = smack_of_ipc(isp);
Etienne Bassetecfcc532009-04-08 20:40:06 +02003016 struct smk_audit_info ad;
Casey Schauflerd166c802014-08-27 14:51:27 -07003017 int rc;
Etienne Bassetecfcc532009-04-08 20:40:06 +02003018
3019#ifdef CONFIG_AUDIT
3020 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_IPC);
Eric W. Biederman0d79cbf2018-03-23 23:56:19 -05003021 ad.a.u.ipc_id = isp->id;
Etienne Bassetecfcc532009-04-08 20:40:06 +02003022#endif
Casey Schauflerd166c802014-08-27 14:51:27 -07003023 rc = smk_curacc(ssp, access, &ad);
3024 rc = smk_bu_current("sem", ssp, access, rc);
3025 return rc;
Etienne Bassetecfcc532009-04-08 20:40:06 +02003026}
3027
3028/**
Casey Schauflere114e472008-02-04 22:29:50 -08003029 * smack_sem_associate - Smack access check for sem
Eric W. Biederman0d79cbf2018-03-23 23:56:19 -05003030 * @isp: the object
Casey Schauflere114e472008-02-04 22:29:50 -08003031 * @semflg: access requested
3032 *
3033 * Returns 0 if current has the requested access, error code otherwise
3034 */
Eric W. Biederman0d79cbf2018-03-23 23:56:19 -05003035static int smack_sem_associate(struct kern_ipc_perm *isp, int semflg)
Casey Schauflere114e472008-02-04 22:29:50 -08003036{
Casey Schauflere114e472008-02-04 22:29:50 -08003037 int may;
3038
3039 may = smack_flags_to_may(semflg);
Eric W. Biederman0d79cbf2018-03-23 23:56:19 -05003040 return smk_curacc_sem(isp, may);
Casey Schauflere114e472008-02-04 22:29:50 -08003041}
3042
3043/**
3044 * smack_sem_shmctl - Smack access check for sem
Eric W. Biederman0d79cbf2018-03-23 23:56:19 -05003045 * @isp: the object
Casey Schauflere114e472008-02-04 22:29:50 -08003046 * @cmd: what it wants to do
3047 *
3048 * Returns 0 if current has the requested access, error code otherwise
3049 */
Eric W. Biederman0d79cbf2018-03-23 23:56:19 -05003050static int smack_sem_semctl(struct kern_ipc_perm *isp, int cmd)
Casey Schauflere114e472008-02-04 22:29:50 -08003051{
Casey Schauflere114e472008-02-04 22:29:50 -08003052 int may;
3053
3054 switch (cmd) {
3055 case GETPID:
3056 case GETNCNT:
3057 case GETZCNT:
3058 case GETVAL:
3059 case GETALL:
3060 case IPC_STAT:
3061 case SEM_STAT:
Davidlohr Buesoa280d6d2018-04-10 16:35:26 -07003062 case SEM_STAT_ANY:
Casey Schauflere114e472008-02-04 22:29:50 -08003063 may = MAY_READ;
3064 break;
3065 case SETVAL:
3066 case SETALL:
3067 case IPC_RMID:
3068 case IPC_SET:
3069 may = MAY_READWRITE;
3070 break;
3071 case IPC_INFO:
3072 case SEM_INFO:
3073 /*
3074 * System level information
3075 */
3076 return 0;
3077 default:
3078 return -EINVAL;
3079 }
3080
Eric W. Biederman0d79cbf2018-03-23 23:56:19 -05003081 return smk_curacc_sem(isp, may);
Casey Schauflere114e472008-02-04 22:29:50 -08003082}
3083
3084/**
3085 * smack_sem_semop - Smack checks of semaphore operations
Eric W. Biederman0d79cbf2018-03-23 23:56:19 -05003086 * @isp: the object
Casey Schauflere114e472008-02-04 22:29:50 -08003087 * @sops: unused
3088 * @nsops: unused
3089 * @alter: unused
3090 *
3091 * Treated as read and write in all cases.
3092 *
3093 * Returns 0 if access is allowed, error code otherwise
3094 */
Eric W. Biederman0d79cbf2018-03-23 23:56:19 -05003095static int smack_sem_semop(struct kern_ipc_perm *isp, struct sembuf *sops,
Casey Schauflere114e472008-02-04 22:29:50 -08003096 unsigned nsops, int alter)
3097{
Eric W. Biederman0d79cbf2018-03-23 23:56:19 -05003098 return smk_curacc_sem(isp, MAY_READWRITE);
Casey Schauflere114e472008-02-04 22:29:50 -08003099}
3100
3101/**
Etienne Bassetecfcc532009-04-08 20:40:06 +02003102 * smk_curacc_msq : helper to check if current has access on msq
Eric W. Biederman0d79cbf2018-03-23 23:56:19 -05003103 * @isp : the msq
Etienne Bassetecfcc532009-04-08 20:40:06 +02003104 * @access : access requested
3105 *
3106 * return 0 if current has access, error otherwise
3107 */
Eric W. Biederman0d79cbf2018-03-23 23:56:19 -05003108static int smk_curacc_msq(struct kern_ipc_perm *isp, int access)
Etienne Bassetecfcc532009-04-08 20:40:06 +02003109{
Eric W. Biederman0d79cbf2018-03-23 23:56:19 -05003110 struct smack_known *msp = smack_of_ipc(isp);
Etienne Bassetecfcc532009-04-08 20:40:06 +02003111 struct smk_audit_info ad;
Casey Schauflerd166c802014-08-27 14:51:27 -07003112 int rc;
Etienne Bassetecfcc532009-04-08 20:40:06 +02003113
3114#ifdef CONFIG_AUDIT
3115 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_IPC);
Eric W. Biederman0d79cbf2018-03-23 23:56:19 -05003116 ad.a.u.ipc_id = isp->id;
Etienne Bassetecfcc532009-04-08 20:40:06 +02003117#endif
Casey Schauflerd166c802014-08-27 14:51:27 -07003118 rc = smk_curacc(msp, access, &ad);
3119 rc = smk_bu_current("msq", msp, access, rc);
3120 return rc;
Etienne Bassetecfcc532009-04-08 20:40:06 +02003121}
3122
3123/**
Casey Schauflere114e472008-02-04 22:29:50 -08003124 * smack_msg_queue_associate - Smack access check for msg_queue
Eric W. Biederman0d79cbf2018-03-23 23:56:19 -05003125 * @isp: the object
Casey Schauflere114e472008-02-04 22:29:50 -08003126 * @msqflg: access requested
3127 *
3128 * Returns 0 if current has the requested access, error code otherwise
3129 */
Eric W. Biederman0d79cbf2018-03-23 23:56:19 -05003130static int smack_msg_queue_associate(struct kern_ipc_perm *isp, int msqflg)
Casey Schauflere114e472008-02-04 22:29:50 -08003131{
Casey Schauflere114e472008-02-04 22:29:50 -08003132 int may;
3133
3134 may = smack_flags_to_may(msqflg);
Eric W. Biederman0d79cbf2018-03-23 23:56:19 -05003135 return smk_curacc_msq(isp, may);
Casey Schauflere114e472008-02-04 22:29:50 -08003136}
3137
3138/**
3139 * smack_msg_queue_msgctl - Smack access check for msg_queue
Eric W. Biederman0d79cbf2018-03-23 23:56:19 -05003140 * @isp: the object
Casey Schauflere114e472008-02-04 22:29:50 -08003141 * @cmd: what it wants to do
3142 *
3143 * Returns 0 if current has the requested access, error code otherwise
3144 */
Eric W. Biederman0d79cbf2018-03-23 23:56:19 -05003145static int smack_msg_queue_msgctl(struct kern_ipc_perm *isp, int cmd)
Casey Schauflere114e472008-02-04 22:29:50 -08003146{
Casey Schauflere114e472008-02-04 22:29:50 -08003147 int may;
3148
3149 switch (cmd) {
3150 case IPC_STAT:
3151 case MSG_STAT:
Davidlohr Bueso23c8cec2018-04-10 16:35:30 -07003152 case MSG_STAT_ANY:
Casey Schauflere114e472008-02-04 22:29:50 -08003153 may = MAY_READ;
3154 break;
3155 case IPC_SET:
3156 case IPC_RMID:
3157 may = MAY_READWRITE;
3158 break;
3159 case IPC_INFO:
3160 case MSG_INFO:
3161 /*
3162 * System level information
3163 */
3164 return 0;
3165 default:
3166 return -EINVAL;
3167 }
3168
Eric W. Biederman0d79cbf2018-03-23 23:56:19 -05003169 return smk_curacc_msq(isp, may);
Casey Schauflere114e472008-02-04 22:29:50 -08003170}
3171
3172/**
3173 * smack_msg_queue_msgsnd - Smack access check for msg_queue
Eric W. Biederman0d79cbf2018-03-23 23:56:19 -05003174 * @isp: the object
Casey Schauflere114e472008-02-04 22:29:50 -08003175 * @msg: unused
3176 * @msqflg: access requested
3177 *
3178 * Returns 0 if current has the requested access, error code otherwise
3179 */
Eric W. Biederman0d79cbf2018-03-23 23:56:19 -05003180static int smack_msg_queue_msgsnd(struct kern_ipc_perm *isp, struct msg_msg *msg,
Casey Schauflere114e472008-02-04 22:29:50 -08003181 int msqflg)
3182{
Etienne Bassetecfcc532009-04-08 20:40:06 +02003183 int may;
Casey Schauflere114e472008-02-04 22:29:50 -08003184
Etienne Bassetecfcc532009-04-08 20:40:06 +02003185 may = smack_flags_to_may(msqflg);
Eric W. Biederman0d79cbf2018-03-23 23:56:19 -05003186 return smk_curacc_msq(isp, may);
Casey Schauflere114e472008-02-04 22:29:50 -08003187}
3188
3189/**
3190 * smack_msg_queue_msgsnd - Smack access check for msg_queue
Eric W. Biederman0d79cbf2018-03-23 23:56:19 -05003191 * @isp: the object
Casey Schauflere114e472008-02-04 22:29:50 -08003192 * @msg: unused
3193 * @target: unused
3194 * @type: unused
3195 * @mode: unused
3196 *
3197 * Returns 0 if current has read and write access, error code otherwise
3198 */
Eric W. Biederman0d79cbf2018-03-23 23:56:19 -05003199static int smack_msg_queue_msgrcv(struct kern_ipc_perm *isp, struct msg_msg *msg,
Casey Schauflere114e472008-02-04 22:29:50 -08003200 struct task_struct *target, long type, int mode)
3201{
Eric W. Biederman0d79cbf2018-03-23 23:56:19 -05003202 return smk_curacc_msq(isp, MAY_READWRITE);
Casey Schauflere114e472008-02-04 22:29:50 -08003203}
3204
3205/**
3206 * smack_ipc_permission - Smack access for ipc_permission()
3207 * @ipp: the object permissions
3208 * @flag: access requested
3209 *
3210 * Returns 0 if current has read and write access, error code otherwise
3211 */
3212static int smack_ipc_permission(struct kern_ipc_perm *ipp, short flag)
3213{
Casey Schaufler019bcca2018-09-21 17:19:54 -07003214 struct smack_known **blob = smack_ipc(ipp);
3215 struct smack_known *iskp = *blob;
Etienne Bassetecfcc532009-04-08 20:40:06 +02003216 int may = smack_flags_to_may(flag);
3217 struct smk_audit_info ad;
Casey Schauflerd166c802014-08-27 14:51:27 -07003218 int rc;
Casey Schauflere114e472008-02-04 22:29:50 -08003219
Etienne Bassetecfcc532009-04-08 20:40:06 +02003220#ifdef CONFIG_AUDIT
3221 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_IPC);
3222 ad.a.u.ipc_id = ipp->id;
3223#endif
Lukasz Pawelczyk21c7eae2014-08-29 17:02:55 +02003224 rc = smk_curacc(iskp, may, &ad);
3225 rc = smk_bu_current("svipc", iskp, may, rc);
Casey Schauflerd166c802014-08-27 14:51:27 -07003226 return rc;
Casey Schauflere114e472008-02-04 22:29:50 -08003227}
3228
Ahmed S. Darwishd20bdda2008-04-30 08:34:10 +10003229/**
3230 * smack_ipc_getsecid - Extract smack security id
Randy Dunlap251a2a92009-02-18 11:42:33 -08003231 * @ipp: the object permissions
Ahmed S. Darwishd20bdda2008-04-30 08:34:10 +10003232 * @secid: where result will be saved
3233 */
3234static void smack_ipc_getsecid(struct kern_ipc_perm *ipp, u32 *secid)
3235{
Casey Schaufler019bcca2018-09-21 17:19:54 -07003236 struct smack_known **blob = smack_ipc(ipp);
3237 struct smack_known *iskp = *blob;
Ahmed S. Darwishd20bdda2008-04-30 08:34:10 +10003238
Lukasz Pawelczyk21c7eae2014-08-29 17:02:55 +02003239 *secid = iskp->smk_secid;
Ahmed S. Darwishd20bdda2008-04-30 08:34:10 +10003240}
3241
Casey Schauflere114e472008-02-04 22:29:50 -08003242/**
3243 * smack_d_instantiate - Make sure the blob is correct on an inode
Dan Carpenter3e62cbb2010-06-01 09:14:04 +02003244 * @opt_dentry: dentry where inode will be attached
Casey Schauflere114e472008-02-04 22:29:50 -08003245 * @inode: the object
3246 *
3247 * Set the inode's security blob if it hasn't been done already.
3248 */
3249static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode)
3250{
3251 struct super_block *sbp;
3252 struct superblock_smack *sbsp;
3253 struct inode_smack *isp;
Casey Schaufler2f823ff2013-05-22 18:43:03 -07003254 struct smack_known *skp;
3255 struct smack_known *ckp = smk_of_current();
Lukasz Pawelczyk21c7eae2014-08-29 17:02:55 +02003256 struct smack_known *final;
Jarkko Sakkinen5c6d1122010-12-07 13:34:01 +02003257 char trattr[TRANS_TRUE_SIZE];
3258 int transflag = 0;
Casey Schaufler2267b132012-03-13 19:14:19 -07003259 int rc;
Casey Schauflere114e472008-02-04 22:29:50 -08003260 struct dentry *dp;
3261
3262 if (inode == NULL)
3263 return;
3264
Casey Schauflerfb4021b2018-11-12 12:43:01 -08003265 isp = smack_inode(inode);
Casey Schauflere114e472008-02-04 22:29:50 -08003266
3267 mutex_lock(&isp->smk_lock);
3268 /*
3269 * If the inode is already instantiated
3270 * take the quick way out
3271 */
3272 if (isp->smk_flags & SMK_INODE_INSTANT)
3273 goto unlockandout;
3274
3275 sbp = inode->i_sb;
3276 sbsp = sbp->s_security;
3277 /*
3278 * We're going to use the superblock default label
3279 * if there's no label on the file.
3280 */
3281 final = sbsp->smk_default;
3282
3283 /*
Casey Schauflere97dcb02008-06-02 10:04:32 -07003284 * If this is the root inode the superblock
3285 * may be in the process of initialization.
3286 * If that is the case use the root value out
3287 * of the superblock.
3288 */
3289 if (opt_dentry->d_parent == opt_dentry) {
Łukasz Stelmach1d8c2322014-12-16 16:53:08 +01003290 switch (sbp->s_magic) {
3291 case CGROUP_SUPER_MAGIC:
José Bollo58c442f2018-02-27 17:06:21 +01003292 case CGROUP2_SUPER_MAGIC:
Casey Schaufler36ea7352014-04-28 15:23:01 -07003293 /*
3294 * The cgroup filesystem is never mounted,
3295 * so there's no opportunity to set the mount
3296 * options.
3297 */
Lukasz Pawelczyk21c7eae2014-08-29 17:02:55 +02003298 sbsp->smk_root = &smack_known_star;
3299 sbsp->smk_default = &smack_known_star;
Łukasz Stelmach1d8c2322014-12-16 16:53:08 +01003300 isp->smk_inode = sbsp->smk_root;
3301 break;
3302 case TMPFS_MAGIC:
3303 /*
3304 * What about shmem/tmpfs anonymous files with dentry
3305 * obtained from d_alloc_pseudo()?
3306 */
3307 isp->smk_inode = smk_of_current();
3308 break;
Roman Kubiak8da4aba2015-10-05 12:27:16 +02003309 case PIPEFS_MAGIC:
3310 isp->smk_inode = smk_of_current();
3311 break;
Rafal Krypa805b65a2016-12-09 14:03:04 +01003312 case SOCKFS_MAGIC:
3313 /*
3314 * Socket access is controlled by the socket
3315 * structures associated with the task involved.
3316 */
3317 isp->smk_inode = &smack_known_star;
3318 break;
Łukasz Stelmach1d8c2322014-12-16 16:53:08 +01003319 default:
3320 isp->smk_inode = sbsp->smk_root;
3321 break;
Casey Schaufler36ea7352014-04-28 15:23:01 -07003322 }
Casey Schauflere97dcb02008-06-02 10:04:32 -07003323 isp->smk_flags |= SMK_INODE_INSTANT;
3324 goto unlockandout;
3325 }
3326
3327 /*
Casey Schauflere114e472008-02-04 22:29:50 -08003328 * This is pretty hackish.
3329 * Casey says that we shouldn't have to do
3330 * file system specific code, but it does help
3331 * with keeping it simple.
3332 */
3333 switch (sbp->s_magic) {
3334 case SMACK_MAGIC:
Casey Schaufler36ea7352014-04-28 15:23:01 -07003335 case CGROUP_SUPER_MAGIC:
José Bollo58c442f2018-02-27 17:06:21 +01003336 case CGROUP2_SUPER_MAGIC:
Casey Schauflere114e472008-02-04 22:29:50 -08003337 /*
Lucas De Marchi25985ed2011-03-30 22:57:33 -03003338 * Casey says that it's a little embarrassing
Casey Schauflere114e472008-02-04 22:29:50 -08003339 * that the smack file system doesn't do
3340 * extended attributes.
Casey Schaufler36ea7352014-04-28 15:23:01 -07003341 *
Casey Schaufler36ea7352014-04-28 15:23:01 -07003342 * Cgroupfs is special
Casey Schauflere114e472008-02-04 22:29:50 -08003343 */
Lukasz Pawelczyk21c7eae2014-08-29 17:02:55 +02003344 final = &smack_known_star;
Casey Schauflere114e472008-02-04 22:29:50 -08003345 break;
3346 case DEVPTS_SUPER_MAGIC:
3347 /*
3348 * devpts seems content with the label of the task.
3349 * Programs that change smack have to treat the
3350 * pty with respect.
3351 */
Lukasz Pawelczyk21c7eae2014-08-29 17:02:55 +02003352 final = ckp;
Casey Schauflere114e472008-02-04 22:29:50 -08003353 break;
Casey Schauflere114e472008-02-04 22:29:50 -08003354 case PROC_SUPER_MAGIC:
3355 /*
3356 * Casey says procfs appears not to care.
3357 * The superblock default suffices.
3358 */
3359 break;
3360 case TMPFS_MAGIC:
3361 /*
3362 * Device labels should come from the filesystem,
3363 * but watch out, because they're volitile,
3364 * getting recreated on every reboot.
3365 */
Lukasz Pawelczyk21c7eae2014-08-29 17:02:55 +02003366 final = &smack_known_star;
Casey Schauflere114e472008-02-04 22:29:50 -08003367 /*
Casey Schauflere114e472008-02-04 22:29:50 -08003368 * If a smack value has been set we want to use it,
3369 * but since tmpfs isn't giving us the opportunity
3370 * to set mount options simulate setting the
3371 * superblock default.
3372 */
Gustavo A. R. Silva09186e52019-02-08 14:54:53 -06003373 /* Fall through */
Casey Schauflere114e472008-02-04 22:29:50 -08003374 default:
3375 /*
3376 * This isn't an understood special case.
3377 * Get the value from the xattr.
Casey Schauflerb4e0d5f2010-11-24 17:12:10 -08003378 */
3379
3380 /*
3381 * UNIX domain sockets use lower level socket data.
3382 */
3383 if (S_ISSOCK(inode->i_mode)) {
Lukasz Pawelczyk21c7eae2014-08-29 17:02:55 +02003384 final = &smack_known_star;
Casey Schauflerb4e0d5f2010-11-24 17:12:10 -08003385 break;
3386 }
3387 /*
Casey Schauflere114e472008-02-04 22:29:50 -08003388 * No xattr support means, alas, no SMACK label.
3389 * Use the aforeapplied default.
3390 * It would be curious if the label of the task
3391 * does not match that assigned.
3392 */
Andreas Gruenbacher5d6c3192016-09-29 17:48:42 +02003393 if (!(inode->i_opflags & IOP_XATTR))
3394 break;
Casey Schauflere114e472008-02-04 22:29:50 -08003395 /*
3396 * Get the dentry for xattr.
3397 */
Dan Carpenter3e62cbb2010-06-01 09:14:04 +02003398 dp = dget(opt_dentry);
Casey Schaufler2f823ff2013-05-22 18:43:03 -07003399 skp = smk_fetch(XATTR_NAME_SMACK, inode, dp);
Lukasz Pawelczyke774ad62015-04-20 17:12:54 +02003400 if (!IS_ERR_OR_NULL(skp))
Lukasz Pawelczyk21c7eae2014-08-29 17:02:55 +02003401 final = skp;
Casey Schaufler2267b132012-03-13 19:14:19 -07003402
3403 /*
3404 * Transmuting directory
3405 */
3406 if (S_ISDIR(inode->i_mode)) {
3407 /*
3408 * If this is a new directory and the label was
3409 * transmuted when the inode was initialized
3410 * set the transmute attribute on the directory
3411 * and mark the inode.
3412 *
3413 * If there is a transmute attribute on the
3414 * directory mark the inode.
3415 */
3416 if (isp->smk_flags & SMK_INODE_CHANGED) {
3417 isp->smk_flags &= ~SMK_INODE_CHANGED;
Andreas Gruenbacher5d6c3192016-09-29 17:48:42 +02003418 rc = __vfs_setxattr(dp, inode,
Jarkko Sakkinen5c6d1122010-12-07 13:34:01 +02003419 XATTR_NAME_SMACKTRANSMUTE,
Casey Schaufler2267b132012-03-13 19:14:19 -07003420 TRANS_TRUE, TRANS_TRUE_SIZE,
3421 0);
3422 } else {
Andreas Gruenbacher5d6c3192016-09-29 17:48:42 +02003423 rc = __vfs_getxattr(dp, inode,
Casey Schaufler2267b132012-03-13 19:14:19 -07003424 XATTR_NAME_SMACKTRANSMUTE, trattr,
3425 TRANS_TRUE_SIZE);
3426 if (rc >= 0 && strncmp(trattr, TRANS_TRUE,
3427 TRANS_TRUE_SIZE) != 0)
3428 rc = -EINVAL;
Jarkko Sakkinen5c6d1122010-12-07 13:34:01 +02003429 }
Casey Schaufler2267b132012-03-13 19:14:19 -07003430 if (rc >= 0)
3431 transflag = SMK_INODE_TRANSMUTE;
Jarkko Sakkinen5c6d1122010-12-07 13:34:01 +02003432 }
Seth Forshee809c02e2016-04-26 14:36:22 -05003433 /*
3434 * Don't let the exec or mmap label be "*" or "@".
3435 */
3436 skp = smk_fetch(XATTR_NAME_SMACKEXEC, inode, dp);
3437 if (IS_ERR(skp) || skp == &smack_known_star ||
3438 skp == &smack_known_web)
3439 skp = NULL;
3440 isp->smk_task = skp;
Lukasz Pawelczyke774ad62015-04-20 17:12:54 +02003441
Casey Schaufler19760ad2013-12-16 16:27:26 -08003442 skp = smk_fetch(XATTR_NAME_SMACKMMAP, inode, dp);
Lukasz Pawelczyke774ad62015-04-20 17:12:54 +02003443 if (IS_ERR(skp) || skp == &smack_known_star ||
3444 skp == &smack_known_web)
Casey Schaufler19760ad2013-12-16 16:27:26 -08003445 skp = NULL;
3446 isp->smk_mmap = skp;
Casey Schaufler676dac42010-12-02 06:43:39 -08003447
Casey Schauflere114e472008-02-04 22:29:50 -08003448 dput(dp);
3449 break;
3450 }
3451
3452 if (final == NULL)
Lukasz Pawelczyk21c7eae2014-08-29 17:02:55 +02003453 isp->smk_inode = ckp;
Casey Schauflere114e472008-02-04 22:29:50 -08003454 else
3455 isp->smk_inode = final;
3456
Jarkko Sakkinen5c6d1122010-12-07 13:34:01 +02003457 isp->smk_flags |= (SMK_INODE_INSTANT | transflag);
Casey Schauflere114e472008-02-04 22:29:50 -08003458
3459unlockandout:
3460 mutex_unlock(&isp->smk_lock);
3461 return;
3462}
3463
3464/**
3465 * smack_getprocattr - Smack process attribute access
3466 * @p: the object task
3467 * @name: the name of the attribute in /proc/.../attr
3468 * @value: where to put the result
3469 *
3470 * Places a copy of the task Smack into value
3471 *
3472 * Returns the length of the smack label or an error code
3473 */
3474static int smack_getprocattr(struct task_struct *p, char *name, char **value)
3475{
Andrey Ryabinin6d1cff22015-01-13 18:52:40 +03003476 struct smack_known *skp = smk_of_task_struct(p);
Casey Schauflere114e472008-02-04 22:29:50 -08003477 char *cp;
3478 int slen;
3479
3480 if (strcmp(name, "current") != 0)
3481 return -EINVAL;
3482
Casey Schaufler2f823ff2013-05-22 18:43:03 -07003483 cp = kstrdup(skp->smk_known, GFP_KERNEL);
Casey Schauflere114e472008-02-04 22:29:50 -08003484 if (cp == NULL)
3485 return -ENOMEM;
3486
3487 slen = strlen(cp);
3488 *value = cp;
3489 return slen;
3490}
3491
3492/**
3493 * smack_setprocattr - Smack process attribute setting
Casey Schauflere114e472008-02-04 22:29:50 -08003494 * @name: the name of the attribute in /proc/.../attr
3495 * @value: the value to set
3496 * @size: the size of the value
3497 *
3498 * Sets the Smack value of the task. Only setting self
3499 * is permitted and only with privilege
3500 *
3501 * Returns the length of the smack label or an error code
3502 */
Stephen Smalleyb21507e2017-01-09 10:07:31 -05003503static int smack_setprocattr(const char *name, void *value, size_t size)
Casey Schauflere114e472008-02-04 22:29:50 -08003504{
Casey Schauflerb17103a2018-11-09 16:12:56 -08003505 struct task_smack *tsp = smack_cred(current_cred());
David Howellsd84f4f92008-11-14 10:39:23 +11003506 struct cred *new;
Casey Schaufler2f823ff2013-05-22 18:43:03 -07003507 struct smack_known *skp;
Zbigniew Jasinski38416e52015-10-19 18:23:53 +02003508 struct smack_known_list_elem *sklep;
3509 int rc;
Casey Schauflere114e472008-02-04 22:29:50 -08003510
Zbigniew Jasinski38416e52015-10-19 18:23:53 +02003511 if (!smack_privileged(CAP_MAC_ADMIN) && list_empty(&tsp->smk_relabel))
David Howells5cd9c582008-08-14 11:37:28 +01003512 return -EPERM;
3513
Casey Schauflerf7112e62012-05-06 15:22:02 -07003514 if (value == NULL || size == 0 || size >= SMK_LONGLABEL)
Casey Schauflere114e472008-02-04 22:29:50 -08003515 return -EINVAL;
3516
3517 if (strcmp(name, "current") != 0)
3518 return -EINVAL;
3519
Casey Schaufler2f823ff2013-05-22 18:43:03 -07003520 skp = smk_import_entry(value, size);
Lukasz Pawelczyke774ad62015-04-20 17:12:54 +02003521 if (IS_ERR(skp))
3522 return PTR_ERR(skp);
Casey Schauflere114e472008-02-04 22:29:50 -08003523
Casey Schaufler6d3dc072008-12-31 12:54:12 -05003524 /*
Himanshu Shukla7128ea12016-11-10 16:17:49 +05303525 * No process is ever allowed the web ("@") label
3526 * and the star ("*") label.
Casey Schaufler6d3dc072008-12-31 12:54:12 -05003527 */
Himanshu Shukla7128ea12016-11-10 16:17:49 +05303528 if (skp == &smack_known_web || skp == &smack_known_star)
3529 return -EINVAL;
Casey Schaufler6d3dc072008-12-31 12:54:12 -05003530
Zbigniew Jasinski38416e52015-10-19 18:23:53 +02003531 if (!smack_privileged(CAP_MAC_ADMIN)) {
3532 rc = -EPERM;
3533 list_for_each_entry(sklep, &tsp->smk_relabel, list)
3534 if (sklep->smk_label == skp) {
3535 rc = 0;
3536 break;
3537 }
3538 if (rc)
3539 return rc;
3540 }
3541
David Howellsd84f4f92008-11-14 10:39:23 +11003542 new = prepare_creds();
Casey Schaufler6d3dc072008-12-31 12:54:12 -05003543 if (new == NULL)
David Howellsd84f4f92008-11-14 10:39:23 +11003544 return -ENOMEM;
Casey Schaufler7898e1f2011-01-17 08:05:27 -08003545
Casey Schauflerb17103a2018-11-09 16:12:56 -08003546 tsp = smack_cred(new);
Casey Schaufler2f823ff2013-05-22 18:43:03 -07003547 tsp->smk_task = skp;
Zbigniew Jasinski38416e52015-10-19 18:23:53 +02003548 /*
3549 * process can change its label only once
3550 */
3551 smk_destroy_label_list(&tsp->smk_relabel);
Casey Schaufler7898e1f2011-01-17 08:05:27 -08003552
David Howellsd84f4f92008-11-14 10:39:23 +11003553 commit_creds(new);
Casey Schauflere114e472008-02-04 22:29:50 -08003554 return size;
3555}
3556
3557/**
3558 * smack_unix_stream_connect - Smack access on UDS
David S. Miller3610cda2011-01-05 15:38:53 -08003559 * @sock: one sock
3560 * @other: the other sock
Casey Schauflere114e472008-02-04 22:29:50 -08003561 * @newsk: unused
3562 *
3563 * Return 0 if a subject with the smack of sock could access
3564 * an object with the smack of other, otherwise an error code
3565 */
David S. Miller3610cda2011-01-05 15:38:53 -08003566static int smack_unix_stream_connect(struct sock *sock,
3567 struct sock *other, struct sock *newsk)
Casey Schauflere114e472008-02-04 22:29:50 -08003568{
Casey Schaufler2f823ff2013-05-22 18:43:03 -07003569 struct smack_known *skp;
Casey Schaufler54e70ec2014-04-10 16:37:08 -07003570 struct smack_known *okp;
James Morrisd2e7ad12011-01-10 09:46:24 +11003571 struct socket_smack *ssp = sock->sk_security;
3572 struct socket_smack *osp = other->sk_security;
Casey Schaufler975d5e52011-09-26 14:43:39 -07003573 struct socket_smack *nsp = newsk->sk_security;
Etienne Bassetecfcc532009-04-08 20:40:06 +02003574 struct smk_audit_info ad;
Casey Schauflerb4e0d5f2010-11-24 17:12:10 -08003575 int rc = 0;
Kees Cook923e9a12012-04-10 13:26:44 -07003576#ifdef CONFIG_AUDIT
3577 struct lsm_network_audit net;
Kees Cook923e9a12012-04-10 13:26:44 -07003578#endif
Casey Schauflerb4e0d5f2010-11-24 17:12:10 -08003579
Casey Schaufler2f823ff2013-05-22 18:43:03 -07003580 if (!smack_privileged(CAP_MAC_OVERRIDE)) {
3581 skp = ssp->smk_out;
Zbigniew Jasinski96be7b52014-12-29 15:34:58 +01003582 okp = osp->smk_in;
Casey Schaufler54e70ec2014-04-10 16:37:08 -07003583#ifdef CONFIG_AUDIT
3584 smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net);
3585 smk_ad_setfield_u_net_sk(&ad, other);
3586#endif
Lukasz Pawelczyk21c7eae2014-08-29 17:02:55 +02003587 rc = smk_access(skp, okp, MAY_WRITE, &ad);
3588 rc = smk_bu_note("UDS connect", skp, okp, MAY_WRITE, rc);
Casey Schauflerd166c802014-08-27 14:51:27 -07003589 if (rc == 0) {
Zbigniew Jasinski96be7b52014-12-29 15:34:58 +01003590 okp = osp->smk_out;
3591 skp = ssp->smk_in;
Rafal Krypa138a8682015-01-08 18:52:45 +01003592 rc = smk_access(okp, skp, MAY_WRITE, &ad);
Lukasz Pawelczyk21c7eae2014-08-29 17:02:55 +02003593 rc = smk_bu_note("UDS connect", okp, skp,
Casey Schauflerd166c802014-08-27 14:51:27 -07003594 MAY_WRITE, rc);
3595 }
Casey Schaufler2f823ff2013-05-22 18:43:03 -07003596 }
Casey Schauflerb4e0d5f2010-11-24 17:12:10 -08003597
Casey Schaufler975d5e52011-09-26 14:43:39 -07003598 /*
3599 * Cross reference the peer labels for SO_PEERSEC.
3600 */
3601 if (rc == 0) {
Casey Schaufler54e70ec2014-04-10 16:37:08 -07003602 nsp->smk_packet = ssp->smk_out;
3603 ssp->smk_packet = osp->smk_out;
Casey Schaufler975d5e52011-09-26 14:43:39 -07003604 }
3605
Casey Schauflerb4e0d5f2010-11-24 17:12:10 -08003606 return rc;
Casey Schauflere114e472008-02-04 22:29:50 -08003607}
3608
3609/**
3610 * smack_unix_may_send - Smack access on UDS
3611 * @sock: one socket
3612 * @other: the other socket
3613 *
3614 * Return 0 if a subject with the smack of sock could access
3615 * an object with the smack of other, otherwise an error code
3616 */
3617static int smack_unix_may_send(struct socket *sock, struct socket *other)
3618{
Casey Schauflerb4e0d5f2010-11-24 17:12:10 -08003619 struct socket_smack *ssp = sock->sk->sk_security;
3620 struct socket_smack *osp = other->sk->sk_security;
Etienne Bassetecfcc532009-04-08 20:40:06 +02003621 struct smk_audit_info ad;
Casey Schauflerd166c802014-08-27 14:51:27 -07003622 int rc;
Casey Schauflere114e472008-02-04 22:29:50 -08003623
Kees Cook923e9a12012-04-10 13:26:44 -07003624#ifdef CONFIG_AUDIT
3625 struct lsm_network_audit net;
3626
Eric Paris48c62af2012-04-02 13:15:44 -04003627 smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net);
Etienne Bassetecfcc532009-04-08 20:40:06 +02003628 smk_ad_setfield_u_net_sk(&ad, other->sk);
Kees Cook923e9a12012-04-10 13:26:44 -07003629#endif
Casey Schauflerb4e0d5f2010-11-24 17:12:10 -08003630
Casey Schaufler2f823ff2013-05-22 18:43:03 -07003631 if (smack_privileged(CAP_MAC_OVERRIDE))
3632 return 0;
Casey Schauflerb4e0d5f2010-11-24 17:12:10 -08003633
Lukasz Pawelczyk21c7eae2014-08-29 17:02:55 +02003634 rc = smk_access(ssp->smk_out, osp->smk_in, MAY_WRITE, &ad);
3635 rc = smk_bu_note("UDS send", ssp->smk_out, osp->smk_in, MAY_WRITE, rc);
Casey Schauflerd166c802014-08-27 14:51:27 -07003636 return rc;
Casey Schauflere114e472008-02-04 22:29:50 -08003637}
3638
3639/**
Casey Schaufler6d3dc072008-12-31 12:54:12 -05003640 * smack_socket_sendmsg - Smack check based on destination host
3641 * @sock: the socket
Randy Dunlap251a2a92009-02-18 11:42:33 -08003642 * @msg: the message
Casey Schaufler6d3dc072008-12-31 12:54:12 -05003643 * @size: the size of the message
3644 *
Casey Schauflerc6739442013-05-22 18:42:56 -07003645 * Return 0 if the current subject can write to the destination host.
3646 * For IPv4 this is only a question if the destination is a single label host.
3647 * For IPv6 this is a check against the label of the port.
Casey Schaufler6d3dc072008-12-31 12:54:12 -05003648 */
3649static int smack_socket_sendmsg(struct socket *sock, struct msghdr *msg,
3650 int size)
3651{
3652 struct sockaddr_in *sip = (struct sockaddr_in *) msg->msg_name;
Casey Schaufler21abb1e2015-07-22 14:25:31 -07003653#if IS_ENABLED(CONFIG_IPV6)
Casey Schaufler6ea06242013-08-05 13:21:22 -07003654 struct sockaddr_in6 *sap = (struct sockaddr_in6 *) msg->msg_name;
Casey Schaufler21abb1e2015-07-22 14:25:31 -07003655#endif
3656#ifdef SMACK_IPV6_SECMARK_LABELING
3657 struct socket_smack *ssp = sock->sk->sk_security;
3658 struct smack_known *rsp;
3659#endif
Casey Schauflerc6739442013-05-22 18:42:56 -07003660 int rc = 0;
Casey Schaufler6d3dc072008-12-31 12:54:12 -05003661
3662 /*
3663 * Perfectly reasonable for this to be NULL
3664 */
Casey Schauflerc6739442013-05-22 18:42:56 -07003665 if (sip == NULL)
Casey Schaufler6d3dc072008-12-31 12:54:12 -05003666 return 0;
3667
Roman Kubiak81bd0d52015-12-17 13:24:35 +01003668 switch (sock->sk->sk_family) {
Casey Schauflerc6739442013-05-22 18:42:56 -07003669 case AF_INET:
Tetsuo Handab9ef5512019-04-12 19:59:35 +09003670 if (msg->msg_namelen < sizeof(struct sockaddr_in) ||
3671 sip->sin_family != AF_INET)
3672 return -EINVAL;
Casey Schauflerc6739442013-05-22 18:42:56 -07003673 rc = smack_netlabel_send(sock->sk, sip);
3674 break;
Casey Schaufler619ae032019-04-30 14:13:32 -07003675#if IS_ENABLED(CONFIG_IPV6)
Casey Schauflerc6739442013-05-22 18:42:56 -07003676 case AF_INET6:
Tetsuo Handab9ef5512019-04-12 19:59:35 +09003677 if (msg->msg_namelen < SIN6_LEN_RFC2133 ||
3678 sap->sin6_family != AF_INET6)
3679 return -EINVAL;
Casey Schaufler21abb1e2015-07-22 14:25:31 -07003680#ifdef SMACK_IPV6_SECMARK_LABELING
3681 rsp = smack_ipv6host_label(sap);
3682 if (rsp != NULL)
3683 rc = smk_ipv6_check(ssp->smk_out, rsp, sap,
3684 SMK_CONNECTING);
3685#endif
3686#ifdef SMACK_IPV6_PORT_LABELING
Casey Schauflerc6739442013-05-22 18:42:56 -07003687 rc = smk_ipv6_port_check(sock->sk, sap, SMK_SENDING);
Casey Schaufler21abb1e2015-07-22 14:25:31 -07003688#endif
Casey Schaufler619ae032019-04-30 14:13:32 -07003689#endif /* IS_ENABLED(CONFIG_IPV6) */
Casey Schauflerc6739442013-05-22 18:42:56 -07003690 break;
3691 }
3692 return rc;
Casey Schaufler6d3dc072008-12-31 12:54:12 -05003693}
3694
Casey Schaufler6d3dc072008-12-31 12:54:12 -05003695/**
Randy Dunlap251a2a92009-02-18 11:42:33 -08003696 * smack_from_secattr - Convert a netlabel attr.mls.lvl/attr.mls.cat pair to smack
Casey Schauflere114e472008-02-04 22:29:50 -08003697 * @sap: netlabel secattr
Casey Schaufler272cd7a2011-09-20 12:24:36 -07003698 * @ssp: socket security information
Casey Schauflere114e472008-02-04 22:29:50 -08003699 *
Casey Schaufler2f823ff2013-05-22 18:43:03 -07003700 * Returns a pointer to a Smack label entry found on the label list.
Casey Schauflere114e472008-02-04 22:29:50 -08003701 */
Casey Schaufler2f823ff2013-05-22 18:43:03 -07003702static struct smack_known *smack_from_secattr(struct netlbl_lsm_secattr *sap,
3703 struct socket_smack *ssp)
Casey Schauflere114e472008-02-04 22:29:50 -08003704{
Casey Schaufler2f823ff2013-05-22 18:43:03 -07003705 struct smack_known *skp;
Casey Schauflerf7112e62012-05-06 15:22:02 -07003706 int found = 0;
Casey Schaufler677264e2013-06-28 13:47:07 -07003707 int acat;
3708 int kcat;
Casey Schauflere114e472008-02-04 22:29:50 -08003709
Casey Schaufler6d3dc072008-12-31 12:54:12 -05003710 if ((sap->flags & NETLBL_SECATTR_MLS_LVL) != 0) {
Casey Schauflere114e472008-02-04 22:29:50 -08003711 /*
Casey Schaufler6d3dc072008-12-31 12:54:12 -05003712 * Looks like a CIPSO packet.
Casey Schauflere114e472008-02-04 22:29:50 -08003713 * If there are flags but no level netlabel isn't
3714 * behaving the way we expect it to.
3715 *
Casey Schauflerf7112e62012-05-06 15:22:02 -07003716 * Look it up in the label table
Casey Schauflere114e472008-02-04 22:29:50 -08003717 * Without guidance regarding the smack value
3718 * for the packet fall back on the network
3719 * ambient value.
3720 */
Casey Schauflerf7112e62012-05-06 15:22:02 -07003721 rcu_read_lock();
Vishal Goel348dc282016-11-23 10:45:31 +05303722 list_for_each_entry_rcu(skp, &smack_known_list, list) {
Casey Schaufler2f823ff2013-05-22 18:43:03 -07003723 if (sap->attr.mls.lvl != skp->smk_netlabel.attr.mls.lvl)
Casey Schauflerf7112e62012-05-06 15:22:02 -07003724 continue;
Casey Schaufler677264e2013-06-28 13:47:07 -07003725 /*
3726 * Compare the catsets. Use the netlbl APIs.
3727 */
3728 if ((sap->flags & NETLBL_SECATTR_MLS_CAT) == 0) {
3729 if ((skp->smk_netlabel.flags &
3730 NETLBL_SECATTR_MLS_CAT) == 0)
3731 found = 1;
3732 break;
3733 }
3734 for (acat = -1, kcat = -1; acat == kcat; ) {
Paul Moore4fbe63d2014-08-01 11:17:37 -04003735 acat = netlbl_catmap_walk(sap->attr.mls.cat,
3736 acat + 1);
3737 kcat = netlbl_catmap_walk(
Casey Schaufler677264e2013-06-28 13:47:07 -07003738 skp->smk_netlabel.attr.mls.cat,
3739 kcat + 1);
3740 if (acat < 0 || kcat < 0)
3741 break;
3742 }
3743 if (acat == kcat) {
3744 found = 1;
3745 break;
3746 }
Casey Schauflere114e472008-02-04 22:29:50 -08003747 }
Casey Schauflerf7112e62012-05-06 15:22:02 -07003748 rcu_read_unlock();
3749
3750 if (found)
Casey Schaufler2f823ff2013-05-22 18:43:03 -07003751 return skp;
Casey Schauflerf7112e62012-05-06 15:22:02 -07003752
Casey Schaufler54e70ec2014-04-10 16:37:08 -07003753 if (ssp != NULL && ssp->smk_in == &smack_known_star)
Casey Schaufler2f823ff2013-05-22 18:43:03 -07003754 return &smack_known_web;
3755 return &smack_known_star;
Casey Schaufler6d3dc072008-12-31 12:54:12 -05003756 }
Casey Schaufler152f91d2016-11-14 09:38:15 -08003757 if ((sap->flags & NETLBL_SECATTR_SECID) != 0)
Casey Schaufler6d3dc072008-12-31 12:54:12 -05003758 /*
3759 * Looks like a fallback, which gives us a secid.
3760 */
Casey Schaufler152f91d2016-11-14 09:38:15 -08003761 return smack_from_secid(sap->attr.secid);
Casey Schauflere114e472008-02-04 22:29:50 -08003762 /*
Casey Schaufler6d3dc072008-12-31 12:54:12 -05003763 * Without guidance regarding the smack value
3764 * for the packet fall back on the network
3765 * ambient value.
Casey Schauflere114e472008-02-04 22:29:50 -08003766 */
Casey Schaufler272cd7a2011-09-20 12:24:36 -07003767 return smack_net_ambient;
Casey Schauflere114e472008-02-04 22:29:50 -08003768}
3769
Casey Schaufler69f287a2014-12-12 17:08:40 -08003770#if IS_ENABLED(CONFIG_IPV6)
Casey Schaufler6ea06242013-08-05 13:21:22 -07003771static int smk_skb_to_addr_ipv6(struct sk_buff *skb, struct sockaddr_in6 *sip)
Casey Schauflerc6739442013-05-22 18:42:56 -07003772{
Casey Schauflerc6739442013-05-22 18:42:56 -07003773 u8 nexthdr;
3774 int offset;
3775 int proto = -EINVAL;
3776 struct ipv6hdr _ipv6h;
3777 struct ipv6hdr *ip6;
3778 __be16 frag_off;
3779 struct tcphdr _tcph, *th;
3780 struct udphdr _udph, *uh;
3781 struct dccp_hdr _dccph, *dh;
3782
3783 sip->sin6_port = 0;
3784
3785 offset = skb_network_offset(skb);
3786 ip6 = skb_header_pointer(skb, offset, sizeof(_ipv6h), &_ipv6h);
3787 if (ip6 == NULL)
3788 return -EINVAL;
3789 sip->sin6_addr = ip6->saddr;
3790
3791 nexthdr = ip6->nexthdr;
3792 offset += sizeof(_ipv6h);
3793 offset = ipv6_skip_exthdr(skb, offset, &nexthdr, &frag_off);
3794 if (offset < 0)
3795 return -EINVAL;
3796
3797 proto = nexthdr;
3798 switch (proto) {
3799 case IPPROTO_TCP:
3800 th = skb_header_pointer(skb, offset, sizeof(_tcph), &_tcph);
3801 if (th != NULL)
3802 sip->sin6_port = th->source;
3803 break;
3804 case IPPROTO_UDP:
Piotr Sawickia07ef952018-07-19 11:45:16 +02003805 case IPPROTO_UDPLITE:
Casey Schauflerc6739442013-05-22 18:42:56 -07003806 uh = skb_header_pointer(skb, offset, sizeof(_udph), &_udph);
3807 if (uh != NULL)
3808 sip->sin6_port = uh->source;
3809 break;
3810 case IPPROTO_DCCP:
3811 dh = skb_header_pointer(skb, offset, sizeof(_dccph), &_dccph);
3812 if (dh != NULL)
3813 sip->sin6_port = dh->dccph_sport;
3814 break;
3815 }
3816 return proto;
3817}
Casey Schaufler69f287a2014-12-12 17:08:40 -08003818#endif /* CONFIG_IPV6 */
Casey Schauflerc6739442013-05-22 18:42:56 -07003819
Casey Schauflere114e472008-02-04 22:29:50 -08003820/**
3821 * smack_socket_sock_rcv_skb - Smack packet delivery access check
3822 * @sk: socket
3823 * @skb: packet
3824 *
3825 * Returns 0 if the packet should be delivered, an error code otherwise
3826 */
3827static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
3828{
3829 struct netlbl_lsm_secattr secattr;
3830 struct socket_smack *ssp = sk->sk_security;
Casey Schaufler69f287a2014-12-12 17:08:40 -08003831 struct smack_known *skp = NULL;
Casey Schauflerc6739442013-05-22 18:42:56 -07003832 int rc = 0;
Etienne Bassetecfcc532009-04-08 20:40:06 +02003833 struct smk_audit_info ad;
Piotr Sawicki129a9982018-07-19 11:42:58 +02003834 u16 family = sk->sk_family;
Kees Cook923e9a12012-04-10 13:26:44 -07003835#ifdef CONFIG_AUDIT
Eric Paris48c62af2012-04-02 13:15:44 -04003836 struct lsm_network_audit net;
Kees Cook923e9a12012-04-10 13:26:44 -07003837#endif
Casey Schaufler69f287a2014-12-12 17:08:40 -08003838#if IS_ENABLED(CONFIG_IPV6)
3839 struct sockaddr_in6 sadd;
3840 int proto;
Piotr Sawicki129a9982018-07-19 11:42:58 +02003841
3842 if (family == PF_INET6 && skb->protocol == htons(ETH_P_IP))
3843 family = PF_INET;
Casey Schaufler69f287a2014-12-12 17:08:40 -08003844#endif /* CONFIG_IPV6 */
3845
Piotr Sawicki129a9982018-07-19 11:42:58 +02003846 switch (family) {
Casey Schauflerc6739442013-05-22 18:42:56 -07003847 case PF_INET:
Casey Schaufler69f287a2014-12-12 17:08:40 -08003848#ifdef CONFIG_SECURITY_SMACK_NETFILTER
3849 /*
3850 * If there is a secmark use it rather than the CIPSO label.
3851 * If there is no secmark fall back to CIPSO.
3852 * The secmark is assumed to reflect policy better.
3853 */
3854 if (skb && skb->secmark != 0) {
3855 skp = smack_from_secid(skb->secmark);
3856 goto access_check;
3857 }
3858#endif /* CONFIG_SECURITY_SMACK_NETFILTER */
Casey Schauflerc6739442013-05-22 18:42:56 -07003859 /*
3860 * Translate what netlabel gave us.
3861 */
3862 netlbl_secattr_init(&secattr);
Casey Schauflere114e472008-02-04 22:29:50 -08003863
Piotr Sawicki129a9982018-07-19 11:42:58 +02003864 rc = netlbl_skbuff_getattr(skb, family, &secattr);
Casey Schauflerc6739442013-05-22 18:42:56 -07003865 if (rc == 0)
Casey Schaufler2f823ff2013-05-22 18:43:03 -07003866 skp = smack_from_secattr(&secattr, ssp);
Casey Schauflerc6739442013-05-22 18:42:56 -07003867 else
Casey Schaufler2f823ff2013-05-22 18:43:03 -07003868 skp = smack_net_ambient;
Casey Schaufler6d3dc072008-12-31 12:54:12 -05003869
Casey Schauflerc6739442013-05-22 18:42:56 -07003870 netlbl_secattr_destroy(&secattr);
Casey Schaufler6d3dc072008-12-31 12:54:12 -05003871
Casey Schaufler69f287a2014-12-12 17:08:40 -08003872#ifdef CONFIG_SECURITY_SMACK_NETFILTER
3873access_check:
3874#endif
Etienne Bassetecfcc532009-04-08 20:40:06 +02003875#ifdef CONFIG_AUDIT
Casey Schauflerc6739442013-05-22 18:42:56 -07003876 smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net);
Piotr Sawicki129a9982018-07-19 11:42:58 +02003877 ad.a.u.net->family = family;
Casey Schauflerc6739442013-05-22 18:42:56 -07003878 ad.a.u.net->netif = skb->skb_iif;
3879 ipv4_skb_to_auditdata(skb, &ad.a, NULL);
Etienne Bassetecfcc532009-04-08 20:40:06 +02003880#endif
Casey Schauflerc6739442013-05-22 18:42:56 -07003881 /*
3882 * Receiving a packet requires that the other end
3883 * be able to write here. Read access is not required.
3884 * This is the simplist possible security model
3885 * for networking.
3886 */
Lukasz Pawelczyk21c7eae2014-08-29 17:02:55 +02003887 rc = smk_access(skp, ssp->smk_in, MAY_WRITE, &ad);
3888 rc = smk_bu_note("IPv4 delivery", skp, ssp->smk_in,
Casey Schauflerd166c802014-08-27 14:51:27 -07003889 MAY_WRITE, rc);
Casey Schauflerc6739442013-05-22 18:42:56 -07003890 if (rc != 0)
Piotr Sawicki129a9982018-07-19 11:42:58 +02003891 netlbl_skbuff_err(skb, family, rc, 0);
Casey Schauflerc6739442013-05-22 18:42:56 -07003892 break;
Casey Schaufler69f287a2014-12-12 17:08:40 -08003893#if IS_ENABLED(CONFIG_IPV6)
Casey Schauflerc6739442013-05-22 18:42:56 -07003894 case PF_INET6:
Casey Schaufler69f287a2014-12-12 17:08:40 -08003895 proto = smk_skb_to_addr_ipv6(skb, &sadd);
Piotr Sawickia07ef952018-07-19 11:45:16 +02003896 if (proto != IPPROTO_UDP && proto != IPPROTO_UDPLITE &&
3897 proto != IPPROTO_TCP && proto != IPPROTO_DCCP)
Casey Schaufler69f287a2014-12-12 17:08:40 -08003898 break;
Casey Schaufler21abb1e2015-07-22 14:25:31 -07003899#ifdef SMACK_IPV6_SECMARK_LABELING
Casey Schaufler69f287a2014-12-12 17:08:40 -08003900 if (skb && skb->secmark != 0)
3901 skp = smack_from_secid(skb->secmark);
Casey Schauflerf7450bc2019-04-03 14:28:38 -07003902 else if (smk_ipv6_localhost(&sadd))
3903 break;
Casey Schauflerc6739442013-05-22 18:42:56 -07003904 else
Casey Schaufler21abb1e2015-07-22 14:25:31 -07003905 skp = smack_ipv6host_label(&sadd);
3906 if (skp == NULL)
Casey Schaufler69f287a2014-12-12 17:08:40 -08003907 skp = smack_net_ambient;
Jia-Ju Bai3f4287e2019-07-23 18:00:15 +08003908 if (skb == NULL)
3909 break;
Casey Schaufler69f287a2014-12-12 17:08:40 -08003910#ifdef CONFIG_AUDIT
3911 smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net);
Piotr Sawicki129a9982018-07-19 11:42:58 +02003912 ad.a.u.net->family = family;
Casey Schaufler69f287a2014-12-12 17:08:40 -08003913 ad.a.u.net->netif = skb->skb_iif;
3914 ipv6_skb_to_auditdata(skb, &ad.a, NULL);
3915#endif /* CONFIG_AUDIT */
3916 rc = smk_access(skp, ssp->smk_in, MAY_WRITE, &ad);
3917 rc = smk_bu_note("IPv6 delivery", skp, ssp->smk_in,
3918 MAY_WRITE, rc);
Casey Schaufler21abb1e2015-07-22 14:25:31 -07003919#endif /* SMACK_IPV6_SECMARK_LABELING */
3920#ifdef SMACK_IPV6_PORT_LABELING
Casey Schaufler69f287a2014-12-12 17:08:40 -08003921 rc = smk_ipv6_port_check(sk, &sadd, SMK_RECEIVING);
Casey Schaufler21abb1e2015-07-22 14:25:31 -07003922#endif /* SMACK_IPV6_PORT_LABELING */
Piotr Sawickid66a8ac2018-07-19 11:47:31 +02003923 if (rc != 0)
3924 icmpv6_send(skb, ICMPV6_DEST_UNREACH,
3925 ICMPV6_ADM_PROHIBITED, 0);
Casey Schauflerc6739442013-05-22 18:42:56 -07003926 break;
Casey Schaufler69f287a2014-12-12 17:08:40 -08003927#endif /* CONFIG_IPV6 */
Casey Schauflerc6739442013-05-22 18:42:56 -07003928 }
Casey Schaufler69f287a2014-12-12 17:08:40 -08003929
Paul Moorea8134292008-10-10 10:16:31 -04003930 return rc;
Casey Schauflere114e472008-02-04 22:29:50 -08003931}
3932
3933/**
3934 * smack_socket_getpeersec_stream - pull in packet label
3935 * @sock: the socket
3936 * @optval: user's destination
3937 * @optlen: size thereof
Randy Dunlap251a2a92009-02-18 11:42:33 -08003938 * @len: max thereof
Casey Schauflere114e472008-02-04 22:29:50 -08003939 *
3940 * returns zero on success, an error code otherwise
3941 */
3942static int smack_socket_getpeersec_stream(struct socket *sock,
3943 char __user *optval,
3944 int __user *optlen, unsigned len)
3945{
3946 struct socket_smack *ssp;
Casey Schaufler272cd7a2011-09-20 12:24:36 -07003947 char *rcp = "";
3948 int slen = 1;
Casey Schauflere114e472008-02-04 22:29:50 -08003949 int rc = 0;
3950
3951 ssp = sock->sk->sk_security;
Casey Schaufler272cd7a2011-09-20 12:24:36 -07003952 if (ssp->smk_packet != NULL) {
Casey Schaufler54e70ec2014-04-10 16:37:08 -07003953 rcp = ssp->smk_packet->smk_known;
Casey Schaufler272cd7a2011-09-20 12:24:36 -07003954 slen = strlen(rcp) + 1;
3955 }
Casey Schauflere114e472008-02-04 22:29:50 -08003956
3957 if (slen > len)
3958 rc = -ERANGE;
Casey Schaufler272cd7a2011-09-20 12:24:36 -07003959 else if (copy_to_user(optval, rcp, slen) != 0)
Casey Schauflere114e472008-02-04 22:29:50 -08003960 rc = -EFAULT;
3961
3962 if (put_user(slen, optlen) != 0)
3963 rc = -EFAULT;
3964
3965 return rc;
3966}
3967
3968
3969/**
3970 * smack_socket_getpeersec_dgram - pull in packet label
Casey Schauflerb4e0d5f2010-11-24 17:12:10 -08003971 * @sock: the peer socket
Casey Schauflere114e472008-02-04 22:29:50 -08003972 * @skb: packet data
3973 * @secid: pointer to where to put the secid of the packet
3974 *
3975 * Sets the netlabel socket state on sk from parent
3976 */
3977static int smack_socket_getpeersec_dgram(struct socket *sock,
3978 struct sk_buff *skb, u32 *secid)
3979
3980{
3981 struct netlbl_lsm_secattr secattr;
Casey Schaufler272cd7a2011-09-20 12:24:36 -07003982 struct socket_smack *ssp = NULL;
Casey Schaufler2f823ff2013-05-22 18:43:03 -07003983 struct smack_known *skp;
Casey Schauflerb4e0d5f2010-11-24 17:12:10 -08003984 int family = PF_UNSPEC;
3985 u32 s = 0; /* 0 is the invalid secid */
Casey Schauflere114e472008-02-04 22:29:50 -08003986 int rc;
3987
Casey Schauflerb4e0d5f2010-11-24 17:12:10 -08003988 if (skb != NULL) {
3989 if (skb->protocol == htons(ETH_P_IP))
3990 family = PF_INET;
Casey Schaufler69f287a2014-12-12 17:08:40 -08003991#if IS_ENABLED(CONFIG_IPV6)
Casey Schauflerb4e0d5f2010-11-24 17:12:10 -08003992 else if (skb->protocol == htons(ETH_P_IPV6))
3993 family = PF_INET6;
Casey Schaufler69f287a2014-12-12 17:08:40 -08003994#endif /* CONFIG_IPV6 */
Casey Schauflere114e472008-02-04 22:29:50 -08003995 }
Casey Schauflerb4e0d5f2010-11-24 17:12:10 -08003996 if (family == PF_UNSPEC && sock != NULL)
3997 family = sock->sk->sk_family;
Casey Schauflere114e472008-02-04 22:29:50 -08003998
Casey Schaufler69f287a2014-12-12 17:08:40 -08003999 switch (family) {
4000 case PF_UNIX:
Casey Schaufler272cd7a2011-09-20 12:24:36 -07004001 ssp = sock->sk->sk_security;
Casey Schaufler2f823ff2013-05-22 18:43:03 -07004002 s = ssp->smk_out->smk_secid;
Casey Schaufler69f287a2014-12-12 17:08:40 -08004003 break;
4004 case PF_INET:
4005#ifdef CONFIG_SECURITY_SMACK_NETFILTER
4006 s = skb->secmark;
4007 if (s != 0)
4008 break;
4009#endif
Casey Schauflerb4e0d5f2010-11-24 17:12:10 -08004010 /*
4011 * Translate what netlabel gave us.
4012 */
Casey Schaufler272cd7a2011-09-20 12:24:36 -07004013 if (sock != NULL && sock->sk != NULL)
4014 ssp = sock->sk->sk_security;
Casey Schauflerb4e0d5f2010-11-24 17:12:10 -08004015 netlbl_secattr_init(&secattr);
4016 rc = netlbl_skbuff_getattr(skb, family, &secattr);
4017 if (rc == 0) {
Casey Schaufler2f823ff2013-05-22 18:43:03 -07004018 skp = smack_from_secattr(&secattr, ssp);
4019 s = skp->smk_secid;
Casey Schauflerb4e0d5f2010-11-24 17:12:10 -08004020 }
4021 netlbl_secattr_destroy(&secattr);
Casey Schaufler69f287a2014-12-12 17:08:40 -08004022 break;
Casey Schaufler69f287a2014-12-12 17:08:40 -08004023 case PF_INET6:
Casey Schaufler21abb1e2015-07-22 14:25:31 -07004024#ifdef SMACK_IPV6_SECMARK_LABELING
Casey Schaufler69f287a2014-12-12 17:08:40 -08004025 s = skb->secmark;
Casey Schaufler21abb1e2015-07-22 14:25:31 -07004026#endif
Casey Schaufler69f287a2014-12-12 17:08:40 -08004027 break;
Casey Schauflerb4e0d5f2010-11-24 17:12:10 -08004028 }
4029 *secid = s;
Casey Schauflere114e472008-02-04 22:29:50 -08004030 if (s == 0)
4031 return -EINVAL;
Casey Schauflere114e472008-02-04 22:29:50 -08004032 return 0;
4033}
4034
4035/**
Paul Moore07feee82009-03-27 17:10:54 -04004036 * smack_sock_graft - Initialize a newly created socket with an existing sock
4037 * @sk: child sock
4038 * @parent: parent socket
Casey Schauflere114e472008-02-04 22:29:50 -08004039 *
Paul Moore07feee82009-03-27 17:10:54 -04004040 * Set the smk_{in,out} state of an existing sock based on the process that
4041 * is creating the new socket.
Casey Schauflere114e472008-02-04 22:29:50 -08004042 */
4043static void smack_sock_graft(struct sock *sk, struct socket *parent)
4044{
4045 struct socket_smack *ssp;
Casey Schaufler2f823ff2013-05-22 18:43:03 -07004046 struct smack_known *skp = smk_of_current();
Casey Schauflere114e472008-02-04 22:29:50 -08004047
Paul Moore07feee82009-03-27 17:10:54 -04004048 if (sk == NULL ||
4049 (sk->sk_family != PF_INET && sk->sk_family != PF_INET6))
Casey Schauflere114e472008-02-04 22:29:50 -08004050 return;
4051
4052 ssp = sk->sk_security;
Casey Schaufler54e70ec2014-04-10 16:37:08 -07004053 ssp->smk_in = skp;
Casey Schaufler2f823ff2013-05-22 18:43:03 -07004054 ssp->smk_out = skp;
Paul Moore07feee82009-03-27 17:10:54 -04004055 /* cssp->smk_packet is already set in smack_inet_csk_clone() */
Casey Schauflere114e472008-02-04 22:29:50 -08004056}
4057
4058/**
4059 * smack_inet_conn_request - Smack access check on connect
4060 * @sk: socket involved
4061 * @skb: packet
4062 * @req: unused
4063 *
4064 * Returns 0 if a task with the packet label could write to
4065 * the socket, otherwise an error code
4066 */
4067static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb,
4068 struct request_sock *req)
4069{
Paul Moore07feee82009-03-27 17:10:54 -04004070 u16 family = sk->sk_family;
Casey Schauflerf7112e62012-05-06 15:22:02 -07004071 struct smack_known *skp;
Casey Schauflere114e472008-02-04 22:29:50 -08004072 struct socket_smack *ssp = sk->sk_security;
Paul Moore07feee82009-03-27 17:10:54 -04004073 struct netlbl_lsm_secattr secattr;
4074 struct sockaddr_in addr;
4075 struct iphdr *hdr;
Lukasz Pawelczyk21c7eae2014-08-29 17:02:55 +02004076 struct smack_known *hskp;
Casey Schauflere114e472008-02-04 22:29:50 -08004077 int rc;
Etienne Bassetecfcc532009-04-08 20:40:06 +02004078 struct smk_audit_info ad;
Kees Cook923e9a12012-04-10 13:26:44 -07004079#ifdef CONFIG_AUDIT
Eric Paris48c62af2012-04-02 13:15:44 -04004080 struct lsm_network_audit net;
Kees Cook923e9a12012-04-10 13:26:44 -07004081#endif
Casey Schauflere114e472008-02-04 22:29:50 -08004082
Casey Schaufler69f287a2014-12-12 17:08:40 -08004083#if IS_ENABLED(CONFIG_IPV6)
Casey Schauflerc6739442013-05-22 18:42:56 -07004084 if (family == PF_INET6) {
4085 /*
4086 * Handle mapped IPv4 packets arriving
4087 * via IPv6 sockets. Don't set up netlabel
4088 * processing on IPv6.
4089 */
4090 if (skb->protocol == htons(ETH_P_IP))
4091 family = PF_INET;
4092 else
4093 return 0;
4094 }
Casey Schaufler69f287a2014-12-12 17:08:40 -08004095#endif /* CONFIG_IPV6 */
Casey Schauflere114e472008-02-04 22:29:50 -08004096
Casey Schaufler7f368ad2015-02-11 12:52:32 -08004097#ifdef CONFIG_SECURITY_SMACK_NETFILTER
4098 /*
4099 * If there is a secmark use it rather than the CIPSO label.
4100 * If there is no secmark fall back to CIPSO.
4101 * The secmark is assumed to reflect policy better.
4102 */
4103 if (skb && skb->secmark != 0) {
4104 skp = smack_from_secid(skb->secmark);
4105 goto access_check;
4106 }
4107#endif /* CONFIG_SECURITY_SMACK_NETFILTER */
4108
Paul Moore07feee82009-03-27 17:10:54 -04004109 netlbl_secattr_init(&secattr);
4110 rc = netlbl_skbuff_getattr(skb, family, &secattr);
Casey Schauflere114e472008-02-04 22:29:50 -08004111 if (rc == 0)
Casey Schaufler2f823ff2013-05-22 18:43:03 -07004112 skp = smack_from_secattr(&secattr, ssp);
Casey Schauflere114e472008-02-04 22:29:50 -08004113 else
Casey Schaufler2f823ff2013-05-22 18:43:03 -07004114 skp = &smack_known_huh;
Paul Moore07feee82009-03-27 17:10:54 -04004115 netlbl_secattr_destroy(&secattr);
4116
Casey Schaufler7f368ad2015-02-11 12:52:32 -08004117#ifdef CONFIG_SECURITY_SMACK_NETFILTER
4118access_check:
4119#endif
4120
Etienne Bassetecfcc532009-04-08 20:40:06 +02004121#ifdef CONFIG_AUDIT
Eric Paris48c62af2012-04-02 13:15:44 -04004122 smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net);
4123 ad.a.u.net->family = family;
4124 ad.a.u.net->netif = skb->skb_iif;
Etienne Bassetecfcc532009-04-08 20:40:06 +02004125 ipv4_skb_to_auditdata(skb, &ad.a, NULL);
4126#endif
Casey Schauflere114e472008-02-04 22:29:50 -08004127 /*
Paul Moore07feee82009-03-27 17:10:54 -04004128 * Receiving a packet requires that the other end be able to write
4129 * here. Read access is not required.
Casey Schauflere114e472008-02-04 22:29:50 -08004130 */
Lukasz Pawelczyk21c7eae2014-08-29 17:02:55 +02004131 rc = smk_access(skp, ssp->smk_in, MAY_WRITE, &ad);
4132 rc = smk_bu_note("IPv4 connect", skp, ssp->smk_in, MAY_WRITE, rc);
Paul Moore07feee82009-03-27 17:10:54 -04004133 if (rc != 0)
4134 return rc;
4135
4136 /*
4137 * Save the peer's label in the request_sock so we can later setup
4138 * smk_packet in the child socket so that SO_PEERCRED can report it.
4139 */
Casey Schaufler2f823ff2013-05-22 18:43:03 -07004140 req->peer_secid = skp->smk_secid;
Paul Moore07feee82009-03-27 17:10:54 -04004141
4142 /*
4143 * We need to decide if we want to label the incoming connection here
4144 * if we do we only need to label the request_sock and the stack will
Lucas De Marchi25985ed2011-03-30 22:57:33 -03004145 * propagate the wire-label to the sock when it is created.
Paul Moore07feee82009-03-27 17:10:54 -04004146 */
4147 hdr = ip_hdr(skb);
4148 addr.sin_addr.s_addr = hdr->saddr;
4149 rcu_read_lock();
Casey Schaufler21abb1e2015-07-22 14:25:31 -07004150 hskp = smack_ipv4host_label(&addr);
Casey Schauflerf7112e62012-05-06 15:22:02 -07004151 rcu_read_unlock();
4152
Lukasz Pawelczyk21c7eae2014-08-29 17:02:55 +02004153 if (hskp == NULL)
Casey Schauflerf7112e62012-05-06 15:22:02 -07004154 rc = netlbl_req_setattr(req, &skp->smk_netlabel);
Casey Schaufler2f823ff2013-05-22 18:43:03 -07004155 else
Paul Moore07feee82009-03-27 17:10:54 -04004156 netlbl_req_delattr(req);
Casey Schauflere114e472008-02-04 22:29:50 -08004157
4158 return rc;
4159}
4160
Paul Moore07feee82009-03-27 17:10:54 -04004161/**
4162 * smack_inet_csk_clone - Copy the connection information to the new socket
4163 * @sk: the new socket
4164 * @req: the connection's request_sock
4165 *
4166 * Transfer the connection's peer label to the newly created socket.
4167 */
4168static void smack_inet_csk_clone(struct sock *sk,
4169 const struct request_sock *req)
4170{
4171 struct socket_smack *ssp = sk->sk_security;
Casey Schaufler2f823ff2013-05-22 18:43:03 -07004172 struct smack_known *skp;
Paul Moore07feee82009-03-27 17:10:54 -04004173
Casey Schaufler2f823ff2013-05-22 18:43:03 -07004174 if (req->peer_secid != 0) {
4175 skp = smack_from_secid(req->peer_secid);
Casey Schaufler54e70ec2014-04-10 16:37:08 -07004176 ssp->smk_packet = skp;
Casey Schaufler2f823ff2013-05-22 18:43:03 -07004177 } else
Casey Schaufler272cd7a2011-09-20 12:24:36 -07004178 ssp->smk_packet = NULL;
Paul Moore07feee82009-03-27 17:10:54 -04004179}
4180
Casey Schauflere114e472008-02-04 22:29:50 -08004181/*
4182 * Key management security hooks
4183 *
4184 * Casey has not tested key support very heavily.
4185 * The permission check is most likely too restrictive.
4186 * If you care about keys please have a look.
4187 */
4188#ifdef CONFIG_KEYS
4189
4190/**
4191 * smack_key_alloc - Set the key security blob
4192 * @key: object
David Howellsd84f4f92008-11-14 10:39:23 +11004193 * @cred: the credentials to use
Casey Schauflere114e472008-02-04 22:29:50 -08004194 * @flags: unused
4195 *
4196 * No allocation required
4197 *
4198 * Returns 0
4199 */
David Howellsd84f4f92008-11-14 10:39:23 +11004200static int smack_key_alloc(struct key *key, const struct cred *cred,
Casey Schauflere114e472008-02-04 22:29:50 -08004201 unsigned long flags)
4202{
Casey Schauflerb17103a2018-11-09 16:12:56 -08004203 struct smack_known *skp = smk_of_task(smack_cred(cred));
Casey Schaufler2f823ff2013-05-22 18:43:03 -07004204
Lukasz Pawelczyk21c7eae2014-08-29 17:02:55 +02004205 key->security = skp;
Casey Schauflere114e472008-02-04 22:29:50 -08004206 return 0;
4207}
4208
4209/**
4210 * smack_key_free - Clear the key security blob
4211 * @key: the object
4212 *
4213 * Clear the blob pointer
4214 */
4215static void smack_key_free(struct key *key)
4216{
4217 key->security = NULL;
4218}
4219
Lukasz Pawelczyk1a289792014-11-26 15:31:06 +01004220/**
Casey Schauflere114e472008-02-04 22:29:50 -08004221 * smack_key_permission - Smack access on a key
4222 * @key_ref: gets to the object
David Howellsd84f4f92008-11-14 10:39:23 +11004223 * @cred: the credentials to use
Lukasz Pawelczyk1a289792014-11-26 15:31:06 +01004224 * @perm: requested key permissions
Casey Schauflere114e472008-02-04 22:29:50 -08004225 *
4226 * Return 0 if the task has read and write to the object,
4227 * an error code otherwise
4228 */
4229static int smack_key_permission(key_ref_t key_ref,
David Howellsf5895942014-03-14 17:44:49 +00004230 const struct cred *cred, unsigned perm)
Casey Schauflere114e472008-02-04 22:29:50 -08004231{
4232 struct key *keyp;
Etienne Bassetecfcc532009-04-08 20:40:06 +02004233 struct smk_audit_info ad;
Casey Schauflerb17103a2018-11-09 16:12:56 -08004234 struct smack_known *tkp = smk_of_task(smack_cred(cred));
Dmitry Kasatkinfffea212014-03-14 17:44:49 +00004235 int request = 0;
Casey Schauflerd166c802014-08-27 14:51:27 -07004236 int rc;
Casey Schauflere114e472008-02-04 22:29:50 -08004237
Zoran Markovic5b841bf2018-10-17 16:25:44 -07004238 /*
4239 * Validate requested permissions
4240 */
4241 if (perm & ~KEY_NEED_ALL)
4242 return -EINVAL;
4243
Casey Schauflere114e472008-02-04 22:29:50 -08004244 keyp = key_ref_to_ptr(key_ref);
4245 if (keyp == NULL)
4246 return -EINVAL;
4247 /*
4248 * If the key hasn't been initialized give it access so that
4249 * it may do so.
4250 */
4251 if (keyp->security == NULL)
4252 return 0;
4253 /*
4254 * This should not occur
4255 */
Casey Schaufler2f823ff2013-05-22 18:43:03 -07004256 if (tkp == NULL)
Casey Schauflere114e472008-02-04 22:29:50 -08004257 return -EACCES;
Casey Schauflerd19dfe52018-01-08 10:25:32 -08004258
4259 if (smack_privileged_cred(CAP_MAC_OVERRIDE, cred))
4260 return 0;
4261
Etienne Bassetecfcc532009-04-08 20:40:06 +02004262#ifdef CONFIG_AUDIT
4263 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_KEY);
4264 ad.a.u.key_struct.key = keyp->serial;
4265 ad.a.u.key_struct.key_desc = keyp->description;
4266#endif
Zoran Markovic5b841bf2018-10-17 16:25:44 -07004267 if (perm & (KEY_NEED_READ | KEY_NEED_SEARCH | KEY_NEED_VIEW))
4268 request |= MAY_READ;
Dmitry Kasatkinfffea212014-03-14 17:44:49 +00004269 if (perm & (KEY_NEED_WRITE | KEY_NEED_LINK | KEY_NEED_SETATTR))
Zoran Markovic5b841bf2018-10-17 16:25:44 -07004270 request |= MAY_WRITE;
Casey Schauflerd166c802014-08-27 14:51:27 -07004271 rc = smk_access(tkp, keyp->security, request, &ad);
4272 rc = smk_bu_note("key access", tkp, keyp->security, request, rc);
4273 return rc;
Casey Schauflere114e472008-02-04 22:29:50 -08004274}
José Bollo7fc5f362015-02-17 15:41:22 +01004275
4276/*
4277 * smack_key_getsecurity - Smack label tagging the key
4278 * @key points to the key to be queried
4279 * @_buffer points to a pointer that should be set to point to the
4280 * resulting string (if no label or an error occurs).
4281 * Return the length of the string (including terminating NUL) or -ve if
4282 * an error.
4283 * May also return 0 (and a NULL buffer pointer) if there is no label.
4284 */
4285static int smack_key_getsecurity(struct key *key, char **_buffer)
4286{
4287 struct smack_known *skp = key->security;
4288 size_t length;
4289 char *copy;
4290
4291 if (key->security == NULL) {
4292 *_buffer = NULL;
4293 return 0;
4294 }
4295
4296 copy = kstrdup(skp->smk_known, GFP_KERNEL);
4297 if (copy == NULL)
4298 return -ENOMEM;
4299 length = strlen(copy) + 1;
4300
4301 *_buffer = copy;
4302 return length;
4303}
4304
Casey Schauflere114e472008-02-04 22:29:50 -08004305#endif /* CONFIG_KEYS */
4306
4307/*
Ahmed S. Darwishd20bdda2008-04-30 08:34:10 +10004308 * Smack Audit hooks
4309 *
4310 * Audit requires a unique representation of each Smack specific
4311 * rule. This unique representation is used to distinguish the
4312 * object to be audited from remaining kernel objects and also
4313 * works as a glue between the audit hooks.
4314 *
4315 * Since repository entries are added but never deleted, we'll use
4316 * the smack_known label address related to the given audit rule as
4317 * the needed unique representation. This also better fits the smack
4318 * model where nearly everything is a label.
4319 */
4320#ifdef CONFIG_AUDIT
4321
4322/**
4323 * smack_audit_rule_init - Initialize a smack audit rule
4324 * @field: audit rule fields given from user-space (audit.h)
4325 * @op: required testing operator (=, !=, >, <, ...)
4326 * @rulestr: smack label to be audited
4327 * @vrule: pointer to save our own audit rule representation
4328 *
4329 * Prepare to audit cases where (@field @op @rulestr) is true.
4330 * The label to be audited is created if necessay.
4331 */
4332static int smack_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule)
4333{
Lukasz Pawelczyk21c7eae2014-08-29 17:02:55 +02004334 struct smack_known *skp;
Ahmed S. Darwishd20bdda2008-04-30 08:34:10 +10004335 char **rule = (char **)vrule;
4336 *rule = NULL;
4337
4338 if (field != AUDIT_SUBJ_USER && field != AUDIT_OBJ_USER)
4339 return -EINVAL;
4340
Al Viro5af75d82008-12-16 05:59:26 -05004341 if (op != Audit_equal && op != Audit_not_equal)
Ahmed S. Darwishd20bdda2008-04-30 08:34:10 +10004342 return -EINVAL;
4343
Lukasz Pawelczyk21c7eae2014-08-29 17:02:55 +02004344 skp = smk_import_entry(rulestr, 0);
Lukasz Pawelczyke774ad62015-04-20 17:12:54 +02004345 if (IS_ERR(skp))
4346 return PTR_ERR(skp);
4347
4348 *rule = skp->smk_known;
Ahmed S. Darwishd20bdda2008-04-30 08:34:10 +10004349
4350 return 0;
4351}
4352
4353/**
4354 * smack_audit_rule_known - Distinguish Smack audit rules
4355 * @krule: rule of interest, in Audit kernel representation format
4356 *
4357 * This is used to filter Smack rules from remaining Audit ones.
4358 * If it's proved that this rule belongs to us, the
4359 * audit_rule_match hook will be called to do the final judgement.
4360 */
4361static int smack_audit_rule_known(struct audit_krule *krule)
4362{
4363 struct audit_field *f;
4364 int i;
4365
4366 for (i = 0; i < krule->field_count; i++) {
4367 f = &krule->fields[i];
4368
4369 if (f->type == AUDIT_SUBJ_USER || f->type == AUDIT_OBJ_USER)
4370 return 1;
4371 }
4372
4373 return 0;
4374}
4375
4376/**
4377 * smack_audit_rule_match - Audit given object ?
4378 * @secid: security id for identifying the object to test
4379 * @field: audit rule flags given from user-space
4380 * @op: required testing operator
4381 * @vrule: smack internal rule presentation
Ahmed S. Darwishd20bdda2008-04-30 08:34:10 +10004382 *
4383 * The core Audit hook. It's used to take the decision of
4384 * whether to audit or not to audit a given object.
4385 */
Richard Guy Briggs90462a52019-01-31 11:52:11 -05004386static int smack_audit_rule_match(u32 secid, u32 field, u32 op, void *vrule)
Ahmed S. Darwishd20bdda2008-04-30 08:34:10 +10004387{
Casey Schaufler2f823ff2013-05-22 18:43:03 -07004388 struct smack_known *skp;
Ahmed S. Darwishd20bdda2008-04-30 08:34:10 +10004389 char *rule = vrule;
4390
Richard Guy Briggs4eb0f4a2013-11-21 13:57:33 -05004391 if (unlikely(!rule)) {
4392 WARN_ONCE(1, "Smack: missing rule\n");
Ahmed S. Darwishd20bdda2008-04-30 08:34:10 +10004393 return -ENOENT;
4394 }
4395
4396 if (field != AUDIT_SUBJ_USER && field != AUDIT_OBJ_USER)
4397 return 0;
4398
Casey Schaufler2f823ff2013-05-22 18:43:03 -07004399 skp = smack_from_secid(secid);
Ahmed S. Darwishd20bdda2008-04-30 08:34:10 +10004400
4401 /*
4402 * No need to do string comparisons. If a match occurs,
4403 * both pointers will point to the same smack_known
4404 * label.
4405 */
Al Viro5af75d82008-12-16 05:59:26 -05004406 if (op == Audit_equal)
Casey Schaufler2f823ff2013-05-22 18:43:03 -07004407 return (rule == skp->smk_known);
Al Viro5af75d82008-12-16 05:59:26 -05004408 if (op == Audit_not_equal)
Casey Schaufler2f823ff2013-05-22 18:43:03 -07004409 return (rule != skp->smk_known);
Ahmed S. Darwishd20bdda2008-04-30 08:34:10 +10004410
4411 return 0;
4412}
4413
Casey Schaufler491a0b02016-01-26 15:08:35 -08004414/*
4415 * There is no need for a smack_audit_rule_free hook.
Ahmed S. Darwishd20bdda2008-04-30 08:34:10 +10004416 * No memory was allocated.
4417 */
Ahmed S. Darwishd20bdda2008-04-30 08:34:10 +10004418
4419#endif /* CONFIG_AUDIT */
4420
Randy Dunlap251a2a92009-02-18 11:42:33 -08004421/**
David Quigley746df9b2013-05-22 12:50:35 -04004422 * smack_ismaclabel - check if xattr @name references a smack MAC label
4423 * @name: Full xattr name to check.
4424 */
4425static int smack_ismaclabel(const char *name)
4426{
4427 return (strcmp(name, XATTR_SMACK_SUFFIX) == 0);
4428}
4429
4430
4431/**
Casey Schauflere114e472008-02-04 22:29:50 -08004432 * smack_secid_to_secctx - return the smack label for a secid
4433 * @secid: incoming integer
4434 * @secdata: destination
4435 * @seclen: how long it is
4436 *
4437 * Exists for networking code.
4438 */
4439static int smack_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
4440{
Casey Schaufler2f823ff2013-05-22 18:43:03 -07004441 struct smack_known *skp = smack_from_secid(secid);
Casey Schauflere114e472008-02-04 22:29:50 -08004442
Eric Parisd5630b92010-10-13 16:24:48 -04004443 if (secdata)
Casey Schaufler2f823ff2013-05-22 18:43:03 -07004444 *secdata = skp->smk_known;
4445 *seclen = strlen(skp->smk_known);
Casey Schauflere114e472008-02-04 22:29:50 -08004446 return 0;
4447}
4448
Randy Dunlap251a2a92009-02-18 11:42:33 -08004449/**
Casey Schaufler4bc87e62008-02-15 15:24:25 -08004450 * smack_secctx_to_secid - return the secid for a smack label
4451 * @secdata: smack label
4452 * @seclen: how long result is
4453 * @secid: outgoing integer
4454 *
4455 * Exists for audit and networking code.
4456 */
David Howellse52c17642008-04-29 20:52:51 +01004457static int smack_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid)
Casey Schaufler4bc87e62008-02-15 15:24:25 -08004458{
Lukasz Pawelczyk21c7eae2014-08-29 17:02:55 +02004459 struct smack_known *skp = smk_find_entry(secdata);
4460
4461 if (skp)
4462 *secid = skp->smk_secid;
4463 else
4464 *secid = 0;
Casey Schaufler4bc87e62008-02-15 15:24:25 -08004465 return 0;
4466}
4467
Casey Schaufler491a0b02016-01-26 15:08:35 -08004468/*
4469 * There used to be a smack_release_secctx hook
4470 * that did nothing back when hooks were in a vector.
4471 * Now that there's a list such a hook adds cost.
Casey Schauflere114e472008-02-04 22:29:50 -08004472 */
Casey Schauflere114e472008-02-04 22:29:50 -08004473
David P. Quigley1ee65e32009-09-03 14:25:57 -04004474static int smack_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen)
4475{
4476 return smack_inode_setsecurity(inode, XATTR_SMACK_SUFFIX, ctx, ctxlen, 0);
4477}
4478
4479static int smack_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen)
4480{
4481 return __vfs_setxattr_noperm(dentry, XATTR_NAME_SMACK, ctx, ctxlen, 0);
4482}
4483
4484static int smack_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen)
4485{
Casey Schaufler0f8983c2018-06-01 10:45:12 -07004486 struct smack_known *skp = smk_of_inode(inode);
David P. Quigley1ee65e32009-09-03 14:25:57 -04004487
Casey Schaufler0f8983c2018-06-01 10:45:12 -07004488 *ctx = skp->smk_known;
4489 *ctxlen = strlen(skp->smk_known);
David P. Quigley1ee65e32009-09-03 14:25:57 -04004490 return 0;
4491}
4492
Casey Schauflerd6d80cb2017-09-28 14:54:50 -07004493static int smack_inode_copy_up(struct dentry *dentry, struct cred **new)
4494{
4495
4496 struct task_smack *tsp;
4497 struct smack_known *skp;
4498 struct inode_smack *isp;
4499 struct cred *new_creds = *new;
4500
4501 if (new_creds == NULL) {
4502 new_creds = prepare_creds();
4503 if (new_creds == NULL)
4504 return -ENOMEM;
4505 }
4506
Casey Schauflerb17103a2018-11-09 16:12:56 -08004507 tsp = smack_cred(new_creds);
Casey Schauflerd6d80cb2017-09-28 14:54:50 -07004508
4509 /*
4510 * Get label from overlay inode and set it in create_sid
4511 */
Casey Schauflerfb4021b2018-11-12 12:43:01 -08004512 isp = smack_inode(d_inode(dentry->d_parent));
Casey Schauflerd6d80cb2017-09-28 14:54:50 -07004513 skp = isp->smk_inode;
4514 tsp->smk_task = skp;
4515 *new = new_creds;
4516 return 0;
4517}
4518
4519static int smack_inode_copy_up_xattr(const char *name)
4520{
4521 /*
4522 * Return 1 if this is the smack access Smack attribute.
4523 */
4524 if (strcmp(name, XATTR_NAME_SMACK) == 0)
4525 return 1;
4526
4527 return -EOPNOTSUPP;
4528}
4529
4530static int smack_dentry_create_files_as(struct dentry *dentry, int mode,
4531 struct qstr *name,
4532 const struct cred *old,
4533 struct cred *new)
4534{
Casey Schauflerb17103a2018-11-09 16:12:56 -08004535 struct task_smack *otsp = smack_cred(old);
4536 struct task_smack *ntsp = smack_cred(new);
Casey Schauflerd6d80cb2017-09-28 14:54:50 -07004537 struct inode_smack *isp;
4538 int may;
4539
4540 /*
4541 * Use the process credential unless all of
4542 * the transmuting criteria are met
4543 */
4544 ntsp->smk_task = otsp->smk_task;
4545
4546 /*
4547 * the attribute of the containing directory
4548 */
Casey Schauflerfb4021b2018-11-12 12:43:01 -08004549 isp = smack_inode(d_inode(dentry->d_parent));
Casey Schauflerd6d80cb2017-09-28 14:54:50 -07004550
4551 if (isp->smk_flags & SMK_INODE_TRANSMUTE) {
4552 rcu_read_lock();
4553 may = smk_access_entry(otsp->smk_task->smk_known,
4554 isp->smk_inode->smk_known,
4555 &otsp->smk_task->smk_rules);
4556 rcu_read_unlock();
4557
4558 /*
4559 * If the directory is transmuting and the rule
4560 * providing access is transmuting use the containing
4561 * directory label instead of the process label.
4562 */
4563 if (may > 0 && (may & MAY_TRANSMUTE))
4564 ntsp->smk_task = isp->smk_inode;
4565 }
4566 return 0;
4567}
4568
Casey Schauflerbbd36622018-11-12 09:30:56 -08004569struct lsm_blob_sizes smack_blob_sizes __lsm_ro_after_init = {
4570 .lbs_cred = sizeof(struct task_smack),
Casey Schaufler33bf60c2018-11-12 12:02:49 -08004571 .lbs_file = sizeof(struct smack_known *),
Casey Schauflerafb1cbe32018-09-21 17:19:29 -07004572 .lbs_inode = sizeof(struct inode_smack),
Casey Schauflerecd5f822018-11-20 11:55:02 -08004573 .lbs_ipc = sizeof(struct smack_known *),
4574 .lbs_msg_msg = sizeof(struct smack_known *),
Casey Schauflerbbd36622018-11-12 09:30:56 -08004575};
4576
James Morrisca97d932017-02-15 00:18:51 +11004577static struct security_hook_list smack_hooks[] __lsm_ro_after_init = {
Casey Schauflere20b0432015-05-02 15:11:36 -07004578 LSM_HOOK_INIT(ptrace_access_check, smack_ptrace_access_check),
4579 LSM_HOOK_INIT(ptrace_traceme, smack_ptrace_traceme),
4580 LSM_HOOK_INIT(syslog, smack_syslog),
Casey Schauflere114e472008-02-04 22:29:50 -08004581
Al Viro0b520752018-12-23 16:02:47 -05004582 LSM_HOOK_INIT(fs_context_dup, smack_fs_context_dup),
David Howells2febd252018-11-01 23:07:24 +00004583 LSM_HOOK_INIT(fs_context_parse_param, smack_fs_context_parse_param),
4584
Casey Schauflere20b0432015-05-02 15:11:36 -07004585 LSM_HOOK_INIT(sb_alloc_security, smack_sb_alloc_security),
4586 LSM_HOOK_INIT(sb_free_security, smack_sb_free_security),
Al Viro204cc0c2018-12-13 13:41:47 -05004587 LSM_HOOK_INIT(sb_free_mnt_opts, smack_free_mnt_opts),
Al Viro5b400232018-12-12 20:13:29 -05004588 LSM_HOOK_INIT(sb_eat_lsm_opts, smack_sb_eat_lsm_opts),
Casey Schauflere20b0432015-05-02 15:11:36 -07004589 LSM_HOOK_INIT(sb_statfs, smack_sb_statfs),
Vivek Trivedi3bf27892015-06-22 15:36:06 +05304590 LSM_HOOK_INIT(sb_set_mnt_opts, smack_set_mnt_opts),
Casey Schauflere114e472008-02-04 22:29:50 -08004591
Casey Schauflere20b0432015-05-02 15:11:36 -07004592 LSM_HOOK_INIT(bprm_set_creds, smack_bprm_set_creds),
Casey Schaufler676dac42010-12-02 06:43:39 -08004593
Casey Schauflere20b0432015-05-02 15:11:36 -07004594 LSM_HOOK_INIT(inode_alloc_security, smack_inode_alloc_security),
Casey Schauflere20b0432015-05-02 15:11:36 -07004595 LSM_HOOK_INIT(inode_init_security, smack_inode_init_security),
4596 LSM_HOOK_INIT(inode_link, smack_inode_link),
4597 LSM_HOOK_INIT(inode_unlink, smack_inode_unlink),
4598 LSM_HOOK_INIT(inode_rmdir, smack_inode_rmdir),
4599 LSM_HOOK_INIT(inode_rename, smack_inode_rename),
4600 LSM_HOOK_INIT(inode_permission, smack_inode_permission),
4601 LSM_HOOK_INIT(inode_setattr, smack_inode_setattr),
4602 LSM_HOOK_INIT(inode_getattr, smack_inode_getattr),
4603 LSM_HOOK_INIT(inode_setxattr, smack_inode_setxattr),
4604 LSM_HOOK_INIT(inode_post_setxattr, smack_inode_post_setxattr),
4605 LSM_HOOK_INIT(inode_getxattr, smack_inode_getxattr),
4606 LSM_HOOK_INIT(inode_removexattr, smack_inode_removexattr),
4607 LSM_HOOK_INIT(inode_getsecurity, smack_inode_getsecurity),
4608 LSM_HOOK_INIT(inode_setsecurity, smack_inode_setsecurity),
4609 LSM_HOOK_INIT(inode_listsecurity, smack_inode_listsecurity),
4610 LSM_HOOK_INIT(inode_getsecid, smack_inode_getsecid),
Casey Schauflere114e472008-02-04 22:29:50 -08004611
Casey Schauflere20b0432015-05-02 15:11:36 -07004612 LSM_HOOK_INIT(file_alloc_security, smack_file_alloc_security),
Casey Schauflere20b0432015-05-02 15:11:36 -07004613 LSM_HOOK_INIT(file_ioctl, smack_file_ioctl),
4614 LSM_HOOK_INIT(file_lock, smack_file_lock),
4615 LSM_HOOK_INIT(file_fcntl, smack_file_fcntl),
4616 LSM_HOOK_INIT(mmap_file, smack_mmap_file),
4617 LSM_HOOK_INIT(mmap_addr, cap_mmap_addr),
4618 LSM_HOOK_INIT(file_set_fowner, smack_file_set_fowner),
4619 LSM_HOOK_INIT(file_send_sigiotask, smack_file_send_sigiotask),
4620 LSM_HOOK_INIT(file_receive, smack_file_receive),
Casey Schauflere114e472008-02-04 22:29:50 -08004621
Casey Schauflere20b0432015-05-02 15:11:36 -07004622 LSM_HOOK_INIT(file_open, smack_file_open),
Casey Schaufler531f1d42011-09-19 12:41:42 -07004623
Casey Schauflere20b0432015-05-02 15:11:36 -07004624 LSM_HOOK_INIT(cred_alloc_blank, smack_cred_alloc_blank),
4625 LSM_HOOK_INIT(cred_free, smack_cred_free),
4626 LSM_HOOK_INIT(cred_prepare, smack_cred_prepare),
4627 LSM_HOOK_INIT(cred_transfer, smack_cred_transfer),
Matthew Garrett3ec30112018-01-08 13:36:19 -08004628 LSM_HOOK_INIT(cred_getsecid, smack_cred_getsecid),
Casey Schauflere20b0432015-05-02 15:11:36 -07004629 LSM_HOOK_INIT(kernel_act_as, smack_kernel_act_as),
4630 LSM_HOOK_INIT(kernel_create_files_as, smack_kernel_create_files_as),
4631 LSM_HOOK_INIT(task_setpgid, smack_task_setpgid),
4632 LSM_HOOK_INIT(task_getpgid, smack_task_getpgid),
4633 LSM_HOOK_INIT(task_getsid, smack_task_getsid),
4634 LSM_HOOK_INIT(task_getsecid, smack_task_getsecid),
4635 LSM_HOOK_INIT(task_setnice, smack_task_setnice),
4636 LSM_HOOK_INIT(task_setioprio, smack_task_setioprio),
4637 LSM_HOOK_INIT(task_getioprio, smack_task_getioprio),
4638 LSM_HOOK_INIT(task_setscheduler, smack_task_setscheduler),
4639 LSM_HOOK_INIT(task_getscheduler, smack_task_getscheduler),
4640 LSM_HOOK_INIT(task_movememory, smack_task_movememory),
4641 LSM_HOOK_INIT(task_kill, smack_task_kill),
Casey Schauflere20b0432015-05-02 15:11:36 -07004642 LSM_HOOK_INIT(task_to_inode, smack_task_to_inode),
Casey Schauflere114e472008-02-04 22:29:50 -08004643
Casey Schauflere20b0432015-05-02 15:11:36 -07004644 LSM_HOOK_INIT(ipc_permission, smack_ipc_permission),
4645 LSM_HOOK_INIT(ipc_getsecid, smack_ipc_getsecid),
Casey Schauflere114e472008-02-04 22:29:50 -08004646
Casey Schauflere20b0432015-05-02 15:11:36 -07004647 LSM_HOOK_INIT(msg_msg_alloc_security, smack_msg_msg_alloc_security),
Casey Schauflere114e472008-02-04 22:29:50 -08004648
Eric W. Biederman0d79cbf2018-03-23 23:56:19 -05004649 LSM_HOOK_INIT(msg_queue_alloc_security, smack_ipc_alloc_security),
Casey Schauflere20b0432015-05-02 15:11:36 -07004650 LSM_HOOK_INIT(msg_queue_associate, smack_msg_queue_associate),
4651 LSM_HOOK_INIT(msg_queue_msgctl, smack_msg_queue_msgctl),
4652 LSM_HOOK_INIT(msg_queue_msgsnd, smack_msg_queue_msgsnd),
4653 LSM_HOOK_INIT(msg_queue_msgrcv, smack_msg_queue_msgrcv),
Casey Schauflere114e472008-02-04 22:29:50 -08004654
Eric W. Biederman0d79cbf2018-03-23 23:56:19 -05004655 LSM_HOOK_INIT(shm_alloc_security, smack_ipc_alloc_security),
Casey Schauflere20b0432015-05-02 15:11:36 -07004656 LSM_HOOK_INIT(shm_associate, smack_shm_associate),
4657 LSM_HOOK_INIT(shm_shmctl, smack_shm_shmctl),
4658 LSM_HOOK_INIT(shm_shmat, smack_shm_shmat),
Casey Schauflere114e472008-02-04 22:29:50 -08004659
Eric W. Biederman0d79cbf2018-03-23 23:56:19 -05004660 LSM_HOOK_INIT(sem_alloc_security, smack_ipc_alloc_security),
Casey Schauflere20b0432015-05-02 15:11:36 -07004661 LSM_HOOK_INIT(sem_associate, smack_sem_associate),
4662 LSM_HOOK_INIT(sem_semctl, smack_sem_semctl),
4663 LSM_HOOK_INIT(sem_semop, smack_sem_semop),
Casey Schauflere114e472008-02-04 22:29:50 -08004664
Casey Schauflere20b0432015-05-02 15:11:36 -07004665 LSM_HOOK_INIT(d_instantiate, smack_d_instantiate),
Casey Schauflere114e472008-02-04 22:29:50 -08004666
Casey Schauflere20b0432015-05-02 15:11:36 -07004667 LSM_HOOK_INIT(getprocattr, smack_getprocattr),
4668 LSM_HOOK_INIT(setprocattr, smack_setprocattr),
Casey Schauflere114e472008-02-04 22:29:50 -08004669
Casey Schauflere20b0432015-05-02 15:11:36 -07004670 LSM_HOOK_INIT(unix_stream_connect, smack_unix_stream_connect),
4671 LSM_HOOK_INIT(unix_may_send, smack_unix_may_send),
Casey Schauflere114e472008-02-04 22:29:50 -08004672
Casey Schauflere20b0432015-05-02 15:11:36 -07004673 LSM_HOOK_INIT(socket_post_create, smack_socket_post_create),
Tom Gundersen5859cdf2018-05-04 16:28:22 +02004674 LSM_HOOK_INIT(socket_socketpair, smack_socket_socketpair),
Casey Schaufler21abb1e2015-07-22 14:25:31 -07004675#ifdef SMACK_IPV6_PORT_LABELING
Casey Schauflere20b0432015-05-02 15:11:36 -07004676 LSM_HOOK_INIT(socket_bind, smack_socket_bind),
Casey Schaufler21abb1e2015-07-22 14:25:31 -07004677#endif
Casey Schauflere20b0432015-05-02 15:11:36 -07004678 LSM_HOOK_INIT(socket_connect, smack_socket_connect),
4679 LSM_HOOK_INIT(socket_sendmsg, smack_socket_sendmsg),
4680 LSM_HOOK_INIT(socket_sock_rcv_skb, smack_socket_sock_rcv_skb),
4681 LSM_HOOK_INIT(socket_getpeersec_stream, smack_socket_getpeersec_stream),
4682 LSM_HOOK_INIT(socket_getpeersec_dgram, smack_socket_getpeersec_dgram),
4683 LSM_HOOK_INIT(sk_alloc_security, smack_sk_alloc_security),
4684 LSM_HOOK_INIT(sk_free_security, smack_sk_free_security),
4685 LSM_HOOK_INIT(sock_graft, smack_sock_graft),
4686 LSM_HOOK_INIT(inet_conn_request, smack_inet_conn_request),
4687 LSM_HOOK_INIT(inet_csk_clone, smack_inet_csk_clone),
Ahmed S. Darwishd20bdda2008-04-30 08:34:10 +10004688
Casey Schauflere114e472008-02-04 22:29:50 -08004689 /* key management security hooks */
4690#ifdef CONFIG_KEYS
Casey Schauflere20b0432015-05-02 15:11:36 -07004691 LSM_HOOK_INIT(key_alloc, smack_key_alloc),
4692 LSM_HOOK_INIT(key_free, smack_key_free),
4693 LSM_HOOK_INIT(key_permission, smack_key_permission),
4694 LSM_HOOK_INIT(key_getsecurity, smack_key_getsecurity),
Casey Schauflere114e472008-02-04 22:29:50 -08004695#endif /* CONFIG_KEYS */
Ahmed S. Darwishd20bdda2008-04-30 08:34:10 +10004696
4697 /* Audit hooks */
4698#ifdef CONFIG_AUDIT
Casey Schauflere20b0432015-05-02 15:11:36 -07004699 LSM_HOOK_INIT(audit_rule_init, smack_audit_rule_init),
4700 LSM_HOOK_INIT(audit_rule_known, smack_audit_rule_known),
4701 LSM_HOOK_INIT(audit_rule_match, smack_audit_rule_match),
Ahmed S. Darwishd20bdda2008-04-30 08:34:10 +10004702#endif /* CONFIG_AUDIT */
4703
Casey Schauflere20b0432015-05-02 15:11:36 -07004704 LSM_HOOK_INIT(ismaclabel, smack_ismaclabel),
4705 LSM_HOOK_INIT(secid_to_secctx, smack_secid_to_secctx),
4706 LSM_HOOK_INIT(secctx_to_secid, smack_secctx_to_secid),
Casey Schauflere20b0432015-05-02 15:11:36 -07004707 LSM_HOOK_INIT(inode_notifysecctx, smack_inode_notifysecctx),
4708 LSM_HOOK_INIT(inode_setsecctx, smack_inode_setsecctx),
4709 LSM_HOOK_INIT(inode_getsecctx, smack_inode_getsecctx),
Casey Schauflerd6d80cb2017-09-28 14:54:50 -07004710 LSM_HOOK_INIT(inode_copy_up, smack_inode_copy_up),
4711 LSM_HOOK_INIT(inode_copy_up_xattr, smack_inode_copy_up_xattr),
4712 LSM_HOOK_INIT(dentry_create_files_as, smack_dentry_create_files_as),
Casey Schauflere114e472008-02-04 22:29:50 -08004713};
4714
Etienne Basset7198e2e2009-03-24 20:53:24 +01004715
Casey Schaufler86812bb2012-04-17 18:55:46 -07004716static __init void init_smack_known_list(void)
Etienne Basset7198e2e2009-03-24 20:53:24 +01004717{
Casey Schaufler86812bb2012-04-17 18:55:46 -07004718 /*
Casey Schaufler86812bb2012-04-17 18:55:46 -07004719 * Initialize rule list locks
4720 */
4721 mutex_init(&smack_known_huh.smk_rules_lock);
4722 mutex_init(&smack_known_hat.smk_rules_lock);
4723 mutex_init(&smack_known_floor.smk_rules_lock);
4724 mutex_init(&smack_known_star.smk_rules_lock);
Casey Schaufler86812bb2012-04-17 18:55:46 -07004725 mutex_init(&smack_known_web.smk_rules_lock);
4726 /*
4727 * Initialize rule lists
4728 */
4729 INIT_LIST_HEAD(&smack_known_huh.smk_rules);
4730 INIT_LIST_HEAD(&smack_known_hat.smk_rules);
4731 INIT_LIST_HEAD(&smack_known_star.smk_rules);
4732 INIT_LIST_HEAD(&smack_known_floor.smk_rules);
Casey Schaufler86812bb2012-04-17 18:55:46 -07004733 INIT_LIST_HEAD(&smack_known_web.smk_rules);
4734 /*
4735 * Create the known labels list
4736 */
Tomasz Stanislawski4d7cf4a2013-06-11 14:55:13 +02004737 smk_insert_entry(&smack_known_huh);
4738 smk_insert_entry(&smack_known_hat);
4739 smk_insert_entry(&smack_known_star);
4740 smk_insert_entry(&smack_known_floor);
Tomasz Stanislawski4d7cf4a2013-06-11 14:55:13 +02004741 smk_insert_entry(&smack_known_web);
Etienne Basset7198e2e2009-03-24 20:53:24 +01004742}
4743
Casey Schauflere114e472008-02-04 22:29:50 -08004744/**
4745 * smack_init - initialize the smack system
4746 *
luanshia1a07f22019-07-05 10:35:20 +08004747 * Returns 0 on success, -ENOMEM is there's no memory
Casey Schauflere114e472008-02-04 22:29:50 -08004748 */
4749static __init int smack_init(void)
4750{
Casey Schauflerbbd36622018-11-12 09:30:56 -08004751 struct cred *cred = (struct cred *) current->cred;
Casey Schaufler676dac42010-12-02 06:43:39 -08004752 struct task_smack *tsp;
David Howellsd84f4f92008-11-14 10:39:23 +11004753
Rohit1a5b4722014-10-15 17:40:41 +05304754 smack_inode_cache = KMEM_CACHE(inode_smack, 0);
4755 if (!smack_inode_cache)
4756 return -ENOMEM;
4757
Casey Schaufler4e328b02019-04-02 11:37:12 -07004758 smack_rule_cache = KMEM_CACHE(smack_rule, 0);
4759 if (!smack_rule_cache) {
4760 kmem_cache_destroy(smack_inode_cache);
4761 return -ENOMEM;
4762 }
4763
Casey Schauflerbbd36622018-11-12 09:30:56 -08004764 /*
4765 * Set the security state for the initial task.
4766 */
4767 tsp = smack_cred(cred);
4768 init_task_smack(tsp, &smack_known_floor, &smack_known_floor);
4769
4770 /*
4771 * Register with LSM
4772 */
4773 security_add_hooks(smack_hooks, ARRAY_SIZE(smack_hooks), "smack");
José Bollod21b7b02015-10-02 15:15:56 +02004774 smack_enabled = 1;
4775
Casey Schaufler21abb1e2015-07-22 14:25:31 -07004776 pr_info("Smack: Initializing.\n");
4777#ifdef CONFIG_SECURITY_SMACK_NETFILTER
4778 pr_info("Smack: Netfilter enabled.\n");
4779#endif
4780#ifdef SMACK_IPV6_PORT_LABELING
4781 pr_info("Smack: IPv6 port labeling enabled.\n");
4782#endif
4783#ifdef SMACK_IPV6_SECMARK_LABELING
4784 pr_info("Smack: IPv6 Netfilter enabled.\n");
4785#endif
Casey Schauflere114e472008-02-04 22:29:50 -08004786
Casey Schaufler86812bb2012-04-17 18:55:46 -07004787 /* initialize the smack_known_list */
4788 init_smack_known_list();
Casey Schauflere114e472008-02-04 22:29:50 -08004789
Casey Schauflere114e472008-02-04 22:29:50 -08004790 return 0;
4791}
4792
4793/*
4794 * Smack requires early initialization in order to label
4795 * all processes and objects when they are created.
4796 */
Kees Cook3d6e5f62018-10-10 17:18:23 -07004797DEFINE_LSM(smack) = {
Kees Cook07aed2f2018-10-10 17:18:24 -07004798 .name = "smack",
Kees Cook14bd99c2018-09-19 19:57:06 -07004799 .flags = LSM_FLAG_LEGACY_MAJOR | LSM_FLAG_EXCLUSIVE,
Casey Schauflerbbd36622018-11-12 09:30:56 -08004800 .blobs = &smack_blob_sizes,
Kees Cook3d6e5f62018-10-10 17:18:23 -07004801 .init = smack_init,
4802};