blob: f695438d985c92254c6e82ca1489627e4d03bb34 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * NSA Security-Enhanced Linux (SELinux) security module
3 *
4 * This file contains the SELinux hook function implementations.
5 *
Stephen Smalley7efbb602017-08-17 13:32:36 -04006 * Authors: Stephen Smalley, <sds@tycho.nsa.gov>
Eric Paris828dfe12008-04-17 13:17:49 -04007 * Chris Vance, <cvance@nai.com>
8 * Wayne Salamon, <wsalamon@nai.com>
9 * James Morris <jmorris@redhat.com>
Linus Torvalds1da177e2005-04-16 15:20:36 -070010 *
11 * Copyright (C) 2001,2002 Networks Associates Technology, Inc.
Eric Paris2069f452008-07-04 09:47:13 +100012 * Copyright (C) 2003-2008 Red Hat, Inc., James Morris <jmorris@redhat.com>
13 * Eric Paris <eparis@redhat.com>
Linus Torvalds1da177e2005-04-16 15:20:36 -070014 * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc.
Eric Paris828dfe12008-04-17 13:17:49 -040015 * <dgoeddel@trustedcs.com>
Paul Mooreed6d76e2009-08-28 18:12:49 -040016 * Copyright (C) 2006, 2007, 2009 Hewlett-Packard Development Company, L.P.
Paul Moore82c21bf2011-08-01 11:10:33 +000017 * Paul Moore <paul@paul-moore.com>
Yuichi Nakamura788e7dd2007-09-14 09:27:07 +090018 * Copyright (C) 2007 Hitachi Software Engineering Co., Ltd.
Eric Paris828dfe12008-04-17 13:17:49 -040019 * Yuichi Nakamura <ynakam@hitachisoft.jp>
Daniel Jurgens3a976fa2017-05-19 15:48:56 +030020 * Copyright (C) 2016 Mellanox Technologies
Linus Torvalds1da177e2005-04-16 15:20:36 -070021 *
22 * This program is free software; you can redistribute it and/or modify
23 * it under the terms of the GNU General Public License version 2,
Eric Paris828dfe12008-04-17 13:17:49 -040024 * as published by the Free Software Foundation.
Linus Torvalds1da177e2005-04-16 15:20:36 -070025 */
26
Linus Torvalds1da177e2005-04-16 15:20:36 -070027#include <linux/init.h>
Eric Paris0b24dcb2011-02-25 15:39:20 -050028#include <linux/kd.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070029#include <linux/kernel.h>
Roland McGrath0d094ef2008-07-25 19:45:49 -070030#include <linux/tracehook.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070031#include <linux/errno.h>
Ingo Molnar3f07c012017-02-08 18:51:30 +010032#include <linux/sched/signal.h>
Ingo Molnar29930022017-02-08 18:51:36 +010033#include <linux/sched/task.h>
Casey Schaufler3c4ed7b2015-05-02 15:10:46 -070034#include <linux/lsm_hooks.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070035#include <linux/xattr.h>
36#include <linux/capability.h>
37#include <linux/unistd.h>
38#include <linux/mm.h>
39#include <linux/mman.h>
40#include <linux/slab.h>
41#include <linux/pagemap.h>
Eric Paris0b24dcb2011-02-25 15:39:20 -050042#include <linux/proc_fs.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070043#include <linux/swap.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070044#include <linux/spinlock.h>
45#include <linux/syscalls.h>
Eric Paris2a7dba32011-02-01 11:05:39 -050046#include <linux/dcache.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070047#include <linux/file.h>
Al Viro9f3acc32008-04-24 07:44:08 -040048#include <linux/fdtable.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070049#include <linux/namei.h>
50#include <linux/mount.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070051#include <linux/netfilter_ipv4.h>
52#include <linux/netfilter_ipv6.h>
53#include <linux/tty.h>
54#include <net/icmp.h>
Stephen Hemminger227b60f2007-10-10 17:30:46 -070055#include <net/ip.h> /* for local_port_range[] */
Linus Torvalds1da177e2005-04-16 15:20:36 -070056#include <net/tcp.h> /* struct or_callable used in sock_rcv_skb */
Paul Moore47180062013-12-04 16:10:45 -050057#include <net/inet_connection_sock.h>
Paul Moore220deb92008-01-29 08:38:23 -050058#include <net/net_namespace.h>
Paul Moored621d352008-01-29 08:43:36 -050059#include <net/netlabel.h>
Eric Parisf5269712008-05-14 11:27:45 -040060#include <linux/uaccess.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070061#include <asm/ioctls.h>
Arun Sharma600634972011-07-26 16:09:06 -070062#include <linux/atomic.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070063#include <linux/bitops.h>
64#include <linux/interrupt.h>
65#include <linux/netdevice.h> /* for network interface checks */
Hong zhi guo77954982013-03-27 06:49:35 +000066#include <net/netlink.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070067#include <linux/tcp.h>
68#include <linux/udp.h>
James Morris2ee92d42006-11-13 16:09:01 -080069#include <linux/dccp.h>
Richard Hainesd4529302018-02-13 20:57:18 +000070#include <linux/sctp.h>
71#include <net/sctp/structs.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070072#include <linux/quota.h>
73#include <linux/un.h> /* for Unix socket types */
74#include <net/af_unix.h> /* for Unix socket types */
75#include <linux/parser.h>
76#include <linux/nfs_mount.h>
77#include <net/ipv6.h>
78#include <linux/hugetlb.h>
79#include <linux/personality.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070080#include <linux/audit.h>
Eric Paris6931dfc2005-06-30 02:58:51 -070081#include <linux/string.h>
Catherine Zhang877ce7c2006-06-29 12:27:47 -070082#include <linux/selinux.h>
Eric Paris23970742006-09-25 23:32:01 -070083#include <linux/mutex.h>
Frank Mayharf06febc2008-09-12 09:54:39 -070084#include <linux/posix-timers.h>
Kees Cook00234592010-02-03 15:36:43 -080085#include <linux/syslog.h>
Serge E. Hallyn34867402011-03-23 16:43:17 -070086#include <linux/user_namespace.h>
Paul Gortmaker44fc7ea2011-05-26 20:52:10 -040087#include <linux/export.h>
Al Viro40401532012-02-13 03:58:52 +000088#include <linux/msg.h>
89#include <linux/shm.h>
Chenbo Fengec27c352017-10-18 13:00:25 -070090#include <linux/bpf.h>
David Howellse262e32d2018-11-01 23:07:23 +000091#include <uapi/linux/mount.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070092
93#include "avc.h"
94#include "objsec.h"
95#include "netif.h"
Paul Moore224dfbd2008-01-29 08:38:13 -050096#include "netnode.h"
Paul Moore3e112172008-04-10 10:48:14 -040097#include "netport.h"
Daniel Jurgens409dcf32017-05-19 15:48:59 +030098#include "ibpkey.h"
Trent Jaegerd28d1e02005-12-13 23:12:40 -080099#include "xfrm.h"
Paul Moorec60475b2007-02-28 15:14:23 -0500100#include "netlabel.h"
Ahmed S. Darwish9d57a7f2008-03-01 22:03:14 +0200101#include "audit.h"
James Morris7b98a582011-08-30 12:52:32 +1000102#include "avc_ss.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -0700103
Stephen Smalleyaa8e7122018-03-01 18:48:02 -0500104struct selinux_state selinux_state;
105
Paul Moored621d352008-01-29 08:43:36 -0500106/* SECMARK reference count */
James Morris56a4ca92011-08-17 11:08:43 +1000107static atomic_t selinux_secmark_refcount = ATOMIC_INIT(0);
Paul Moored621d352008-01-29 08:43:36 -0500108
Linus Torvalds1da177e2005-04-16 15:20:36 -0700109#ifdef CONFIG_SECURITY_SELINUX_DEVELOP
Stephen Smalleyaa8e7122018-03-01 18:48:02 -0500110static int selinux_enforcing_boot;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700111
112static int __init enforcing_setup(char *str)
113{
Eric Parisf5269712008-05-14 11:27:45 -0400114 unsigned long enforcing;
Jingoo Han29707b22014-02-05 15:13:14 +0900115 if (!kstrtoul(str, 0, &enforcing))
Stephen Smalleyaa8e7122018-03-01 18:48:02 -0500116 selinux_enforcing_boot = enforcing ? 1 : 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700117 return 1;
118}
119__setup("enforcing=", enforcing_setup);
Stephen Smalleyaa8e7122018-03-01 18:48:02 -0500120#else
121#define selinux_enforcing_boot 1
Linus Torvalds1da177e2005-04-16 15:20:36 -0700122#endif
123
124#ifdef CONFIG_SECURITY_SELINUX_BOOTPARAM
125int selinux_enabled = CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE;
126
127static int __init selinux_enabled_setup(char *str)
128{
Eric Parisf5269712008-05-14 11:27:45 -0400129 unsigned long enabled;
Jingoo Han29707b22014-02-05 15:13:14 +0900130 if (!kstrtoul(str, 0, &enabled))
Eric Parisf5269712008-05-14 11:27:45 -0400131 selinux_enabled = enabled ? 1 : 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700132 return 1;
133}
134__setup("selinux=", selinux_enabled_setup);
Stephen Smalley30d55282006-05-03 10:52:36 -0400135#else
136int selinux_enabled = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700137#endif
138
Stephen Smalleyaa8e7122018-03-01 18:48:02 -0500139static unsigned int selinux_checkreqprot_boot =
140 CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE;
141
142static int __init checkreqprot_setup(char *str)
143{
144 unsigned long checkreqprot;
145
146 if (!kstrtoul(str, 0, &checkreqprot))
147 selinux_checkreqprot_boot = checkreqprot ? 1 : 0;
148 return 1;
149}
150__setup("checkreqprot=", checkreqprot_setup);
151
Christoph Lametere18b8902006-12-06 20:33:20 -0800152static struct kmem_cache *sel_inode_cache;
Sangwoo63205652015-10-21 17:44:30 -0400153static struct kmem_cache *file_security_cache;
James Morris7cae7e22006-03-22 00:09:22 -0800154
Paul Moored621d352008-01-29 08:43:36 -0500155/**
156 * selinux_secmark_enabled - Check to see if SECMARK is currently enabled
157 *
158 * Description:
159 * This function checks the SECMARK reference counter to see if any SECMARK
160 * targets are currently configured, if the reference counter is greater than
161 * zero SECMARK is considered to be enabled. Returns true (1) if SECMARK is
Chris PeBenito2be4d742013-05-03 09:05:39 -0400162 * enabled, false (0) if SECMARK is disabled. If the always_check_network
163 * policy capability is enabled, SECMARK is always considered enabled.
Paul Moored621d352008-01-29 08:43:36 -0500164 *
165 */
166static int selinux_secmark_enabled(void)
167{
Stephen Smalleyaa8e7122018-03-01 18:48:02 -0500168 return (selinux_policycap_alwaysnetwork() ||
169 atomic_read(&selinux_secmark_refcount));
Chris PeBenito2be4d742013-05-03 09:05:39 -0400170}
171
172/**
173 * selinux_peerlbl_enabled - Check to see if peer labeling is currently enabled
174 *
175 * Description:
176 * This function checks if NetLabel or labeled IPSEC is enabled. Returns true
177 * (1) if any are enabled or false (0) if neither are enabled. If the
178 * always_check_network policy capability is enabled, peer labeling
179 * is always considered enabled.
180 *
181 */
182static int selinux_peerlbl_enabled(void)
183{
Stephen Smalleyaa8e7122018-03-01 18:48:02 -0500184 return (selinux_policycap_alwaysnetwork() ||
185 netlbl_enabled() || selinux_xfrm_enabled());
Paul Moored621d352008-01-29 08:43:36 -0500186}
187
Paul Moore615e51f2014-06-26 14:33:56 -0400188static int selinux_netcache_avc_callback(u32 event)
189{
190 if (event == AVC_CALLBACK_RESET) {
191 sel_netif_flush();
192 sel_netnode_flush();
193 sel_netport_flush();
194 synchronize_net();
195 }
196 return 0;
197}
198
Daniel Jurgens8f408ab2017-05-19 15:48:53 +0300199static int selinux_lsm_notifier_avc_callback(u32 event)
200{
Daniel Jurgens409dcf32017-05-19 15:48:59 +0300201 if (event == AVC_CALLBACK_RESET) {
202 sel_ib_pkey_flush();
Daniel Jurgens8f408ab2017-05-19 15:48:53 +0300203 call_lsm_notifier(LSM_POLICY_CHANGE, NULL);
Daniel Jurgens409dcf32017-05-19 15:48:59 +0300204 }
Daniel Jurgens8f408ab2017-05-19 15:48:53 +0300205
206 return 0;
207}
208
David Howellsd84f4f92008-11-14 10:39:23 +1100209/*
210 * initialise the security for the init task
211 */
212static void cred_init_security(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700213{
David Howells3b11a1d2008-11-14 10:39:26 +1100214 struct cred *cred = (struct cred *) current->real_cred;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700215 struct task_security_struct *tsec;
216
James Morris89d155e2005-10-30 14:59:21 -0800217 tsec = kzalloc(sizeof(struct task_security_struct), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700218 if (!tsec)
David Howellsd84f4f92008-11-14 10:39:23 +1100219 panic("SELinux: Failed to initialize initial task.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700220
David Howellsd84f4f92008-11-14 10:39:23 +1100221 tsec->osid = tsec->sid = SECINITSID_KERNEL;
David Howellsf1752ee2008-11-14 10:39:17 +1100222 cred->security = tsec;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700223}
224
David Howells275bb412008-11-14 10:39:19 +1100225/*
David Howells88e67f32008-11-14 10:39:21 +1100226 * get the security ID of a set of credentials
227 */
228static inline u32 cred_sid(const struct cred *cred)
229{
230 const struct task_security_struct *tsec;
231
232 tsec = cred->security;
233 return tsec->sid;
234}
235
236/*
David Howells3b11a1d2008-11-14 10:39:26 +1100237 * get the objective security ID of a task
David Howells275bb412008-11-14 10:39:19 +1100238 */
239static inline u32 task_sid(const struct task_struct *task)
240{
David Howells275bb412008-11-14 10:39:19 +1100241 u32 sid;
242
243 rcu_read_lock();
David Howells88e67f32008-11-14 10:39:21 +1100244 sid = cred_sid(__task_cred(task));
David Howells275bb412008-11-14 10:39:19 +1100245 rcu_read_unlock();
246 return sid;
247}
248
David Howells88e67f32008-11-14 10:39:21 +1100249/* Allocate and free functions for each kind of security blob. */
250
Linus Torvalds1da177e2005-04-16 15:20:36 -0700251static int inode_alloc_security(struct inode *inode)
252{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700253 struct inode_security_struct *isec;
David Howells275bb412008-11-14 10:39:19 +1100254 u32 sid = current_sid();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700255
Josef Bacika02fe132008-04-04 09:35:05 +1100256 isec = kmem_cache_zalloc(sel_inode_cache, GFP_NOFS);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700257 if (!isec)
258 return -ENOMEM;
259
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +0100260 spin_lock_init(&isec->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700261 INIT_LIST_HEAD(&isec->list);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700262 isec->inode = inode;
263 isec->sid = SECINITSID_UNLABELED;
264 isec->sclass = SECCLASS_FILE;
David Howells275bb412008-11-14 10:39:19 +1100265 isec->task_sid = sid;
Andreas Gruenbacher42059112016-11-10 22:18:27 +0100266 isec->initialized = LABEL_INVALID;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700267 inode->i_security = isec;
268
269 return 0;
270}
271
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -0500272static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dentry);
273
274/*
275 * Try reloading inode security labels that have been marked as invalid. The
276 * @may_sleep parameter indicates when sleeping and thus reloading labels is
Andreas Gruenbacher42059112016-11-10 22:18:27 +0100277 * allowed; when set to false, returns -ECHILD when the label is
Al Viroe9193282018-04-24 21:31:02 -0400278 * invalid. The @dentry parameter should be set to a dentry of the inode.
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -0500279 */
280static int __inode_security_revalidate(struct inode *inode,
Al Viroe9193282018-04-24 21:31:02 -0400281 struct dentry *dentry,
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -0500282 bool may_sleep)
283{
284 struct inode_security_struct *isec = inode->i_security;
285
286 might_sleep_if(may_sleep);
287
Stephen Smalleyaa8e7122018-03-01 18:48:02 -0500288 if (selinux_state.initialized &&
289 isec->initialized != LABEL_INITIALIZED) {
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -0500290 if (!may_sleep)
291 return -ECHILD;
292
293 /*
294 * Try reloading the inode security label. This will fail if
295 * @opt_dentry is NULL and no dentry for this inode can be
296 * found; in that case, continue using the old label.
297 */
Al Viroe9193282018-04-24 21:31:02 -0400298 inode_doinit_with_dentry(inode, dentry);
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -0500299 }
300 return 0;
301}
302
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -0500303static struct inode_security_struct *inode_security_novalidate(struct inode *inode)
304{
305 return inode->i_security;
306}
307
308static struct inode_security_struct *inode_security_rcu(struct inode *inode, bool rcu)
309{
310 int error;
311
312 error = __inode_security_revalidate(inode, NULL, !rcu);
313 if (error)
314 return ERR_PTR(error);
315 return inode->i_security;
316}
317
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -0500318/*
319 * Get the security label of an inode.
320 */
321static struct inode_security_struct *inode_security(struct inode *inode)
322{
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -0500323 __inode_security_revalidate(inode, NULL, true);
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -0500324 return inode->i_security;
325}
326
Paul Moore2c971652016-04-19 16:36:28 -0400327static struct inode_security_struct *backing_inode_security_novalidate(struct dentry *dentry)
328{
329 struct inode *inode = d_backing_inode(dentry);
330
331 return inode->i_security;
332}
333
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -0500334/*
335 * Get the security label of a dentry's backing inode.
336 */
337static struct inode_security_struct *backing_inode_security(struct dentry *dentry)
338{
339 struct inode *inode = d_backing_inode(dentry);
340
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -0500341 __inode_security_revalidate(inode, dentry, true);
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -0500342 return inode->i_security;
343}
344
Steven Rostedt3dc91d42014-01-09 21:46:34 -0500345static void inode_free_rcu(struct rcu_head *head)
346{
347 struct inode_security_struct *isec;
348
349 isec = container_of(head, struct inode_security_struct, rcu);
350 kmem_cache_free(sel_inode_cache, isec);
351}
352
Linus Torvalds1da177e2005-04-16 15:20:36 -0700353static void inode_free_security(struct inode *inode)
354{
355 struct inode_security_struct *isec = inode->i_security;
356 struct superblock_security_struct *sbsec = inode->i_sb->s_security;
357
Waiman Long9629d042015-07-10 17:19:56 -0400358 /*
359 * As not all inode security structures are in a list, we check for
360 * empty list outside of the lock to make sure that we won't waste
361 * time taking a lock doing nothing.
362 *
363 * The list_del_init() function can be safely called more than once.
364 * It should not be possible for this function to be called with
365 * concurrent list_add(), but for better safety against future changes
366 * in the code, we use list_empty_careful() here.
367 */
368 if (!list_empty_careful(&isec->list)) {
369 spin_lock(&sbsec->isec_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700370 list_del_init(&isec->list);
Waiman Long9629d042015-07-10 17:19:56 -0400371 spin_unlock(&sbsec->isec_lock);
372 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700373
Steven Rostedt3dc91d42014-01-09 21:46:34 -0500374 /*
375 * The inode may still be referenced in a path walk and
376 * a call to selinux_inode_permission() can be made
377 * after inode_free_security() is called. Ideally, the VFS
378 * wouldn't do this, but fixing that is a much harder
379 * job. For now, simply free the i_security via RCU, and
380 * leave the current inode->i_security pointer intact.
381 * The inode will be freed after the RCU grace period too.
382 */
383 call_rcu(&isec->rcu, inode_free_rcu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700384}
385
386static int file_alloc_security(struct file *file)
387{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700388 struct file_security_struct *fsec;
David Howells275bb412008-11-14 10:39:19 +1100389 u32 sid = current_sid();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700390
Sangwoo63205652015-10-21 17:44:30 -0400391 fsec = kmem_cache_zalloc(file_security_cache, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700392 if (!fsec)
393 return -ENOMEM;
394
David Howells275bb412008-11-14 10:39:19 +1100395 fsec->sid = sid;
396 fsec->fown_sid = sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700397 file->f_security = fsec;
398
399 return 0;
400}
401
402static void file_free_security(struct file *file)
403{
404 struct file_security_struct *fsec = file->f_security;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700405 file->f_security = NULL;
Sangwoo63205652015-10-21 17:44:30 -0400406 kmem_cache_free(file_security_cache, fsec);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700407}
408
409static int superblock_alloc_security(struct super_block *sb)
410{
411 struct superblock_security_struct *sbsec;
412
James Morris89d155e2005-10-30 14:59:21 -0800413 sbsec = kzalloc(sizeof(struct superblock_security_struct), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700414 if (!sbsec)
415 return -ENOMEM;
416
Eric Parisbc7e9822006-09-25 23:32:02 -0700417 mutex_init(&sbsec->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700418 INIT_LIST_HEAD(&sbsec->isec_head);
419 spin_lock_init(&sbsec->isec_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700420 sbsec->sb = sb;
421 sbsec->sid = SECINITSID_UNLABELED;
422 sbsec->def_sid = SECINITSID_FILE;
Eric Parisc312feb2006-07-10 04:43:53 -0700423 sbsec->mntpoint_sid = SECINITSID_UNLABELED;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700424 sb->s_security = sbsec;
425
426 return 0;
427}
428
429static void superblock_free_security(struct super_block *sb)
430{
431 struct superblock_security_struct *sbsec = sb->s_security;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700432 sb->s_security = NULL;
433 kfree(sbsec);
434}
435
Linus Torvalds1da177e2005-04-16 15:20:36 -0700436static inline int inode_doinit(struct inode *inode)
437{
438 return inode_doinit_with_dentry(inode, NULL);
439}
440
441enum {
Eric Paris31e87932007-09-19 17:19:12 -0400442 Opt_error = -1,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700443 Opt_context = 1,
444 Opt_fscontext = 2,
Eric Parisc9180a52007-11-30 13:00:35 -0500445 Opt_defcontext = 3,
446 Opt_rootcontext = 4,
David P. Quigley11689d42009-01-16 09:22:03 -0500447 Opt_labelsupport = 5,
Eric Parisd355987f2012-08-24 15:58:53 -0400448 Opt_nextmntopt = 6,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700449};
450
Eric Parisd355987f2012-08-24 15:58:53 -0400451#define NUM_SEL_MNT_OPTS (Opt_nextmntopt - 1)
452
Steven Whitehousea447c092008-10-13 10:46:57 +0100453static const match_table_t tokens = {
Eric Paris832cbd92008-04-01 13:24:09 -0400454 {Opt_context, CONTEXT_STR "%s"},
455 {Opt_fscontext, FSCONTEXT_STR "%s"},
456 {Opt_defcontext, DEFCONTEXT_STR "%s"},
457 {Opt_rootcontext, ROOTCONTEXT_STR "%s"},
David P. Quigley11689d42009-01-16 09:22:03 -0500458 {Opt_labelsupport, LABELSUPP_STR},
Eric Paris31e87932007-09-19 17:19:12 -0400459 {Opt_error, NULL},
Linus Torvalds1da177e2005-04-16 15:20:36 -0700460};
461
462#define SEL_MOUNT_FAIL_MSG "SELinux: duplicate or incompatible mount options\n"
463
Eric Parisc312feb2006-07-10 04:43:53 -0700464static int may_context_mount_sb_relabel(u32 sid,
465 struct superblock_security_struct *sbsec,
David Howells275bb412008-11-14 10:39:19 +1100466 const struct cred *cred)
Eric Parisc312feb2006-07-10 04:43:53 -0700467{
David Howells275bb412008-11-14 10:39:19 +1100468 const struct task_security_struct *tsec = cred->security;
Eric Parisc312feb2006-07-10 04:43:53 -0700469 int rc;
470
Stephen Smalley6b6bc622018-03-05 11:47:56 -0500471 rc = avc_has_perm(&selinux_state,
472 tsec->sid, sbsec->sid, SECCLASS_FILESYSTEM,
Eric Parisc312feb2006-07-10 04:43:53 -0700473 FILESYSTEM__RELABELFROM, NULL);
474 if (rc)
475 return rc;
476
Stephen Smalley6b6bc622018-03-05 11:47:56 -0500477 rc = avc_has_perm(&selinux_state,
478 tsec->sid, sid, SECCLASS_FILESYSTEM,
Eric Parisc312feb2006-07-10 04:43:53 -0700479 FILESYSTEM__RELABELTO, NULL);
480 return rc;
481}
482
Eric Paris08089252006-07-10 04:43:55 -0700483static int may_context_mount_inode_relabel(u32 sid,
484 struct superblock_security_struct *sbsec,
David Howells275bb412008-11-14 10:39:19 +1100485 const struct cred *cred)
Eric Paris08089252006-07-10 04:43:55 -0700486{
David Howells275bb412008-11-14 10:39:19 +1100487 const struct task_security_struct *tsec = cred->security;
Eric Paris08089252006-07-10 04:43:55 -0700488 int rc;
Stephen Smalley6b6bc622018-03-05 11:47:56 -0500489 rc = avc_has_perm(&selinux_state,
490 tsec->sid, sbsec->sid, SECCLASS_FILESYSTEM,
Eric Paris08089252006-07-10 04:43:55 -0700491 FILESYSTEM__RELABELFROM, NULL);
492 if (rc)
493 return rc;
494
Stephen Smalley6b6bc622018-03-05 11:47:56 -0500495 rc = avc_has_perm(&selinux_state,
496 sid, sbsec->sid, SECCLASS_FILESYSTEM,
Eric Paris08089252006-07-10 04:43:55 -0700497 FILESYSTEM__ASSOCIATE, NULL);
498 return rc;
499}
500
Eric Parisb43e7252012-10-10 14:27:35 -0400501static int selinux_is_sblabel_mnt(struct super_block *sb)
502{
503 struct superblock_security_struct *sbsec = sb->s_security;
504
Mark Salyzynd5f3a5f2015-02-04 11:34:30 -0500505 return sbsec->behavior == SECURITY_FS_USE_XATTR ||
506 sbsec->behavior == SECURITY_FS_USE_TRANS ||
507 sbsec->behavior == SECURITY_FS_USE_TASK ||
J. Bruce Fields9fc2b4b2015-06-04 15:57:25 -0400508 sbsec->behavior == SECURITY_FS_USE_NATIVE ||
Mark Salyzynd5f3a5f2015-02-04 11:34:30 -0500509 /* Special handling. Genfs but also in-core setxattr handler */
510 !strcmp(sb->s_type->name, "sysfs") ||
511 !strcmp(sb->s_type->name, "pstore") ||
512 !strcmp(sb->s_type->name, "debugfs") ||
Yongqin Liua2c7c6f2017-01-09 10:07:30 -0500513 !strcmp(sb->s_type->name, "tracefs") ||
Stephen Smalley2651225b2017-02-28 10:35:56 -0500514 !strcmp(sb->s_type->name, "rootfs") ||
Stephen Smalleyaa8e7122018-03-01 18:48:02 -0500515 (selinux_policycap_cgroupseclabel() &&
Stephen Smalley2651225b2017-02-28 10:35:56 -0500516 (!strcmp(sb->s_type->name, "cgroup") ||
517 !strcmp(sb->s_type->name, "cgroup2")));
Eric Parisb43e7252012-10-10 14:27:35 -0400518}
519
Eric Parisc9180a52007-11-30 13:00:35 -0500520static int sb_finish_set_opts(struct super_block *sb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700521{
522 struct superblock_security_struct *sbsec = sb->s_security;
523 struct dentry *root = sb->s_root;
David Howellsc6f493d2015-03-17 22:26:22 +0000524 struct inode *root_inode = d_backing_inode(root);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700525 int rc = 0;
526
Linus Torvalds1da177e2005-04-16 15:20:36 -0700527 if (sbsec->behavior == SECURITY_FS_USE_XATTR) {
528 /* Make sure that the xattr handler exists and that no
529 error other than -ENODATA is returned by getxattr on
530 the root directory. -ENODATA is ok, as this may be
531 the first boot of the SELinux kernel before we have
532 assigned xattr values to the filesystem. */
Andreas Gruenbacher5d6c3192016-09-29 17:48:42 +0200533 if (!(root_inode->i_opflags & IOP_XATTR)) {
peter enderborgc103a912018-06-12 10:09:03 +0200534 pr_warn("SELinux: (dev %s, type %s) has no "
Linus Torvalds29b1deb2013-12-15 11:17:45 -0800535 "xattr support\n", sb->s_id, sb->s_type->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700536 rc = -EOPNOTSUPP;
537 goto out;
538 }
Andreas Gruenbacher5d6c3192016-09-29 17:48:42 +0200539
540 rc = __vfs_getxattr(root, root_inode, XATTR_NAME_SELINUX, NULL, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700541 if (rc < 0 && rc != -ENODATA) {
542 if (rc == -EOPNOTSUPP)
peter enderborgc103a912018-06-12 10:09:03 +0200543 pr_warn("SELinux: (dev %s, type "
Linus Torvalds29b1deb2013-12-15 11:17:45 -0800544 "%s) has no security xattr handler\n",
545 sb->s_id, sb->s_type->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700546 else
peter enderborgc103a912018-06-12 10:09:03 +0200547 pr_warn("SELinux: (dev %s, type "
Linus Torvalds29b1deb2013-12-15 11:17:45 -0800548 "%s) getxattr errno %d\n", sb->s_id,
549 sb->s_type->name, -rc);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700550 goto out;
551 }
552 }
553
Eric Pariseadcabc2012-08-24 15:59:14 -0400554 sbsec->flags |= SE_SBINITIALIZED;
Scott Mayhew0b4d3452017-06-05 11:45:04 -0400555
556 /*
557 * Explicitly set or clear SBLABEL_MNT. It's not sufficient to simply
558 * leave the flag untouched because sb_clone_mnt_opts might be handing
559 * us a superblock that needs the flag to be cleared.
560 */
Eric Parisb43e7252012-10-10 14:27:35 -0400561 if (selinux_is_sblabel_mnt(sb))
Eric Paris12f348b2012-10-09 10:56:25 -0400562 sbsec->flags |= SBLABEL_MNT;
Scott Mayhew0b4d3452017-06-05 11:45:04 -0400563 else
564 sbsec->flags &= ~SBLABEL_MNT;
David P. Quigleyddd29ec2009-09-09 14:25:37 -0400565
Linus Torvalds1da177e2005-04-16 15:20:36 -0700566 /* Initialize the root inode. */
Eric Parisc9180a52007-11-30 13:00:35 -0500567 rc = inode_doinit_with_dentry(root_inode, root);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700568
569 /* Initialize any other inodes associated with the superblock, e.g.
570 inodes created prior to initial policy load or inodes created
571 during get_sb by a pseudo filesystem that directly
572 populates itself. */
573 spin_lock(&sbsec->isec_lock);
574next_inode:
575 if (!list_empty(&sbsec->isec_head)) {
576 struct inode_security_struct *isec =
577 list_entry(sbsec->isec_head.next,
Eric Parisc9180a52007-11-30 13:00:35 -0500578 struct inode_security_struct, list);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700579 struct inode *inode = isec->inode;
Stephen Smalley923190d2014-10-06 16:32:52 -0400580 list_del_init(&isec->list);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700581 spin_unlock(&sbsec->isec_lock);
582 inode = igrab(inode);
583 if (inode) {
Eric Parisc9180a52007-11-30 13:00:35 -0500584 if (!IS_PRIVATE(inode))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700585 inode_doinit(inode);
586 iput(inode);
587 }
588 spin_lock(&sbsec->isec_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700589 goto next_inode;
590 }
591 spin_unlock(&sbsec->isec_lock);
592out:
Eric Parisc9180a52007-11-30 13:00:35 -0500593 return rc;
594}
595
596/*
597 * This function should allow an FS to ask what it's mount security
598 * options were so it can use those later for submounts, displaying
599 * mount options, or whatever.
600 */
601static int selinux_get_mnt_opts(const struct super_block *sb,
Eric Parise0007522008-03-05 10:31:54 -0500602 struct security_mnt_opts *opts)
Eric Parisc9180a52007-11-30 13:00:35 -0500603{
604 int rc = 0, i;
605 struct superblock_security_struct *sbsec = sb->s_security;
606 char *context = NULL;
607 u32 len;
608 char tmp;
609
Eric Parise0007522008-03-05 10:31:54 -0500610 security_init_mnt_opts(opts);
Eric Parisc9180a52007-11-30 13:00:35 -0500611
David P. Quigley0d90a7e2009-01-16 09:22:02 -0500612 if (!(sbsec->flags & SE_SBINITIALIZED))
Eric Parisc9180a52007-11-30 13:00:35 -0500613 return -EINVAL;
614
Stephen Smalleyaa8e7122018-03-01 18:48:02 -0500615 if (!selinux_state.initialized)
Eric Parisc9180a52007-11-30 13:00:35 -0500616 return -EINVAL;
617
Eric Parisaf8e50c2012-08-24 15:59:00 -0400618 /* make sure we always check enough bits to cover the mask */
619 BUILD_BUG_ON(SE_MNTMASK >= (1 << NUM_SEL_MNT_OPTS));
620
David P. Quigley0d90a7e2009-01-16 09:22:02 -0500621 tmp = sbsec->flags & SE_MNTMASK;
Eric Parisc9180a52007-11-30 13:00:35 -0500622 /* count the number of mount options for this sb */
Eric Parisaf8e50c2012-08-24 15:59:00 -0400623 for (i = 0; i < NUM_SEL_MNT_OPTS; i++) {
Eric Parisc9180a52007-11-30 13:00:35 -0500624 if (tmp & 0x01)
Eric Parise0007522008-03-05 10:31:54 -0500625 opts->num_mnt_opts++;
Eric Parisc9180a52007-11-30 13:00:35 -0500626 tmp >>= 1;
627 }
David P. Quigley11689d42009-01-16 09:22:03 -0500628 /* Check if the Label support flag is set */
Eric Paris0b4bdb32013-08-28 13:32:42 -0400629 if (sbsec->flags & SBLABEL_MNT)
David P. Quigley11689d42009-01-16 09:22:03 -0500630 opts->num_mnt_opts++;
Eric Parisc9180a52007-11-30 13:00:35 -0500631
Eric Parise0007522008-03-05 10:31:54 -0500632 opts->mnt_opts = kcalloc(opts->num_mnt_opts, sizeof(char *), GFP_ATOMIC);
633 if (!opts->mnt_opts) {
Eric Parisc9180a52007-11-30 13:00:35 -0500634 rc = -ENOMEM;
635 goto out_free;
636 }
637
Eric Parise0007522008-03-05 10:31:54 -0500638 opts->mnt_opts_flags = kcalloc(opts->num_mnt_opts, sizeof(int), GFP_ATOMIC);
639 if (!opts->mnt_opts_flags) {
Eric Parisc9180a52007-11-30 13:00:35 -0500640 rc = -ENOMEM;
641 goto out_free;
642 }
643
644 i = 0;
645 if (sbsec->flags & FSCONTEXT_MNT) {
Stephen Smalleyaa8e7122018-03-01 18:48:02 -0500646 rc = security_sid_to_context(&selinux_state, sbsec->sid,
647 &context, &len);
Eric Parisc9180a52007-11-30 13:00:35 -0500648 if (rc)
649 goto out_free;
Eric Parise0007522008-03-05 10:31:54 -0500650 opts->mnt_opts[i] = context;
651 opts->mnt_opts_flags[i++] = FSCONTEXT_MNT;
Eric Parisc9180a52007-11-30 13:00:35 -0500652 }
653 if (sbsec->flags & CONTEXT_MNT) {
Stephen Smalleyaa8e7122018-03-01 18:48:02 -0500654 rc = security_sid_to_context(&selinux_state,
655 sbsec->mntpoint_sid,
656 &context, &len);
Eric Parisc9180a52007-11-30 13:00:35 -0500657 if (rc)
658 goto out_free;
Eric Parise0007522008-03-05 10:31:54 -0500659 opts->mnt_opts[i] = context;
660 opts->mnt_opts_flags[i++] = CONTEXT_MNT;
Eric Parisc9180a52007-11-30 13:00:35 -0500661 }
662 if (sbsec->flags & DEFCONTEXT_MNT) {
Stephen Smalleyaa8e7122018-03-01 18:48:02 -0500663 rc = security_sid_to_context(&selinux_state, sbsec->def_sid,
664 &context, &len);
Eric Parisc9180a52007-11-30 13:00:35 -0500665 if (rc)
666 goto out_free;
Eric Parise0007522008-03-05 10:31:54 -0500667 opts->mnt_opts[i] = context;
668 opts->mnt_opts_flags[i++] = DEFCONTEXT_MNT;
Eric Parisc9180a52007-11-30 13:00:35 -0500669 }
670 if (sbsec->flags & ROOTCONTEXT_MNT) {
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -0500671 struct dentry *root = sbsec->sb->s_root;
672 struct inode_security_struct *isec = backing_inode_security(root);
Eric Parisc9180a52007-11-30 13:00:35 -0500673
Stephen Smalleyaa8e7122018-03-01 18:48:02 -0500674 rc = security_sid_to_context(&selinux_state, isec->sid,
675 &context, &len);
Eric Parisc9180a52007-11-30 13:00:35 -0500676 if (rc)
677 goto out_free;
Eric Parise0007522008-03-05 10:31:54 -0500678 opts->mnt_opts[i] = context;
679 opts->mnt_opts_flags[i++] = ROOTCONTEXT_MNT;
Eric Parisc9180a52007-11-30 13:00:35 -0500680 }
Eric Paris12f348b2012-10-09 10:56:25 -0400681 if (sbsec->flags & SBLABEL_MNT) {
David P. Quigley11689d42009-01-16 09:22:03 -0500682 opts->mnt_opts[i] = NULL;
Eric Paris12f348b2012-10-09 10:56:25 -0400683 opts->mnt_opts_flags[i++] = SBLABEL_MNT;
David P. Quigley11689d42009-01-16 09:22:03 -0500684 }
Eric Parisc9180a52007-11-30 13:00:35 -0500685
Eric Parise0007522008-03-05 10:31:54 -0500686 BUG_ON(i != opts->num_mnt_opts);
Eric Parisc9180a52007-11-30 13:00:35 -0500687
688 return 0;
689
690out_free:
Eric Parise0007522008-03-05 10:31:54 -0500691 security_free_mnt_opts(opts);
Eric Parisc9180a52007-11-30 13:00:35 -0500692 return rc;
693}
694
695static int bad_option(struct superblock_security_struct *sbsec, char flag,
696 u32 old_sid, u32 new_sid)
697{
David P. Quigley0d90a7e2009-01-16 09:22:02 -0500698 char mnt_flags = sbsec->flags & SE_MNTMASK;
699
Eric Parisc9180a52007-11-30 13:00:35 -0500700 /* check if the old mount command had the same options */
David P. Quigley0d90a7e2009-01-16 09:22:02 -0500701 if (sbsec->flags & SE_SBINITIALIZED)
Eric Parisc9180a52007-11-30 13:00:35 -0500702 if (!(sbsec->flags & flag) ||
703 (old_sid != new_sid))
704 return 1;
705
706 /* check if we were passed the same options twice,
707 * aka someone passed context=a,context=b
708 */
David P. Quigley0d90a7e2009-01-16 09:22:02 -0500709 if (!(sbsec->flags & SE_SBINITIALIZED))
710 if (mnt_flags & flag)
Eric Parisc9180a52007-11-30 13:00:35 -0500711 return 1;
712 return 0;
713}
Eric Parise0007522008-03-05 10:31:54 -0500714
Eric Parisc9180a52007-11-30 13:00:35 -0500715/*
716 * Allow filesystems with binary mount data to explicitly set mount point
717 * labeling information.
718 */
Eric Parise0007522008-03-05 10:31:54 -0500719static int selinux_set_mnt_opts(struct super_block *sb,
David Quigley649f6e72013-05-22 12:50:36 -0400720 struct security_mnt_opts *opts,
721 unsigned long kern_flags,
722 unsigned long *set_kern_flags)
Eric Parisc9180a52007-11-30 13:00:35 -0500723{
David Howells275bb412008-11-14 10:39:19 +1100724 const struct cred *cred = current_cred();
Eric Parisc9180a52007-11-30 13:00:35 -0500725 int rc = 0, i;
Eric Parisc9180a52007-11-30 13:00:35 -0500726 struct superblock_security_struct *sbsec = sb->s_security;
Linus Torvalds29b1deb2013-12-15 11:17:45 -0800727 const char *name = sb->s_type->name;
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -0500728 struct dentry *root = sbsec->sb->s_root;
Paul Moore2c971652016-04-19 16:36:28 -0400729 struct inode_security_struct *root_isec;
Eric Parisc9180a52007-11-30 13:00:35 -0500730 u32 fscontext_sid = 0, context_sid = 0, rootcontext_sid = 0;
731 u32 defcontext_sid = 0;
Eric Parise0007522008-03-05 10:31:54 -0500732 char **mount_options = opts->mnt_opts;
733 int *flags = opts->mnt_opts_flags;
734 int num_opts = opts->num_mnt_opts;
Eric Parisc9180a52007-11-30 13:00:35 -0500735
736 mutex_lock(&sbsec->lock);
737
Stephen Smalleyaa8e7122018-03-01 18:48:02 -0500738 if (!selinux_state.initialized) {
Eric Parisc9180a52007-11-30 13:00:35 -0500739 if (!num_opts) {
740 /* Defer initialization until selinux_complete_init,
741 after the initial policy is loaded and the security
742 server is ready to handle calls. */
Eric Parisc9180a52007-11-30 13:00:35 -0500743 goto out;
744 }
745 rc = -EINVAL;
peter enderborgc103a912018-06-12 10:09:03 +0200746 pr_warn("SELinux: Unable to set superblock options "
Eric Paris744ba352008-04-17 11:52:44 -0400747 "before the security server is initialized\n");
Eric Parisc9180a52007-11-30 13:00:35 -0500748 goto out;
749 }
David Quigley649f6e72013-05-22 12:50:36 -0400750 if (kern_flags && !set_kern_flags) {
751 /* Specifying internal flags without providing a place to
752 * place the results is not allowed */
753 rc = -EINVAL;
754 goto out;
755 }
Eric Parisc9180a52007-11-30 13:00:35 -0500756
757 /*
Eric Parise0007522008-03-05 10:31:54 -0500758 * Binary mount data FS will come through this function twice. Once
759 * from an explicit call and once from the generic calls from the vfs.
760 * Since the generic VFS calls will not contain any security mount data
761 * we need to skip the double mount verification.
762 *
763 * This does open a hole in which we will not notice if the first
764 * mount using this sb set explict options and a second mount using
765 * this sb does not set any security options. (The first options
766 * will be used for both mounts)
767 */
David P. Quigley0d90a7e2009-01-16 09:22:02 -0500768 if ((sbsec->flags & SE_SBINITIALIZED) && (sb->s_type->fs_flags & FS_BINARY_MOUNTDATA)
Eric Parise0007522008-03-05 10:31:54 -0500769 && (num_opts == 0))
Eric Parisf5269712008-05-14 11:27:45 -0400770 goto out;
Eric Parise0007522008-03-05 10:31:54 -0500771
Paul Moore2c971652016-04-19 16:36:28 -0400772 root_isec = backing_inode_security_novalidate(root);
773
Eric Parise0007522008-03-05 10:31:54 -0500774 /*
Eric Parisc9180a52007-11-30 13:00:35 -0500775 * parse the mount options, check if they are valid sids.
776 * also check if someone is trying to mount the same sb more
777 * than once with different security options.
778 */
779 for (i = 0; i < num_opts; i++) {
780 u32 sid;
David P. Quigley11689d42009-01-16 09:22:03 -0500781
Eric Paris12f348b2012-10-09 10:56:25 -0400782 if (flags[i] == SBLABEL_MNT)
David P. Quigley11689d42009-01-16 09:22:03 -0500783 continue;
Stephen Smalleyaa8e7122018-03-01 18:48:02 -0500784 rc = security_context_str_to_sid(&selinux_state,
785 mount_options[i], &sid,
786 GFP_KERNEL);
Eric Parisc9180a52007-11-30 13:00:35 -0500787 if (rc) {
peter enderborgc103a912018-06-12 10:09:03 +0200788 pr_warn("SELinux: security_context_str_to_sid"
Linus Torvalds29b1deb2013-12-15 11:17:45 -0800789 "(%s) failed for (dev %s, type %s) errno=%d\n",
790 mount_options[i], sb->s_id, name, rc);
Eric Parisc9180a52007-11-30 13:00:35 -0500791 goto out;
792 }
793 switch (flags[i]) {
794 case FSCONTEXT_MNT:
795 fscontext_sid = sid;
796
797 if (bad_option(sbsec, FSCONTEXT_MNT, sbsec->sid,
798 fscontext_sid))
799 goto out_double_mount;
800
801 sbsec->flags |= FSCONTEXT_MNT;
802 break;
803 case CONTEXT_MNT:
804 context_sid = sid;
805
806 if (bad_option(sbsec, CONTEXT_MNT, sbsec->mntpoint_sid,
807 context_sid))
808 goto out_double_mount;
809
810 sbsec->flags |= CONTEXT_MNT;
811 break;
812 case ROOTCONTEXT_MNT:
813 rootcontext_sid = sid;
814
815 if (bad_option(sbsec, ROOTCONTEXT_MNT, root_isec->sid,
816 rootcontext_sid))
817 goto out_double_mount;
818
819 sbsec->flags |= ROOTCONTEXT_MNT;
820
821 break;
822 case DEFCONTEXT_MNT:
823 defcontext_sid = sid;
824
825 if (bad_option(sbsec, DEFCONTEXT_MNT, sbsec->def_sid,
826 defcontext_sid))
827 goto out_double_mount;
828
829 sbsec->flags |= DEFCONTEXT_MNT;
830
831 break;
832 default:
833 rc = -EINVAL;
834 goto out;
835 }
836 }
837
David P. Quigley0d90a7e2009-01-16 09:22:02 -0500838 if (sbsec->flags & SE_SBINITIALIZED) {
Eric Parisc9180a52007-11-30 13:00:35 -0500839 /* previously mounted with options, but not on this attempt? */
David P. Quigley0d90a7e2009-01-16 09:22:02 -0500840 if ((sbsec->flags & SE_MNTMASK) && !num_opts)
Eric Parisc9180a52007-11-30 13:00:35 -0500841 goto out_double_mount;
842 rc = 0;
843 goto out;
844 }
845
James Morris089be432008-07-15 18:32:49 +1000846 if (strcmp(sb->s_type->name, "proc") == 0)
Stephen Smalley134509d2015-06-04 16:22:17 -0400847 sbsec->flags |= SE_SBPROC | SE_SBGENFS;
848
Stephen Smalley8e014722015-06-04 16:22:17 -0400849 if (!strcmp(sb->s_type->name, "debugfs") ||
Jeff Vander Stoep6a391182017-06-20 09:35:33 -0700850 !strcmp(sb->s_type->name, "tracefs") ||
Stephen Smalley8e014722015-06-04 16:22:17 -0400851 !strcmp(sb->s_type->name, "sysfs") ||
Antonio Murdaca901ef842017-02-09 17:02:42 +0100852 !strcmp(sb->s_type->name, "pstore") ||
853 !strcmp(sb->s_type->name, "cgroup") ||
854 !strcmp(sb->s_type->name, "cgroup2"))
Stephen Smalley134509d2015-06-04 16:22:17 -0400855 sbsec->flags |= SE_SBGENFS;
Eric Parisc9180a52007-11-30 13:00:35 -0500856
David Quigleyeb9ae682013-05-22 12:50:37 -0400857 if (!sbsec->behavior) {
858 /*
859 * Determine the labeling behavior to use for this
860 * filesystem type.
861 */
Stephen Smalleyaa8e7122018-03-01 18:48:02 -0500862 rc = security_fs_use(&selinux_state, sb);
David Quigleyeb9ae682013-05-22 12:50:37 -0400863 if (rc) {
peter enderborgc103a912018-06-12 10:09:03 +0200864 pr_warn("%s: security_fs_use(%s) returned %d\n",
David Quigleyeb9ae682013-05-22 12:50:37 -0400865 __func__, sb->s_type->name, rc);
866 goto out;
867 }
Eric Parisc9180a52007-11-30 13:00:35 -0500868 }
Seth Forsheeaad82892016-04-26 14:36:20 -0500869
870 /*
Stephen Smalley01593d32017-01-09 10:07:31 -0500871 * If this is a user namespace mount and the filesystem type is not
872 * explicitly whitelisted, then no contexts are allowed on the command
873 * line and security labels must be ignored.
Seth Forsheeaad82892016-04-26 14:36:20 -0500874 */
Stephen Smalley01593d32017-01-09 10:07:31 -0500875 if (sb->s_user_ns != &init_user_ns &&
876 strcmp(sb->s_type->name, "tmpfs") &&
877 strcmp(sb->s_type->name, "ramfs") &&
878 strcmp(sb->s_type->name, "devpts")) {
Seth Forsheeaad82892016-04-26 14:36:20 -0500879 if (context_sid || fscontext_sid || rootcontext_sid ||
880 defcontext_sid) {
881 rc = -EACCES;
882 goto out;
883 }
884 if (sbsec->behavior == SECURITY_FS_USE_XATTR) {
885 sbsec->behavior = SECURITY_FS_USE_MNTPOINT;
Stephen Smalleyaa8e7122018-03-01 18:48:02 -0500886 rc = security_transition_sid(&selinux_state,
887 current_sid(),
888 current_sid(),
Seth Forsheeaad82892016-04-26 14:36:20 -0500889 SECCLASS_FILE, NULL,
890 &sbsec->mntpoint_sid);
891 if (rc)
892 goto out;
893 }
894 goto out_set_opts;
895 }
896
Eric Parisc9180a52007-11-30 13:00:35 -0500897 /* sets the context of the superblock for the fs being mounted. */
898 if (fscontext_sid) {
David Howells275bb412008-11-14 10:39:19 +1100899 rc = may_context_mount_sb_relabel(fscontext_sid, sbsec, cred);
Eric Parisc9180a52007-11-30 13:00:35 -0500900 if (rc)
901 goto out;
902
903 sbsec->sid = fscontext_sid;
904 }
905
906 /*
907 * Switch to using mount point labeling behavior.
908 * sets the label used on all file below the mountpoint, and will set
909 * the superblock context if not already set.
910 */
David Quigleyeb9ae682013-05-22 12:50:37 -0400911 if (kern_flags & SECURITY_LSM_NATIVE_LABELS && !context_sid) {
912 sbsec->behavior = SECURITY_FS_USE_NATIVE;
913 *set_kern_flags |= SECURITY_LSM_NATIVE_LABELS;
914 }
915
Eric Parisc9180a52007-11-30 13:00:35 -0500916 if (context_sid) {
917 if (!fscontext_sid) {
David Howells275bb412008-11-14 10:39:19 +1100918 rc = may_context_mount_sb_relabel(context_sid, sbsec,
919 cred);
Eric Parisc9180a52007-11-30 13:00:35 -0500920 if (rc)
921 goto out;
922 sbsec->sid = context_sid;
923 } else {
David Howells275bb412008-11-14 10:39:19 +1100924 rc = may_context_mount_inode_relabel(context_sid, sbsec,
925 cred);
Eric Parisc9180a52007-11-30 13:00:35 -0500926 if (rc)
927 goto out;
928 }
929 if (!rootcontext_sid)
930 rootcontext_sid = context_sid;
931
932 sbsec->mntpoint_sid = context_sid;
933 sbsec->behavior = SECURITY_FS_USE_MNTPOINT;
934 }
935
936 if (rootcontext_sid) {
David Howells275bb412008-11-14 10:39:19 +1100937 rc = may_context_mount_inode_relabel(rootcontext_sid, sbsec,
938 cred);
Eric Parisc9180a52007-11-30 13:00:35 -0500939 if (rc)
940 goto out;
941
942 root_isec->sid = rootcontext_sid;
Andreas Gruenbacher6f3be9f2015-12-24 11:09:40 -0500943 root_isec->initialized = LABEL_INITIALIZED;
Eric Parisc9180a52007-11-30 13:00:35 -0500944 }
945
946 if (defcontext_sid) {
David Quigleyeb9ae682013-05-22 12:50:37 -0400947 if (sbsec->behavior != SECURITY_FS_USE_XATTR &&
948 sbsec->behavior != SECURITY_FS_USE_NATIVE) {
Eric Parisc9180a52007-11-30 13:00:35 -0500949 rc = -EINVAL;
peter enderborgc103a912018-06-12 10:09:03 +0200950 pr_warn("SELinux: defcontext option is "
Eric Parisc9180a52007-11-30 13:00:35 -0500951 "invalid for this filesystem type\n");
952 goto out;
953 }
954
955 if (defcontext_sid != sbsec->def_sid) {
956 rc = may_context_mount_inode_relabel(defcontext_sid,
David Howells275bb412008-11-14 10:39:19 +1100957 sbsec, cred);
Eric Parisc9180a52007-11-30 13:00:35 -0500958 if (rc)
959 goto out;
960 }
961
962 sbsec->def_sid = defcontext_sid;
963 }
964
Seth Forsheeaad82892016-04-26 14:36:20 -0500965out_set_opts:
Eric Parisc9180a52007-11-30 13:00:35 -0500966 rc = sb_finish_set_opts(sb);
967out:
Eric Parisbc7e9822006-09-25 23:32:02 -0700968 mutex_unlock(&sbsec->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700969 return rc;
Eric Parisc9180a52007-11-30 13:00:35 -0500970out_double_mount:
971 rc = -EINVAL;
peter enderborgc103a912018-06-12 10:09:03 +0200972 pr_warn("SELinux: mount invalid. Same superblock, different "
Linus Torvalds29b1deb2013-12-15 11:17:45 -0800973 "security settings for (dev %s, type %s)\n", sb->s_id, name);
Eric Parisc9180a52007-11-30 13:00:35 -0500974 goto out;
975}
976
Jeff Layton094f7b62013-04-01 08:14:24 -0400977static int selinux_cmp_sb_context(const struct super_block *oldsb,
978 const struct super_block *newsb)
979{
980 struct superblock_security_struct *old = oldsb->s_security;
981 struct superblock_security_struct *new = newsb->s_security;
982 char oldflags = old->flags & SE_MNTMASK;
983 char newflags = new->flags & SE_MNTMASK;
984
985 if (oldflags != newflags)
986 goto mismatch;
987 if ((oldflags & FSCONTEXT_MNT) && old->sid != new->sid)
988 goto mismatch;
989 if ((oldflags & CONTEXT_MNT) && old->mntpoint_sid != new->mntpoint_sid)
990 goto mismatch;
991 if ((oldflags & DEFCONTEXT_MNT) && old->def_sid != new->def_sid)
992 goto mismatch;
993 if (oldflags & ROOTCONTEXT_MNT) {
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -0500994 struct inode_security_struct *oldroot = backing_inode_security(oldsb->s_root);
995 struct inode_security_struct *newroot = backing_inode_security(newsb->s_root);
Jeff Layton094f7b62013-04-01 08:14:24 -0400996 if (oldroot->sid != newroot->sid)
997 goto mismatch;
998 }
999 return 0;
1000mismatch:
peter enderborgc103a912018-06-12 10:09:03 +02001001 pr_warn("SELinux: mount invalid. Same superblock, "
Jeff Layton094f7b62013-04-01 08:14:24 -04001002 "different security settings for (dev %s, "
1003 "type %s)\n", newsb->s_id, newsb->s_type->name);
1004 return -EBUSY;
1005}
1006
1007static int selinux_sb_clone_mnt_opts(const struct super_block *oldsb,
Scott Mayhew0b4d3452017-06-05 11:45:04 -04001008 struct super_block *newsb,
1009 unsigned long kern_flags,
1010 unsigned long *set_kern_flags)
Eric Parisc9180a52007-11-30 13:00:35 -05001011{
Scott Mayhew0b4d3452017-06-05 11:45:04 -04001012 int rc = 0;
Eric Parisc9180a52007-11-30 13:00:35 -05001013 const struct superblock_security_struct *oldsbsec = oldsb->s_security;
1014 struct superblock_security_struct *newsbsec = newsb->s_security;
1015
1016 int set_fscontext = (oldsbsec->flags & FSCONTEXT_MNT);
1017 int set_context = (oldsbsec->flags & CONTEXT_MNT);
1018 int set_rootcontext = (oldsbsec->flags & ROOTCONTEXT_MNT);
1019
Eric Paris0f5e6422008-04-21 16:24:11 -04001020 /*
1021 * if the parent was able to be mounted it clearly had no special lsm
Al Viroe8c26252010-03-23 06:36:54 -04001022 * mount options. thus we can safely deal with this superblock later
Eric Paris0f5e6422008-04-21 16:24:11 -04001023 */
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05001024 if (!selinux_state.initialized)
Jeff Layton094f7b62013-04-01 08:14:24 -04001025 return 0;
Eric Parisc9180a52007-11-30 13:00:35 -05001026
Scott Mayhew0b4d3452017-06-05 11:45:04 -04001027 /*
1028 * Specifying internal flags without providing a place to
1029 * place the results is not allowed.
1030 */
1031 if (kern_flags && !set_kern_flags)
1032 return -EINVAL;
1033
Eric Parisc9180a52007-11-30 13:00:35 -05001034 /* how can we clone if the old one wasn't set up?? */
David P. Quigley0d90a7e2009-01-16 09:22:02 -05001035 BUG_ON(!(oldsbsec->flags & SE_SBINITIALIZED));
Eric Parisc9180a52007-11-30 13:00:35 -05001036
Jeff Layton094f7b62013-04-01 08:14:24 -04001037 /* if fs is reusing a sb, make sure that the contexts match */
David P. Quigley0d90a7e2009-01-16 09:22:02 -05001038 if (newsbsec->flags & SE_SBINITIALIZED)
Jeff Layton094f7b62013-04-01 08:14:24 -04001039 return selinux_cmp_sb_context(oldsb, newsb);
Eric Paris5a552612008-04-09 14:08:35 -04001040
Eric Parisc9180a52007-11-30 13:00:35 -05001041 mutex_lock(&newsbsec->lock);
1042
1043 newsbsec->flags = oldsbsec->flags;
1044
1045 newsbsec->sid = oldsbsec->sid;
1046 newsbsec->def_sid = oldsbsec->def_sid;
1047 newsbsec->behavior = oldsbsec->behavior;
1048
Scott Mayhew0b4d3452017-06-05 11:45:04 -04001049 if (newsbsec->behavior == SECURITY_FS_USE_NATIVE &&
1050 !(kern_flags & SECURITY_LSM_NATIVE_LABELS) && !set_context) {
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05001051 rc = security_fs_use(&selinux_state, newsb);
Scott Mayhew0b4d3452017-06-05 11:45:04 -04001052 if (rc)
1053 goto out;
1054 }
1055
1056 if (kern_flags & SECURITY_LSM_NATIVE_LABELS && !set_context) {
1057 newsbsec->behavior = SECURITY_FS_USE_NATIVE;
1058 *set_kern_flags |= SECURITY_LSM_NATIVE_LABELS;
1059 }
1060
Eric Parisc9180a52007-11-30 13:00:35 -05001061 if (set_context) {
1062 u32 sid = oldsbsec->mntpoint_sid;
1063
1064 if (!set_fscontext)
1065 newsbsec->sid = sid;
1066 if (!set_rootcontext) {
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -05001067 struct inode_security_struct *newisec = backing_inode_security(newsb->s_root);
Eric Parisc9180a52007-11-30 13:00:35 -05001068 newisec->sid = sid;
1069 }
1070 newsbsec->mntpoint_sid = sid;
1071 }
1072 if (set_rootcontext) {
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -05001073 const struct inode_security_struct *oldisec = backing_inode_security(oldsb->s_root);
1074 struct inode_security_struct *newisec = backing_inode_security(newsb->s_root);
Eric Parisc9180a52007-11-30 13:00:35 -05001075
1076 newisec->sid = oldisec->sid;
1077 }
1078
1079 sb_finish_set_opts(newsb);
Scott Mayhew0b4d3452017-06-05 11:45:04 -04001080out:
Eric Parisc9180a52007-11-30 13:00:35 -05001081 mutex_unlock(&newsbsec->lock);
Scott Mayhew0b4d3452017-06-05 11:45:04 -04001082 return rc;
Eric Parisc9180a52007-11-30 13:00:35 -05001083}
1084
Adrian Bunk2e1479d2008-03-17 22:29:23 +02001085static int selinux_parse_opts_str(char *options,
1086 struct security_mnt_opts *opts)
Eric Parisc9180a52007-11-30 13:00:35 -05001087{
Eric Parise0007522008-03-05 10:31:54 -05001088 char *p;
Eric Parisc9180a52007-11-30 13:00:35 -05001089 char *context = NULL, *defcontext = NULL;
1090 char *fscontext = NULL, *rootcontext = NULL;
Eric Parise0007522008-03-05 10:31:54 -05001091 int rc, num_mnt_opts = 0;
Eric Parisc9180a52007-11-30 13:00:35 -05001092
Eric Parise0007522008-03-05 10:31:54 -05001093 opts->num_mnt_opts = 0;
Eric Parisc9180a52007-11-30 13:00:35 -05001094
1095 /* Standard string-based options. */
1096 while ((p = strsep(&options, "|")) != NULL) {
1097 int token;
1098 substring_t args[MAX_OPT_ARGS];
1099
1100 if (!*p)
1101 continue;
1102
1103 token = match_token(p, tokens, args);
1104
1105 switch (token) {
1106 case Opt_context:
1107 if (context || defcontext) {
1108 rc = -EINVAL;
peter enderborgc103a912018-06-12 10:09:03 +02001109 pr_warn(SEL_MOUNT_FAIL_MSG);
Eric Parisc9180a52007-11-30 13:00:35 -05001110 goto out_err;
1111 }
1112 context = match_strdup(&args[0]);
1113 if (!context) {
1114 rc = -ENOMEM;
1115 goto out_err;
1116 }
1117 break;
1118
1119 case Opt_fscontext:
1120 if (fscontext) {
1121 rc = -EINVAL;
peter enderborgc103a912018-06-12 10:09:03 +02001122 pr_warn(SEL_MOUNT_FAIL_MSG);
Eric Parisc9180a52007-11-30 13:00:35 -05001123 goto out_err;
1124 }
1125 fscontext = match_strdup(&args[0]);
1126 if (!fscontext) {
1127 rc = -ENOMEM;
1128 goto out_err;
1129 }
1130 break;
1131
1132 case Opt_rootcontext:
1133 if (rootcontext) {
1134 rc = -EINVAL;
peter enderborgc103a912018-06-12 10:09:03 +02001135 pr_warn(SEL_MOUNT_FAIL_MSG);
Eric Parisc9180a52007-11-30 13:00:35 -05001136 goto out_err;
1137 }
1138 rootcontext = match_strdup(&args[0]);
1139 if (!rootcontext) {
1140 rc = -ENOMEM;
1141 goto out_err;
1142 }
1143 break;
1144
1145 case Opt_defcontext:
1146 if (context || defcontext) {
1147 rc = -EINVAL;
peter enderborgc103a912018-06-12 10:09:03 +02001148 pr_warn(SEL_MOUNT_FAIL_MSG);
Eric Parisc9180a52007-11-30 13:00:35 -05001149 goto out_err;
1150 }
1151 defcontext = match_strdup(&args[0]);
1152 if (!defcontext) {
1153 rc = -ENOMEM;
1154 goto out_err;
1155 }
1156 break;
David P. Quigley11689d42009-01-16 09:22:03 -05001157 case Opt_labelsupport:
1158 break;
Eric Parisc9180a52007-11-30 13:00:35 -05001159 default:
1160 rc = -EINVAL;
peter enderborgc103a912018-06-12 10:09:03 +02001161 pr_warn("SELinux: unknown mount option\n");
Eric Parisc9180a52007-11-30 13:00:35 -05001162 goto out_err;
1163
1164 }
1165 }
1166
Eric Parise0007522008-03-05 10:31:54 -05001167 rc = -ENOMEM;
Tetsuo Handa8931c3b2016-11-14 20:16:12 +09001168 opts->mnt_opts = kcalloc(NUM_SEL_MNT_OPTS, sizeof(char *), GFP_KERNEL);
Eric Parise0007522008-03-05 10:31:54 -05001169 if (!opts->mnt_opts)
1170 goto out_err;
1171
Tetsuo Handa8931c3b2016-11-14 20:16:12 +09001172 opts->mnt_opts_flags = kcalloc(NUM_SEL_MNT_OPTS, sizeof(int),
1173 GFP_KERNEL);
Paul Moore023f1082017-06-07 16:48:19 -04001174 if (!opts->mnt_opts_flags)
Eric Parise0007522008-03-05 10:31:54 -05001175 goto out_err;
Eric Parisc9180a52007-11-30 13:00:35 -05001176
Eric Parise0007522008-03-05 10:31:54 -05001177 if (fscontext) {
1178 opts->mnt_opts[num_mnt_opts] = fscontext;
1179 opts->mnt_opts_flags[num_mnt_opts++] = FSCONTEXT_MNT;
1180 }
1181 if (context) {
1182 opts->mnt_opts[num_mnt_opts] = context;
1183 opts->mnt_opts_flags[num_mnt_opts++] = CONTEXT_MNT;
1184 }
1185 if (rootcontext) {
1186 opts->mnt_opts[num_mnt_opts] = rootcontext;
1187 opts->mnt_opts_flags[num_mnt_opts++] = ROOTCONTEXT_MNT;
1188 }
1189 if (defcontext) {
1190 opts->mnt_opts[num_mnt_opts] = defcontext;
1191 opts->mnt_opts_flags[num_mnt_opts++] = DEFCONTEXT_MNT;
1192 }
1193
1194 opts->num_mnt_opts = num_mnt_opts;
1195 return 0;
1196
Eric Parisc9180a52007-11-30 13:00:35 -05001197out_err:
Paul Moore023f1082017-06-07 16:48:19 -04001198 security_free_mnt_opts(opts);
Eric Parisc9180a52007-11-30 13:00:35 -05001199 kfree(context);
1200 kfree(defcontext);
1201 kfree(fscontext);
1202 kfree(rootcontext);
1203 return rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001204}
Eric Parise0007522008-03-05 10:31:54 -05001205/*
1206 * string mount options parsing and call set the sbsec
1207 */
1208static int superblock_doinit(struct super_block *sb, void *data)
1209{
1210 int rc = 0;
1211 char *options = data;
1212 struct security_mnt_opts opts;
1213
1214 security_init_mnt_opts(&opts);
1215
1216 if (!data)
1217 goto out;
1218
1219 BUG_ON(sb->s_type->fs_flags & FS_BINARY_MOUNTDATA);
1220
1221 rc = selinux_parse_opts_str(options, &opts);
1222 if (rc)
1223 goto out_err;
1224
1225out:
David Quigley649f6e72013-05-22 12:50:36 -04001226 rc = selinux_set_mnt_opts(sb, &opts, 0, NULL);
Eric Parise0007522008-03-05 10:31:54 -05001227
1228out_err:
1229 security_free_mnt_opts(&opts);
1230 return rc;
1231}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001232
Adrian Bunk3583a712008-07-22 20:21:23 +03001233static void selinux_write_opts(struct seq_file *m,
1234 struct security_mnt_opts *opts)
Eric Paris2069f452008-07-04 09:47:13 +10001235{
1236 int i;
1237 char *prefix;
1238
1239 for (i = 0; i < opts->num_mnt_opts; i++) {
David P. Quigley11689d42009-01-16 09:22:03 -05001240 char *has_comma;
1241
1242 if (opts->mnt_opts[i])
1243 has_comma = strchr(opts->mnt_opts[i], ',');
1244 else
1245 has_comma = NULL;
Eric Paris2069f452008-07-04 09:47:13 +10001246
1247 switch (opts->mnt_opts_flags[i]) {
1248 case CONTEXT_MNT:
1249 prefix = CONTEXT_STR;
1250 break;
1251 case FSCONTEXT_MNT:
1252 prefix = FSCONTEXT_STR;
1253 break;
1254 case ROOTCONTEXT_MNT:
1255 prefix = ROOTCONTEXT_STR;
1256 break;
1257 case DEFCONTEXT_MNT:
1258 prefix = DEFCONTEXT_STR;
1259 break;
Eric Paris12f348b2012-10-09 10:56:25 -04001260 case SBLABEL_MNT:
David P. Quigley11689d42009-01-16 09:22:03 -05001261 seq_putc(m, ',');
1262 seq_puts(m, LABELSUPP_STR);
1263 continue;
Eric Paris2069f452008-07-04 09:47:13 +10001264 default:
1265 BUG();
Eric Parisa35c6c832011-04-20 10:21:28 -04001266 return;
Eric Paris2069f452008-07-04 09:47:13 +10001267 };
1268 /* we need a comma before each option */
1269 seq_putc(m, ',');
1270 seq_puts(m, prefix);
1271 if (has_comma)
1272 seq_putc(m, '\"');
Kees Cooka068acf2015-09-04 15:44:57 -07001273 seq_escape(m, opts->mnt_opts[i], "\"\n\\");
Eric Paris2069f452008-07-04 09:47:13 +10001274 if (has_comma)
1275 seq_putc(m, '\"');
1276 }
1277}
1278
1279static int selinux_sb_show_options(struct seq_file *m, struct super_block *sb)
1280{
1281 struct security_mnt_opts opts;
1282 int rc;
1283
1284 rc = selinux_get_mnt_opts(sb, &opts);
Eric Paris383795c2008-07-29 17:07:26 -04001285 if (rc) {
1286 /* before policy load we may get EINVAL, don't show anything */
1287 if (rc == -EINVAL)
1288 rc = 0;
Eric Paris2069f452008-07-04 09:47:13 +10001289 return rc;
Eric Paris383795c2008-07-29 17:07:26 -04001290 }
Eric Paris2069f452008-07-04 09:47:13 +10001291
1292 selinux_write_opts(m, &opts);
1293
1294 security_free_mnt_opts(&opts);
1295
1296 return rc;
1297}
1298
Linus Torvalds1da177e2005-04-16 15:20:36 -07001299static inline u16 inode_mode_to_security_class(umode_t mode)
1300{
1301 switch (mode & S_IFMT) {
1302 case S_IFSOCK:
1303 return SECCLASS_SOCK_FILE;
1304 case S_IFLNK:
1305 return SECCLASS_LNK_FILE;
1306 case S_IFREG:
1307 return SECCLASS_FILE;
1308 case S_IFBLK:
1309 return SECCLASS_BLK_FILE;
1310 case S_IFDIR:
1311 return SECCLASS_DIR;
1312 case S_IFCHR:
1313 return SECCLASS_CHR_FILE;
1314 case S_IFIFO:
1315 return SECCLASS_FIFO_FILE;
1316
1317 }
1318
1319 return SECCLASS_FILE;
1320}
1321
James Morris13402582005-09-30 14:24:34 -04001322static inline int default_protocol_stream(int protocol)
1323{
1324 return (protocol == IPPROTO_IP || protocol == IPPROTO_TCP);
1325}
1326
1327static inline int default_protocol_dgram(int protocol)
1328{
1329 return (protocol == IPPROTO_IP || protocol == IPPROTO_UDP);
1330}
1331
Linus Torvalds1da177e2005-04-16 15:20:36 -07001332static inline u16 socket_type_to_security_class(int family, int type, int protocol)
1333{
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05001334 int extsockclass = selinux_policycap_extsockclass();
Stephen Smalleyda69a532017-01-09 10:07:30 -05001335
Linus Torvalds1da177e2005-04-16 15:20:36 -07001336 switch (family) {
1337 case PF_UNIX:
1338 switch (type) {
1339 case SOCK_STREAM:
1340 case SOCK_SEQPACKET:
1341 return SECCLASS_UNIX_STREAM_SOCKET;
1342 case SOCK_DGRAM:
Luis Ressel2a764b52017-07-25 15:13:41 -04001343 case SOCK_RAW:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001344 return SECCLASS_UNIX_DGRAM_SOCKET;
1345 }
1346 break;
1347 case PF_INET:
1348 case PF_INET6:
1349 switch (type) {
1350 case SOCK_STREAM:
Stephen Smalleyda69a532017-01-09 10:07:30 -05001351 case SOCK_SEQPACKET:
James Morris13402582005-09-30 14:24:34 -04001352 if (default_protocol_stream(protocol))
1353 return SECCLASS_TCP_SOCKET;
Stephen Smalleyda69a532017-01-09 10:07:30 -05001354 else if (extsockclass && protocol == IPPROTO_SCTP)
1355 return SECCLASS_SCTP_SOCKET;
James Morris13402582005-09-30 14:24:34 -04001356 else
1357 return SECCLASS_RAWIP_SOCKET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001358 case SOCK_DGRAM:
James Morris13402582005-09-30 14:24:34 -04001359 if (default_protocol_dgram(protocol))
1360 return SECCLASS_UDP_SOCKET;
Stephen Smalleyef379792017-01-09 10:07:31 -05001361 else if (extsockclass && (protocol == IPPROTO_ICMP ||
1362 protocol == IPPROTO_ICMPV6))
Stephen Smalleyda69a532017-01-09 10:07:30 -05001363 return SECCLASS_ICMP_SOCKET;
James Morris13402582005-09-30 14:24:34 -04001364 else
1365 return SECCLASS_RAWIP_SOCKET;
James Morris2ee92d42006-11-13 16:09:01 -08001366 case SOCK_DCCP:
1367 return SECCLASS_DCCP_SOCKET;
James Morris13402582005-09-30 14:24:34 -04001368 default:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001369 return SECCLASS_RAWIP_SOCKET;
1370 }
1371 break;
1372 case PF_NETLINK:
1373 switch (protocol) {
1374 case NETLINK_ROUTE:
1375 return SECCLASS_NETLINK_ROUTE_SOCKET;
Pavel Emelyanov7f1fb602011-12-06 07:56:43 +00001376 case NETLINK_SOCK_DIAG:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001377 return SECCLASS_NETLINK_TCPDIAG_SOCKET;
1378 case NETLINK_NFLOG:
1379 return SECCLASS_NETLINK_NFLOG_SOCKET;
1380 case NETLINK_XFRM:
1381 return SECCLASS_NETLINK_XFRM_SOCKET;
1382 case NETLINK_SELINUX:
1383 return SECCLASS_NETLINK_SELINUX_SOCKET;
Stephen Smalley6c6d2e92015-06-04 16:22:16 -04001384 case NETLINK_ISCSI:
1385 return SECCLASS_NETLINK_ISCSI_SOCKET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001386 case NETLINK_AUDIT:
1387 return SECCLASS_NETLINK_AUDIT_SOCKET;
Stephen Smalley6c6d2e92015-06-04 16:22:16 -04001388 case NETLINK_FIB_LOOKUP:
1389 return SECCLASS_NETLINK_FIB_LOOKUP_SOCKET;
1390 case NETLINK_CONNECTOR:
1391 return SECCLASS_NETLINK_CONNECTOR_SOCKET;
1392 case NETLINK_NETFILTER:
1393 return SECCLASS_NETLINK_NETFILTER_SOCKET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001394 case NETLINK_DNRTMSG:
1395 return SECCLASS_NETLINK_DNRT_SOCKET;
James Morris0c9b7942005-04-16 15:24:13 -07001396 case NETLINK_KOBJECT_UEVENT:
1397 return SECCLASS_NETLINK_KOBJECT_UEVENT_SOCKET;
Stephen Smalley6c6d2e92015-06-04 16:22:16 -04001398 case NETLINK_GENERIC:
1399 return SECCLASS_NETLINK_GENERIC_SOCKET;
1400 case NETLINK_SCSITRANSPORT:
1401 return SECCLASS_NETLINK_SCSITRANSPORT_SOCKET;
1402 case NETLINK_RDMA:
1403 return SECCLASS_NETLINK_RDMA_SOCKET;
1404 case NETLINK_CRYPTO:
1405 return SECCLASS_NETLINK_CRYPTO_SOCKET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001406 default:
1407 return SECCLASS_NETLINK_SOCKET;
1408 }
1409 case PF_PACKET:
1410 return SECCLASS_PACKET_SOCKET;
1411 case PF_KEY:
1412 return SECCLASS_KEY_SOCKET;
Christopher J. PeBenito3e3ff152006-06-09 00:25:03 -07001413 case PF_APPLETALK:
1414 return SECCLASS_APPLETALK_SOCKET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001415 }
1416
Stephen Smalleyda69a532017-01-09 10:07:30 -05001417 if (extsockclass) {
1418 switch (family) {
1419 case PF_AX25:
1420 return SECCLASS_AX25_SOCKET;
1421 case PF_IPX:
1422 return SECCLASS_IPX_SOCKET;
1423 case PF_NETROM:
1424 return SECCLASS_NETROM_SOCKET;
Stephen Smalleyda69a532017-01-09 10:07:30 -05001425 case PF_ATMPVC:
1426 return SECCLASS_ATMPVC_SOCKET;
1427 case PF_X25:
1428 return SECCLASS_X25_SOCKET;
1429 case PF_ROSE:
1430 return SECCLASS_ROSE_SOCKET;
1431 case PF_DECnet:
1432 return SECCLASS_DECNET_SOCKET;
1433 case PF_ATMSVC:
1434 return SECCLASS_ATMSVC_SOCKET;
1435 case PF_RDS:
1436 return SECCLASS_RDS_SOCKET;
1437 case PF_IRDA:
1438 return SECCLASS_IRDA_SOCKET;
1439 case PF_PPPOX:
1440 return SECCLASS_PPPOX_SOCKET;
1441 case PF_LLC:
1442 return SECCLASS_LLC_SOCKET;
Stephen Smalleyda69a532017-01-09 10:07:30 -05001443 case PF_CAN:
1444 return SECCLASS_CAN_SOCKET;
1445 case PF_TIPC:
1446 return SECCLASS_TIPC_SOCKET;
1447 case PF_BLUETOOTH:
1448 return SECCLASS_BLUETOOTH_SOCKET;
1449 case PF_IUCV:
1450 return SECCLASS_IUCV_SOCKET;
1451 case PF_RXRPC:
1452 return SECCLASS_RXRPC_SOCKET;
1453 case PF_ISDN:
1454 return SECCLASS_ISDN_SOCKET;
1455 case PF_PHONET:
1456 return SECCLASS_PHONET_SOCKET;
1457 case PF_IEEE802154:
1458 return SECCLASS_IEEE802154_SOCKET;
1459 case PF_CAIF:
1460 return SECCLASS_CAIF_SOCKET;
1461 case PF_ALG:
1462 return SECCLASS_ALG_SOCKET;
1463 case PF_NFC:
1464 return SECCLASS_NFC_SOCKET;
1465 case PF_VSOCK:
1466 return SECCLASS_VSOCK_SOCKET;
1467 case PF_KCM:
1468 return SECCLASS_KCM_SOCKET;
1469 case PF_QIPCRTR:
1470 return SECCLASS_QIPCRTR_SOCKET;
Linus Torvalds3051bf32017-02-22 10:15:09 -08001471 case PF_SMC:
1472 return SECCLASS_SMC_SOCKET;
Björn Töpel68e8b842018-05-02 13:01:22 +02001473 case PF_XDP:
1474 return SECCLASS_XDP_SOCKET;
1475#if PF_MAX > 45
Stephen Smalleyda69a532017-01-09 10:07:30 -05001476#error New address family defined, please update this function.
1477#endif
1478 }
1479 }
1480
Linus Torvalds1da177e2005-04-16 15:20:36 -07001481 return SECCLASS_SOCKET;
1482}
1483
Stephen Smalley134509d2015-06-04 16:22:17 -04001484static int selinux_genfs_get_sid(struct dentry *dentry,
1485 u16 tclass,
1486 u16 flags,
1487 u32 *sid)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001488{
Lucian Adrian Grijincu8e6c9692011-02-01 18:42:22 +02001489 int rc;
Al Virofc640052016-04-10 01:33:30 -04001490 struct super_block *sb = dentry->d_sb;
Lucian Adrian Grijincu8e6c9692011-02-01 18:42:22 +02001491 char *buffer, *path;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001492
Eric Paris828dfe12008-04-17 13:17:49 -04001493 buffer = (char *)__get_free_page(GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001494 if (!buffer)
1495 return -ENOMEM;
1496
Lucian Adrian Grijincu8e6c9692011-02-01 18:42:22 +02001497 path = dentry_path_raw(dentry, buffer, PAGE_SIZE);
1498 if (IS_ERR(path))
1499 rc = PTR_ERR(path);
1500 else {
Stephen Smalley134509d2015-06-04 16:22:17 -04001501 if (flags & SE_SBPROC) {
1502 /* each process gets a /proc/PID/ entry. Strip off the
1503 * PID part to get a valid selinux labeling.
1504 * e.g. /proc/1/net/rpc/nfs -> /net/rpc/nfs */
1505 while (path[1] >= '0' && path[1] <= '9') {
1506 path[1] = '/';
1507 path++;
1508 }
Lucian Adrian Grijincu8e6c9692011-02-01 18:42:22 +02001509 }
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05001510 rc = security_genfs_sid(&selinux_state, sb->s_type->name,
1511 path, tclass, sid);
Stephen Smalley7bb185e2018-09-04 16:51:36 -04001512 if (rc == -ENOENT) {
1513 /* No match in policy, mark as unlabeled. */
1514 *sid = SECINITSID_UNLABELED;
1515 rc = 0;
1516 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001517 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001518 free_page((unsigned long)buffer);
1519 return rc;
1520}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001521
1522/* The inode's security attributes must be initialized before first use. */
1523static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dentry)
1524{
1525 struct superblock_security_struct *sbsec = NULL;
1526 struct inode_security_struct *isec = inode->i_security;
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001527 u32 task_sid, sid = 0;
1528 u16 sclass;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001529 struct dentry *dentry;
1530#define INITCONTEXTLEN 255
1531 char *context = NULL;
1532 unsigned len = 0;
1533 int rc = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001534
Andreas Gruenbacher6f3be9f2015-12-24 11:09:40 -05001535 if (isec->initialized == LABEL_INITIALIZED)
Andreas Gruenbacher13457d02016-11-10 22:18:29 +01001536 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001537
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001538 spin_lock(&isec->lock);
Andreas Gruenbacher6f3be9f2015-12-24 11:09:40 -05001539 if (isec->initialized == LABEL_INITIALIZED)
Eric Paris23970742006-09-25 23:32:01 -07001540 goto out_unlock;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001541
Andreas Gruenbacher13457d02016-11-10 22:18:29 +01001542 if (isec->sclass == SECCLASS_FILE)
1543 isec->sclass = inode_mode_to_security_class(inode->i_mode);
1544
Linus Torvalds1da177e2005-04-16 15:20:36 -07001545 sbsec = inode->i_sb->s_security;
David P. Quigley0d90a7e2009-01-16 09:22:02 -05001546 if (!(sbsec->flags & SE_SBINITIALIZED)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001547 /* Defer initialization until selinux_complete_init,
1548 after the initial policy is loaded and the security
1549 server is ready to handle calls. */
1550 spin_lock(&sbsec->isec_lock);
1551 if (list_empty(&isec->list))
1552 list_add(&isec->list, &sbsec->isec_head);
1553 spin_unlock(&sbsec->isec_lock);
Eric Paris23970742006-09-25 23:32:01 -07001554 goto out_unlock;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001555 }
1556
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001557 sclass = isec->sclass;
1558 task_sid = isec->task_sid;
1559 sid = isec->sid;
1560 isec->initialized = LABEL_PENDING;
1561 spin_unlock(&isec->lock);
1562
Linus Torvalds1da177e2005-04-16 15:20:36 -07001563 switch (sbsec->behavior) {
David Quigleyeb9ae682013-05-22 12:50:37 -04001564 case SECURITY_FS_USE_NATIVE:
1565 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001566 case SECURITY_FS_USE_XATTR:
Andreas Gruenbacher5d6c3192016-09-29 17:48:42 +02001567 if (!(inode->i_opflags & IOP_XATTR)) {
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001568 sid = sbsec->def_sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001569 break;
1570 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001571 /* Need a dentry, since the xattr API requires one.
1572 Life would be simpler if we could just pass the inode. */
1573 if (opt_dentry) {
1574 /* Called from d_instantiate or d_splice_alias. */
1575 dentry = dget(opt_dentry);
1576 } else {
Al Virob1271252018-04-25 10:28:38 -04001577 /*
1578 * Called from selinux_complete_init, try to find a dentry.
1579 * Some filesystems really want a connected one, so try
1580 * that first. We could split SECURITY_FS_USE_XATTR in
1581 * two, depending upon that...
1582 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001583 dentry = d_find_alias(inode);
Al Virob1271252018-04-25 10:28:38 -04001584 if (!dentry)
1585 dentry = d_find_any_alias(inode);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001586 }
1587 if (!dentry) {
Eric Parisdf7f54c2009-03-09 14:35:58 -04001588 /*
1589 * this is can be hit on boot when a file is accessed
1590 * before the policy is loaded. When we load policy we
1591 * may find inodes that have no dentry on the
1592 * sbsec->isec_head list. No reason to complain as these
1593 * will get fixed up the next time we go through
1594 * inode_doinit with a dentry, before these inodes could
1595 * be used again by userspace.
1596 */
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001597 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001598 }
1599
1600 len = INITCONTEXTLEN;
Eric Paris4cb912f2009-02-12 14:50:05 -05001601 context = kmalloc(len+1, GFP_NOFS);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001602 if (!context) {
1603 rc = -ENOMEM;
1604 dput(dentry);
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001605 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001606 }
Eric Paris4cb912f2009-02-12 14:50:05 -05001607 context[len] = '\0';
Andreas Gruenbacher5d6c3192016-09-29 17:48:42 +02001608 rc = __vfs_getxattr(dentry, inode, XATTR_NAME_SELINUX, context, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001609 if (rc == -ERANGE) {
James Morris314dabb2009-08-10 22:00:13 +10001610 kfree(context);
1611
Linus Torvalds1da177e2005-04-16 15:20:36 -07001612 /* Need a larger buffer. Query for the right size. */
Andreas Gruenbacher5d6c3192016-09-29 17:48:42 +02001613 rc = __vfs_getxattr(dentry, inode, XATTR_NAME_SELINUX, NULL, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001614 if (rc < 0) {
1615 dput(dentry);
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001616 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001617 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001618 len = rc;
Eric Paris4cb912f2009-02-12 14:50:05 -05001619 context = kmalloc(len+1, GFP_NOFS);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001620 if (!context) {
1621 rc = -ENOMEM;
1622 dput(dentry);
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001623 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001624 }
Eric Paris4cb912f2009-02-12 14:50:05 -05001625 context[len] = '\0';
Andreas Gruenbacher5d6c3192016-09-29 17:48:42 +02001626 rc = __vfs_getxattr(dentry, inode, XATTR_NAME_SELINUX, context, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001627 }
1628 dput(dentry);
1629 if (rc < 0) {
1630 if (rc != -ENODATA) {
peter enderborgc103a912018-06-12 10:09:03 +02001631 pr_warn("SELinux: %s: getxattr returned "
Harvey Harrisondd6f9532008-03-06 10:03:59 +11001632 "%d for dev=%s ino=%ld\n", __func__,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001633 -rc, inode->i_sb->s_id, inode->i_ino);
1634 kfree(context);
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001635 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001636 }
1637 /* Map ENODATA to the default file SID */
1638 sid = sbsec->def_sid;
1639 rc = 0;
1640 } else {
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05001641 rc = security_context_to_sid_default(&selinux_state,
1642 context, rc, &sid,
Stephen Smalley869ab512008-04-04 08:46:05 -04001643 sbsec->def_sid,
1644 GFP_NOFS);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001645 if (rc) {
Eric Paris4ba0a8a2009-02-12 15:01:10 -05001646 char *dev = inode->i_sb->s_id;
1647 unsigned long ino = inode->i_ino;
1648
1649 if (rc == -EINVAL) {
1650 if (printk_ratelimit())
peter enderborgc103a912018-06-12 10:09:03 +02001651 pr_notice("SELinux: inode=%lu on dev=%s was found to have an invalid "
Eric Paris4ba0a8a2009-02-12 15:01:10 -05001652 "context=%s. This indicates you may need to relabel the inode or the "
1653 "filesystem in question.\n", ino, dev, context);
1654 } else {
peter enderborgc103a912018-06-12 10:09:03 +02001655 pr_warn("SELinux: %s: context_to_sid(%s) "
Eric Paris4ba0a8a2009-02-12 15:01:10 -05001656 "returned %d for dev=%s ino=%ld\n",
1657 __func__, context, -rc, dev, ino);
1658 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001659 kfree(context);
1660 /* Leave with the unlabeled SID */
1661 rc = 0;
1662 break;
1663 }
1664 }
1665 kfree(context);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001666 break;
1667 case SECURITY_FS_USE_TASK:
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001668 sid = task_sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001669 break;
1670 case SECURITY_FS_USE_TRANS:
1671 /* Default to the fs SID. */
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001672 sid = sbsec->sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001673
1674 /* Try to obtain a transition SID. */
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05001675 rc = security_transition_sid(&selinux_state, task_sid, sid,
1676 sclass, NULL, &sid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001677 if (rc)
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001678 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001679 break;
Eric Parisc312feb2006-07-10 04:43:53 -07001680 case SECURITY_FS_USE_MNTPOINT:
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001681 sid = sbsec->mntpoint_sid;
Eric Parisc312feb2006-07-10 04:43:53 -07001682 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001683 default:
Eric Parisc312feb2006-07-10 04:43:53 -07001684 /* Default to the fs superblock SID. */
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001685 sid = sbsec->sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001686
Stephen Smalley134509d2015-06-04 16:22:17 -04001687 if ((sbsec->flags & SE_SBGENFS) && !S_ISLNK(inode->i_mode)) {
Paul Mooref64410e2014-03-19 16:46:18 -04001688 /* We must have a dentry to determine the label on
1689 * procfs inodes */
Al Virob1271252018-04-25 10:28:38 -04001690 if (opt_dentry) {
Paul Mooref64410e2014-03-19 16:46:18 -04001691 /* Called from d_instantiate or
1692 * d_splice_alias. */
1693 dentry = dget(opt_dentry);
Al Virob1271252018-04-25 10:28:38 -04001694 } else {
Paul Mooref64410e2014-03-19 16:46:18 -04001695 /* Called from selinux_complete_init, try to
Al Virob1271252018-04-25 10:28:38 -04001696 * find a dentry. Some filesystems really want
1697 * a connected one, so try that first.
1698 */
Paul Mooref64410e2014-03-19 16:46:18 -04001699 dentry = d_find_alias(inode);
Al Virob1271252018-04-25 10:28:38 -04001700 if (!dentry)
1701 dentry = d_find_any_alias(inode);
1702 }
Paul Mooref64410e2014-03-19 16:46:18 -04001703 /*
1704 * This can be hit on boot when a file is accessed
1705 * before the policy is loaded. When we load policy we
1706 * may find inodes that have no dentry on the
1707 * sbsec->isec_head list. No reason to complain as
1708 * these will get fixed up the next time we go through
1709 * inode_doinit() with a dentry, before these inodes
1710 * could be used again by userspace.
1711 */
1712 if (!dentry)
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001713 goto out;
1714 rc = selinux_genfs_get_sid(dentry, sclass,
Stephen Smalley134509d2015-06-04 16:22:17 -04001715 sbsec->flags, &sid);
Paul Mooref64410e2014-03-19 16:46:18 -04001716 dput(dentry);
1717 if (rc)
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001718 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001719 }
1720 break;
1721 }
1722
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001723out:
1724 spin_lock(&isec->lock);
1725 if (isec->initialized == LABEL_PENDING) {
1726 if (!sid || rc) {
1727 isec->initialized = LABEL_INVALID;
1728 goto out_unlock;
1729 }
1730
1731 isec->initialized = LABEL_INITIALIZED;
1732 isec->sid = sid;
1733 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001734
Eric Paris23970742006-09-25 23:32:01 -07001735out_unlock:
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001736 spin_unlock(&isec->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001737 return rc;
1738}
1739
1740/* Convert a Linux signal to an access vector. */
1741static inline u32 signal_to_av(int sig)
1742{
1743 u32 perm = 0;
1744
1745 switch (sig) {
1746 case SIGCHLD:
1747 /* Commonly granted from child to parent. */
1748 perm = PROCESS__SIGCHLD;
1749 break;
1750 case SIGKILL:
1751 /* Cannot be caught or ignored */
1752 perm = PROCESS__SIGKILL;
1753 break;
1754 case SIGSTOP:
1755 /* Cannot be caught or ignored */
1756 perm = PROCESS__SIGSTOP;
1757 break;
1758 default:
1759 /* All other signals. */
1760 perm = PROCESS__SIGNAL;
1761 break;
1762 }
1763
1764 return perm;
1765}
1766
Stephen Smalleyb68e4182008-02-07 11:21:04 -05001767#if CAP_LAST_CAP > 63
1768#error Fix SELinux to handle capabilities > 63.
1769#endif
1770
Linus Torvalds1da177e2005-04-16 15:20:36 -07001771/* Check whether a task is allowed to use a capability. */
Eric Paris6a9de492012-01-03 12:25:14 -05001772static int cred_has_capability(const struct cred *cred,
Stephen Smalley8e4ff6f2016-04-08 13:52:00 -04001773 int cap, int audit, bool initns)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001774{
Thomas Liu2bf49692009-07-14 12:14:09 -04001775 struct common_audit_data ad;
Eric Paris06112162008-11-11 22:02:50 +11001776 struct av_decision avd;
Stephen Smalleyb68e4182008-02-07 11:21:04 -05001777 u16 sclass;
David Howells3699c532009-01-06 22:27:01 +00001778 u32 sid = cred_sid(cred);
Stephen Smalleyb68e4182008-02-07 11:21:04 -05001779 u32 av = CAP_TO_MASK(cap);
Eric Paris06112162008-11-11 22:02:50 +11001780 int rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001781
Eric Paris50c205f2012-04-04 15:01:43 -04001782 ad.type = LSM_AUDIT_DATA_CAP;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001783 ad.u.cap = cap;
1784
Stephen Smalleyb68e4182008-02-07 11:21:04 -05001785 switch (CAP_TO_INDEX(cap)) {
1786 case 0:
Stephen Smalley8e4ff6f2016-04-08 13:52:00 -04001787 sclass = initns ? SECCLASS_CAPABILITY : SECCLASS_CAP_USERNS;
Stephen Smalleyb68e4182008-02-07 11:21:04 -05001788 break;
1789 case 1:
Stephen Smalley8e4ff6f2016-04-08 13:52:00 -04001790 sclass = initns ? SECCLASS_CAPABILITY2 : SECCLASS_CAP2_USERNS;
Stephen Smalleyb68e4182008-02-07 11:21:04 -05001791 break;
1792 default:
peter enderborgc103a912018-06-12 10:09:03 +02001793 pr_err("SELinux: out of range capability %d\n", cap);
Stephen Smalleyb68e4182008-02-07 11:21:04 -05001794 BUG();
Eric Parisa35c6c832011-04-20 10:21:28 -04001795 return -EINVAL;
Stephen Smalleyb68e4182008-02-07 11:21:04 -05001796 }
Eric Paris06112162008-11-11 22:02:50 +11001797
Stephen Smalley6b6bc622018-03-05 11:47:56 -05001798 rc = avc_has_perm_noaudit(&selinux_state,
1799 sid, sid, sclass, av, 0, &avd);
Eric Paris9ade0cf2011-04-25 16:26:29 -04001800 if (audit == SECURITY_CAP_AUDIT) {
Stephen Smalley6b6bc622018-03-05 11:47:56 -05001801 int rc2 = avc_audit(&selinux_state,
1802 sid, sid, sclass, av, &avd, rc, &ad, 0);
Eric Paris9ade0cf2011-04-25 16:26:29 -04001803 if (rc2)
1804 return rc2;
1805 }
Eric Paris06112162008-11-11 22:02:50 +11001806 return rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001807}
1808
Linus Torvalds1da177e2005-04-16 15:20:36 -07001809/* Check whether a task has a particular permission to an inode.
1810 The 'adp' parameter is optional and allows other audit
1811 data to be passed (e.g. the dentry). */
David Howells88e67f32008-11-14 10:39:21 +11001812static int inode_has_perm(const struct cred *cred,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001813 struct inode *inode,
1814 u32 perms,
Linus Torvalds19e49832013-10-04 12:54:11 -07001815 struct common_audit_data *adp)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001816{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001817 struct inode_security_struct *isec;
David Howells275bb412008-11-14 10:39:19 +11001818 u32 sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001819
David Howellse0e81732009-09-02 09:13:40 +01001820 validate_creds(cred);
1821
Eric Paris828dfe12008-04-17 13:17:49 -04001822 if (unlikely(IS_PRIVATE(inode)))
Stephen Smalleybbaca6c2007-02-14 00:34:16 -08001823 return 0;
1824
David Howells88e67f32008-11-14 10:39:21 +11001825 sid = cred_sid(cred);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001826 isec = inode->i_security;
1827
Stephen Smalley6b6bc622018-03-05 11:47:56 -05001828 return avc_has_perm(&selinux_state,
1829 sid, isec->sid, isec->sclass, perms, adp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001830}
1831
1832/* Same as inode_has_perm, but pass explicit audit data containing
1833 the dentry to help the auditing code to more easily generate the
1834 pathname if needed. */
David Howells88e67f32008-11-14 10:39:21 +11001835static inline int dentry_has_perm(const struct cred *cred,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001836 struct dentry *dentry,
1837 u32 av)
1838{
David Howellsc6f493d2015-03-17 22:26:22 +00001839 struct inode *inode = d_backing_inode(dentry);
Thomas Liu2bf49692009-07-14 12:14:09 -04001840 struct common_audit_data ad;
David Howells88e67f32008-11-14 10:39:21 +11001841
Eric Paris50c205f2012-04-04 15:01:43 -04001842 ad.type = LSM_AUDIT_DATA_DENTRY;
Eric Paris2875fa02011-04-28 16:04:24 -04001843 ad.u.dentry = dentry;
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -05001844 __inode_security_revalidate(inode, dentry, true);
Linus Torvalds19e49832013-10-04 12:54:11 -07001845 return inode_has_perm(cred, inode, av, &ad);
Eric Paris2875fa02011-04-28 16:04:24 -04001846}
1847
1848/* Same as inode_has_perm, but pass explicit audit data containing
1849 the path to help the auditing code to more easily generate the
1850 pathname if needed. */
1851static inline int path_has_perm(const struct cred *cred,
Al Viro3f7036a2015-03-08 19:28:30 -04001852 const struct path *path,
Eric Paris2875fa02011-04-28 16:04:24 -04001853 u32 av)
1854{
David Howellsc6f493d2015-03-17 22:26:22 +00001855 struct inode *inode = d_backing_inode(path->dentry);
Eric Paris2875fa02011-04-28 16:04:24 -04001856 struct common_audit_data ad;
1857
Eric Paris50c205f2012-04-04 15:01:43 -04001858 ad.type = LSM_AUDIT_DATA_PATH;
Eric Paris2875fa02011-04-28 16:04:24 -04001859 ad.u.path = *path;
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -05001860 __inode_security_revalidate(inode, path->dentry, true);
Linus Torvalds19e49832013-10-04 12:54:11 -07001861 return inode_has_perm(cred, inode, av, &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001862}
1863
David Howells13f8e982013-06-13 23:37:55 +01001864/* Same as path_has_perm, but uses the inode from the file struct. */
1865static inline int file_path_has_perm(const struct cred *cred,
1866 struct file *file,
1867 u32 av)
1868{
1869 struct common_audit_data ad;
1870
Vivek Goyal43af5de2016-09-09 11:37:49 -04001871 ad.type = LSM_AUDIT_DATA_FILE;
1872 ad.u.file = file;
Linus Torvalds19e49832013-10-04 12:54:11 -07001873 return inode_has_perm(cred, file_inode(file), av, &ad);
David Howells13f8e982013-06-13 23:37:55 +01001874}
1875
Chenbo Fengf66e4482017-10-18 13:00:26 -07001876#ifdef CONFIG_BPF_SYSCALL
1877static int bpf_fd_pass(struct file *file, u32 sid);
1878#endif
1879
Linus Torvalds1da177e2005-04-16 15:20:36 -07001880/* Check whether a task can use an open file descriptor to
1881 access an inode in a given way. Check access to the
1882 descriptor itself, and then use dentry_has_perm to
1883 check a particular permission to the file.
1884 Access to the descriptor is implicitly granted if it
1885 has the same SID as the process. If av is zero, then
1886 access to the file is not checked, e.g. for cases
1887 where only the descriptor is affected like seek. */
David Howells88e67f32008-11-14 10:39:21 +11001888static int file_has_perm(const struct cred *cred,
1889 struct file *file,
1890 u32 av)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001891{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001892 struct file_security_struct *fsec = file->f_security;
Al Viro496ad9a2013-01-23 17:07:38 -05001893 struct inode *inode = file_inode(file);
Thomas Liu2bf49692009-07-14 12:14:09 -04001894 struct common_audit_data ad;
David Howells88e67f32008-11-14 10:39:21 +11001895 u32 sid = cred_sid(cred);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001896 int rc;
1897
Vivek Goyal43af5de2016-09-09 11:37:49 -04001898 ad.type = LSM_AUDIT_DATA_FILE;
1899 ad.u.file = file;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001900
David Howells275bb412008-11-14 10:39:19 +11001901 if (sid != fsec->sid) {
Stephen Smalley6b6bc622018-03-05 11:47:56 -05001902 rc = avc_has_perm(&selinux_state,
1903 sid, fsec->sid,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001904 SECCLASS_FD,
1905 FD__USE,
1906 &ad);
1907 if (rc)
David Howells88e67f32008-11-14 10:39:21 +11001908 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001909 }
1910
Chenbo Fengf66e4482017-10-18 13:00:26 -07001911#ifdef CONFIG_BPF_SYSCALL
1912 rc = bpf_fd_pass(file, cred_sid(cred));
1913 if (rc)
1914 return rc;
1915#endif
1916
Linus Torvalds1da177e2005-04-16 15:20:36 -07001917 /* av is zero if only checking access to the descriptor. */
David Howells88e67f32008-11-14 10:39:21 +11001918 rc = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001919 if (av)
Linus Torvalds19e49832013-10-04 12:54:11 -07001920 rc = inode_has_perm(cred, inode, av, &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001921
David Howells88e67f32008-11-14 10:39:21 +11001922out:
1923 return rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001924}
1925
David Howellsc3c188b2015-07-10 17:19:58 -04001926/*
1927 * Determine the label for an inode that might be unioned.
1928 */
Vivek Goyalc957f6d2016-07-13 10:44:51 -04001929static int
1930selinux_determine_inode_label(const struct task_security_struct *tsec,
1931 struct inode *dir,
1932 const struct qstr *name, u16 tclass,
1933 u32 *_new_isid)
David Howellsc3c188b2015-07-10 17:19:58 -04001934{
1935 const struct superblock_security_struct *sbsec = dir->i_sb->s_security;
David Howellsc3c188b2015-07-10 17:19:58 -04001936
1937 if ((sbsec->flags & SE_SBINITIALIZED) &&
1938 (sbsec->behavior == SECURITY_FS_USE_MNTPOINT)) {
1939 *_new_isid = sbsec->mntpoint_sid;
1940 } else if ((sbsec->flags & SBLABEL_MNT) &&
1941 tsec->create_sid) {
1942 *_new_isid = tsec->create_sid;
1943 } else {
Paul Moore20cdef82016-04-04 14:14:42 -04001944 const struct inode_security_struct *dsec = inode_security(dir);
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05001945 return security_transition_sid(&selinux_state, tsec->sid,
1946 dsec->sid, tclass,
David Howellsc3c188b2015-07-10 17:19:58 -04001947 name, _new_isid);
1948 }
1949
1950 return 0;
1951}
1952
Linus Torvalds1da177e2005-04-16 15:20:36 -07001953/* Check whether a task can create a file. */
1954static int may_create(struct inode *dir,
1955 struct dentry *dentry,
1956 u16 tclass)
1957{
Paul Moore5fb49872010-04-22 14:46:19 -04001958 const struct task_security_struct *tsec = current_security();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001959 struct inode_security_struct *dsec;
1960 struct superblock_security_struct *sbsec;
David Howells275bb412008-11-14 10:39:19 +11001961 u32 sid, newsid;
Thomas Liu2bf49692009-07-14 12:14:09 -04001962 struct common_audit_data ad;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001963 int rc;
1964
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -05001965 dsec = inode_security(dir);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001966 sbsec = dir->i_sb->s_security;
1967
David Howells275bb412008-11-14 10:39:19 +11001968 sid = tsec->sid;
David Howells275bb412008-11-14 10:39:19 +11001969
Eric Paris50c205f2012-04-04 15:01:43 -04001970 ad.type = LSM_AUDIT_DATA_DENTRY;
Eric Parisa2694342011-04-25 13:10:27 -04001971 ad.u.dentry = dentry;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001972
Stephen Smalley6b6bc622018-03-05 11:47:56 -05001973 rc = avc_has_perm(&selinux_state,
1974 sid, dsec->sid, SECCLASS_DIR,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001975 DIR__ADD_NAME | DIR__SEARCH,
1976 &ad);
1977 if (rc)
1978 return rc;
1979
Vivek Goyalc957f6d2016-07-13 10:44:51 -04001980 rc = selinux_determine_inode_label(current_security(), dir,
1981 &dentry->d_name, tclass, &newsid);
David Howellsc3c188b2015-07-10 17:19:58 -04001982 if (rc)
1983 return rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001984
Stephen Smalley6b6bc622018-03-05 11:47:56 -05001985 rc = avc_has_perm(&selinux_state,
1986 sid, newsid, tclass, FILE__CREATE, &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001987 if (rc)
1988 return rc;
1989
Stephen Smalley6b6bc622018-03-05 11:47:56 -05001990 return avc_has_perm(&selinux_state,
1991 newsid, sbsec->sid,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001992 SECCLASS_FILESYSTEM,
1993 FILESYSTEM__ASSOCIATE, &ad);
1994}
1995
Eric Paris828dfe12008-04-17 13:17:49 -04001996#define MAY_LINK 0
1997#define MAY_UNLINK 1
1998#define MAY_RMDIR 2
Linus Torvalds1da177e2005-04-16 15:20:36 -07001999
2000/* Check whether a task can link, unlink, or rmdir a file/directory. */
2001static int may_link(struct inode *dir,
2002 struct dentry *dentry,
2003 int kind)
2004
2005{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002006 struct inode_security_struct *dsec, *isec;
Thomas Liu2bf49692009-07-14 12:14:09 -04002007 struct common_audit_data ad;
David Howells275bb412008-11-14 10:39:19 +11002008 u32 sid = current_sid();
Linus Torvalds1da177e2005-04-16 15:20:36 -07002009 u32 av;
2010 int rc;
2011
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -05002012 dsec = inode_security(dir);
2013 isec = backing_inode_security(dentry);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002014
Eric Paris50c205f2012-04-04 15:01:43 -04002015 ad.type = LSM_AUDIT_DATA_DENTRY;
Eric Parisa2694342011-04-25 13:10:27 -04002016 ad.u.dentry = dentry;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002017
2018 av = DIR__SEARCH;
2019 av |= (kind ? DIR__REMOVE_NAME : DIR__ADD_NAME);
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002020 rc = avc_has_perm(&selinux_state,
2021 sid, dsec->sid, SECCLASS_DIR, av, &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002022 if (rc)
2023 return rc;
2024
2025 switch (kind) {
2026 case MAY_LINK:
2027 av = FILE__LINK;
2028 break;
2029 case MAY_UNLINK:
2030 av = FILE__UNLINK;
2031 break;
2032 case MAY_RMDIR:
2033 av = DIR__RMDIR;
2034 break;
2035 default:
peter enderborgc103a912018-06-12 10:09:03 +02002036 pr_warn("SELinux: %s: unrecognized kind %d\n",
Eric Paris744ba352008-04-17 11:52:44 -04002037 __func__, kind);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002038 return 0;
2039 }
2040
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002041 rc = avc_has_perm(&selinux_state,
2042 sid, isec->sid, isec->sclass, av, &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002043 return rc;
2044}
2045
2046static inline int may_rename(struct inode *old_dir,
2047 struct dentry *old_dentry,
2048 struct inode *new_dir,
2049 struct dentry *new_dentry)
2050{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002051 struct inode_security_struct *old_dsec, *new_dsec, *old_isec, *new_isec;
Thomas Liu2bf49692009-07-14 12:14:09 -04002052 struct common_audit_data ad;
David Howells275bb412008-11-14 10:39:19 +11002053 u32 sid = current_sid();
Linus Torvalds1da177e2005-04-16 15:20:36 -07002054 u32 av;
2055 int old_is_dir, new_is_dir;
2056 int rc;
2057
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -05002058 old_dsec = inode_security(old_dir);
2059 old_isec = backing_inode_security(old_dentry);
David Howellse36cb0b2015-01-29 12:02:35 +00002060 old_is_dir = d_is_dir(old_dentry);
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -05002061 new_dsec = inode_security(new_dir);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002062
Eric Paris50c205f2012-04-04 15:01:43 -04002063 ad.type = LSM_AUDIT_DATA_DENTRY;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002064
Eric Parisa2694342011-04-25 13:10:27 -04002065 ad.u.dentry = old_dentry;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002066 rc = avc_has_perm(&selinux_state,
2067 sid, old_dsec->sid, SECCLASS_DIR,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002068 DIR__REMOVE_NAME | DIR__SEARCH, &ad);
2069 if (rc)
2070 return rc;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002071 rc = avc_has_perm(&selinux_state,
2072 sid, old_isec->sid,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002073 old_isec->sclass, FILE__RENAME, &ad);
2074 if (rc)
2075 return rc;
2076 if (old_is_dir && new_dir != old_dir) {
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002077 rc = avc_has_perm(&selinux_state,
2078 sid, old_isec->sid,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002079 old_isec->sclass, DIR__REPARENT, &ad);
2080 if (rc)
2081 return rc;
2082 }
2083
Eric Parisa2694342011-04-25 13:10:27 -04002084 ad.u.dentry = new_dentry;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002085 av = DIR__ADD_NAME | DIR__SEARCH;
David Howells2c616d42015-01-29 12:02:33 +00002086 if (d_is_positive(new_dentry))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002087 av |= DIR__REMOVE_NAME;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002088 rc = avc_has_perm(&selinux_state,
2089 sid, new_dsec->sid, SECCLASS_DIR, av, &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002090 if (rc)
2091 return rc;
David Howells2c616d42015-01-29 12:02:33 +00002092 if (d_is_positive(new_dentry)) {
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -05002093 new_isec = backing_inode_security(new_dentry);
David Howellse36cb0b2015-01-29 12:02:35 +00002094 new_is_dir = d_is_dir(new_dentry);
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002095 rc = avc_has_perm(&selinux_state,
2096 sid, new_isec->sid,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002097 new_isec->sclass,
2098 (new_is_dir ? DIR__RMDIR : FILE__UNLINK), &ad);
2099 if (rc)
2100 return rc;
2101 }
2102
2103 return 0;
2104}
2105
2106/* Check whether a task can perform a filesystem operation. */
David Howells88e67f32008-11-14 10:39:21 +11002107static int superblock_has_perm(const struct cred *cred,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002108 struct super_block *sb,
2109 u32 perms,
Thomas Liu2bf49692009-07-14 12:14:09 -04002110 struct common_audit_data *ad)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002111{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002112 struct superblock_security_struct *sbsec;
David Howells88e67f32008-11-14 10:39:21 +11002113 u32 sid = cred_sid(cred);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002114
Linus Torvalds1da177e2005-04-16 15:20:36 -07002115 sbsec = sb->s_security;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002116 return avc_has_perm(&selinux_state,
2117 sid, sbsec->sid, SECCLASS_FILESYSTEM, perms, ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002118}
2119
2120/* Convert a Linux mode and permission mask to an access vector. */
2121static inline u32 file_mask_to_av(int mode, int mask)
2122{
2123 u32 av = 0;
2124
Al Virodba19c62011-07-25 20:49:29 -04002125 if (!S_ISDIR(mode)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002126 if (mask & MAY_EXEC)
2127 av |= FILE__EXECUTE;
2128 if (mask & MAY_READ)
2129 av |= FILE__READ;
2130
2131 if (mask & MAY_APPEND)
2132 av |= FILE__APPEND;
2133 else if (mask & MAY_WRITE)
2134 av |= FILE__WRITE;
2135
2136 } else {
2137 if (mask & MAY_EXEC)
2138 av |= DIR__SEARCH;
2139 if (mask & MAY_WRITE)
2140 av |= DIR__WRITE;
2141 if (mask & MAY_READ)
2142 av |= DIR__READ;
2143 }
2144
2145 return av;
2146}
2147
2148/* Convert a Linux file to an access vector. */
2149static inline u32 file_to_av(struct file *file)
2150{
2151 u32 av = 0;
2152
2153 if (file->f_mode & FMODE_READ)
2154 av |= FILE__READ;
2155 if (file->f_mode & FMODE_WRITE) {
2156 if (file->f_flags & O_APPEND)
2157 av |= FILE__APPEND;
2158 else
2159 av |= FILE__WRITE;
2160 }
Stephen Smalley0794c662008-03-17 08:55:18 -04002161 if (!av) {
2162 /*
2163 * Special file opened with flags 3 for ioctl-only use.
2164 */
2165 av = FILE__IOCTL;
2166 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002167
2168 return av;
2169}
2170
Eric Paris8b6a5a32008-10-29 17:06:46 -04002171/*
2172 * Convert a file to an access vector and include the correct open
2173 * open permission.
2174 */
2175static inline u32 open_file_to_av(struct file *file)
2176{
2177 u32 av = file_to_av(file);
Stephen Smalleyccb54472017-05-12 12:41:24 -04002178 struct inode *inode = file_inode(file);
Eric Paris8b6a5a32008-10-29 17:06:46 -04002179
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05002180 if (selinux_policycap_openperm() &&
2181 inode->i_sb->s_magic != SOCKFS_MAGIC)
Eric Paris49b7b8d2010-07-23 11:44:09 -04002182 av |= FILE__OPEN;
2183
Eric Paris8b6a5a32008-10-29 17:06:46 -04002184 return av;
2185}
2186
Linus Torvalds1da177e2005-04-16 15:20:36 -07002187/* Hook functions begin here. */
2188
Stephen Smalley79af7302015-01-21 10:54:10 -05002189static int selinux_binder_set_context_mgr(struct task_struct *mgr)
2190{
2191 u32 mysid = current_sid();
2192 u32 mgrsid = task_sid(mgr);
2193
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002194 return avc_has_perm(&selinux_state,
2195 mysid, mgrsid, SECCLASS_BINDER,
Stephen Smalley79af7302015-01-21 10:54:10 -05002196 BINDER__SET_CONTEXT_MGR, NULL);
2197}
2198
2199static int selinux_binder_transaction(struct task_struct *from,
2200 struct task_struct *to)
2201{
2202 u32 mysid = current_sid();
2203 u32 fromsid = task_sid(from);
2204 u32 tosid = task_sid(to);
2205 int rc;
2206
2207 if (mysid != fromsid) {
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002208 rc = avc_has_perm(&selinux_state,
2209 mysid, fromsid, SECCLASS_BINDER,
Stephen Smalley79af7302015-01-21 10:54:10 -05002210 BINDER__IMPERSONATE, NULL);
2211 if (rc)
2212 return rc;
2213 }
2214
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002215 return avc_has_perm(&selinux_state,
2216 fromsid, tosid, SECCLASS_BINDER, BINDER__CALL,
Stephen Smalley79af7302015-01-21 10:54:10 -05002217 NULL);
2218}
2219
2220static int selinux_binder_transfer_binder(struct task_struct *from,
2221 struct task_struct *to)
2222{
2223 u32 fromsid = task_sid(from);
2224 u32 tosid = task_sid(to);
2225
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002226 return avc_has_perm(&selinux_state,
2227 fromsid, tosid, SECCLASS_BINDER, BINDER__TRANSFER,
Stephen Smalley79af7302015-01-21 10:54:10 -05002228 NULL);
2229}
2230
2231static int selinux_binder_transfer_file(struct task_struct *from,
2232 struct task_struct *to,
2233 struct file *file)
2234{
2235 u32 sid = task_sid(to);
2236 struct file_security_struct *fsec = file->f_security;
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -05002237 struct dentry *dentry = file->f_path.dentry;
Paul Moore20cdef82016-04-04 14:14:42 -04002238 struct inode_security_struct *isec;
Stephen Smalley79af7302015-01-21 10:54:10 -05002239 struct common_audit_data ad;
2240 int rc;
2241
2242 ad.type = LSM_AUDIT_DATA_PATH;
2243 ad.u.path = file->f_path;
2244
2245 if (sid != fsec->sid) {
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002246 rc = avc_has_perm(&selinux_state,
2247 sid, fsec->sid,
Stephen Smalley79af7302015-01-21 10:54:10 -05002248 SECCLASS_FD,
2249 FD__USE,
2250 &ad);
2251 if (rc)
2252 return rc;
2253 }
2254
Chenbo Fengf66e4482017-10-18 13:00:26 -07002255#ifdef CONFIG_BPF_SYSCALL
2256 rc = bpf_fd_pass(file, sid);
2257 if (rc)
2258 return rc;
2259#endif
2260
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -05002261 if (unlikely(IS_PRIVATE(d_backing_inode(dentry))))
Stephen Smalley79af7302015-01-21 10:54:10 -05002262 return 0;
2263
Paul Moore20cdef82016-04-04 14:14:42 -04002264 isec = backing_inode_security(dentry);
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002265 return avc_has_perm(&selinux_state,
2266 sid, isec->sid, isec->sclass, file_to_av(file),
Stephen Smalley79af7302015-01-21 10:54:10 -05002267 &ad);
2268}
2269
Ingo Molnar9e488582009-05-07 19:26:19 +10002270static int selinux_ptrace_access_check(struct task_struct *child,
David Howells5cd9c582008-08-14 11:37:28 +01002271 unsigned int mode)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002272{
Stephen Smalleybe0554c2017-01-09 10:07:31 -05002273 u32 sid = current_sid();
2274 u32 csid = task_sid(child);
Stephen Smalley006ebb42008-05-19 08:32:49 -04002275
Stephen Smalleybe0554c2017-01-09 10:07:31 -05002276 if (mode & PTRACE_MODE_READ)
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002277 return avc_has_perm(&selinux_state,
2278 sid, csid, SECCLASS_FILE, FILE__READ, NULL);
Stephen Smalleybe0554c2017-01-09 10:07:31 -05002279
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002280 return avc_has_perm(&selinux_state,
2281 sid, csid, SECCLASS_PROCESS, PROCESS__PTRACE, NULL);
David Howells5cd9c582008-08-14 11:37:28 +01002282}
2283
2284static int selinux_ptrace_traceme(struct task_struct *parent)
2285{
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002286 return avc_has_perm(&selinux_state,
2287 task_sid(parent), current_sid(), SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05002288 PROCESS__PTRACE, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002289}
2290
2291static int selinux_capget(struct task_struct *target, kernel_cap_t *effective,
Eric Paris828dfe12008-04-17 13:17:49 -04002292 kernel_cap_t *inheritable, kernel_cap_t *permitted)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002293{
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002294 return avc_has_perm(&selinux_state,
2295 current_sid(), task_sid(target), SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05002296 PROCESS__GETCAP, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002297}
2298
David Howellsd84f4f92008-11-14 10:39:23 +11002299static int selinux_capset(struct cred *new, const struct cred *old,
2300 const kernel_cap_t *effective,
2301 const kernel_cap_t *inheritable,
2302 const kernel_cap_t *permitted)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002303{
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002304 return avc_has_perm(&selinux_state,
2305 cred_sid(old), cred_sid(new), SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05002306 PROCESS__SETCAP, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002307}
2308
James Morris5626d3e2009-01-30 10:05:06 +11002309/*
2310 * (This comment used to live with the selinux_task_setuid hook,
2311 * which was removed).
2312 *
2313 * Since setuid only affects the current process, and since the SELinux
2314 * controls are not based on the Linux identity attributes, SELinux does not
2315 * need to control this operation. However, SELinux does control the use of
2316 * the CAP_SETUID and CAP_SETGID capabilities using the capable hook.
2317 */
2318
Eric Paris6a9de492012-01-03 12:25:14 -05002319static int selinux_capable(const struct cred *cred, struct user_namespace *ns,
2320 int cap, int audit)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002321{
Stephen Smalley8e4ff6f2016-04-08 13:52:00 -04002322 return cred_has_capability(cred, cap, audit, ns == &init_user_ns);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002323}
2324
Linus Torvalds1da177e2005-04-16 15:20:36 -07002325static int selinux_quotactl(int cmds, int type, int id, struct super_block *sb)
2326{
David Howells88e67f32008-11-14 10:39:21 +11002327 const struct cred *cred = current_cred();
Linus Torvalds1da177e2005-04-16 15:20:36 -07002328 int rc = 0;
2329
2330 if (!sb)
2331 return 0;
2332
2333 switch (cmds) {
Eric Paris828dfe12008-04-17 13:17:49 -04002334 case Q_SYNC:
2335 case Q_QUOTAON:
2336 case Q_QUOTAOFF:
2337 case Q_SETINFO:
2338 case Q_SETQUOTA:
David Howells88e67f32008-11-14 10:39:21 +11002339 rc = superblock_has_perm(cred, sb, FILESYSTEM__QUOTAMOD, NULL);
Eric Paris828dfe12008-04-17 13:17:49 -04002340 break;
2341 case Q_GETFMT:
2342 case Q_GETINFO:
2343 case Q_GETQUOTA:
David Howells88e67f32008-11-14 10:39:21 +11002344 rc = superblock_has_perm(cred, sb, FILESYSTEM__QUOTAGET, NULL);
Eric Paris828dfe12008-04-17 13:17:49 -04002345 break;
2346 default:
2347 rc = 0; /* let the kernel handle invalid cmds */
2348 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002349 }
2350 return rc;
2351}
2352
2353static int selinux_quota_on(struct dentry *dentry)
2354{
David Howells88e67f32008-11-14 10:39:21 +11002355 const struct cred *cred = current_cred();
2356
Eric Paris2875fa02011-04-28 16:04:24 -04002357 return dentry_has_perm(cred, dentry, FILE__QUOTAON);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002358}
2359
Eric Paris12b30522010-11-15 18:36:29 -05002360static int selinux_syslog(int type)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002361{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002362 switch (type) {
Kees Cookd78ca3c2010-02-03 15:37:13 -08002363 case SYSLOG_ACTION_READ_ALL: /* Read last kernel messages */
2364 case SYSLOG_ACTION_SIZE_BUFFER: /* Return size of the log buffer */
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002365 return avc_has_perm(&selinux_state,
2366 current_sid(), SECINITSID_KERNEL,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05002367 SECCLASS_SYSTEM, SYSTEM__SYSLOG_READ, NULL);
Kees Cookd78ca3c2010-02-03 15:37:13 -08002368 case SYSLOG_ACTION_CONSOLE_OFF: /* Disable logging to console */
2369 case SYSLOG_ACTION_CONSOLE_ON: /* Enable logging to console */
2370 /* Set level of messages printed to console */
2371 case SYSLOG_ACTION_CONSOLE_LEVEL:
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002372 return avc_has_perm(&selinux_state,
2373 current_sid(), SECINITSID_KERNEL,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05002374 SECCLASS_SYSTEM, SYSTEM__SYSLOG_CONSOLE,
2375 NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002376 }
Stephen Smalleybe0554c2017-01-09 10:07:31 -05002377 /* All other syslog types */
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002378 return avc_has_perm(&selinux_state,
2379 current_sid(), SECINITSID_KERNEL,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05002380 SECCLASS_SYSTEM, SYSTEM__SYSLOG_MOD, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002381}
2382
2383/*
2384 * Check that a process has enough memory to allocate a new virtual
2385 * mapping. 0 means there is enough memory for the allocation to
2386 * succeed and -ENOMEM implies there is not.
2387 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07002388 * Do not audit the selinux permission check, as this is applied to all
2389 * processes that allocate mappings.
2390 */
Alan Cox34b4e4a2007-08-22 14:01:28 -07002391static int selinux_vm_enough_memory(struct mm_struct *mm, long pages)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002392{
2393 int rc, cap_sys_admin = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002394
Casey Schauflerb1d9e6b2015-05-02 15:11:42 -07002395 rc = cred_has_capability(current_cred(), CAP_SYS_ADMIN,
Stephen Smalley8e4ff6f2016-04-08 13:52:00 -04002396 SECURITY_CAP_NOAUDIT, true);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002397 if (rc == 0)
2398 cap_sys_admin = 1;
2399
Casey Schauflerb1d9e6b2015-05-02 15:11:42 -07002400 return cap_sys_admin;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002401}
2402
2403/* binprm security operations */
2404
Stephen Smalleybe0554c2017-01-09 10:07:31 -05002405static u32 ptrace_parent_sid(void)
Paul Moore0c6181c2016-03-30 21:41:21 -04002406{
2407 u32 sid = 0;
2408 struct task_struct *tracer;
2409
2410 rcu_read_lock();
Stephen Smalleybe0554c2017-01-09 10:07:31 -05002411 tracer = ptrace_parent(current);
Paul Moore0c6181c2016-03-30 21:41:21 -04002412 if (tracer)
2413 sid = task_sid(tracer);
2414 rcu_read_unlock();
2415
2416 return sid;
2417}
2418
Stephen Smalley7b0d0b42014-08-04 13:36:49 -04002419static int check_nnp_nosuid(const struct linux_binprm *bprm,
2420 const struct task_security_struct *old_tsec,
2421 const struct task_security_struct *new_tsec)
2422{
2423 int nnp = (bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS);
Andy Lutomirski380cf5b2016-06-23 16:41:05 -05002424 int nosuid = !mnt_may_suid(bprm->file->f_path.mnt);
Stephen Smalley7b0d0b42014-08-04 13:36:49 -04002425 int rc;
Stephen Smalleyaf63f412017-07-31 10:12:46 -04002426 u32 av;
Stephen Smalley7b0d0b42014-08-04 13:36:49 -04002427
2428 if (!nnp && !nosuid)
2429 return 0; /* neither NNP nor nosuid */
2430
2431 if (new_tsec->sid == old_tsec->sid)
2432 return 0; /* No change in credentials */
2433
2434 /*
Stephen Smalleyaf63f412017-07-31 10:12:46 -04002435 * If the policy enables the nnp_nosuid_transition policy capability,
2436 * then we permit transitions under NNP or nosuid if the
2437 * policy allows the corresponding permission between
2438 * the old and new contexts.
2439 */
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05002440 if (selinux_policycap_nnp_nosuid_transition()) {
Stephen Smalleyaf63f412017-07-31 10:12:46 -04002441 av = 0;
2442 if (nnp)
2443 av |= PROCESS2__NNP_TRANSITION;
2444 if (nosuid)
2445 av |= PROCESS2__NOSUID_TRANSITION;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002446 rc = avc_has_perm(&selinux_state,
2447 old_tsec->sid, new_tsec->sid,
Stephen Smalleyaf63f412017-07-31 10:12:46 -04002448 SECCLASS_PROCESS2, av, NULL);
2449 if (!rc)
2450 return 0;
2451 }
2452
2453 /*
2454 * We also permit NNP or nosuid transitions to bounded SIDs,
2455 * i.e. SIDs that are guaranteed to only be allowed a subset
2456 * of the permissions of the current SID.
Stephen Smalley7b0d0b42014-08-04 13:36:49 -04002457 */
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05002458 rc = security_bounded_transition(&selinux_state, old_tsec->sid,
2459 new_tsec->sid);
Stephen Smalleyaf63f412017-07-31 10:12:46 -04002460 if (!rc)
2461 return 0;
2462
2463 /*
2464 * On failure, preserve the errno values for NNP vs nosuid.
2465 * NNP: Operation not permitted for caller.
2466 * nosuid: Permission denied to file.
2467 */
2468 if (nnp)
2469 return -EPERM;
2470 return -EACCES;
Stephen Smalley7b0d0b42014-08-04 13:36:49 -04002471}
2472
David Howellsa6f76f22008-11-14 10:39:24 +11002473static int selinux_bprm_set_creds(struct linux_binprm *bprm)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002474{
David Howellsa6f76f22008-11-14 10:39:24 +11002475 const struct task_security_struct *old_tsec;
2476 struct task_security_struct *new_tsec;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002477 struct inode_security_struct *isec;
Thomas Liu2bf49692009-07-14 12:14:09 -04002478 struct common_audit_data ad;
Al Viro496ad9a2013-01-23 17:07:38 -05002479 struct inode *inode = file_inode(bprm->file);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002480 int rc;
2481
David Howellsa6f76f22008-11-14 10:39:24 +11002482 /* SELinux context only depends on initial program or script and not
2483 * the script interpreter */
Kees Cookddb4a142017-07-18 15:25:23 -07002484 if (bprm->called_set_creds)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002485 return 0;
2486
David Howellsa6f76f22008-11-14 10:39:24 +11002487 old_tsec = current_security();
2488 new_tsec = bprm->cred->security;
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -05002489 isec = inode_security(inode);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002490
2491 /* Default to the current task SID. */
David Howellsa6f76f22008-11-14 10:39:24 +11002492 new_tsec->sid = old_tsec->sid;
2493 new_tsec->osid = old_tsec->sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002494
Michael LeMay28eba5b2006-06-27 02:53:42 -07002495 /* Reset fs, key, and sock SIDs on execve. */
David Howellsa6f76f22008-11-14 10:39:24 +11002496 new_tsec->create_sid = 0;
2497 new_tsec->keycreate_sid = 0;
2498 new_tsec->sockcreate_sid = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002499
David Howellsa6f76f22008-11-14 10:39:24 +11002500 if (old_tsec->exec_sid) {
2501 new_tsec->sid = old_tsec->exec_sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002502 /* Reset exec SID on execve. */
David Howellsa6f76f22008-11-14 10:39:24 +11002503 new_tsec->exec_sid = 0;
Andy Lutomirski259e5e62012-04-12 16:47:50 -05002504
Stephen Smalley7b0d0b42014-08-04 13:36:49 -04002505 /* Fail on NNP or nosuid if not an allowed transition. */
2506 rc = check_nnp_nosuid(bprm, old_tsec, new_tsec);
2507 if (rc)
2508 return rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002509 } else {
2510 /* Check for a default transition on this program. */
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05002511 rc = security_transition_sid(&selinux_state, old_tsec->sid,
2512 isec->sid, SECCLASS_PROCESS, NULL,
Eric Paris652bb9b2011-02-01 11:05:40 -05002513 &new_tsec->sid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002514 if (rc)
2515 return rc;
Stephen Smalley7b0d0b42014-08-04 13:36:49 -04002516
2517 /*
2518 * Fallback to old SID on NNP or nosuid if not an allowed
2519 * transition.
2520 */
2521 rc = check_nnp_nosuid(bprm, old_tsec, new_tsec);
2522 if (rc)
2523 new_tsec->sid = old_tsec->sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002524 }
2525
Vivek Goyal43af5de2016-09-09 11:37:49 -04002526 ad.type = LSM_AUDIT_DATA_FILE;
2527 ad.u.file = bprm->file;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002528
David Howellsa6f76f22008-11-14 10:39:24 +11002529 if (new_tsec->sid == old_tsec->sid) {
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002530 rc = avc_has_perm(&selinux_state,
2531 old_tsec->sid, isec->sid,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002532 SECCLASS_FILE, FILE__EXECUTE_NO_TRANS, &ad);
2533 if (rc)
2534 return rc;
2535 } else {
2536 /* Check permissions for the transition. */
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002537 rc = avc_has_perm(&selinux_state,
2538 old_tsec->sid, new_tsec->sid,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002539 SECCLASS_PROCESS, PROCESS__TRANSITION, &ad);
2540 if (rc)
2541 return rc;
2542
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002543 rc = avc_has_perm(&selinux_state,
2544 new_tsec->sid, isec->sid,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002545 SECCLASS_FILE, FILE__ENTRYPOINT, &ad);
2546 if (rc)
2547 return rc;
2548
David Howellsa6f76f22008-11-14 10:39:24 +11002549 /* Check for shared state */
2550 if (bprm->unsafe & LSM_UNSAFE_SHARE) {
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002551 rc = avc_has_perm(&selinux_state,
2552 old_tsec->sid, new_tsec->sid,
David Howellsa6f76f22008-11-14 10:39:24 +11002553 SECCLASS_PROCESS, PROCESS__SHARE,
2554 NULL);
2555 if (rc)
2556 return -EPERM;
2557 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002558
David Howellsa6f76f22008-11-14 10:39:24 +11002559 /* Make sure that anyone attempting to ptrace over a task that
2560 * changes its SID has the appropriate permit */
Eric W. Biederman9227dd22017-01-23 17:26:31 +13002561 if (bprm->unsafe & LSM_UNSAFE_PTRACE) {
Stephen Smalleybe0554c2017-01-09 10:07:31 -05002562 u32 ptsid = ptrace_parent_sid();
David Howellsa6f76f22008-11-14 10:39:24 +11002563 if (ptsid != 0) {
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002564 rc = avc_has_perm(&selinux_state,
2565 ptsid, new_tsec->sid,
David Howellsa6f76f22008-11-14 10:39:24 +11002566 SECCLASS_PROCESS,
2567 PROCESS__PTRACE, NULL);
2568 if (rc)
2569 return -EPERM;
2570 }
2571 }
2572
2573 /* Clear any possibly unsafe personality bits on exec: */
2574 bprm->per_clear |= PER_CLEAR_ON_SETID;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002575
Linus Torvalds1da177e2005-04-16 15:20:36 -07002576 /* Enable secure mode for SIDs transitions unless
2577 the noatsecure permission is granted between
2578 the two SIDs, i.e. ahp returns 0. */
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002579 rc = avc_has_perm(&selinux_state,
2580 old_tsec->sid, new_tsec->sid,
Kees Cook62874c32017-07-18 15:25:25 -07002581 SECCLASS_PROCESS, PROCESS__NOATSECURE,
2582 NULL);
2583 bprm->secureexec |= !!rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002584 }
2585
Kees Cook62874c32017-07-18 15:25:25 -07002586 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002587}
2588
Al Viroc3c073f2012-08-21 22:32:06 -04002589static int match_file(const void *p, struct file *file, unsigned fd)
2590{
2591 return file_has_perm(p, file, file_to_av(file)) ? fd + 1 : 0;
2592}
2593
Linus Torvalds1da177e2005-04-16 15:20:36 -07002594/* Derived from fs/exec.c:flush_old_files. */
David Howells745ca242008-11-14 10:39:22 +11002595static inline void flush_unauthorized_files(const struct cred *cred,
2596 struct files_struct *files)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002597{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002598 struct file *file, *devnull = NULL;
Stephen Smalleyb20c8122006-09-25 23:32:03 -07002599 struct tty_struct *tty;
Peter Zijlstra24ec8392006-12-08 02:36:04 -08002600 int drop_tty = 0;
Al Viroc3c073f2012-08-21 22:32:06 -04002601 unsigned n;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002602
Peter Zijlstra24ec8392006-12-08 02:36:04 -08002603 tty = get_current_tty();
Linus Torvalds1da177e2005-04-16 15:20:36 -07002604 if (tty) {
Peter Hurley4a510962016-01-09 21:35:23 -08002605 spin_lock(&tty->files_lock);
Eric Paris37dd0bd2008-10-31 17:40:00 -04002606 if (!list_empty(&tty->tty_files)) {
Nick Piggind996b622010-08-18 04:37:36 +10002607 struct tty_file_private *file_priv;
Eric Paris37dd0bd2008-10-31 17:40:00 -04002608
Linus Torvalds1da177e2005-04-16 15:20:36 -07002609 /* Revalidate access to controlling tty.
David Howells13f8e982013-06-13 23:37:55 +01002610 Use file_path_has_perm on the tty path directly
2611 rather than using file_has_perm, as this particular
2612 open file may belong to another process and we are
2613 only interested in the inode-based check here. */
Nick Piggind996b622010-08-18 04:37:36 +10002614 file_priv = list_first_entry(&tty->tty_files,
2615 struct tty_file_private, list);
2616 file = file_priv->file;
David Howells13f8e982013-06-13 23:37:55 +01002617 if (file_path_has_perm(cred, file, FILE__READ | FILE__WRITE))
Peter Zijlstra24ec8392006-12-08 02:36:04 -08002618 drop_tty = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002619 }
Peter Hurley4a510962016-01-09 21:35:23 -08002620 spin_unlock(&tty->files_lock);
Alan Cox452a00d2008-10-13 10:39:13 +01002621 tty_kref_put(tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002622 }
Eric W. Biederman98a27ba2007-05-08 00:26:56 -07002623 /* Reset controlling tty. */
2624 if (drop_tty)
2625 no_tty();
Linus Torvalds1da177e2005-04-16 15:20:36 -07002626
2627 /* Revalidate access to inherited open files. */
Al Viroc3c073f2012-08-21 22:32:06 -04002628 n = iterate_fd(files, 0, match_file, cred);
2629 if (!n) /* none found? */
2630 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002631
Al Viroc3c073f2012-08-21 22:32:06 -04002632 devnull = dentry_open(&selinux_null, O_RDWR, cred);
Al Viro45525b22012-10-16 13:30:07 -04002633 if (IS_ERR(devnull))
2634 devnull = NULL;
2635 /* replace all the matching ones with this */
2636 do {
2637 replace_fd(n - 1, devnull, 0);
2638 } while ((n = iterate_fd(files, n, match_file, cred)) != 0);
2639 if (devnull)
Al Viroc3c073f2012-08-21 22:32:06 -04002640 fput(devnull);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002641}
2642
Linus Torvalds1da177e2005-04-16 15:20:36 -07002643/*
David Howellsa6f76f22008-11-14 10:39:24 +11002644 * Prepare a process for imminent new credential changes due to exec
Linus Torvalds1da177e2005-04-16 15:20:36 -07002645 */
David Howellsa6f76f22008-11-14 10:39:24 +11002646static void selinux_bprm_committing_creds(struct linux_binprm *bprm)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002647{
David Howellsa6f76f22008-11-14 10:39:24 +11002648 struct task_security_struct *new_tsec;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002649 struct rlimit *rlim, *initrlim;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002650 int rc, i;
2651
David Howellsa6f76f22008-11-14 10:39:24 +11002652 new_tsec = bprm->cred->security;
2653 if (new_tsec->sid == new_tsec->osid)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002654 return;
2655
2656 /* Close files for which the new task SID is not authorized. */
David Howellsa6f76f22008-11-14 10:39:24 +11002657 flush_unauthorized_files(bprm->cred, current->files);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002658
David Howellsa6f76f22008-11-14 10:39:24 +11002659 /* Always clear parent death signal on SID transitions. */
2660 current->pdeath_signal = 0;
2661
2662 /* Check whether the new SID can inherit resource limits from the old
2663 * SID. If not, reset all soft limits to the lower of the current
2664 * task's hard limit and the init task's soft limit.
2665 *
2666 * Note that the setting of hard limits (even to lower them) can be
2667 * controlled by the setrlimit check. The inclusion of the init task's
2668 * soft limit into the computation is to avoid resetting soft limits
2669 * higher than the default soft limit for cases where the default is
2670 * lower than the hard limit, e.g. RLIMIT_CORE or RLIMIT_STACK.
2671 */
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002672 rc = avc_has_perm(&selinux_state,
2673 new_tsec->osid, new_tsec->sid, SECCLASS_PROCESS,
David Howellsa6f76f22008-11-14 10:39:24 +11002674 PROCESS__RLIMITINH, NULL);
2675 if (rc) {
Oleg Nesteroveb2d55a2010-06-23 22:43:32 +02002676 /* protect against do_prlimit() */
2677 task_lock(current);
David Howellsa6f76f22008-11-14 10:39:24 +11002678 for (i = 0; i < RLIM_NLIMITS; i++) {
2679 rlim = current->signal->rlim + i;
2680 initrlim = init_task.signal->rlim + i;
2681 rlim->rlim_cur = min(rlim->rlim_max, initrlim->rlim_cur);
2682 }
Oleg Nesteroveb2d55a2010-06-23 22:43:32 +02002683 task_unlock(current);
Nicolas Pitrebaa73d92016-11-11 00:10:10 -05002684 if (IS_ENABLED(CONFIG_POSIX_TIMERS))
2685 update_rlimit_cpu(current, rlimit(RLIMIT_CPU));
David Howellsa6f76f22008-11-14 10:39:24 +11002686 }
2687}
2688
2689/*
2690 * Clean up the process immediately after the installation of new credentials
2691 * due to exec
2692 */
2693static void selinux_bprm_committed_creds(struct linux_binprm *bprm)
2694{
2695 const struct task_security_struct *tsec = current_security();
2696 struct itimerval itimer;
David Howellsa6f76f22008-11-14 10:39:24 +11002697 u32 osid, sid;
2698 int rc, i;
David Howellsa6f76f22008-11-14 10:39:24 +11002699
David Howellsa6f76f22008-11-14 10:39:24 +11002700 osid = tsec->osid;
2701 sid = tsec->sid;
2702
2703 if (sid == osid)
2704 return;
2705
2706 /* Check whether the new SID can inherit signal state from the old SID.
2707 * If not, clear itimers to avoid subsequent signal generation and
2708 * flush and unblock signals.
2709 *
2710 * This must occur _after_ the task SID has been updated so that any
2711 * kill done after the flush will be checked against the new SID.
2712 */
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002713 rc = avc_has_perm(&selinux_state,
2714 osid, sid, SECCLASS_PROCESS, PROCESS__SIGINH, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002715 if (rc) {
Nicolas Pitrebaa73d92016-11-11 00:10:10 -05002716 if (IS_ENABLED(CONFIG_POSIX_TIMERS)) {
2717 memset(&itimer, 0, sizeof itimer);
2718 for (i = 0; i < 3; i++)
2719 do_setitimer(i, &itimer, NULL);
2720 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002721 spin_lock_irq(&current->sighand->siglock);
Oleg Nesterov9e7c8f82015-06-04 16:22:16 -04002722 if (!fatal_signal_pending(current)) {
2723 flush_sigqueue(&current->pending);
2724 flush_sigqueue(&current->signal->shared_pending);
David Howells3bcac022009-04-29 13:45:05 +01002725 flush_signal_handlers(current, 1);
2726 sigemptyset(&current->blocked);
Oleg Nesterov9e7c8f82015-06-04 16:22:16 -04002727 recalc_sigpending();
David Howells3bcac022009-04-29 13:45:05 +01002728 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002729 spin_unlock_irq(&current->sighand->siglock);
2730 }
2731
David Howellsa6f76f22008-11-14 10:39:24 +11002732 /* Wake up the parent if it is waiting so that it can recheck
2733 * wait permission to the new task SID. */
Oleg Nesterovecd6de32009-04-29 16:02:24 +02002734 read_lock(&tasklist_lock);
Oleg Nesterov0b7570e2009-09-23 15:56:46 -07002735 __wake_up_parent(current, current->real_parent);
Oleg Nesterovecd6de32009-04-29 16:02:24 +02002736 read_unlock(&tasklist_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002737}
2738
2739/* superblock security operations */
2740
2741static int selinux_sb_alloc_security(struct super_block *sb)
2742{
2743 return superblock_alloc_security(sb);
2744}
2745
2746static void selinux_sb_free_security(struct super_block *sb)
2747{
2748 superblock_free_security(sb);
2749}
2750
2751static inline int match_prefix(char *prefix, int plen, char *option, int olen)
2752{
2753 if (plen > olen)
2754 return 0;
2755
2756 return !memcmp(prefix, option, plen);
2757}
2758
2759static inline int selinux_option(char *option, int len)
2760{
Eric Paris832cbd92008-04-01 13:24:09 -04002761 return (match_prefix(CONTEXT_STR, sizeof(CONTEXT_STR)-1, option, len) ||
2762 match_prefix(FSCONTEXT_STR, sizeof(FSCONTEXT_STR)-1, option, len) ||
2763 match_prefix(DEFCONTEXT_STR, sizeof(DEFCONTEXT_STR)-1, option, len) ||
David P. Quigley11689d42009-01-16 09:22:03 -05002764 match_prefix(ROOTCONTEXT_STR, sizeof(ROOTCONTEXT_STR)-1, option, len) ||
2765 match_prefix(LABELSUPP_STR, sizeof(LABELSUPP_STR)-1, option, len));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002766}
2767
2768static inline void take_option(char **to, char *from, int *first, int len)
2769{
2770 if (!*first) {
2771 **to = ',';
2772 *to += 1;
Cory Olmo3528a952006-09-29 01:58:44 -07002773 } else
Linus Torvalds1da177e2005-04-16 15:20:36 -07002774 *first = 0;
2775 memcpy(*to, from, len);
2776 *to += len;
2777}
2778
Eric Paris828dfe12008-04-17 13:17:49 -04002779static inline void take_selinux_option(char **to, char *from, int *first,
2780 int len)
Cory Olmo3528a952006-09-29 01:58:44 -07002781{
2782 int current_size = 0;
2783
2784 if (!*first) {
2785 **to = '|';
2786 *to += 1;
Eric Paris828dfe12008-04-17 13:17:49 -04002787 } else
Cory Olmo3528a952006-09-29 01:58:44 -07002788 *first = 0;
2789
2790 while (current_size < len) {
2791 if (*from != '"') {
2792 **to = *from;
2793 *to += 1;
2794 }
2795 from += 1;
2796 current_size += 1;
2797 }
2798}
2799
Eric Parise0007522008-03-05 10:31:54 -05002800static int selinux_sb_copy_data(char *orig, char *copy)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002801{
2802 int fnosec, fsec, rc = 0;
2803 char *in_save, *in_curr, *in_end;
2804 char *sec_curr, *nosec_save, *nosec;
Cory Olmo3528a952006-09-29 01:58:44 -07002805 int open_quote = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002806
2807 in_curr = orig;
2808 sec_curr = copy;
2809
Linus Torvalds1da177e2005-04-16 15:20:36 -07002810 nosec = (char *)get_zeroed_page(GFP_KERNEL);
2811 if (!nosec) {
2812 rc = -ENOMEM;
2813 goto out;
2814 }
2815
2816 nosec_save = nosec;
2817 fnosec = fsec = 1;
2818 in_save = in_end = orig;
2819
2820 do {
Cory Olmo3528a952006-09-29 01:58:44 -07002821 if (*in_end == '"')
2822 open_quote = !open_quote;
2823 if ((*in_end == ',' && open_quote == 0) ||
2824 *in_end == '\0') {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002825 int len = in_end - in_curr;
2826
2827 if (selinux_option(in_curr, len))
Cory Olmo3528a952006-09-29 01:58:44 -07002828 take_selinux_option(&sec_curr, in_curr, &fsec, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002829 else
2830 take_option(&nosec, in_curr, &fnosec, len);
2831
2832 in_curr = in_end + 1;
2833 }
2834 } while (*in_end++);
2835
Eric Paris6931dfc2005-06-30 02:58:51 -07002836 strcpy(in_save, nosec_save);
Gerald Schaeferda3caa22005-06-21 17:15:18 -07002837 free_page((unsigned long)nosec_save);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002838out:
2839 return rc;
2840}
2841
Eric Paris026eb162011-03-03 16:09:14 -05002842static int selinux_sb_remount(struct super_block *sb, void *data)
2843{
2844 int rc, i, *flags;
2845 struct security_mnt_opts opts;
2846 char *secdata, **mount_options;
2847 struct superblock_security_struct *sbsec = sb->s_security;
2848
2849 if (!(sbsec->flags & SE_SBINITIALIZED))
2850 return 0;
2851
2852 if (!data)
2853 return 0;
2854
2855 if (sb->s_type->fs_flags & FS_BINARY_MOUNTDATA)
2856 return 0;
2857
2858 security_init_mnt_opts(&opts);
2859 secdata = alloc_secdata();
2860 if (!secdata)
2861 return -ENOMEM;
2862 rc = selinux_sb_copy_data(data, secdata);
2863 if (rc)
2864 goto out_free_secdata;
2865
2866 rc = selinux_parse_opts_str(secdata, &opts);
2867 if (rc)
2868 goto out_free_secdata;
2869
2870 mount_options = opts.mnt_opts;
2871 flags = opts.mnt_opts_flags;
2872
2873 for (i = 0; i < opts.num_mnt_opts; i++) {
2874 u32 sid;
Eric Paris026eb162011-03-03 16:09:14 -05002875
Eric Paris12f348b2012-10-09 10:56:25 -04002876 if (flags[i] == SBLABEL_MNT)
Eric Paris026eb162011-03-03 16:09:14 -05002877 continue;
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05002878 rc = security_context_str_to_sid(&selinux_state,
2879 mount_options[i], &sid,
2880 GFP_KERNEL);
Eric Paris026eb162011-03-03 16:09:14 -05002881 if (rc) {
peter enderborgc103a912018-06-12 10:09:03 +02002882 pr_warn("SELinux: security_context_str_to_sid"
Linus Torvalds29b1deb2013-12-15 11:17:45 -08002883 "(%s) failed for (dev %s, type %s) errno=%d\n",
2884 mount_options[i], sb->s_id, sb->s_type->name, rc);
Eric Paris026eb162011-03-03 16:09:14 -05002885 goto out_free_opts;
2886 }
2887 rc = -EINVAL;
2888 switch (flags[i]) {
2889 case FSCONTEXT_MNT:
2890 if (bad_option(sbsec, FSCONTEXT_MNT, sbsec->sid, sid))
2891 goto out_bad_option;
2892 break;
2893 case CONTEXT_MNT:
2894 if (bad_option(sbsec, CONTEXT_MNT, sbsec->mntpoint_sid, sid))
2895 goto out_bad_option;
2896 break;
2897 case ROOTCONTEXT_MNT: {
2898 struct inode_security_struct *root_isec;
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -05002899 root_isec = backing_inode_security(sb->s_root);
Eric Paris026eb162011-03-03 16:09:14 -05002900
2901 if (bad_option(sbsec, ROOTCONTEXT_MNT, root_isec->sid, sid))
2902 goto out_bad_option;
2903 break;
2904 }
2905 case DEFCONTEXT_MNT:
2906 if (bad_option(sbsec, DEFCONTEXT_MNT, sbsec->def_sid, sid))
2907 goto out_bad_option;
2908 break;
2909 default:
2910 goto out_free_opts;
2911 }
2912 }
2913
2914 rc = 0;
2915out_free_opts:
2916 security_free_mnt_opts(&opts);
2917out_free_secdata:
2918 free_secdata(secdata);
2919 return rc;
2920out_bad_option:
peter enderborgc103a912018-06-12 10:09:03 +02002921 pr_warn("SELinux: unable to change security options "
Linus Torvalds29b1deb2013-12-15 11:17:45 -08002922 "during remount (dev %s, type=%s)\n", sb->s_id,
2923 sb->s_type->name);
Eric Paris026eb162011-03-03 16:09:14 -05002924 goto out_free_opts;
2925}
2926
James Morris12204e22008-12-19 10:44:42 +11002927static int selinux_sb_kern_mount(struct super_block *sb, int flags, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002928{
David Howells88e67f32008-11-14 10:39:21 +11002929 const struct cred *cred = current_cred();
Thomas Liu2bf49692009-07-14 12:14:09 -04002930 struct common_audit_data ad;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002931 int rc;
2932
2933 rc = superblock_doinit(sb, data);
2934 if (rc)
2935 return rc;
2936
James Morris74192242008-12-19 11:41:10 +11002937 /* Allow all mounts performed by the kernel */
2938 if (flags & MS_KERNMOUNT)
2939 return 0;
2940
Eric Paris50c205f2012-04-04 15:01:43 -04002941 ad.type = LSM_AUDIT_DATA_DENTRY;
Eric Parisa2694342011-04-25 13:10:27 -04002942 ad.u.dentry = sb->s_root;
David Howells88e67f32008-11-14 10:39:21 +11002943 return superblock_has_perm(cred, sb, FILESYSTEM__MOUNT, &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002944}
2945
David Howells726c3342006-06-23 02:02:58 -07002946static int selinux_sb_statfs(struct dentry *dentry)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002947{
David Howells88e67f32008-11-14 10:39:21 +11002948 const struct cred *cred = current_cred();
Thomas Liu2bf49692009-07-14 12:14:09 -04002949 struct common_audit_data ad;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002950
Eric Paris50c205f2012-04-04 15:01:43 -04002951 ad.type = LSM_AUDIT_DATA_DENTRY;
Eric Parisa2694342011-04-25 13:10:27 -04002952 ad.u.dentry = dentry->d_sb->s_root;
David Howells88e67f32008-11-14 10:39:21 +11002953 return superblock_has_perm(cred, dentry->d_sb, FILESYSTEM__GETATTR, &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002954}
2955
Al Viro808d4e32012-10-11 11:42:01 -04002956static int selinux_mount(const char *dev_name,
Al Viro8a04c432016-03-25 14:52:53 -04002957 const struct path *path,
Al Viro808d4e32012-10-11 11:42:01 -04002958 const char *type,
Eric Paris828dfe12008-04-17 13:17:49 -04002959 unsigned long flags,
2960 void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002961{
David Howells88e67f32008-11-14 10:39:21 +11002962 const struct cred *cred = current_cred();
Linus Torvalds1da177e2005-04-16 15:20:36 -07002963
2964 if (flags & MS_REMOUNT)
Al Virod8c95842011-12-07 18:16:57 -05002965 return superblock_has_perm(cred, path->dentry->d_sb,
Eric Paris828dfe12008-04-17 13:17:49 -04002966 FILESYSTEM__REMOUNT, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002967 else
Eric Paris2875fa02011-04-28 16:04:24 -04002968 return path_has_perm(cred, path, FILE__MOUNTON);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002969}
2970
2971static int selinux_umount(struct vfsmount *mnt, int flags)
2972{
David Howells88e67f32008-11-14 10:39:21 +11002973 const struct cred *cred = current_cred();
Linus Torvalds1da177e2005-04-16 15:20:36 -07002974
David Howells88e67f32008-11-14 10:39:21 +11002975 return superblock_has_perm(cred, mnt->mnt_sb,
Eric Paris828dfe12008-04-17 13:17:49 -04002976 FILESYSTEM__UNMOUNT, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002977}
2978
2979/* inode security operations */
2980
2981static int selinux_inode_alloc_security(struct inode *inode)
2982{
2983 return inode_alloc_security(inode);
2984}
2985
2986static void selinux_inode_free_security(struct inode *inode)
2987{
2988 inode_free_security(inode);
2989}
2990
David Quigleyd47be3d2013-05-22 12:50:34 -04002991static int selinux_dentry_init_security(struct dentry *dentry, int mode,
Al Viro4f3ccd72016-07-20 16:06:15 -04002992 const struct qstr *name, void **ctx,
David Quigleyd47be3d2013-05-22 12:50:34 -04002993 u32 *ctxlen)
2994{
David Quigleyd47be3d2013-05-22 12:50:34 -04002995 u32 newsid;
2996 int rc;
2997
Vivek Goyalc957f6d2016-07-13 10:44:51 -04002998 rc = selinux_determine_inode_label(current_security(),
2999 d_inode(dentry->d_parent), name,
David Howellsc3c188b2015-07-10 17:19:58 -04003000 inode_mode_to_security_class(mode),
3001 &newsid);
3002 if (rc)
3003 return rc;
David Quigleyd47be3d2013-05-22 12:50:34 -04003004
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05003005 return security_sid_to_context(&selinux_state, newsid, (char **)ctx,
3006 ctxlen);
David Quigleyd47be3d2013-05-22 12:50:34 -04003007}
3008
Vivek Goyala518b0a2016-07-13 10:44:53 -04003009static int selinux_dentry_create_files_as(struct dentry *dentry, int mode,
3010 struct qstr *name,
3011 const struct cred *old,
3012 struct cred *new)
3013{
3014 u32 newsid;
3015 int rc;
3016 struct task_security_struct *tsec;
3017
3018 rc = selinux_determine_inode_label(old->security,
3019 d_inode(dentry->d_parent), name,
3020 inode_mode_to_security_class(mode),
3021 &newsid);
3022 if (rc)
3023 return rc;
3024
3025 tsec = new->security;
3026 tsec->create_sid = newsid;
3027 return 0;
3028}
3029
Stephen Smalley5e41ff92005-09-09 13:01:35 -07003030static int selinux_inode_init_security(struct inode *inode, struct inode *dir,
Tetsuo Handa95489062013-07-25 05:44:02 +09003031 const struct qstr *qstr,
3032 const char **name,
Eric Paris2a7dba32011-02-01 11:05:39 -05003033 void **value, size_t *len)
Stephen Smalley5e41ff92005-09-09 13:01:35 -07003034{
Paul Moore5fb49872010-04-22 14:46:19 -04003035 const struct task_security_struct *tsec = current_security();
Stephen Smalley5e41ff92005-09-09 13:01:35 -07003036 struct superblock_security_struct *sbsec;
Corentin LABBEc0d4f462017-10-04 20:32:17 +02003037 u32 newsid, clen;
Stephen Smalley5e41ff92005-09-09 13:01:35 -07003038 int rc;
Tetsuo Handa95489062013-07-25 05:44:02 +09003039 char *context;
Stephen Smalley5e41ff92005-09-09 13:01:35 -07003040
Stephen Smalley5e41ff92005-09-09 13:01:35 -07003041 sbsec = dir->i_sb->s_security;
Stephen Smalley5e41ff92005-09-09 13:01:35 -07003042
David Howells275bb412008-11-14 10:39:19 +11003043 newsid = tsec->create_sid;
3044
Vivek Goyalc957f6d2016-07-13 10:44:51 -04003045 rc = selinux_determine_inode_label(current_security(),
David Howellsc3c188b2015-07-10 17:19:58 -04003046 dir, qstr,
3047 inode_mode_to_security_class(inode->i_mode),
3048 &newsid);
3049 if (rc)
3050 return rc;
Stephen Smalley5e41ff92005-09-09 13:01:35 -07003051
Eric Paris296fddf2006-09-25 23:32:00 -07003052 /* Possibly defer initialization to selinux_complete_init. */
David P. Quigley0d90a7e2009-01-16 09:22:02 -05003053 if (sbsec->flags & SE_SBINITIALIZED) {
Eric Paris296fddf2006-09-25 23:32:00 -07003054 struct inode_security_struct *isec = inode->i_security;
3055 isec->sclass = inode_mode_to_security_class(inode->i_mode);
3056 isec->sid = newsid;
Andreas Gruenbacher6f3be9f2015-12-24 11:09:40 -05003057 isec->initialized = LABEL_INITIALIZED;
Eric Paris296fddf2006-09-25 23:32:00 -07003058 }
Stephen Smalley5e41ff92005-09-09 13:01:35 -07003059
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05003060 if (!selinux_state.initialized || !(sbsec->flags & SBLABEL_MNT))
Stephen Smalley25a74f32005-11-08 21:34:33 -08003061 return -EOPNOTSUPP;
3062
Tetsuo Handa95489062013-07-25 05:44:02 +09003063 if (name)
3064 *name = XATTR_SELINUX_SUFFIX;
Stephen Smalley570bc1c2005-09-09 13:01:43 -07003065
3066 if (value && len) {
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05003067 rc = security_sid_to_context_force(&selinux_state, newsid,
3068 &context, &clen);
Tetsuo Handa95489062013-07-25 05:44:02 +09003069 if (rc)
Stephen Smalley570bc1c2005-09-09 13:01:43 -07003070 return rc;
Stephen Smalley570bc1c2005-09-09 13:01:43 -07003071 *value = context;
3072 *len = clen;
3073 }
Stephen Smalley5e41ff92005-09-09 13:01:35 -07003074
Stephen Smalley5e41ff92005-09-09 13:01:35 -07003075 return 0;
3076}
3077
Al Viro4acdaf22011-07-26 01:42:34 -04003078static int selinux_inode_create(struct inode *dir, struct dentry *dentry, umode_t mode)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003079{
3080 return may_create(dir, dentry, SECCLASS_FILE);
3081}
3082
Linus Torvalds1da177e2005-04-16 15:20:36 -07003083static int selinux_inode_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry)
3084{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003085 return may_link(dir, old_dentry, MAY_LINK);
3086}
3087
Linus Torvalds1da177e2005-04-16 15:20:36 -07003088static int selinux_inode_unlink(struct inode *dir, struct dentry *dentry)
3089{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003090 return may_link(dir, dentry, MAY_UNLINK);
3091}
3092
3093static int selinux_inode_symlink(struct inode *dir, struct dentry *dentry, const char *name)
3094{
3095 return may_create(dir, dentry, SECCLASS_LNK_FILE);
3096}
3097
Al Viro18bb1db2011-07-26 01:41:39 -04003098static int selinux_inode_mkdir(struct inode *dir, struct dentry *dentry, umode_t mask)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003099{
3100 return may_create(dir, dentry, SECCLASS_DIR);
3101}
3102
Linus Torvalds1da177e2005-04-16 15:20:36 -07003103static int selinux_inode_rmdir(struct inode *dir, struct dentry *dentry)
3104{
3105 return may_link(dir, dentry, MAY_RMDIR);
3106}
3107
Al Viro1a67aaf2011-07-26 01:52:52 -04003108static int selinux_inode_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003109{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003110 return may_create(dir, dentry, inode_mode_to_security_class(mode));
3111}
3112
Linus Torvalds1da177e2005-04-16 15:20:36 -07003113static int selinux_inode_rename(struct inode *old_inode, struct dentry *old_dentry,
Eric Paris828dfe12008-04-17 13:17:49 -04003114 struct inode *new_inode, struct dentry *new_dentry)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003115{
3116 return may_rename(old_inode, old_dentry, new_inode, new_dentry);
3117}
3118
Linus Torvalds1da177e2005-04-16 15:20:36 -07003119static int selinux_inode_readlink(struct dentry *dentry)
3120{
David Howells88e67f32008-11-14 10:39:21 +11003121 const struct cred *cred = current_cred();
3122
Eric Paris2875fa02011-04-28 16:04:24 -04003123 return dentry_has_perm(cred, dentry, FILE__READ);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003124}
3125
NeilBrownbda0be72015-03-23 13:37:39 +11003126static int selinux_inode_follow_link(struct dentry *dentry, struct inode *inode,
3127 bool rcu)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003128{
David Howells88e67f32008-11-14 10:39:21 +11003129 const struct cred *cred = current_cred();
NeilBrownbda0be72015-03-23 13:37:39 +11003130 struct common_audit_data ad;
3131 struct inode_security_struct *isec;
3132 u32 sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003133
NeilBrownbda0be72015-03-23 13:37:39 +11003134 validate_creds(cred);
3135
3136 ad.type = LSM_AUDIT_DATA_DENTRY;
3137 ad.u.dentry = dentry;
3138 sid = cred_sid(cred);
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -05003139 isec = inode_security_rcu(inode, rcu);
3140 if (IS_ERR(isec))
3141 return PTR_ERR(isec);
NeilBrownbda0be72015-03-23 13:37:39 +11003142
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003143 return avc_has_perm_flags(&selinux_state,
3144 sid, isec->sid, isec->sclass, FILE__READ, &ad,
NeilBrownbda0be72015-03-23 13:37:39 +11003145 rcu ? MAY_NOT_BLOCK : 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003146}
3147
Eric Parisd4cf970d2012-04-04 15:01:42 -04003148static noinline int audit_inode_permission(struct inode *inode,
3149 u32 perms, u32 audited, u32 denied,
Stephen Smalley626b9742014-04-29 11:29:04 -07003150 int result,
Eric Parisd4cf970d2012-04-04 15:01:42 -04003151 unsigned flags)
3152{
3153 struct common_audit_data ad;
Eric Parisd4cf970d2012-04-04 15:01:42 -04003154 struct inode_security_struct *isec = inode->i_security;
3155 int rc;
3156
Eric Paris50c205f2012-04-04 15:01:43 -04003157 ad.type = LSM_AUDIT_DATA_INODE;
Eric Parisd4cf970d2012-04-04 15:01:42 -04003158 ad.u.inode = inode;
3159
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003160 rc = slow_avc_audit(&selinux_state,
3161 current_sid(), isec->sid, isec->sclass, perms,
Stephen Smalley626b9742014-04-29 11:29:04 -07003162 audited, denied, result, &ad, flags);
Eric Parisd4cf970d2012-04-04 15:01:42 -04003163 if (rc)
3164 return rc;
3165 return 0;
3166}
3167
Al Viroe74f71e2011-06-20 19:38:15 -04003168static int selinux_inode_permission(struct inode *inode, int mask)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003169{
David Howells88e67f32008-11-14 10:39:21 +11003170 const struct cred *cred = current_cred();
Eric Parisb782e0a2010-07-23 11:44:03 -04003171 u32 perms;
3172 bool from_access;
Al Virocf1dd1d2011-06-20 19:44:08 -04003173 unsigned flags = mask & MAY_NOT_BLOCK;
Eric Paris2e334052012-04-04 15:01:42 -04003174 struct inode_security_struct *isec;
3175 u32 sid;
3176 struct av_decision avd;
3177 int rc, rc2;
3178 u32 audited, denied;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003179
Eric Parisb782e0a2010-07-23 11:44:03 -04003180 from_access = mask & MAY_ACCESS;
Eric Parisd09ca732010-07-23 11:43:57 -04003181 mask &= (MAY_READ|MAY_WRITE|MAY_EXEC|MAY_APPEND);
3182
Eric Parisb782e0a2010-07-23 11:44:03 -04003183 /* No permission to check. Existence test. */
3184 if (!mask)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003185 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003186
Eric Paris2e334052012-04-04 15:01:42 -04003187 validate_creds(cred);
Eric Parisb782e0a2010-07-23 11:44:03 -04003188
Eric Paris2e334052012-04-04 15:01:42 -04003189 if (unlikely(IS_PRIVATE(inode)))
3190 return 0;
Eric Parisb782e0a2010-07-23 11:44:03 -04003191
3192 perms = file_mask_to_av(inode->i_mode, mask);
3193
Eric Paris2e334052012-04-04 15:01:42 -04003194 sid = cred_sid(cred);
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -05003195 isec = inode_security_rcu(inode, flags & MAY_NOT_BLOCK);
3196 if (IS_ERR(isec))
3197 return PTR_ERR(isec);
Eric Paris2e334052012-04-04 15:01:42 -04003198
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003199 rc = avc_has_perm_noaudit(&selinux_state,
3200 sid, isec->sid, isec->sclass, perms, 0, &avd);
Eric Paris2e334052012-04-04 15:01:42 -04003201 audited = avc_audit_required(perms, &avd, rc,
3202 from_access ? FILE__AUDIT_ACCESS : 0,
3203 &denied);
3204 if (likely(!audited))
3205 return rc;
3206
Stephen Smalley626b9742014-04-29 11:29:04 -07003207 rc2 = audit_inode_permission(inode, perms, audited, denied, rc, flags);
Eric Paris2e334052012-04-04 15:01:42 -04003208 if (rc2)
3209 return rc2;
3210 return rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003211}
3212
3213static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr)
3214{
David Howells88e67f32008-11-14 10:39:21 +11003215 const struct cred *cred = current_cred();
Stephen Smalleyccb54472017-05-12 12:41:24 -04003216 struct inode *inode = d_backing_inode(dentry);
Amerigo Wangbc6a6002009-08-20 19:29:02 -07003217 unsigned int ia_valid = iattr->ia_valid;
Eric Paris95dbf732012-04-04 13:45:34 -04003218 __u32 av = FILE__WRITE;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003219
Amerigo Wangbc6a6002009-08-20 19:29:02 -07003220 /* ATTR_FORCE is just used for ATTR_KILL_S[UG]ID. */
3221 if (ia_valid & ATTR_FORCE) {
3222 ia_valid &= ~(ATTR_KILL_SUID | ATTR_KILL_SGID | ATTR_MODE |
3223 ATTR_FORCE);
3224 if (!ia_valid)
3225 return 0;
3226 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003227
Amerigo Wangbc6a6002009-08-20 19:29:02 -07003228 if (ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID |
3229 ATTR_ATIME_SET | ATTR_MTIME_SET | ATTR_TIMES_SET))
Eric Paris2875fa02011-04-28 16:04:24 -04003230 return dentry_has_perm(cred, dentry, FILE__SETATTR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003231
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05003232 if (selinux_policycap_openperm() &&
Stephen Smalleyccb54472017-05-12 12:41:24 -04003233 inode->i_sb->s_magic != SOCKFS_MAGIC &&
3234 (ia_valid & ATTR_SIZE) &&
3235 !(ia_valid & ATTR_FILE))
Eric Paris95dbf732012-04-04 13:45:34 -04003236 av |= FILE__OPEN;
3237
3238 return dentry_has_perm(cred, dentry, av);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003239}
3240
Al Viro3f7036a2015-03-08 19:28:30 -04003241static int selinux_inode_getattr(const struct path *path)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003242{
Al Viro3f7036a2015-03-08 19:28:30 -04003243 return path_has_perm(current_cred(), path, FILE__GETATTR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003244}
3245
Stephen Smalleydb590002017-04-20 11:31:30 -04003246static bool has_cap_mac_admin(bool audit)
3247{
3248 const struct cred *cred = current_cred();
3249 int cap_audit = audit ? SECURITY_CAP_AUDIT : SECURITY_CAP_NOAUDIT;
3250
3251 if (cap_capable(cred, &init_user_ns, CAP_MAC_ADMIN, cap_audit))
3252 return false;
3253 if (cred_has_capability(cred, CAP_MAC_ADMIN, cap_audit, true))
3254 return false;
3255 return true;
3256}
3257
David Howells8f0cfa52008-04-29 00:59:41 -07003258static int selinux_inode_setxattr(struct dentry *dentry, const char *name,
3259 const void *value, size_t size, int flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003260{
David Howellsc6f493d2015-03-17 22:26:22 +00003261 struct inode *inode = d_backing_inode(dentry);
Paul Moore20cdef82016-04-04 14:14:42 -04003262 struct inode_security_struct *isec;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003263 struct superblock_security_struct *sbsec;
Thomas Liu2bf49692009-07-14 12:14:09 -04003264 struct common_audit_data ad;
David Howells275bb412008-11-14 10:39:19 +11003265 u32 newsid, sid = current_sid();
Linus Torvalds1da177e2005-04-16 15:20:36 -07003266 int rc = 0;
3267
Eric W. Biederman6b240302017-10-02 09:38:20 -05003268 if (strcmp(name, XATTR_NAME_SELINUX)) {
3269 rc = cap_inode_setxattr(dentry, name, value, size, flags);
3270 if (rc)
3271 return rc;
3272
3273 /* Not an attribute we recognize, so just check the
3274 ordinary setattr permission. */
3275 return dentry_has_perm(current_cred(), dentry, FILE__SETATTR);
3276 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003277
3278 sbsec = inode->i_sb->s_security;
Eric Paris12f348b2012-10-09 10:56:25 -04003279 if (!(sbsec->flags & SBLABEL_MNT))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003280 return -EOPNOTSUPP;
3281
Serge E. Hallyn2e149672011-03-23 16:43:26 -07003282 if (!inode_owner_or_capable(inode))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003283 return -EPERM;
3284
Eric Paris50c205f2012-04-04 15:01:43 -04003285 ad.type = LSM_AUDIT_DATA_DENTRY;
Eric Parisa2694342011-04-25 13:10:27 -04003286 ad.u.dentry = dentry;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003287
Paul Moore20cdef82016-04-04 14:14:42 -04003288 isec = backing_inode_security(dentry);
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003289 rc = avc_has_perm(&selinux_state,
3290 sid, isec->sid, isec->sclass,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003291 FILE__RELABELFROM, &ad);
3292 if (rc)
3293 return rc;
3294
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05003295 rc = security_context_to_sid(&selinux_state, value, size, &newsid,
3296 GFP_KERNEL);
Stephen Smalley12b29f32008-05-07 13:03:20 -04003297 if (rc == -EINVAL) {
Stephen Smalleydb590002017-04-20 11:31:30 -04003298 if (!has_cap_mac_admin(true)) {
Eric Parisd6ea83e2012-04-04 13:45:49 -04003299 struct audit_buffer *ab;
3300 size_t audit_size;
Eric Parisd6ea83e2012-04-04 13:45:49 -04003301
3302 /* We strip a nul only if it is at the end, otherwise the
3303 * context contains a nul and we should audit that */
Al Viroe3fea3f2012-06-09 08:15:16 +01003304 if (value) {
Colin Ian Kingadd24372017-10-14 13:46:55 +01003305 const char *str = value;
3306
Al Viroe3fea3f2012-06-09 08:15:16 +01003307 if (str[size - 1] == '\0')
3308 audit_size = size - 1;
3309 else
3310 audit_size = size;
3311 } else {
Al Viroe3fea3f2012-06-09 08:15:16 +01003312 audit_size = 0;
3313 }
Richard Guy Briggscdfb6b32018-05-12 21:58:20 -04003314 ab = audit_log_start(audit_context(),
3315 GFP_ATOMIC, AUDIT_SELINUX_ERR);
Eric Parisd6ea83e2012-04-04 13:45:49 -04003316 audit_log_format(ab, "op=setxattr invalid_context=");
3317 audit_log_n_untrustedstring(ab, value, audit_size);
3318 audit_log_end(ab);
3319
Stephen Smalley12b29f32008-05-07 13:03:20 -04003320 return rc;
Eric Parisd6ea83e2012-04-04 13:45:49 -04003321 }
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05003322 rc = security_context_to_sid_force(&selinux_state, value,
3323 size, &newsid);
Stephen Smalley12b29f32008-05-07 13:03:20 -04003324 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003325 if (rc)
3326 return rc;
3327
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003328 rc = avc_has_perm(&selinux_state,
3329 sid, newsid, isec->sclass,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003330 FILE__RELABELTO, &ad);
3331 if (rc)
3332 return rc;
3333
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05003334 rc = security_validate_transition(&selinux_state, isec->sid, newsid,
3335 sid, isec->sclass);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003336 if (rc)
3337 return rc;
3338
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003339 return avc_has_perm(&selinux_state,
3340 newsid,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003341 sbsec->sid,
3342 SECCLASS_FILESYSTEM,
3343 FILESYSTEM__ASSOCIATE,
3344 &ad);
3345}
3346
David Howells8f0cfa52008-04-29 00:59:41 -07003347static void selinux_inode_post_setxattr(struct dentry *dentry, const char *name,
Eric Parisf5269712008-05-14 11:27:45 -04003348 const void *value, size_t size,
David Howells8f0cfa52008-04-29 00:59:41 -07003349 int flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003350{
David Howellsc6f493d2015-03-17 22:26:22 +00003351 struct inode *inode = d_backing_inode(dentry);
Paul Moore20cdef82016-04-04 14:14:42 -04003352 struct inode_security_struct *isec;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003353 u32 newsid;
3354 int rc;
3355
3356 if (strcmp(name, XATTR_NAME_SELINUX)) {
3357 /* Not an attribute we recognize, so nothing to do. */
3358 return;
3359 }
3360
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05003361 rc = security_context_to_sid_force(&selinux_state, value, size,
3362 &newsid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003363 if (rc) {
peter enderborgc103a912018-06-12 10:09:03 +02003364 pr_err("SELinux: unable to map context to SID"
Stephen Smalley12b29f32008-05-07 13:03:20 -04003365 "for (%s, %lu), rc=%d\n",
3366 inode->i_sb->s_id, inode->i_ino, -rc);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003367 return;
3368 }
3369
Paul Moore20cdef82016-04-04 14:14:42 -04003370 isec = backing_inode_security(dentry);
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01003371 spin_lock(&isec->lock);
David Quigleyaa9c2662013-05-22 12:50:44 -04003372 isec->sclass = inode_mode_to_security_class(inode->i_mode);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003373 isec->sid = newsid;
Andreas Gruenbacher6f3be9f2015-12-24 11:09:40 -05003374 isec->initialized = LABEL_INITIALIZED;
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01003375 spin_unlock(&isec->lock);
David Quigleyaa9c2662013-05-22 12:50:44 -04003376
Linus Torvalds1da177e2005-04-16 15:20:36 -07003377 return;
3378}
3379
David Howells8f0cfa52008-04-29 00:59:41 -07003380static int selinux_inode_getxattr(struct dentry *dentry, const char *name)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003381{
David Howells88e67f32008-11-14 10:39:21 +11003382 const struct cred *cred = current_cred();
3383
Eric Paris2875fa02011-04-28 16:04:24 -04003384 return dentry_has_perm(cred, dentry, FILE__GETATTR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003385}
3386
Eric Paris828dfe12008-04-17 13:17:49 -04003387static int selinux_inode_listxattr(struct dentry *dentry)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003388{
David Howells88e67f32008-11-14 10:39:21 +11003389 const struct cred *cred = current_cred();
3390
Eric Paris2875fa02011-04-28 16:04:24 -04003391 return dentry_has_perm(cred, dentry, FILE__GETATTR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003392}
3393
David Howells8f0cfa52008-04-29 00:59:41 -07003394static int selinux_inode_removexattr(struct dentry *dentry, const char *name)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003395{
Eric W. Biederman6b240302017-10-02 09:38:20 -05003396 if (strcmp(name, XATTR_NAME_SELINUX)) {
3397 int rc = cap_inode_removexattr(dentry, name);
3398 if (rc)
3399 return rc;
3400
3401 /* Not an attribute we recognize, so just check the
3402 ordinary setattr permission. */
3403 return dentry_has_perm(current_cred(), dentry, FILE__SETATTR);
3404 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003405
3406 /* No one is allowed to remove a SELinux security label.
3407 You can change the label, but all data must be labeled. */
3408 return -EACCES;
3409}
3410
James Morrisd381d8a2005-10-30 14:59:22 -08003411/*
Stephen Smalleyabc69bb2008-05-21 14:16:12 -04003412 * Copy the inode security context value to the user.
James Morrisd381d8a2005-10-30 14:59:22 -08003413 *
3414 * Permission check is handled by selinux_inode_getxattr hook.
3415 */
Andreas Gruenbacherea861df2015-12-24 11:09:39 -05003416static int selinux_inode_getsecurity(struct inode *inode, const char *name, void **buffer, bool alloc)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003417{
David P. Quigley42492592008-02-04 22:29:39 -08003418 u32 size;
3419 int error;
3420 char *context = NULL;
Paul Moore20cdef82016-04-04 14:14:42 -04003421 struct inode_security_struct *isec;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003422
Dustin Kirkland8c8570f2005-11-03 17:15:16 +00003423 if (strcmp(name, XATTR_SELINUX_SUFFIX))
3424 return -EOPNOTSUPP;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003425
Stephen Smalleyabc69bb2008-05-21 14:16:12 -04003426 /*
3427 * If the caller has CAP_MAC_ADMIN, then get the raw context
3428 * value even if it is not defined by current policy; otherwise,
3429 * use the in-core value under current policy.
3430 * Use the non-auditing forms of the permission checks since
3431 * getxattr may be called by unprivileged processes commonly
3432 * and lack of permission just means that we fall back to the
3433 * in-core context value, not a denial.
3434 */
Paul Moore20cdef82016-04-04 14:14:42 -04003435 isec = inode_security(inode);
Stephen Smalleydb590002017-04-20 11:31:30 -04003436 if (has_cap_mac_admin(false))
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05003437 error = security_sid_to_context_force(&selinux_state,
3438 isec->sid, &context,
Stephen Smalleyabc69bb2008-05-21 14:16:12 -04003439 &size);
3440 else
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05003441 error = security_sid_to_context(&selinux_state, isec->sid,
3442 &context, &size);
David P. Quigley42492592008-02-04 22:29:39 -08003443 if (error)
3444 return error;
3445 error = size;
3446 if (alloc) {
3447 *buffer = context;
3448 goto out_nofree;
3449 }
3450 kfree(context);
3451out_nofree:
3452 return error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003453}
3454
3455static int selinux_inode_setsecurity(struct inode *inode, const char *name,
Eric Paris828dfe12008-04-17 13:17:49 -04003456 const void *value, size_t size, int flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003457{
Paul Moore2c971652016-04-19 16:36:28 -04003458 struct inode_security_struct *isec = inode_security_novalidate(inode);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003459 u32 newsid;
3460 int rc;
3461
3462 if (strcmp(name, XATTR_SELINUX_SUFFIX))
3463 return -EOPNOTSUPP;
3464
3465 if (!value || !size)
3466 return -EACCES;
3467
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05003468 rc = security_context_to_sid(&selinux_state, value, size, &newsid,
3469 GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003470 if (rc)
3471 return rc;
3472
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01003473 spin_lock(&isec->lock);
David Quigleyaa9c2662013-05-22 12:50:44 -04003474 isec->sclass = inode_mode_to_security_class(inode->i_mode);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003475 isec->sid = newsid;
Andreas Gruenbacher6f3be9f2015-12-24 11:09:40 -05003476 isec->initialized = LABEL_INITIALIZED;
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01003477 spin_unlock(&isec->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003478 return 0;
3479}
3480
3481static int selinux_inode_listsecurity(struct inode *inode, char *buffer, size_t buffer_size)
3482{
3483 const int len = sizeof(XATTR_NAME_SELINUX);
3484 if (buffer && len <= buffer_size)
3485 memcpy(buffer, XATTR_NAME_SELINUX, len);
3486 return len;
3487}
3488
Andreas Gruenbacherd6335d72015-12-24 11:09:39 -05003489static void selinux_inode_getsecid(struct inode *inode, u32 *secid)
Ahmed S. Darwish713a04ae2008-03-01 21:52:30 +02003490{
Andreas Gruenbachere817c2f2016-02-18 12:04:08 +01003491 struct inode_security_struct *isec = inode_security_novalidate(inode);
Ahmed S. Darwish713a04ae2008-03-01 21:52:30 +02003492 *secid = isec->sid;
3493}
3494
Vivek Goyal56909eb2016-07-13 10:44:48 -04003495static int selinux_inode_copy_up(struct dentry *src, struct cred **new)
3496{
3497 u32 sid;
3498 struct task_security_struct *tsec;
3499 struct cred *new_creds = *new;
3500
3501 if (new_creds == NULL) {
3502 new_creds = prepare_creds();
3503 if (!new_creds)
3504 return -ENOMEM;
3505 }
3506
3507 tsec = new_creds->security;
3508 /* Get label from overlay inode and set it in create_sid */
3509 selinux_inode_getsecid(d_inode(src), &sid);
3510 tsec->create_sid = sid;
3511 *new = new_creds;
3512 return 0;
3513}
3514
Vivek Goyal19472b62016-07-13 10:44:50 -04003515static int selinux_inode_copy_up_xattr(const char *name)
3516{
3517 /* The copy_up hook above sets the initial context on an inode, but we
3518 * don't then want to overwrite it by blindly copying all the lower
3519 * xattrs up. Instead, we have to filter out SELinux-related xattrs.
3520 */
3521 if (strcmp(name, XATTR_NAME_SELINUX) == 0)
3522 return 1; /* Discard */
3523 /*
3524 * Any other attribute apart from SELINUX is not claimed, supported
3525 * by selinux.
3526 */
3527 return -EOPNOTSUPP;
3528}
3529
Linus Torvalds1da177e2005-04-16 15:20:36 -07003530/* file security operations */
3531
Yuichi Nakamura788e7dd2007-09-14 09:27:07 +09003532static int selinux_revalidate_file_permission(struct file *file, int mask)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003533{
David Howells88e67f32008-11-14 10:39:21 +11003534 const struct cred *cred = current_cred();
Al Viro496ad9a2013-01-23 17:07:38 -05003535 struct inode *inode = file_inode(file);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003536
Linus Torvalds1da177e2005-04-16 15:20:36 -07003537 /* file_mask_to_av won't add FILE__WRITE if MAY_APPEND is set */
3538 if ((file->f_flags & O_APPEND) && (mask & MAY_WRITE))
3539 mask |= MAY_APPEND;
3540
Paul Moore389fb8002009-03-27 17:10:34 -04003541 return file_has_perm(cred, file,
3542 file_mask_to_av(inode->i_mode, mask));
Linus Torvalds1da177e2005-04-16 15:20:36 -07003543}
3544
Yuichi Nakamura788e7dd2007-09-14 09:27:07 +09003545static int selinux_file_permission(struct file *file, int mask)
3546{
Al Viro496ad9a2013-01-23 17:07:38 -05003547 struct inode *inode = file_inode(file);
Stephen Smalley20dda182009-06-22 14:54:53 -04003548 struct file_security_struct *fsec = file->f_security;
Andreas Gruenbacherb1973672016-01-05 23:12:33 +01003549 struct inode_security_struct *isec;
Stephen Smalley20dda182009-06-22 14:54:53 -04003550 u32 sid = current_sid();
3551
Paul Moore389fb8002009-03-27 17:10:34 -04003552 if (!mask)
Yuichi Nakamura788e7dd2007-09-14 09:27:07 +09003553 /* No permission to check. Existence test. */
3554 return 0;
Yuichi Nakamura788e7dd2007-09-14 09:27:07 +09003555
Andreas Gruenbacherb1973672016-01-05 23:12:33 +01003556 isec = inode_security(inode);
Stephen Smalley20dda182009-06-22 14:54:53 -04003557 if (sid == fsec->sid && fsec->isid == isec->sid &&
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003558 fsec->pseqno == avc_policy_seqno(&selinux_state))
Eric Paris83d49852012-04-04 13:45:40 -04003559 /* No change since file_open check. */
Stephen Smalley20dda182009-06-22 14:54:53 -04003560 return 0;
3561
Yuichi Nakamura788e7dd2007-09-14 09:27:07 +09003562 return selinux_revalidate_file_permission(file, mask);
3563}
3564
Linus Torvalds1da177e2005-04-16 15:20:36 -07003565static int selinux_file_alloc_security(struct file *file)
3566{
3567 return file_alloc_security(file);
3568}
3569
3570static void selinux_file_free_security(struct file *file)
3571{
3572 file_free_security(file);
3573}
3574
Jeff Vander Stoepfa1aa142015-07-10 17:19:56 -04003575/*
3576 * Check whether a task has the ioctl permission and cmd
3577 * operation to an inode.
3578 */
Geliang Tang1d2a1682015-10-21 17:44:27 -04003579static int ioctl_has_perm(const struct cred *cred, struct file *file,
Jeff Vander Stoepfa1aa142015-07-10 17:19:56 -04003580 u32 requested, u16 cmd)
3581{
3582 struct common_audit_data ad;
3583 struct file_security_struct *fsec = file->f_security;
3584 struct inode *inode = file_inode(file);
Paul Moore20cdef82016-04-04 14:14:42 -04003585 struct inode_security_struct *isec;
Jeff Vander Stoepfa1aa142015-07-10 17:19:56 -04003586 struct lsm_ioctlop_audit ioctl;
3587 u32 ssid = cred_sid(cred);
3588 int rc;
3589 u8 driver = cmd >> 8;
3590 u8 xperm = cmd & 0xff;
3591
3592 ad.type = LSM_AUDIT_DATA_IOCTL_OP;
3593 ad.u.op = &ioctl;
3594 ad.u.op->cmd = cmd;
3595 ad.u.op->path = file->f_path;
3596
3597 if (ssid != fsec->sid) {
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003598 rc = avc_has_perm(&selinux_state,
3599 ssid, fsec->sid,
Jeff Vander Stoepfa1aa142015-07-10 17:19:56 -04003600 SECCLASS_FD,
3601 FD__USE,
3602 &ad);
3603 if (rc)
3604 goto out;
3605 }
3606
3607 if (unlikely(IS_PRIVATE(inode)))
3608 return 0;
3609
Paul Moore20cdef82016-04-04 14:14:42 -04003610 isec = inode_security(inode);
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003611 rc = avc_has_extended_perms(&selinux_state,
3612 ssid, isec->sid, isec->sclass,
3613 requested, driver, xperm, &ad);
Jeff Vander Stoepfa1aa142015-07-10 17:19:56 -04003614out:
3615 return rc;
3616}
3617
Linus Torvalds1da177e2005-04-16 15:20:36 -07003618static int selinux_file_ioctl(struct file *file, unsigned int cmd,
3619 unsigned long arg)
3620{
David Howells88e67f32008-11-14 10:39:21 +11003621 const struct cred *cred = current_cred();
Eric Paris0b24dcb2011-02-25 15:39:20 -05003622 int error = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003623
Eric Paris0b24dcb2011-02-25 15:39:20 -05003624 switch (cmd) {
3625 case FIONREAD:
3626 /* fall through */
3627 case FIBMAP:
3628 /* fall through */
3629 case FIGETBSZ:
3630 /* fall through */
Al Viro2f99c362012-03-23 16:04:05 -04003631 case FS_IOC_GETFLAGS:
Eric Paris0b24dcb2011-02-25 15:39:20 -05003632 /* fall through */
Al Viro2f99c362012-03-23 16:04:05 -04003633 case FS_IOC_GETVERSION:
Eric Paris0b24dcb2011-02-25 15:39:20 -05003634 error = file_has_perm(cred, file, FILE__GETATTR);
3635 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003636
Al Viro2f99c362012-03-23 16:04:05 -04003637 case FS_IOC_SETFLAGS:
Eric Paris0b24dcb2011-02-25 15:39:20 -05003638 /* fall through */
Al Viro2f99c362012-03-23 16:04:05 -04003639 case FS_IOC_SETVERSION:
Eric Paris0b24dcb2011-02-25 15:39:20 -05003640 error = file_has_perm(cred, file, FILE__SETATTR);
3641 break;
3642
3643 /* sys_ioctl() checks */
3644 case FIONBIO:
3645 /* fall through */
3646 case FIOASYNC:
3647 error = file_has_perm(cred, file, 0);
3648 break;
3649
3650 case KDSKBENT:
3651 case KDSKBSENT:
Eric Paris6a9de492012-01-03 12:25:14 -05003652 error = cred_has_capability(cred, CAP_SYS_TTY_CONFIG,
Stephen Smalley8e4ff6f2016-04-08 13:52:00 -04003653 SECURITY_CAP_AUDIT, true);
Eric Paris0b24dcb2011-02-25 15:39:20 -05003654 break;
3655
3656 /* default case assumes that the command will go
3657 * to the file's ioctl() function.
3658 */
3659 default:
Jeff Vander Stoepfa1aa142015-07-10 17:19:56 -04003660 error = ioctl_has_perm(cred, file, FILE__IOCTL, (u16) cmd);
Eric Paris0b24dcb2011-02-25 15:39:20 -05003661 }
3662 return error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003663}
3664
Stephen Smalleyfcaaade2010-04-28 15:57:57 -04003665static int default_noexec;
3666
Linus Torvalds1da177e2005-04-16 15:20:36 -07003667static int file_map_prot_check(struct file *file, unsigned long prot, int shared)
3668{
David Howells88e67f32008-11-14 10:39:21 +11003669 const struct cred *cred = current_cred();
Stephen Smalleybe0554c2017-01-09 10:07:31 -05003670 u32 sid = cred_sid(cred);
David Howellsd84f4f92008-11-14 10:39:23 +11003671 int rc = 0;
David Howells88e67f32008-11-14 10:39:21 +11003672
Stephen Smalleyfcaaade2010-04-28 15:57:57 -04003673 if (default_noexec &&
Stephen Smalley892e8ca2015-07-10 09:40:59 -04003674 (prot & PROT_EXEC) && (!file || IS_PRIVATE(file_inode(file)) ||
3675 (!shared && (prot & PROT_WRITE)))) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003676 /*
3677 * We are making executable an anonymous mapping or a
3678 * private file mapping that will also be writable.
3679 * This has an additional check.
3680 */
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003681 rc = avc_has_perm(&selinux_state,
3682 sid, sid, SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05003683 PROCESS__EXECMEM, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003684 if (rc)
David Howellsd84f4f92008-11-14 10:39:23 +11003685 goto error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003686 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003687
3688 if (file) {
3689 /* read access is always possible with a mapping */
3690 u32 av = FILE__READ;
3691
3692 /* write access only matters if the mapping is shared */
3693 if (shared && (prot & PROT_WRITE))
3694 av |= FILE__WRITE;
3695
3696 if (prot & PROT_EXEC)
3697 av |= FILE__EXECUTE;
3698
David Howells88e67f32008-11-14 10:39:21 +11003699 return file_has_perm(cred, file, av);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003700 }
David Howellsd84f4f92008-11-14 10:39:23 +11003701
3702error:
3703 return rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003704}
3705
Al Viroe5467852012-05-30 13:30:51 -04003706static int selinux_mmap_addr(unsigned long addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003707{
Casey Schauflerb1d9e6b2015-05-02 15:11:42 -07003708 int rc = 0;
Paul Moore98883bf2014-03-19 16:46:11 -04003709
3710 if (addr < CONFIG_LSM_MMAP_MIN_ADDR) {
3711 u32 sid = current_sid();
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003712 rc = avc_has_perm(&selinux_state,
3713 sid, sid, SECCLASS_MEMPROTECT,
Paul Moore98883bf2014-03-19 16:46:11 -04003714 MEMPROTECT__MMAP_ZERO, NULL);
3715 }
3716
3717 return rc;
Al Viroe5467852012-05-30 13:30:51 -04003718}
Linus Torvalds1da177e2005-04-16 15:20:36 -07003719
Al Viroe5467852012-05-30 13:30:51 -04003720static int selinux_mmap_file(struct file *file, unsigned long reqprot,
3721 unsigned long prot, unsigned long flags)
3722{
Stephen Smalley3ba4bf52017-05-05 09:14:48 -04003723 struct common_audit_data ad;
3724 int rc;
3725
3726 if (file) {
3727 ad.type = LSM_AUDIT_DATA_FILE;
3728 ad.u.file = file;
3729 rc = inode_has_perm(current_cred(), file_inode(file),
3730 FILE__MAP, &ad);
3731 if (rc)
3732 return rc;
3733 }
3734
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05003735 if (selinux_state.checkreqprot)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003736 prot = reqprot;
3737
3738 return file_map_prot_check(file, prot,
3739 (flags & MAP_TYPE) == MAP_SHARED);
3740}
3741
3742static int selinux_file_mprotect(struct vm_area_struct *vma,
3743 unsigned long reqprot,
3744 unsigned long prot)
3745{
David Howells88e67f32008-11-14 10:39:21 +11003746 const struct cred *cred = current_cred();
Stephen Smalleybe0554c2017-01-09 10:07:31 -05003747 u32 sid = cred_sid(cred);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003748
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05003749 if (selinux_state.checkreqprot)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003750 prot = reqprot;
3751
Stephen Smalleyfcaaade2010-04-28 15:57:57 -04003752 if (default_noexec &&
3753 (prot & PROT_EXEC) && !(vma->vm_flags & VM_EXEC)) {
James Morrisd541bbe2009-01-29 12:19:51 +11003754 int rc = 0;
Stephen Smalleydb4c9642006-02-01 03:05:54 -08003755 if (vma->vm_start >= vma->vm_mm->start_brk &&
3756 vma->vm_end <= vma->vm_mm->brk) {
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003757 rc = avc_has_perm(&selinux_state,
3758 sid, sid, SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05003759 PROCESS__EXECHEAP, NULL);
Stephen Smalleydb4c9642006-02-01 03:05:54 -08003760 } else if (!vma->vm_file &&
Stephen Smalleyc2316db2016-04-08 13:55:03 -04003761 ((vma->vm_start <= vma->vm_mm->start_stack &&
3762 vma->vm_end >= vma->vm_mm->start_stack) ||
Andy Lutomirskid17af502016-09-30 10:58:58 -07003763 vma_is_stack_for_current(vma))) {
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003764 rc = avc_has_perm(&selinux_state,
3765 sid, sid, SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05003766 PROCESS__EXECSTACK, NULL);
Stephen Smalleydb4c9642006-02-01 03:05:54 -08003767 } else if (vma->vm_file && vma->anon_vma) {
3768 /*
3769 * We are making executable a file mapping that has
3770 * had some COW done. Since pages might have been
3771 * written, check ability to execute the possibly
3772 * modified content. This typically should only
3773 * occur for text relocations.
3774 */
David Howellsd84f4f92008-11-14 10:39:23 +11003775 rc = file_has_perm(cred, vma->vm_file, FILE__EXECMOD);
Stephen Smalleydb4c9642006-02-01 03:05:54 -08003776 }
Lorenzo Hernandez García-Hierro6b992192005-06-25 14:54:34 -07003777 if (rc)
3778 return rc;
3779 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003780
3781 return file_map_prot_check(vma->vm_file, prot, vma->vm_flags&VM_SHARED);
3782}
3783
3784static int selinux_file_lock(struct file *file, unsigned int cmd)
3785{
David Howells88e67f32008-11-14 10:39:21 +11003786 const struct cred *cred = current_cred();
3787
3788 return file_has_perm(cred, file, FILE__LOCK);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003789}
3790
3791static int selinux_file_fcntl(struct file *file, unsigned int cmd,
3792 unsigned long arg)
3793{
David Howells88e67f32008-11-14 10:39:21 +11003794 const struct cred *cred = current_cred();
Linus Torvalds1da177e2005-04-16 15:20:36 -07003795 int err = 0;
3796
3797 switch (cmd) {
Eric Paris828dfe12008-04-17 13:17:49 -04003798 case F_SETFL:
Eric Paris828dfe12008-04-17 13:17:49 -04003799 if ((file->f_flags & O_APPEND) && !(arg & O_APPEND)) {
David Howells88e67f32008-11-14 10:39:21 +11003800 err = file_has_perm(cred, file, FILE__WRITE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003801 break;
Eric Paris828dfe12008-04-17 13:17:49 -04003802 }
3803 /* fall through */
3804 case F_SETOWN:
3805 case F_SETSIG:
3806 case F_GETFL:
3807 case F_GETOWN:
3808 case F_GETSIG:
Cyrill Gorcunov1d151c32012-07-30 14:43:00 -07003809 case F_GETOWNER_UIDS:
Eric Paris828dfe12008-04-17 13:17:49 -04003810 /* Just check FD__USE permission */
David Howells88e67f32008-11-14 10:39:21 +11003811 err = file_has_perm(cred, file, 0);
Eric Paris828dfe12008-04-17 13:17:49 -04003812 break;
3813 case F_GETLK:
3814 case F_SETLK:
3815 case F_SETLKW:
Jeff Layton0d3f7a22014-04-22 08:23:58 -04003816 case F_OFD_GETLK:
3817 case F_OFD_SETLK:
3818 case F_OFD_SETLKW:
Linus Torvalds1da177e2005-04-16 15:20:36 -07003819#if BITS_PER_LONG == 32
Eric Paris828dfe12008-04-17 13:17:49 -04003820 case F_GETLK64:
3821 case F_SETLK64:
3822 case F_SETLKW64:
Linus Torvalds1da177e2005-04-16 15:20:36 -07003823#endif
David Howells88e67f32008-11-14 10:39:21 +11003824 err = file_has_perm(cred, file, FILE__LOCK);
Eric Paris828dfe12008-04-17 13:17:49 -04003825 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003826 }
3827
3828 return err;
3829}
3830
Jeff Laytone0b93ed2014-08-22 11:27:32 -04003831static void selinux_file_set_fowner(struct file *file)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003832{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003833 struct file_security_struct *fsec;
3834
Linus Torvalds1da177e2005-04-16 15:20:36 -07003835 fsec = file->f_security;
David Howells275bb412008-11-14 10:39:19 +11003836 fsec->fown_sid = current_sid();
Linus Torvalds1da177e2005-04-16 15:20:36 -07003837}
3838
3839static int selinux_file_send_sigiotask(struct task_struct *tsk,
3840 struct fown_struct *fown, int signum)
3841{
Eric Paris828dfe12008-04-17 13:17:49 -04003842 struct file *file;
Stephen Smalley65c90bc2009-05-04 15:43:18 -04003843 u32 sid = task_sid(tsk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003844 u32 perm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003845 struct file_security_struct *fsec;
3846
3847 /* struct fown_struct is never outside the context of a struct file */
Eric Paris828dfe12008-04-17 13:17:49 -04003848 file = container_of(fown, struct file, f_owner);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003849
Linus Torvalds1da177e2005-04-16 15:20:36 -07003850 fsec = file->f_security;
3851
3852 if (!signum)
3853 perm = signal_to_av(SIGIO); /* as per send_sigio_to_task */
3854 else
3855 perm = signal_to_av(signum);
3856
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003857 return avc_has_perm(&selinux_state,
3858 fsec->fown_sid, sid,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003859 SECCLASS_PROCESS, perm, NULL);
3860}
3861
3862static int selinux_file_receive(struct file *file)
3863{
David Howells88e67f32008-11-14 10:39:21 +11003864 const struct cred *cred = current_cred();
3865
3866 return file_has_perm(cred, file, file_to_av(file));
Linus Torvalds1da177e2005-04-16 15:20:36 -07003867}
3868
Al Viro94817692018-07-10 14:13:18 -04003869static int selinux_file_open(struct file *file)
Yuichi Nakamura788e7dd2007-09-14 09:27:07 +09003870{
3871 struct file_security_struct *fsec;
Yuichi Nakamura788e7dd2007-09-14 09:27:07 +09003872 struct inode_security_struct *isec;
David Howellsd84f4f92008-11-14 10:39:23 +11003873
Yuichi Nakamura788e7dd2007-09-14 09:27:07 +09003874 fsec = file->f_security;
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -05003875 isec = inode_security(file_inode(file));
Yuichi Nakamura788e7dd2007-09-14 09:27:07 +09003876 /*
3877 * Save inode label and policy sequence number
3878 * at open-time so that selinux_file_permission
3879 * can determine whether revalidation is necessary.
3880 * Task label is already saved in the file security
3881 * struct as its SID.
3882 */
3883 fsec->isid = isec->sid;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003884 fsec->pseqno = avc_policy_seqno(&selinux_state);
Yuichi Nakamura788e7dd2007-09-14 09:27:07 +09003885 /*
3886 * Since the inode label or policy seqno may have changed
3887 * between the selinux_inode_permission check and the saving
3888 * of state above, recheck that access is still permitted.
3889 * Otherwise, access might never be revalidated against the
3890 * new inode label or new policy.
3891 * This check is not redundant - do not remove.
3892 */
Al Viro94817692018-07-10 14:13:18 -04003893 return file_path_has_perm(file->f_cred, file, open_file_to_av(file));
Yuichi Nakamura788e7dd2007-09-14 09:27:07 +09003894}
3895
Linus Torvalds1da177e2005-04-16 15:20:36 -07003896/* task security operations */
3897
Tetsuo Handaa79be232017-03-28 23:08:45 +09003898static int selinux_task_alloc(struct task_struct *task,
3899 unsigned long clone_flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003900{
Stephen Smalleybe0554c2017-01-09 10:07:31 -05003901 u32 sid = current_sid();
3902
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003903 return avc_has_perm(&selinux_state,
3904 sid, sid, SECCLASS_PROCESS, PROCESS__FORK, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003905}
3906
David Howellsf1752ee2008-11-14 10:39:17 +11003907/*
David Howellsee18d642009-09-02 09:14:21 +01003908 * allocate the SELinux part of blank credentials
3909 */
3910static int selinux_cred_alloc_blank(struct cred *cred, gfp_t gfp)
3911{
3912 struct task_security_struct *tsec;
3913
3914 tsec = kzalloc(sizeof(struct task_security_struct), gfp);
3915 if (!tsec)
3916 return -ENOMEM;
3917
3918 cred->security = tsec;
3919 return 0;
3920}
3921
3922/*
David Howellsf1752ee2008-11-14 10:39:17 +11003923 * detach and free the LSM part of a set of credentials
3924 */
3925static void selinux_cred_free(struct cred *cred)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003926{
David Howellsf1752ee2008-11-14 10:39:17 +11003927 struct task_security_struct *tsec = cred->security;
David Howellse0e81732009-09-02 09:13:40 +01003928
Tetsuo Handa2edeaa32011-02-07 13:36:10 +00003929 /*
3930 * cred->security == NULL if security_cred_alloc_blank() or
3931 * security_prepare_creds() returned an error.
3932 */
3933 BUG_ON(cred->security && (unsigned long) cred->security < PAGE_SIZE);
David Howellse0e81732009-09-02 09:13:40 +01003934 cred->security = (void *) 0x7UL;
David Howellsf1752ee2008-11-14 10:39:17 +11003935 kfree(tsec);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003936}
3937
David Howellsd84f4f92008-11-14 10:39:23 +11003938/*
3939 * prepare a new set of credentials for modification
3940 */
3941static int selinux_cred_prepare(struct cred *new, const struct cred *old,
3942 gfp_t gfp)
3943{
3944 const struct task_security_struct *old_tsec;
3945 struct task_security_struct *tsec;
3946
3947 old_tsec = old->security;
3948
3949 tsec = kmemdup(old_tsec, sizeof(struct task_security_struct), gfp);
3950 if (!tsec)
3951 return -ENOMEM;
3952
3953 new->security = tsec;
3954 return 0;
3955}
3956
3957/*
David Howellsee18d642009-09-02 09:14:21 +01003958 * transfer the SELinux data to a blank set of creds
3959 */
3960static void selinux_cred_transfer(struct cred *new, const struct cred *old)
3961{
3962 const struct task_security_struct *old_tsec = old->security;
3963 struct task_security_struct *tsec = new->security;
3964
3965 *tsec = *old_tsec;
3966}
3967
Matthew Garrett3ec30112018-01-08 13:36:19 -08003968static void selinux_cred_getsecid(const struct cred *c, u32 *secid)
3969{
3970 *secid = cred_sid(c);
3971}
3972
David Howellsee18d642009-09-02 09:14:21 +01003973/*
David Howells3a3b7ce2008-11-14 10:39:28 +11003974 * set the security data for a kernel service
3975 * - all the creation contexts are set to unlabelled
3976 */
3977static int selinux_kernel_act_as(struct cred *new, u32 secid)
3978{
3979 struct task_security_struct *tsec = new->security;
3980 u32 sid = current_sid();
3981 int ret;
3982
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003983 ret = avc_has_perm(&selinux_state,
3984 sid, secid,
David Howells3a3b7ce2008-11-14 10:39:28 +11003985 SECCLASS_KERNEL_SERVICE,
3986 KERNEL_SERVICE__USE_AS_OVERRIDE,
3987 NULL);
3988 if (ret == 0) {
3989 tsec->sid = secid;
3990 tsec->create_sid = 0;
3991 tsec->keycreate_sid = 0;
3992 tsec->sockcreate_sid = 0;
3993 }
3994 return ret;
3995}
3996
3997/*
3998 * set the file creation context in a security record to the same as the
3999 * objective context of the specified inode
4000 */
4001static int selinux_kernel_create_files_as(struct cred *new, struct inode *inode)
4002{
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -05004003 struct inode_security_struct *isec = inode_security(inode);
David Howells3a3b7ce2008-11-14 10:39:28 +11004004 struct task_security_struct *tsec = new->security;
4005 u32 sid = current_sid();
4006 int ret;
4007
Stephen Smalley6b6bc622018-03-05 11:47:56 -05004008 ret = avc_has_perm(&selinux_state,
4009 sid, isec->sid,
David Howells3a3b7ce2008-11-14 10:39:28 +11004010 SECCLASS_KERNEL_SERVICE,
4011 KERNEL_SERVICE__CREATE_FILES_AS,
4012 NULL);
4013
4014 if (ret == 0)
4015 tsec->create_sid = isec->sid;
David Howellsef574712010-02-26 01:56:16 +00004016 return ret;
David Howells3a3b7ce2008-11-14 10:39:28 +11004017}
4018
Eric Parisdd8dbf22009-11-03 16:35:32 +11004019static int selinux_kernel_module_request(char *kmod_name)
Eric Paris25354c42009-08-13 09:45:03 -04004020{
Eric Parisdd8dbf22009-11-03 16:35:32 +11004021 struct common_audit_data ad;
4022
Eric Paris50c205f2012-04-04 15:01:43 -04004023 ad.type = LSM_AUDIT_DATA_KMOD;
Eric Parisdd8dbf22009-11-03 16:35:32 +11004024 ad.u.kmod_name = kmod_name;
4025
Stephen Smalley6b6bc622018-03-05 11:47:56 -05004026 return avc_has_perm(&selinux_state,
4027 current_sid(), SECINITSID_KERNEL, SECCLASS_SYSTEM,
Eric Parisdd8dbf22009-11-03 16:35:32 +11004028 SYSTEM__MODULE_REQUEST, &ad);
Eric Paris25354c42009-08-13 09:45:03 -04004029}
4030
Jeff Vander Stoep61d612ea2016-04-05 13:06:27 -07004031static int selinux_kernel_module_from_file(struct file *file)
4032{
4033 struct common_audit_data ad;
4034 struct inode_security_struct *isec;
4035 struct file_security_struct *fsec;
4036 u32 sid = current_sid();
4037 int rc;
4038
4039 /* init_module */
4040 if (file == NULL)
Stephen Smalley6b6bc622018-03-05 11:47:56 -05004041 return avc_has_perm(&selinux_state,
4042 sid, sid, SECCLASS_SYSTEM,
Jeff Vander Stoep61d612ea2016-04-05 13:06:27 -07004043 SYSTEM__MODULE_LOAD, NULL);
4044
4045 /* finit_module */
Paul Moore20cdef82016-04-04 14:14:42 -04004046
Vivek Goyal43af5de2016-09-09 11:37:49 -04004047 ad.type = LSM_AUDIT_DATA_FILE;
4048 ad.u.file = file;
Jeff Vander Stoep61d612ea2016-04-05 13:06:27 -07004049
Jeff Vander Stoep61d612ea2016-04-05 13:06:27 -07004050 fsec = file->f_security;
Jeff Vander Stoep61d612ea2016-04-05 13:06:27 -07004051 if (sid != fsec->sid) {
Stephen Smalley6b6bc622018-03-05 11:47:56 -05004052 rc = avc_has_perm(&selinux_state,
4053 sid, fsec->sid, SECCLASS_FD, FD__USE, &ad);
Jeff Vander Stoep61d612ea2016-04-05 13:06:27 -07004054 if (rc)
4055 return rc;
4056 }
4057
Paul Moore20cdef82016-04-04 14:14:42 -04004058 isec = inode_security(file_inode(file));
Stephen Smalley6b6bc622018-03-05 11:47:56 -05004059 return avc_has_perm(&selinux_state,
4060 sid, isec->sid, SECCLASS_SYSTEM,
Jeff Vander Stoep61d612ea2016-04-05 13:06:27 -07004061 SYSTEM__MODULE_LOAD, &ad);
4062}
4063
4064static int selinux_kernel_read_file(struct file *file,
4065 enum kernel_read_file_id id)
4066{
4067 int rc = 0;
4068
4069 switch (id) {
4070 case READING_MODULE:
4071 rc = selinux_kernel_module_from_file(file);
4072 break;
4073 default:
4074 break;
4075 }
4076
4077 return rc;
4078}
4079
Mimi Zoharc77b8cd2018-07-13 14:06:02 -04004080static int selinux_kernel_load_data(enum kernel_load_data_id id)
4081{
4082 int rc = 0;
4083
4084 switch (id) {
4085 case LOADING_MODULE:
4086 rc = selinux_kernel_module_from_file(NULL);
4087 default:
4088 break;
4089 }
4090
4091 return rc;
4092}
4093
Linus Torvalds1da177e2005-04-16 15:20:36 -07004094static int selinux_task_setpgid(struct task_struct *p, pid_t pgid)
4095{
Stephen Smalley6b6bc622018-03-05 11:47:56 -05004096 return avc_has_perm(&selinux_state,
4097 current_sid(), task_sid(p), SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05004098 PROCESS__SETPGID, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004099}
4100
4101static int selinux_task_getpgid(struct task_struct *p)
4102{
Stephen Smalley6b6bc622018-03-05 11:47:56 -05004103 return avc_has_perm(&selinux_state,
4104 current_sid(), task_sid(p), SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05004105 PROCESS__GETPGID, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004106}
4107
4108static int selinux_task_getsid(struct task_struct *p)
4109{
Stephen Smalley6b6bc622018-03-05 11:47:56 -05004110 return avc_has_perm(&selinux_state,
4111 current_sid(), task_sid(p), SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05004112 PROCESS__GETSESSION, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004113}
4114
David Quigleyf9008e4c2006-06-30 01:55:46 -07004115static void selinux_task_getsecid(struct task_struct *p, u32 *secid)
4116{
David Howells275bb412008-11-14 10:39:19 +11004117 *secid = task_sid(p);
David Quigleyf9008e4c2006-06-30 01:55:46 -07004118}
4119
Linus Torvalds1da177e2005-04-16 15:20:36 -07004120static int selinux_task_setnice(struct task_struct *p, int nice)
4121{
Stephen Smalley6b6bc622018-03-05 11:47:56 -05004122 return avc_has_perm(&selinux_state,
4123 current_sid(), task_sid(p), SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05004124 PROCESS__SETSCHED, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004125}
4126
James Morris03e68062006-06-23 02:03:58 -07004127static int selinux_task_setioprio(struct task_struct *p, int ioprio)
4128{
Stephen Smalley6b6bc622018-03-05 11:47:56 -05004129 return avc_has_perm(&selinux_state,
4130 current_sid(), task_sid(p), SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05004131 PROCESS__SETSCHED, NULL);
James Morris03e68062006-06-23 02:03:58 -07004132}
4133
David Quigleya1836a42006-06-30 01:55:49 -07004134static int selinux_task_getioprio(struct task_struct *p)
4135{
Stephen Smalley6b6bc622018-03-05 11:47:56 -05004136 return avc_has_perm(&selinux_state,
4137 current_sid(), task_sid(p), SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05004138 PROCESS__GETSCHED, NULL);
David Quigleya1836a42006-06-30 01:55:49 -07004139}
4140
Corentin LABBE42985552017-10-04 20:32:18 +02004141static int selinux_task_prlimit(const struct cred *cred, const struct cred *tcred,
4142 unsigned int flags)
Stephen Smalley791ec492017-02-17 07:57:00 -05004143{
4144 u32 av = 0;
4145
Stephen Smalley84e68852017-02-28 09:35:08 -05004146 if (!flags)
4147 return 0;
Stephen Smalley791ec492017-02-17 07:57:00 -05004148 if (flags & LSM_PRLIMIT_WRITE)
4149 av |= PROCESS__SETRLIMIT;
4150 if (flags & LSM_PRLIMIT_READ)
4151 av |= PROCESS__GETRLIMIT;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05004152 return avc_has_perm(&selinux_state,
4153 cred_sid(cred), cred_sid(tcred),
Stephen Smalley791ec492017-02-17 07:57:00 -05004154 SECCLASS_PROCESS, av, NULL);
4155}
4156
Jiri Slaby8fd00b42009-08-26 18:41:16 +02004157static int selinux_task_setrlimit(struct task_struct *p, unsigned int resource,
4158 struct rlimit *new_rlim)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004159{
Jiri Slaby8fd00b42009-08-26 18:41:16 +02004160 struct rlimit *old_rlim = p->signal->rlim + resource;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004161
4162 /* Control the ability to change the hard limit (whether
4163 lowering or raising it), so that the hard limit can
4164 later be used as a safe reset point for the soft limit
David Howellsd84f4f92008-11-14 10:39:23 +11004165 upon context transitions. See selinux_bprm_committing_creds. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07004166 if (old_rlim->rlim_max != new_rlim->rlim_max)
Stephen Smalley6b6bc622018-03-05 11:47:56 -05004167 return avc_has_perm(&selinux_state,
4168 current_sid(), task_sid(p),
Stephen Smalleybe0554c2017-01-09 10:07:31 -05004169 SECCLASS_PROCESS, PROCESS__SETRLIMIT, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004170
4171 return 0;
4172}
4173
KOSAKI Motohirob0ae1982010-10-15 04:21:18 +09004174static int selinux_task_setscheduler(struct task_struct *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004175{
Stephen Smalley6b6bc622018-03-05 11:47:56 -05004176 return avc_has_perm(&selinux_state,
4177 current_sid(), task_sid(p), SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05004178 PROCESS__SETSCHED, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004179}
4180
4181static int selinux_task_getscheduler(struct task_struct *p)
4182{
Stephen Smalley6b6bc622018-03-05 11:47:56 -05004183 return avc_has_perm(&selinux_state,
4184 current_sid(), task_sid(p), SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05004185 PROCESS__GETSCHED, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004186}
4187
David Quigley35601542006-06-23 02:04:01 -07004188static int selinux_task_movememory(struct task_struct *p)
4189{
Stephen Smalley6b6bc622018-03-05 11:47:56 -05004190 return avc_has_perm(&selinux_state,
4191 current_sid(), task_sid(p), SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05004192 PROCESS__SETSCHED, NULL);
David Quigley35601542006-06-23 02:04:01 -07004193}
4194
Eric W. Biedermanae7795b2018-09-25 11:27:20 +02004195static int selinux_task_kill(struct task_struct *p, struct kernel_siginfo *info,
Stephen Smalley6b4f3d02017-09-08 12:40:01 -04004196 int sig, const struct cred *cred)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004197{
Stephen Smalley6b4f3d02017-09-08 12:40:01 -04004198 u32 secid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004199 u32 perm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004200
Linus Torvalds1da177e2005-04-16 15:20:36 -07004201 if (!sig)
4202 perm = PROCESS__SIGNULL; /* null signal; existence test */
4203 else
4204 perm = signal_to_av(sig);
Stephen Smalley6b4f3d02017-09-08 12:40:01 -04004205 if (!cred)
Stephen Smalleybe0554c2017-01-09 10:07:31 -05004206 secid = current_sid();
Stephen Smalley6b4f3d02017-09-08 12:40:01 -04004207 else
4208 secid = cred_sid(cred);
Stephen Smalley6b6bc622018-03-05 11:47:56 -05004209 return avc_has_perm(&selinux_state,
4210 secid, task_sid(p), SECCLASS_PROCESS, perm, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004211}
4212
Linus Torvalds1da177e2005-04-16 15:20:36 -07004213static void selinux_task_to_inode(struct task_struct *p,
4214 struct inode *inode)
4215{
Linus Torvalds1da177e2005-04-16 15:20:36 -07004216 struct inode_security_struct *isec = inode->i_security;
David Howells275bb412008-11-14 10:39:19 +11004217 u32 sid = task_sid(p);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004218
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01004219 spin_lock(&isec->lock);
Andreas Gruenbacherdb978da2016-11-10 22:18:28 +01004220 isec->sclass = inode_mode_to_security_class(inode->i_mode);
David Howells275bb412008-11-14 10:39:19 +11004221 isec->sid = sid;
Andreas Gruenbacher6f3be9f2015-12-24 11:09:40 -05004222 isec->initialized = LABEL_INITIALIZED;
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01004223 spin_unlock(&isec->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004224}
4225
Linus Torvalds1da177e2005-04-16 15:20:36 -07004226/* Returns error only if unable to parse addresses */
Venkat Yekkirala67f83cb2006-11-08 17:04:26 -06004227static int selinux_parse_skb_ipv4(struct sk_buff *skb,
Thomas Liu2bf49692009-07-14 12:14:09 -04004228 struct common_audit_data *ad, u8 *proto)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004229{
4230 int offset, ihlen, ret = -EINVAL;
4231 struct iphdr _iph, *ih;
4232
Arnaldo Carvalho de Melobbe735e2007-03-10 22:16:10 -03004233 offset = skb_network_offset(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004234 ih = skb_header_pointer(skb, offset, sizeof(_iph), &_iph);
4235 if (ih == NULL)
4236 goto out;
4237
4238 ihlen = ih->ihl * 4;
4239 if (ihlen < sizeof(_iph))
4240 goto out;
4241
Eric Paris48c62af2012-04-02 13:15:44 -04004242 ad->u.net->v4info.saddr = ih->saddr;
4243 ad->u.net->v4info.daddr = ih->daddr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004244 ret = 0;
4245
Venkat Yekkirala67f83cb2006-11-08 17:04:26 -06004246 if (proto)
4247 *proto = ih->protocol;
4248
Linus Torvalds1da177e2005-04-16 15:20:36 -07004249 switch (ih->protocol) {
Eric Paris828dfe12008-04-17 13:17:49 -04004250 case IPPROTO_TCP: {
4251 struct tcphdr _tcph, *th;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004252
Eric Paris828dfe12008-04-17 13:17:49 -04004253 if (ntohs(ih->frag_off) & IP_OFFSET)
4254 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004255
4256 offset += ihlen;
4257 th = skb_header_pointer(skb, offset, sizeof(_tcph), &_tcph);
4258 if (th == NULL)
4259 break;
4260
Eric Paris48c62af2012-04-02 13:15:44 -04004261 ad->u.net->sport = th->source;
4262 ad->u.net->dport = th->dest;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004263 break;
Eric Paris828dfe12008-04-17 13:17:49 -04004264 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004265
Eric Paris828dfe12008-04-17 13:17:49 -04004266 case IPPROTO_UDP: {
4267 struct udphdr _udph, *uh;
4268
4269 if (ntohs(ih->frag_off) & IP_OFFSET)
4270 break;
4271
4272 offset += ihlen;
4273 uh = skb_header_pointer(skb, offset, sizeof(_udph), &_udph);
4274 if (uh == NULL)
4275 break;
4276
Eric Paris48c62af2012-04-02 13:15:44 -04004277 ad->u.net->sport = uh->source;
4278 ad->u.net->dport = uh->dest;
Eric Paris828dfe12008-04-17 13:17:49 -04004279 break;
4280 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004281
James Morris2ee92d42006-11-13 16:09:01 -08004282 case IPPROTO_DCCP: {
4283 struct dccp_hdr _dccph, *dh;
4284
4285 if (ntohs(ih->frag_off) & IP_OFFSET)
4286 break;
4287
4288 offset += ihlen;
4289 dh = skb_header_pointer(skb, offset, sizeof(_dccph), &_dccph);
4290 if (dh == NULL)
4291 break;
4292
Eric Paris48c62af2012-04-02 13:15:44 -04004293 ad->u.net->sport = dh->dccph_sport;
4294 ad->u.net->dport = dh->dccph_dport;
James Morris2ee92d42006-11-13 16:09:01 -08004295 break;
Eric Paris828dfe12008-04-17 13:17:49 -04004296 }
James Morris2ee92d42006-11-13 16:09:01 -08004297
Richard Hainesd4529302018-02-13 20:57:18 +00004298#if IS_ENABLED(CONFIG_IP_SCTP)
4299 case IPPROTO_SCTP: {
4300 struct sctphdr _sctph, *sh;
4301
4302 if (ntohs(ih->frag_off) & IP_OFFSET)
4303 break;
4304
4305 offset += ihlen;
4306 sh = skb_header_pointer(skb, offset, sizeof(_sctph), &_sctph);
4307 if (sh == NULL)
4308 break;
4309
4310 ad->u.net->sport = sh->source;
4311 ad->u.net->dport = sh->dest;
4312 break;
4313 }
4314#endif
Eric Paris828dfe12008-04-17 13:17:49 -04004315 default:
4316 break;
4317 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004318out:
4319 return ret;
4320}
4321
Javier Martinez Canillas1a93a6e2016-08-08 13:08:25 -04004322#if IS_ENABLED(CONFIG_IPV6)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004323
4324/* Returns error only if unable to parse addresses */
Venkat Yekkirala67f83cb2006-11-08 17:04:26 -06004325static int selinux_parse_skb_ipv6(struct sk_buff *skb,
Thomas Liu2bf49692009-07-14 12:14:09 -04004326 struct common_audit_data *ad, u8 *proto)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004327{
4328 u8 nexthdr;
4329 int ret = -EINVAL, offset;
4330 struct ipv6hdr _ipv6h, *ip6;
Jesse Gross75f28112011-11-30 17:05:51 -08004331 __be16 frag_off;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004332
Arnaldo Carvalho de Melobbe735e2007-03-10 22:16:10 -03004333 offset = skb_network_offset(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004334 ip6 = skb_header_pointer(skb, offset, sizeof(_ipv6h), &_ipv6h);
4335 if (ip6 == NULL)
4336 goto out;
4337
Eric Paris48c62af2012-04-02 13:15:44 -04004338 ad->u.net->v6info.saddr = ip6->saddr;
4339 ad->u.net->v6info.daddr = ip6->daddr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004340 ret = 0;
4341
4342 nexthdr = ip6->nexthdr;
4343 offset += sizeof(_ipv6h);
Jesse Gross75f28112011-11-30 17:05:51 -08004344 offset = ipv6_skip_exthdr(skb, offset, &nexthdr, &frag_off);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004345 if (offset < 0)
4346 goto out;
4347
Venkat Yekkirala67f83cb2006-11-08 17:04:26 -06004348 if (proto)
4349 *proto = nexthdr;
4350
Linus Torvalds1da177e2005-04-16 15:20:36 -07004351 switch (nexthdr) {
4352 case IPPROTO_TCP: {
Eric Paris828dfe12008-04-17 13:17:49 -04004353 struct tcphdr _tcph, *th;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004354
4355 th = skb_header_pointer(skb, offset, sizeof(_tcph), &_tcph);
4356 if (th == NULL)
4357 break;
4358
Eric Paris48c62af2012-04-02 13:15:44 -04004359 ad->u.net->sport = th->source;
4360 ad->u.net->dport = th->dest;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004361 break;
4362 }
4363
4364 case IPPROTO_UDP: {
4365 struct udphdr _udph, *uh;
4366
4367 uh = skb_header_pointer(skb, offset, sizeof(_udph), &_udph);
4368 if (uh == NULL)
4369 break;
4370
Eric Paris48c62af2012-04-02 13:15:44 -04004371 ad->u.net->sport = uh->source;
4372 ad->u.net->dport = uh->dest;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004373 break;
4374 }
4375
James Morris2ee92d42006-11-13 16:09:01 -08004376 case IPPROTO_DCCP: {
4377 struct dccp_hdr _dccph, *dh;
4378
4379 dh = skb_header_pointer(skb, offset, sizeof(_dccph), &_dccph);
4380 if (dh == NULL)
4381 break;
4382
Eric Paris48c62af2012-04-02 13:15:44 -04004383 ad->u.net->sport = dh->dccph_sport;
4384 ad->u.net->dport = dh->dccph_dport;
James Morris2ee92d42006-11-13 16:09:01 -08004385 break;
Eric Paris828dfe12008-04-17 13:17:49 -04004386 }
James Morris2ee92d42006-11-13 16:09:01 -08004387
Richard Hainesd4529302018-02-13 20:57:18 +00004388#if IS_ENABLED(CONFIG_IP_SCTP)
4389 case IPPROTO_SCTP: {
4390 struct sctphdr _sctph, *sh;
4391
4392 sh = skb_header_pointer(skb, offset, sizeof(_sctph), &_sctph);
4393 if (sh == NULL)
4394 break;
4395
4396 ad->u.net->sport = sh->source;
4397 ad->u.net->dport = sh->dest;
4398 break;
4399 }
4400#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07004401 /* includes fragments */
4402 default:
4403 break;
4404 }
4405out:
4406 return ret;
4407}
4408
4409#endif /* IPV6 */
4410
Thomas Liu2bf49692009-07-14 12:14:09 -04004411static int selinux_parse_skb(struct sk_buff *skb, struct common_audit_data *ad,
David Howellscf9481e2008-07-27 21:31:07 +10004412 char **_addrp, int src, u8 *proto)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004413{
David Howellscf9481e2008-07-27 21:31:07 +10004414 char *addrp;
4415 int ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004416
Eric Paris48c62af2012-04-02 13:15:44 -04004417 switch (ad->u.net->family) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004418 case PF_INET:
Venkat Yekkirala67f83cb2006-11-08 17:04:26 -06004419 ret = selinux_parse_skb_ipv4(skb, ad, proto);
David Howellscf9481e2008-07-27 21:31:07 +10004420 if (ret)
4421 goto parse_error;
Eric Paris48c62af2012-04-02 13:15:44 -04004422 addrp = (char *)(src ? &ad->u.net->v4info.saddr :
4423 &ad->u.net->v4info.daddr);
David Howellscf9481e2008-07-27 21:31:07 +10004424 goto okay;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004425
Javier Martinez Canillas1a93a6e2016-08-08 13:08:25 -04004426#if IS_ENABLED(CONFIG_IPV6)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004427 case PF_INET6:
Venkat Yekkirala67f83cb2006-11-08 17:04:26 -06004428 ret = selinux_parse_skb_ipv6(skb, ad, proto);
David Howellscf9481e2008-07-27 21:31:07 +10004429 if (ret)
4430 goto parse_error;
Eric Paris48c62af2012-04-02 13:15:44 -04004431 addrp = (char *)(src ? &ad->u.net->v6info.saddr :
4432 &ad->u.net->v6info.daddr);
David Howellscf9481e2008-07-27 21:31:07 +10004433 goto okay;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004434#endif /* IPV6 */
4435 default:
David Howellscf9481e2008-07-27 21:31:07 +10004436 addrp = NULL;
4437 goto okay;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004438 }
4439
David Howellscf9481e2008-07-27 21:31:07 +10004440parse_error:
peter enderborgc103a912018-06-12 10:09:03 +02004441 pr_warn(
David Howellscf9481e2008-07-27 21:31:07 +10004442 "SELinux: failure in selinux_parse_skb(),"
4443 " unable to parse packet\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07004444 return ret;
David Howellscf9481e2008-07-27 21:31:07 +10004445
4446okay:
4447 if (_addrp)
4448 *_addrp = addrp;
4449 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004450}
4451
Paul Moore4f6a9932007-03-01 14:35:22 -05004452/**
Paul Moore220deb92008-01-29 08:38:23 -05004453 * selinux_skb_peerlbl_sid - Determine the peer label of a packet
Paul Moore4f6a9932007-03-01 14:35:22 -05004454 * @skb: the packet
Paul Moore75e22912008-01-29 08:38:04 -05004455 * @family: protocol family
Paul Moore220deb92008-01-29 08:38:23 -05004456 * @sid: the packet's peer label SID
Paul Moore4f6a9932007-03-01 14:35:22 -05004457 *
4458 * Description:
Paul Moore220deb92008-01-29 08:38:23 -05004459 * Check the various different forms of network peer labeling and determine
4460 * the peer label/SID for the packet; most of the magic actually occurs in
4461 * the security server function security_net_peersid_cmp(). The function
4462 * returns zero if the value in @sid is valid (although it may be SECSID_NULL)
4463 * or -EACCES if @sid is invalid due to inconsistencies with the different
4464 * peer labels.
Paul Moore4f6a9932007-03-01 14:35:22 -05004465 *
4466 */
Paul Moore220deb92008-01-29 08:38:23 -05004467static int selinux_skb_peerlbl_sid(struct sk_buff *skb, u16 family, u32 *sid)
Paul Moore4f6a9932007-03-01 14:35:22 -05004468{
Paul Moore71f1cb02008-01-29 08:51:16 -05004469 int err;
Paul Moore4f6a9932007-03-01 14:35:22 -05004470 u32 xfrm_sid;
4471 u32 nlbl_sid;
Paul Moore220deb92008-01-29 08:38:23 -05004472 u32 nlbl_type;
Paul Moore4f6a9932007-03-01 14:35:22 -05004473
Paul Moore817eff72013-12-10 14:57:54 -05004474 err = selinux_xfrm_skb_sid(skb, &xfrm_sid);
Paul Moorebed4d7e2013-07-23 17:38:40 -04004475 if (unlikely(err))
4476 return -EACCES;
4477 err = selinux_netlbl_skbuff_getsid(skb, family, &nlbl_type, &nlbl_sid);
4478 if (unlikely(err))
4479 return -EACCES;
Paul Moore220deb92008-01-29 08:38:23 -05004480
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05004481 err = security_net_peersid_resolve(&selinux_state, nlbl_sid,
4482 nlbl_type, xfrm_sid, sid);
Paul Moore71f1cb02008-01-29 08:51:16 -05004483 if (unlikely(err)) {
peter enderborgc103a912018-06-12 10:09:03 +02004484 pr_warn(
Paul Moore71f1cb02008-01-29 08:51:16 -05004485 "SELinux: failure in selinux_skb_peerlbl_sid(),"
4486 " unable to determine packet's peer label\n");
Paul Moore220deb92008-01-29 08:38:23 -05004487 return -EACCES;
Paul Moore71f1cb02008-01-29 08:51:16 -05004488 }
Paul Moore220deb92008-01-29 08:38:23 -05004489
4490 return 0;
Paul Moore4f6a9932007-03-01 14:35:22 -05004491}
4492
Paul Moore446b8022013-12-04 16:10:51 -05004493/**
4494 * selinux_conn_sid - Determine the child socket label for a connection
4495 * @sk_sid: the parent socket's SID
4496 * @skb_sid: the packet's SID
4497 * @conn_sid: the resulting connection SID
4498 *
4499 * If @skb_sid is valid then the user:role:type information from @sk_sid is
4500 * combined with the MLS information from @skb_sid in order to create
4501 * @conn_sid. If @skb_sid is not valid then then @conn_sid is simply a copy
4502 * of @sk_sid. Returns zero on success, negative values on failure.
4503 *
4504 */
4505static int selinux_conn_sid(u32 sk_sid, u32 skb_sid, u32 *conn_sid)
4506{
4507 int err = 0;
4508
4509 if (skb_sid != SECSID_NULL)
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05004510 err = security_sid_mls_copy(&selinux_state, sk_sid, skb_sid,
4511 conn_sid);
Paul Moore446b8022013-12-04 16:10:51 -05004512 else
4513 *conn_sid = sk_sid;
4514
4515 return err;
4516}
4517
Linus Torvalds1da177e2005-04-16 15:20:36 -07004518/* socket security operations */
Paul Moored4f2d972010-04-22 14:46:18 -04004519
Harry Ciao2ad18bd2011-03-02 13:32:34 +08004520static int socket_sockcreate_sid(const struct task_security_struct *tsec,
4521 u16 secclass, u32 *socksid)
Paul Moored4f2d972010-04-22 14:46:18 -04004522{
Harry Ciao2ad18bd2011-03-02 13:32:34 +08004523 if (tsec->sockcreate_sid > SECSID_NULL) {
4524 *socksid = tsec->sockcreate_sid;
4525 return 0;
4526 }
4527
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05004528 return security_transition_sid(&selinux_state, tsec->sid, tsec->sid,
4529 secclass, NULL, socksid);
Paul Moored4f2d972010-04-22 14:46:18 -04004530}
4531
Stephen Smalleybe0554c2017-01-09 10:07:31 -05004532static int sock_has_perm(struct sock *sk, u32 perms)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004533{
Paul Moore253bfae2010-04-22 14:46:19 -04004534 struct sk_security_struct *sksec = sk->sk_security;
Thomas Liu2bf49692009-07-14 12:14:09 -04004535 struct common_audit_data ad;
Eric Paris48c62af2012-04-02 13:15:44 -04004536 struct lsm_network_audit net = {0,};
Linus Torvalds1da177e2005-04-16 15:20:36 -07004537
Paul Moore253bfae2010-04-22 14:46:19 -04004538 if (sksec->sid == SECINITSID_KERNEL)
4539 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004540
Eric Paris50c205f2012-04-04 15:01:43 -04004541 ad.type = LSM_AUDIT_DATA_NET;
Eric Paris48c62af2012-04-02 13:15:44 -04004542 ad.u.net = &net;
4543 ad.u.net->sk = sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004544
Stephen Smalley6b6bc622018-03-05 11:47:56 -05004545 return avc_has_perm(&selinux_state,
4546 current_sid(), sksec->sid, sksec->sclass, perms,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05004547 &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004548}
4549
4550static int selinux_socket_create(int family, int type,
4551 int protocol, int kern)
4552{
Paul Moore5fb49872010-04-22 14:46:19 -04004553 const struct task_security_struct *tsec = current_security();
Paul Moored4f2d972010-04-22 14:46:18 -04004554 u32 newsid;
David Howells275bb412008-11-14 10:39:19 +11004555 u16 secclass;
Harry Ciao2ad18bd2011-03-02 13:32:34 +08004556 int rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004557
4558 if (kern)
Paul Moored4f2d972010-04-22 14:46:18 -04004559 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004560
David Howells275bb412008-11-14 10:39:19 +11004561 secclass = socket_type_to_security_class(family, type, protocol);
Harry Ciao2ad18bd2011-03-02 13:32:34 +08004562 rc = socket_sockcreate_sid(tsec, secclass, &newsid);
4563 if (rc)
4564 return rc;
4565
Stephen Smalley6b6bc622018-03-05 11:47:56 -05004566 return avc_has_perm(&selinux_state,
4567 tsec->sid, newsid, secclass, SOCKET__CREATE, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004568}
4569
Venkat Yekkirala7420ed22006-08-04 23:17:57 -07004570static int selinux_socket_post_create(struct socket *sock, int family,
4571 int type, int protocol, int kern)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004572{
Paul Moore5fb49872010-04-22 14:46:19 -04004573 const struct task_security_struct *tsec = current_security();
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -05004574 struct inode_security_struct *isec = inode_security_novalidate(SOCK_INODE(sock));
Venkat Yekkirala892c1412006-08-04 23:08:56 -07004575 struct sk_security_struct *sksec;
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01004576 u16 sclass = socket_type_to_security_class(family, type, protocol);
4577 u32 sid = SECINITSID_KERNEL;
David Howells275bb412008-11-14 10:39:19 +11004578 int err = 0;
4579
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01004580 if (!kern) {
4581 err = socket_sockcreate_sid(tsec, sclass, &sid);
Harry Ciao2ad18bd2011-03-02 13:32:34 +08004582 if (err)
4583 return err;
4584 }
David Howells275bb412008-11-14 10:39:19 +11004585
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01004586 isec->sclass = sclass;
4587 isec->sid = sid;
Andreas Gruenbacher6f3be9f2015-12-24 11:09:40 -05004588 isec->initialized = LABEL_INITIALIZED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004589
Venkat Yekkirala892c1412006-08-04 23:08:56 -07004590 if (sock->sk) {
4591 sksec = sock->sk->sk_security;
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01004592 sksec->sclass = sclass;
4593 sksec->sid = sid;
Richard Hainesd4529302018-02-13 20:57:18 +00004594 /* Allows detection of the first association on this socket */
4595 if (sksec->sclass == SECCLASS_SCTP_SOCKET)
4596 sksec->sctp_assoc_state = SCTP_ASSOC_UNSET;
4597
Paul Moore389fb8002009-03-27 17:10:34 -04004598 err = selinux_netlbl_socket_post_create(sock->sk, family);
Venkat Yekkirala892c1412006-08-04 23:08:56 -07004599 }
4600
Venkat Yekkirala7420ed22006-08-04 23:17:57 -07004601 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004602}
4603
David Herrmann0b811db2018-05-04 16:28:21 +02004604static int selinux_socket_socketpair(struct socket *socka,
4605 struct socket *sockb)
4606{
4607 struct sk_security_struct *sksec_a = socka->sk->sk_security;
4608 struct sk_security_struct *sksec_b = sockb->sk->sk_security;
4609
4610 sksec_a->peer_sid = sksec_b->sid;
4611 sksec_b->peer_sid = sksec_a->sid;
4612
4613 return 0;
4614}
4615
Linus Torvalds1da177e2005-04-16 15:20:36 -07004616/* Range of port numbers used to automatically bind.
4617 Need to determine whether we should perform a name_bind
4618 permission check between the socket and the port number. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07004619
4620static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, int addrlen)
4621{
Paul Moore253bfae2010-04-22 14:46:19 -04004622 struct sock *sk = sock->sk;
Alexey Kodanev0f8db8c2018-05-11 20:15:11 +03004623 struct sk_security_struct *sksec = sk->sk_security;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004624 u16 family;
4625 int err;
4626
Stephen Smalleybe0554c2017-01-09 10:07:31 -05004627 err = sock_has_perm(sk, SOCKET__BIND);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004628 if (err)
4629 goto out;
4630
Richard Hainesd4529302018-02-13 20:57:18 +00004631 /* If PF_INET or PF_INET6, check name_bind permission for the port. */
Paul Moore253bfae2010-04-22 14:46:19 -04004632 family = sk->sk_family;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004633 if (family == PF_INET || family == PF_INET6) {
4634 char *addrp;
Thomas Liu2bf49692009-07-14 12:14:09 -04004635 struct common_audit_data ad;
Eric Paris48c62af2012-04-02 13:15:44 -04004636 struct lsm_network_audit net = {0,};
Linus Torvalds1da177e2005-04-16 15:20:36 -07004637 struct sockaddr_in *addr4 = NULL;
4638 struct sockaddr_in6 *addr6 = NULL;
Alexey Kodanev0f8db8c2018-05-11 20:15:11 +03004639 u16 family_sa = address->sa_family;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004640 unsigned short snum;
James Morrise399f982008-06-12 01:39:58 +10004641 u32 sid, node_perm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004642
Richard Hainesd4529302018-02-13 20:57:18 +00004643 /*
4644 * sctp_bindx(3) calls via selinux_sctp_bind_connect()
4645 * that validates multiple binding addresses. Because of this
4646 * need to check address->sa_family as it is possible to have
4647 * sk->sk_family = PF_INET6 with addr->sa_family = AF_INET.
4648 */
Alexey Kodanev0f8db8c2018-05-11 20:15:11 +03004649 switch (family_sa) {
4650 case AF_UNSPEC:
Richard Haines68741a8a2018-03-02 19:54:34 +00004651 case AF_INET:
4652 if (addrlen < sizeof(struct sockaddr_in))
4653 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004654 addr4 = (struct sockaddr_in *)address;
Alexey Kodanev0f8db8c2018-05-11 20:15:11 +03004655 if (family_sa == AF_UNSPEC) {
4656 /* see __inet_bind(), we only want to allow
4657 * AF_UNSPEC if the address is INADDR_ANY
4658 */
4659 if (addr4->sin_addr.s_addr != htonl(INADDR_ANY))
4660 goto err_af;
4661 family_sa = AF_INET;
4662 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004663 snum = ntohs(addr4->sin_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004664 addrp = (char *)&addr4->sin_addr.s_addr;
Richard Haines68741a8a2018-03-02 19:54:34 +00004665 break;
4666 case AF_INET6:
4667 if (addrlen < SIN6_LEN_RFC2133)
4668 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004669 addr6 = (struct sockaddr_in6 *)address;
4670 snum = ntohs(addr6->sin6_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004671 addrp = (char *)&addr6->sin6_addr.s6_addr;
Richard Haines68741a8a2018-03-02 19:54:34 +00004672 break;
4673 default:
Alexey Kodanev0f8db8c2018-05-11 20:15:11 +03004674 goto err_af;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004675 }
4676
Alexey Kodanev88b7d372018-05-11 20:15:12 +03004677 ad.type = LSM_AUDIT_DATA_NET;
4678 ad.u.net = &net;
4679 ad.u.net->sport = htons(snum);
4680 ad.u.net->family = family_sa;
4681
Stephen Hemminger227b60f2007-10-10 17:30:46 -07004682 if (snum) {
4683 int low, high;
4684
Eric W. Biederman0bbf87d2013-09-28 14:10:59 -07004685 inet_get_local_port_range(sock_net(sk), &low, &high);
Stephen Hemminger227b60f2007-10-10 17:30:46 -07004686
Krister Johansen4548b682017-01-20 17:49:11 -08004687 if (snum < max(inet_prot_sock(sock_net(sk)), low) ||
4688 snum > high) {
Paul Moore3e112172008-04-10 10:48:14 -04004689 err = sel_netport_sid(sk->sk_protocol,
4690 snum, &sid);
Stephen Hemminger227b60f2007-10-10 17:30:46 -07004691 if (err)
4692 goto out;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05004693 err = avc_has_perm(&selinux_state,
4694 sksec->sid, sid,
Paul Moore253bfae2010-04-22 14:46:19 -04004695 sksec->sclass,
Stephen Hemminger227b60f2007-10-10 17:30:46 -07004696 SOCKET__NAME_BIND, &ad);
4697 if (err)
4698 goto out;
4699 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004700 }
Eric Paris828dfe12008-04-17 13:17:49 -04004701
Paul Moore253bfae2010-04-22 14:46:19 -04004702 switch (sksec->sclass) {
James Morris13402582005-09-30 14:24:34 -04004703 case SECCLASS_TCP_SOCKET:
Linus Torvalds1da177e2005-04-16 15:20:36 -07004704 node_perm = TCP_SOCKET__NODE_BIND;
4705 break;
Eric Paris828dfe12008-04-17 13:17:49 -04004706
James Morris13402582005-09-30 14:24:34 -04004707 case SECCLASS_UDP_SOCKET:
Linus Torvalds1da177e2005-04-16 15:20:36 -07004708 node_perm = UDP_SOCKET__NODE_BIND;
4709 break;
James Morris2ee92d42006-11-13 16:09:01 -08004710
4711 case SECCLASS_DCCP_SOCKET:
4712 node_perm = DCCP_SOCKET__NODE_BIND;
4713 break;
4714
Richard Hainesd4529302018-02-13 20:57:18 +00004715 case SECCLASS_SCTP_SOCKET:
4716 node_perm = SCTP_SOCKET__NODE_BIND;
4717 break;
4718
Linus Torvalds1da177e2005-04-16 15:20:36 -07004719 default:
4720 node_perm = RAWIP_SOCKET__NODE_BIND;
4721 break;
4722 }
Eric Paris828dfe12008-04-17 13:17:49 -04004723
Alexey Kodanev88b7d372018-05-11 20:15:12 +03004724 err = sel_netnode_sid(addrp, family_sa, &sid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004725 if (err)
4726 goto out;
Eric Paris828dfe12008-04-17 13:17:49 -04004727
Alexey Kodanev0f8db8c2018-05-11 20:15:11 +03004728 if (family_sa == AF_INET)
Eric Paris48c62af2012-04-02 13:15:44 -04004729 ad.u.net->v4info.saddr = addr4->sin_addr.s_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004730 else
Eric Paris48c62af2012-04-02 13:15:44 -04004731 ad.u.net->v6info.saddr = addr6->sin6_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004732
Stephen Smalley6b6bc622018-03-05 11:47:56 -05004733 err = avc_has_perm(&selinux_state,
4734 sksec->sid, sid,
Paul Moore253bfae2010-04-22 14:46:19 -04004735 sksec->sclass, node_perm, &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004736 if (err)
4737 goto out;
4738 }
4739out:
4740 return err;
Alexey Kodanev0f8db8c2018-05-11 20:15:11 +03004741err_af:
4742 /* Note that SCTP services expect -EINVAL, others -EAFNOSUPPORT. */
4743 if (sksec->sclass == SECCLASS_SCTP_SOCKET)
4744 return -EINVAL;
4745 return -EAFNOSUPPORT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004746}
4747
Richard Hainesd4529302018-02-13 20:57:18 +00004748/* This supports connect(2) and SCTP connect services such as sctp_connectx(3)
Mauro Carvalho Chehab5fb94e92018-05-08 15:14:57 -03004749 * and sctp_sendmsg(3) as described in Documentation/security/LSM-sctp.rst
Richard Hainesd4529302018-02-13 20:57:18 +00004750 */
4751static int selinux_socket_connect_helper(struct socket *sock,
4752 struct sockaddr *address, int addrlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004753{
Paul Moore014ab192008-10-10 10:16:33 -04004754 struct sock *sk = sock->sk;
Paul Moore253bfae2010-04-22 14:46:19 -04004755 struct sk_security_struct *sksec = sk->sk_security;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004756 int err;
4757
Stephen Smalleybe0554c2017-01-09 10:07:31 -05004758 err = sock_has_perm(sk, SOCKET__CONNECT);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004759 if (err)
4760 return err;
4761
4762 /*
Richard Hainesd4529302018-02-13 20:57:18 +00004763 * If a TCP, DCCP or SCTP socket, check name_connect permission
4764 * for the port.
Linus Torvalds1da177e2005-04-16 15:20:36 -07004765 */
Paul Moore253bfae2010-04-22 14:46:19 -04004766 if (sksec->sclass == SECCLASS_TCP_SOCKET ||
Richard Hainesd4529302018-02-13 20:57:18 +00004767 sksec->sclass == SECCLASS_DCCP_SOCKET ||
4768 sksec->sclass == SECCLASS_SCTP_SOCKET) {
Thomas Liu2bf49692009-07-14 12:14:09 -04004769 struct common_audit_data ad;
Eric Paris48c62af2012-04-02 13:15:44 -04004770 struct lsm_network_audit net = {0,};
Linus Torvalds1da177e2005-04-16 15:20:36 -07004771 struct sockaddr_in *addr4 = NULL;
4772 struct sockaddr_in6 *addr6 = NULL;
4773 unsigned short snum;
James Morris2ee92d42006-11-13 16:09:01 -08004774 u32 sid, perm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004775
Richard Hainesd4529302018-02-13 20:57:18 +00004776 /* sctp_connectx(3) calls via selinux_sctp_bind_connect()
4777 * that validates multiple connect addresses. Because of this
4778 * need to check address->sa_family as it is possible to have
4779 * sk->sk_family = PF_INET6 with addr->sa_family = AF_INET.
4780 */
Richard Haines68741a8a2018-03-02 19:54:34 +00004781 switch (address->sa_family) {
4782 case AF_INET:
Linus Torvalds1da177e2005-04-16 15:20:36 -07004783 addr4 = (struct sockaddr_in *)address;
Stephen Smalley911656f2005-07-28 21:16:21 -07004784 if (addrlen < sizeof(struct sockaddr_in))
Linus Torvalds1da177e2005-04-16 15:20:36 -07004785 return -EINVAL;
4786 snum = ntohs(addr4->sin_port);
Richard Haines68741a8a2018-03-02 19:54:34 +00004787 break;
4788 case AF_INET6:
Linus Torvalds1da177e2005-04-16 15:20:36 -07004789 addr6 = (struct sockaddr_in6 *)address;
Stephen Smalley911656f2005-07-28 21:16:21 -07004790 if (addrlen < SIN6_LEN_RFC2133)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004791 return -EINVAL;
4792 snum = ntohs(addr6->sin6_port);
Richard Haines68741a8a2018-03-02 19:54:34 +00004793 break;
4794 default:
4795 /* Note that SCTP services expect -EINVAL, whereas
4796 * others expect -EAFNOSUPPORT.
4797 */
4798 if (sksec->sclass == SECCLASS_SCTP_SOCKET)
4799 return -EINVAL;
4800 else
4801 return -EAFNOSUPPORT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004802 }
4803
Paul Moore3e112172008-04-10 10:48:14 -04004804 err = sel_netport_sid(sk->sk_protocol, snum, &sid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004805 if (err)
Richard Hainesd4529302018-02-13 20:57:18 +00004806 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004807
Richard Hainesd4529302018-02-13 20:57:18 +00004808 switch (sksec->sclass) {
4809 case SECCLASS_TCP_SOCKET:
4810 perm = TCP_SOCKET__NAME_CONNECT;
4811 break;
4812 case SECCLASS_DCCP_SOCKET:
4813 perm = DCCP_SOCKET__NAME_CONNECT;
4814 break;
4815 case SECCLASS_SCTP_SOCKET:
4816 perm = SCTP_SOCKET__NAME_CONNECT;
4817 break;
4818 }
James Morris2ee92d42006-11-13 16:09:01 -08004819
Eric Paris50c205f2012-04-04 15:01:43 -04004820 ad.type = LSM_AUDIT_DATA_NET;
Eric Paris48c62af2012-04-02 13:15:44 -04004821 ad.u.net = &net;
4822 ad.u.net->dport = htons(snum);
Alexey Kodanev88b7d372018-05-11 20:15:12 +03004823 ad.u.net->family = address->sa_family;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05004824 err = avc_has_perm(&selinux_state,
4825 sksec->sid, sid, sksec->sclass, perm, &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004826 if (err)
Richard Hainesd4529302018-02-13 20:57:18 +00004827 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004828 }
4829
Richard Hainesd4529302018-02-13 20:57:18 +00004830 return 0;
4831}
Paul Moore014ab192008-10-10 10:16:33 -04004832
Richard Hainesd4529302018-02-13 20:57:18 +00004833/* Supports connect(2), see comments in selinux_socket_connect_helper() */
4834static int selinux_socket_connect(struct socket *sock,
4835 struct sockaddr *address, int addrlen)
4836{
4837 int err;
4838 struct sock *sk = sock->sk;
4839
4840 err = selinux_socket_connect_helper(sock, address, addrlen);
4841 if (err)
4842 return err;
4843
4844 return selinux_netlbl_socket_connect(sk, address);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004845}
4846
4847static int selinux_socket_listen(struct socket *sock, int backlog)
4848{
Stephen Smalleybe0554c2017-01-09 10:07:31 -05004849 return sock_has_perm(sock->sk, SOCKET__LISTEN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004850}
4851
4852static int selinux_socket_accept(struct socket *sock, struct socket *newsock)
4853{
4854 int err;
4855 struct inode_security_struct *isec;
4856 struct inode_security_struct *newisec;
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01004857 u16 sclass;
4858 u32 sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004859
Stephen Smalleybe0554c2017-01-09 10:07:31 -05004860 err = sock_has_perm(sock->sk, SOCKET__ACCEPT);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004861 if (err)
4862 return err;
4863
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -05004864 isec = inode_security_novalidate(SOCK_INODE(sock));
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01004865 spin_lock(&isec->lock);
4866 sclass = isec->sclass;
4867 sid = isec->sid;
4868 spin_unlock(&isec->lock);
4869
4870 newisec = inode_security_novalidate(SOCK_INODE(newsock));
4871 newisec->sclass = sclass;
4872 newisec->sid = sid;
Andreas Gruenbacher6f3be9f2015-12-24 11:09:40 -05004873 newisec->initialized = LABEL_INITIALIZED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004874
4875 return 0;
4876}
4877
4878static int selinux_socket_sendmsg(struct socket *sock, struct msghdr *msg,
Eric Paris828dfe12008-04-17 13:17:49 -04004879 int size)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004880{
Stephen Smalleybe0554c2017-01-09 10:07:31 -05004881 return sock_has_perm(sock->sk, SOCKET__WRITE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004882}
4883
4884static int selinux_socket_recvmsg(struct socket *sock, struct msghdr *msg,
4885 int size, int flags)
4886{
Stephen Smalleybe0554c2017-01-09 10:07:31 -05004887 return sock_has_perm(sock->sk, SOCKET__READ);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004888}
4889
4890static int selinux_socket_getsockname(struct socket *sock)
4891{
Stephen Smalleybe0554c2017-01-09 10:07:31 -05004892 return sock_has_perm(sock->sk, SOCKET__GETATTR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004893}
4894
4895static int selinux_socket_getpeername(struct socket *sock)
4896{
Stephen Smalleybe0554c2017-01-09 10:07:31 -05004897 return sock_has_perm(sock->sk, SOCKET__GETATTR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004898}
4899
Eric Paris828dfe12008-04-17 13:17:49 -04004900static int selinux_socket_setsockopt(struct socket *sock, int level, int optname)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004901{
Paul Mooref8687af2006-10-30 15:22:15 -08004902 int err;
4903
Stephen Smalleybe0554c2017-01-09 10:07:31 -05004904 err = sock_has_perm(sock->sk, SOCKET__SETOPT);
Paul Mooref8687af2006-10-30 15:22:15 -08004905 if (err)
4906 return err;
4907
4908 return selinux_netlbl_socket_setsockopt(sock, level, optname);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004909}
4910
4911static int selinux_socket_getsockopt(struct socket *sock, int level,
4912 int optname)
4913{
Stephen Smalleybe0554c2017-01-09 10:07:31 -05004914 return sock_has_perm(sock->sk, SOCKET__GETOPT);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004915}
4916
4917static int selinux_socket_shutdown(struct socket *sock, int how)
4918{
Stephen Smalleybe0554c2017-01-09 10:07:31 -05004919 return sock_has_perm(sock->sk, SOCKET__SHUTDOWN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004920}
4921
David S. Miller3610cda2011-01-05 15:38:53 -08004922static int selinux_socket_unix_stream_connect(struct sock *sock,
4923 struct sock *other,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004924 struct sock *newsk)
4925{
David S. Miller3610cda2011-01-05 15:38:53 -08004926 struct sk_security_struct *sksec_sock = sock->sk_security;
4927 struct sk_security_struct *sksec_other = other->sk_security;
Paul Moore4d1e2452010-04-22 14:46:18 -04004928 struct sk_security_struct *sksec_new = newsk->sk_security;
Thomas Liu2bf49692009-07-14 12:14:09 -04004929 struct common_audit_data ad;
Eric Paris48c62af2012-04-02 13:15:44 -04004930 struct lsm_network_audit net = {0,};
Linus Torvalds1da177e2005-04-16 15:20:36 -07004931 int err;
4932
Eric Paris50c205f2012-04-04 15:01:43 -04004933 ad.type = LSM_AUDIT_DATA_NET;
Eric Paris48c62af2012-04-02 13:15:44 -04004934 ad.u.net = &net;
4935 ad.u.net->sk = other;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004936
Stephen Smalley6b6bc622018-03-05 11:47:56 -05004937 err = avc_has_perm(&selinux_state,
4938 sksec_sock->sid, sksec_other->sid,
Paul Moore4d1e2452010-04-22 14:46:18 -04004939 sksec_other->sclass,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004940 UNIX_STREAM_SOCKET__CONNECTTO, &ad);
4941 if (err)
4942 return err;
4943
Linus Torvalds1da177e2005-04-16 15:20:36 -07004944 /* server child socket */
Paul Moore4d1e2452010-04-22 14:46:18 -04004945 sksec_new->peer_sid = sksec_sock->sid;
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05004946 err = security_sid_mls_copy(&selinux_state, sksec_other->sid,
4947 sksec_sock->sid, &sksec_new->sid);
Paul Moore4d1e2452010-04-22 14:46:18 -04004948 if (err)
4949 return err;
Venkat Yekkirala4237c752006-07-24 23:32:50 -07004950
Paul Moore4d1e2452010-04-22 14:46:18 -04004951 /* connecting socket */
4952 sksec_sock->peer_sid = sksec_new->sid;
4953
4954 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004955}
4956
4957static int selinux_socket_unix_may_send(struct socket *sock,
4958 struct socket *other)
4959{
Paul Moore253bfae2010-04-22 14:46:19 -04004960 struct sk_security_struct *ssec = sock->sk->sk_security;
4961 struct sk_security_struct *osec = other->sk->sk_security;
Thomas Liu2bf49692009-07-14 12:14:09 -04004962 struct common_audit_data ad;
Eric Paris48c62af2012-04-02 13:15:44 -04004963 struct lsm_network_audit net = {0,};
Linus Torvalds1da177e2005-04-16 15:20:36 -07004964
Eric Paris50c205f2012-04-04 15:01:43 -04004965 ad.type = LSM_AUDIT_DATA_NET;
Eric Paris48c62af2012-04-02 13:15:44 -04004966 ad.u.net = &net;
4967 ad.u.net->sk = other->sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004968
Stephen Smalley6b6bc622018-03-05 11:47:56 -05004969 return avc_has_perm(&selinux_state,
4970 ssec->sid, osec->sid, osec->sclass, SOCKET__SENDTO,
Paul Moore253bfae2010-04-22 14:46:19 -04004971 &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004972}
4973
Paul Moorecbe0d6e2014-09-10 17:09:57 -04004974static int selinux_inet_sys_rcv_skb(struct net *ns, int ifindex,
4975 char *addrp, u16 family, u32 peer_sid,
Thomas Liu2bf49692009-07-14 12:14:09 -04004976 struct common_audit_data *ad)
Paul Mooreeffad8d2008-01-29 08:49:27 -05004977{
4978 int err;
4979 u32 if_sid;
4980 u32 node_sid;
4981
Paul Moorecbe0d6e2014-09-10 17:09:57 -04004982 err = sel_netif_sid(ns, ifindex, &if_sid);
Paul Mooreeffad8d2008-01-29 08:49:27 -05004983 if (err)
4984 return err;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05004985 err = avc_has_perm(&selinux_state,
4986 peer_sid, if_sid,
Paul Mooreeffad8d2008-01-29 08:49:27 -05004987 SECCLASS_NETIF, NETIF__INGRESS, ad);
4988 if (err)
4989 return err;
4990
4991 err = sel_netnode_sid(addrp, family, &node_sid);
4992 if (err)
4993 return err;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05004994 return avc_has_perm(&selinux_state,
4995 peer_sid, node_sid,
Paul Mooreeffad8d2008-01-29 08:49:27 -05004996 SECCLASS_NODE, NODE__RECVFROM, ad);
4997}
4998
Paul Moore220deb92008-01-29 08:38:23 -05004999static int selinux_sock_rcv_skb_compat(struct sock *sk, struct sk_buff *skb,
Paul Moored8395c82008-10-10 10:16:30 -04005000 u16 family)
Paul Moore220deb92008-01-29 08:38:23 -05005001{
Paul Moore277d3422008-12-31 12:54:11 -05005002 int err = 0;
Paul Moore220deb92008-01-29 08:38:23 -05005003 struct sk_security_struct *sksec = sk->sk_security;
Paul Moore220deb92008-01-29 08:38:23 -05005004 u32 sk_sid = sksec->sid;
Thomas Liu2bf49692009-07-14 12:14:09 -04005005 struct common_audit_data ad;
Eric Paris48c62af2012-04-02 13:15:44 -04005006 struct lsm_network_audit net = {0,};
Paul Moored8395c82008-10-10 10:16:30 -04005007 char *addrp;
5008
Eric Paris50c205f2012-04-04 15:01:43 -04005009 ad.type = LSM_AUDIT_DATA_NET;
Eric Paris48c62af2012-04-02 13:15:44 -04005010 ad.u.net = &net;
5011 ad.u.net->netif = skb->skb_iif;
5012 ad.u.net->family = family;
Paul Moored8395c82008-10-10 10:16:30 -04005013 err = selinux_parse_skb(skb, &ad, &addrp, 1, NULL);
5014 if (err)
5015 return err;
Paul Moore220deb92008-01-29 08:38:23 -05005016
Paul Moore58bfbb52009-03-27 17:10:41 -04005017 if (selinux_secmark_enabled()) {
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005018 err = avc_has_perm(&selinux_state,
5019 sk_sid, skb->secmark, SECCLASS_PACKET,
Paul Moored8395c82008-10-10 10:16:30 -04005020 PACKET__RECV, &ad);
Paul Moore58bfbb52009-03-27 17:10:41 -04005021 if (err)
5022 return err;
5023 }
Paul Moore220deb92008-01-29 08:38:23 -05005024
Steffen Klassertb9679a72011-02-23 12:55:21 +01005025 err = selinux_netlbl_sock_rcv_skb(sksec, skb, family, &ad);
5026 if (err)
5027 return err;
5028 err = selinux_xfrm_sock_rcv_skb(sksec->sid, skb, &ad);
Trent Jaegerd28d1e02005-12-13 23:12:40 -08005029
James Morris4e5ab4c2006-06-09 00:33:33 -07005030 return err;
5031}
Trent Jaegerd28d1e02005-12-13 23:12:40 -08005032
James Morris4e5ab4c2006-06-09 00:33:33 -07005033static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
5034{
Paul Moore220deb92008-01-29 08:38:23 -05005035 int err;
Venkat Yekkirala4237c752006-07-24 23:32:50 -07005036 struct sk_security_struct *sksec = sk->sk_security;
Paul Moore220deb92008-01-29 08:38:23 -05005037 u16 family = sk->sk_family;
5038 u32 sk_sid = sksec->sid;
Thomas Liu2bf49692009-07-14 12:14:09 -04005039 struct common_audit_data ad;
Eric Paris48c62af2012-04-02 13:15:44 -04005040 struct lsm_network_audit net = {0,};
Paul Moore220deb92008-01-29 08:38:23 -05005041 char *addrp;
Paul Moored8395c82008-10-10 10:16:30 -04005042 u8 secmark_active;
5043 u8 peerlbl_active;
James Morris4e5ab4c2006-06-09 00:33:33 -07005044
James Morris4e5ab4c2006-06-09 00:33:33 -07005045 if (family != PF_INET && family != PF_INET6)
Paul Moore220deb92008-01-29 08:38:23 -05005046 return 0;
James Morris4e5ab4c2006-06-09 00:33:33 -07005047
5048 /* Handle mapped IPv4 packets arriving via IPv6 sockets */
Al Viro87fcd702006-12-04 22:00:55 +00005049 if (family == PF_INET6 && skb->protocol == htons(ETH_P_IP))
James Morris4e5ab4c2006-06-09 00:33:33 -07005050 family = PF_INET;
5051
Paul Moored8395c82008-10-10 10:16:30 -04005052 /* If any sort of compatibility mode is enabled then handoff processing
5053 * to the selinux_sock_rcv_skb_compat() function to deal with the
5054 * special handling. We do this in an attempt to keep this function
5055 * as fast and as clean as possible. */
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05005056 if (!selinux_policycap_netpeer())
Paul Moored8395c82008-10-10 10:16:30 -04005057 return selinux_sock_rcv_skb_compat(sk, skb, family);
5058
5059 secmark_active = selinux_secmark_enabled();
Chris PeBenito2be4d742013-05-03 09:05:39 -04005060 peerlbl_active = selinux_peerlbl_enabled();
Paul Moored8395c82008-10-10 10:16:30 -04005061 if (!secmark_active && !peerlbl_active)
5062 return 0;
5063
Eric Paris50c205f2012-04-04 15:01:43 -04005064 ad.type = LSM_AUDIT_DATA_NET;
Eric Paris48c62af2012-04-02 13:15:44 -04005065 ad.u.net = &net;
5066 ad.u.net->netif = skb->skb_iif;
5067 ad.u.net->family = family;
Paul Moore224dfbd2008-01-29 08:38:13 -05005068 err = selinux_parse_skb(skb, &ad, &addrp, 1, NULL);
James Morris4e5ab4c2006-06-09 00:33:33 -07005069 if (err)
Paul Moore220deb92008-01-29 08:38:23 -05005070 return err;
James Morris4e5ab4c2006-06-09 00:33:33 -07005071
Paul Moored8395c82008-10-10 10:16:30 -04005072 if (peerlbl_active) {
Paul Moored621d352008-01-29 08:43:36 -05005073 u32 peer_sid;
5074
5075 err = selinux_skb_peerlbl_sid(skb, family, &peer_sid);
5076 if (err)
5077 return err;
Paul Moorecbe0d6e2014-09-10 17:09:57 -04005078 err = selinux_inet_sys_rcv_skb(sock_net(sk), skb->skb_iif,
5079 addrp, family, peer_sid, &ad);
Paul Mooredfaebe92008-10-10 10:16:31 -04005080 if (err) {
Huw Daviesa04e71f2016-06-27 15:06:16 -04005081 selinux_netlbl_err(skb, family, err, 0);
Paul Mooreeffad8d2008-01-29 08:49:27 -05005082 return err;
Paul Mooredfaebe92008-10-10 10:16:31 -04005083 }
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005084 err = avc_has_perm(&selinux_state,
5085 sk_sid, peer_sid, SECCLASS_PEER,
Paul Moored621d352008-01-29 08:43:36 -05005086 PEER__RECV, &ad);
Chad Hanson46d01d62013-12-23 17:45:01 -05005087 if (err) {
Huw Daviesa04e71f2016-06-27 15:06:16 -04005088 selinux_netlbl_err(skb, family, err, 0);
Chad Hanson46d01d62013-12-23 17:45:01 -05005089 return err;
5090 }
Paul Moored621d352008-01-29 08:43:36 -05005091 }
5092
Paul Moored8395c82008-10-10 10:16:30 -04005093 if (secmark_active) {
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005094 err = avc_has_perm(&selinux_state,
5095 sk_sid, skb->secmark, SECCLASS_PACKET,
Paul Mooreeffad8d2008-01-29 08:49:27 -05005096 PACKET__RECV, &ad);
5097 if (err)
5098 return err;
5099 }
5100
Paul Moored621d352008-01-29 08:43:36 -05005101 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005102}
5103
Catherine Zhang2c7946a2006-03-20 22:41:23 -08005104static int selinux_socket_getpeersec_stream(struct socket *sock, char __user *optval,
5105 int __user *optlen, unsigned len)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005106{
5107 int err = 0;
5108 char *scontext;
5109 u32 scontext_len;
Paul Moore253bfae2010-04-22 14:46:19 -04005110 struct sk_security_struct *sksec = sock->sk->sk_security;
Paul Moore3de4bab2006-11-17 17:38:54 -05005111 u32 peer_sid = SECSID_NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005112
Paul Moore253bfae2010-04-22 14:46:19 -04005113 if (sksec->sclass == SECCLASS_UNIX_STREAM_SOCKET ||
Richard Hainesd4529302018-02-13 20:57:18 +00005114 sksec->sclass == SECCLASS_TCP_SOCKET ||
5115 sksec->sclass == SECCLASS_SCTP_SOCKET)
Eric Parisdd3e7832010-04-07 15:08:46 -04005116 peer_sid = sksec->peer_sid;
Paul Moore253bfae2010-04-22 14:46:19 -04005117 if (peer_sid == SECSID_NULL)
5118 return -ENOPROTOOPT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005119
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05005120 err = security_sid_to_context(&selinux_state, peer_sid, &scontext,
5121 &scontext_len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005122 if (err)
Paul Moore253bfae2010-04-22 14:46:19 -04005123 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005124
5125 if (scontext_len > len) {
5126 err = -ERANGE;
5127 goto out_len;
5128 }
5129
5130 if (copy_to_user(optval, scontext, scontext_len))
5131 err = -EFAULT;
5132
5133out_len:
5134 if (put_user(scontext_len, optlen))
5135 err = -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005136 kfree(scontext);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005137 return err;
5138}
5139
Catherine Zhangdc49c1f2006-08-02 14:12:06 -07005140static int selinux_socket_getpeersec_dgram(struct socket *sock, struct sk_buff *skb, u32 *secid)
Catherine Zhang2c7946a2006-03-20 22:41:23 -08005141{
Catherine Zhangdc49c1f2006-08-02 14:12:06 -07005142 u32 peer_secid = SECSID_NULL;
Paul Moore75e22912008-01-29 08:38:04 -05005143 u16 family;
Paul Moore899134f2016-03-28 15:19:10 -04005144 struct inode_security_struct *isec;
Catherine Zhang877ce7c2006-06-29 12:27:47 -07005145
Paul Mooreaa862902008-10-10 10:16:29 -04005146 if (skb && skb->protocol == htons(ETH_P_IP))
5147 family = PF_INET;
5148 else if (skb && skb->protocol == htons(ETH_P_IPV6))
5149 family = PF_INET6;
5150 else if (sock)
Paul Moore75e22912008-01-29 08:38:04 -05005151 family = sock->sk->sk_family;
Paul Moore75e22912008-01-29 08:38:04 -05005152 else
5153 goto out;
5154
Paul Moore899134f2016-03-28 15:19:10 -04005155 if (sock && family == PF_UNIX) {
5156 isec = inode_security_novalidate(SOCK_INODE(sock));
5157 peer_secid = isec->sid;
5158 } else if (skb)
Paul Moore220deb92008-01-29 08:38:23 -05005159 selinux_skb_peerlbl_sid(skb, family, &peer_secid);
Catherine Zhang2c7946a2006-03-20 22:41:23 -08005160
Paul Moore75e22912008-01-29 08:38:04 -05005161out:
Catherine Zhangdc49c1f2006-08-02 14:12:06 -07005162 *secid = peer_secid;
Paul Moore75e22912008-01-29 08:38:04 -05005163 if (peer_secid == SECSID_NULL)
5164 return -EINVAL;
5165 return 0;
Catherine Zhang2c7946a2006-03-20 22:41:23 -08005166}
5167
Al Viro7d877f32005-10-21 03:20:43 -04005168static int selinux_sk_alloc_security(struct sock *sk, int family, gfp_t priority)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005169{
Paul Moore84914b72010-04-22 14:46:18 -04005170 struct sk_security_struct *sksec;
5171
5172 sksec = kzalloc(sizeof(*sksec), priority);
5173 if (!sksec)
5174 return -ENOMEM;
5175
5176 sksec->peer_sid = SECINITSID_UNLABELED;
5177 sksec->sid = SECINITSID_UNLABELED;
Stephen Smalley5dee25d2015-07-10 17:19:57 -04005178 sksec->sclass = SECCLASS_SOCKET;
Paul Moore84914b72010-04-22 14:46:18 -04005179 selinux_netlbl_sk_security_reset(sksec);
5180 sk->sk_security = sksec;
5181
5182 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005183}
5184
5185static void selinux_sk_free_security(struct sock *sk)
5186{
Paul Moore84914b72010-04-22 14:46:18 -04005187 struct sk_security_struct *sksec = sk->sk_security;
5188
5189 sk->sk_security = NULL;
5190 selinux_netlbl_sk_security_free(sksec);
5191 kfree(sksec);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005192}
5193
Venkat Yekkirala892c1412006-08-04 23:08:56 -07005194static void selinux_sk_clone_security(const struct sock *sk, struct sock *newsk)
5195{
Eric Parisdd3e7832010-04-07 15:08:46 -04005196 struct sk_security_struct *sksec = sk->sk_security;
5197 struct sk_security_struct *newsksec = newsk->sk_security;
Venkat Yekkirala892c1412006-08-04 23:08:56 -07005198
Eric Parisdd3e7832010-04-07 15:08:46 -04005199 newsksec->sid = sksec->sid;
5200 newsksec->peer_sid = sksec->peer_sid;
5201 newsksec->sclass = sksec->sclass;
Paul Moore99f59ed2006-08-29 17:53:48 -07005202
Eric Parisdd3e7832010-04-07 15:08:46 -04005203 selinux_netlbl_sk_security_reset(newsksec);
Venkat Yekkirala892c1412006-08-04 23:08:56 -07005204}
5205
Venkat Yekkiralabeb8d132006-08-04 23:12:42 -07005206static void selinux_sk_getsecid(struct sock *sk, u32 *secid)
Trent Jaegerd28d1e02005-12-13 23:12:40 -08005207{
Trent Jaegerd28d1e02005-12-13 23:12:40 -08005208 if (!sk)
Venkat Yekkiralabeb8d132006-08-04 23:12:42 -07005209 *secid = SECINITSID_ANY_SOCKET;
Venkat Yekkirala892c1412006-08-04 23:08:56 -07005210 else {
5211 struct sk_security_struct *sksec = sk->sk_security;
Trent Jaegerd28d1e02005-12-13 23:12:40 -08005212
Venkat Yekkiralabeb8d132006-08-04 23:12:42 -07005213 *secid = sksec->sid;
Venkat Yekkirala892c1412006-08-04 23:08:56 -07005214 }
Trent Jaegerd28d1e02005-12-13 23:12:40 -08005215}
5216
Eric Paris828dfe12008-04-17 13:17:49 -04005217static void selinux_sock_graft(struct sock *sk, struct socket *parent)
Venkat Yekkirala4237c752006-07-24 23:32:50 -07005218{
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -05005219 struct inode_security_struct *isec =
5220 inode_security_novalidate(SOCK_INODE(parent));
Venkat Yekkirala4237c752006-07-24 23:32:50 -07005221 struct sk_security_struct *sksec = sk->sk_security;
5222
Paul Moore2873ead2014-07-28 10:42:48 -04005223 if (sk->sk_family == PF_INET || sk->sk_family == PF_INET6 ||
5224 sk->sk_family == PF_UNIX)
David Woodhouse2148ccc2006-09-29 15:50:25 -07005225 isec->sid = sksec->sid;
Paul Moore220deb92008-01-29 08:38:23 -05005226 sksec->sclass = isec->sclass;
Venkat Yekkirala4237c752006-07-24 23:32:50 -07005227}
5228
Richard Hainesd4529302018-02-13 20:57:18 +00005229/* Called whenever SCTP receives an INIT chunk. This happens when an incoming
5230 * connect(2), sctp_connectx(3) or sctp_sendmsg(3) (with no association
5231 * already present).
5232 */
5233static int selinux_sctp_assoc_request(struct sctp_endpoint *ep,
5234 struct sk_buff *skb)
5235{
5236 struct sk_security_struct *sksec = ep->base.sk->sk_security;
5237 struct common_audit_data ad;
5238 struct lsm_network_audit net = {0,};
5239 u8 peerlbl_active;
5240 u32 peer_sid = SECINITSID_UNLABELED;
5241 u32 conn_sid;
5242 int err = 0;
5243
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05005244 if (!selinux_policycap_extsockclass())
Richard Hainesd4529302018-02-13 20:57:18 +00005245 return 0;
5246
5247 peerlbl_active = selinux_peerlbl_enabled();
5248
5249 if (peerlbl_active) {
5250 /* This will return peer_sid = SECSID_NULL if there are
5251 * no peer labels, see security_net_peersid_resolve().
5252 */
5253 err = selinux_skb_peerlbl_sid(skb, ep->base.sk->sk_family,
5254 &peer_sid);
5255 if (err)
5256 return err;
5257
5258 if (peer_sid == SECSID_NULL)
5259 peer_sid = SECINITSID_UNLABELED;
5260 }
5261
5262 if (sksec->sctp_assoc_state == SCTP_ASSOC_UNSET) {
5263 sksec->sctp_assoc_state = SCTP_ASSOC_SET;
5264
5265 /* Here as first association on socket. As the peer SID
5266 * was allowed by peer recv (and the netif/node checks),
5267 * then it is approved by policy and used as the primary
5268 * peer SID for getpeercon(3).
5269 */
5270 sksec->peer_sid = peer_sid;
5271 } else if (sksec->peer_sid != peer_sid) {
5272 /* Other association peer SIDs are checked to enforce
5273 * consistency among the peer SIDs.
5274 */
5275 ad.type = LSM_AUDIT_DATA_NET;
5276 ad.u.net = &net;
5277 ad.u.net->sk = ep->base.sk;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005278 err = avc_has_perm(&selinux_state,
5279 sksec->peer_sid, peer_sid, sksec->sclass,
Richard Hainesd4529302018-02-13 20:57:18 +00005280 SCTP_SOCKET__ASSOCIATION, &ad);
5281 if (err)
5282 return err;
5283 }
5284
5285 /* Compute the MLS component for the connection and store
5286 * the information in ep. This will be used by SCTP TCP type
5287 * sockets and peeled off connections as they cause a new
5288 * socket to be generated. selinux_sctp_sk_clone() will then
5289 * plug this into the new socket.
5290 */
5291 err = selinux_conn_sid(sksec->sid, peer_sid, &conn_sid);
5292 if (err)
5293 return err;
5294
5295 ep->secid = conn_sid;
5296 ep->peer_secid = peer_sid;
5297
5298 /* Set any NetLabel labels including CIPSO/CALIPSO options. */
5299 return selinux_netlbl_sctp_assoc_request(ep, skb);
5300}
5301
5302/* Check if sctp IPv4/IPv6 addresses are valid for binding or connecting
5303 * based on their @optname.
5304 */
5305static int selinux_sctp_bind_connect(struct sock *sk, int optname,
5306 struct sockaddr *address,
5307 int addrlen)
5308{
5309 int len, err = 0, walk_size = 0;
5310 void *addr_buf;
5311 struct sockaddr *addr;
5312 struct socket *sock;
5313
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05005314 if (!selinux_policycap_extsockclass())
Richard Hainesd4529302018-02-13 20:57:18 +00005315 return 0;
5316
5317 /* Process one or more addresses that may be IPv4 or IPv6 */
5318 sock = sk->sk_socket;
5319 addr_buf = address;
5320
5321 while (walk_size < addrlen) {
5322 addr = addr_buf;
5323 switch (addr->sa_family) {
Alexey Kodanev4152dc92018-05-11 20:15:13 +03005324 case AF_UNSPEC:
Richard Hainesd4529302018-02-13 20:57:18 +00005325 case AF_INET:
5326 len = sizeof(struct sockaddr_in);
5327 break;
5328 case AF_INET6:
5329 len = sizeof(struct sockaddr_in6);
5330 break;
5331 default:
Alexey Kodanev4152dc92018-05-11 20:15:13 +03005332 return -EINVAL;
Richard Hainesd4529302018-02-13 20:57:18 +00005333 }
5334
5335 err = -EINVAL;
5336 switch (optname) {
5337 /* Bind checks */
5338 case SCTP_PRIMARY_ADDR:
5339 case SCTP_SET_PEER_PRIMARY_ADDR:
5340 case SCTP_SOCKOPT_BINDX_ADD:
5341 err = selinux_socket_bind(sock, addr, len);
5342 break;
5343 /* Connect checks */
5344 case SCTP_SOCKOPT_CONNECTX:
5345 case SCTP_PARAM_SET_PRIMARY:
5346 case SCTP_PARAM_ADD_IP:
5347 case SCTP_SENDMSG_CONNECT:
5348 err = selinux_socket_connect_helper(sock, addr, len);
5349 if (err)
5350 return err;
5351
5352 /* As selinux_sctp_bind_connect() is called by the
5353 * SCTP protocol layer, the socket is already locked,
5354 * therefore selinux_netlbl_socket_connect_locked() is
5355 * is called here. The situations handled are:
5356 * sctp_connectx(3), sctp_sendmsg(3), sendmsg(2),
5357 * whenever a new IP address is added or when a new
5358 * primary address is selected.
5359 * Note that an SCTP connect(2) call happens before
5360 * the SCTP protocol layer and is handled via
5361 * selinux_socket_connect().
5362 */
5363 err = selinux_netlbl_socket_connect_locked(sk, addr);
5364 break;
5365 }
5366
5367 if (err)
5368 return err;
5369
5370 addr_buf += len;
5371 walk_size += len;
5372 }
5373
5374 return 0;
5375}
5376
5377/* Called whenever a new socket is created by accept(2) or sctp_peeloff(3). */
5378static void selinux_sctp_sk_clone(struct sctp_endpoint *ep, struct sock *sk,
5379 struct sock *newsk)
5380{
5381 struct sk_security_struct *sksec = sk->sk_security;
5382 struct sk_security_struct *newsksec = newsk->sk_security;
5383
5384 /* If policy does not support SECCLASS_SCTP_SOCKET then call
5385 * the non-sctp clone version.
5386 */
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05005387 if (!selinux_policycap_extsockclass())
Richard Hainesd4529302018-02-13 20:57:18 +00005388 return selinux_sk_clone_security(sk, newsk);
5389
5390 newsksec->sid = ep->secid;
5391 newsksec->peer_sid = ep->peer_secid;
5392 newsksec->sclass = sksec->sclass;
5393 selinux_netlbl_sctp_sk_clone(sk, newsk);
5394}
5395
Adrian Bunk9a673e52006-08-15 00:03:53 -07005396static int selinux_inet_conn_request(struct sock *sk, struct sk_buff *skb,
5397 struct request_sock *req)
Venkat Yekkirala4237c752006-07-24 23:32:50 -07005398{
5399 struct sk_security_struct *sksec = sk->sk_security;
5400 int err;
Paul Moore0b1f24e2013-12-03 11:39:13 -05005401 u16 family = req->rsk_ops->family;
Paul Moore446b8022013-12-04 16:10:51 -05005402 u32 connsid;
Venkat Yekkirala4237c752006-07-24 23:32:50 -07005403 u32 peersid;
5404
Paul Mooreaa862902008-10-10 10:16:29 -04005405 err = selinux_skb_peerlbl_sid(skb, family, &peersid);
Paul Moore220deb92008-01-29 08:38:23 -05005406 if (err)
5407 return err;
Paul Moore446b8022013-12-04 16:10:51 -05005408 err = selinux_conn_sid(sksec->sid, peersid, &connsid);
5409 if (err)
5410 return err;
5411 req->secid = connsid;
5412 req->peer_secid = peersid;
Venkat Yekkiralaa51c64f2006-07-27 22:01:34 -07005413
Paul Moore389fb8002009-03-27 17:10:34 -04005414 return selinux_netlbl_inet_conn_request(req, family);
Venkat Yekkirala4237c752006-07-24 23:32:50 -07005415}
5416
Adrian Bunk9a673e52006-08-15 00:03:53 -07005417static void selinux_inet_csk_clone(struct sock *newsk,
5418 const struct request_sock *req)
Venkat Yekkirala4237c752006-07-24 23:32:50 -07005419{
5420 struct sk_security_struct *newsksec = newsk->sk_security;
5421
5422 newsksec->sid = req->secid;
Venkat Yekkirala6b877692006-11-08 17:04:09 -06005423 newsksec->peer_sid = req->peer_secid;
Venkat Yekkirala4237c752006-07-24 23:32:50 -07005424 /* NOTE: Ideally, we should also get the isec->sid for the
5425 new socket in sync, but we don't have the isec available yet.
5426 So we will wait until sock_graft to do it, by which
5427 time it will have been created and available. */
Paul Moore99f59ed2006-08-29 17:53:48 -07005428
Paul Moore9f2ad662006-11-17 17:38:53 -05005429 /* We don't need to take any sort of lock here as we are the only
5430 * thread with access to newsksec */
Paul Moore389fb8002009-03-27 17:10:34 -04005431 selinux_netlbl_inet_csk_clone(newsk, req->rsk_ops->family);
Venkat Yekkirala4237c752006-07-24 23:32:50 -07005432}
5433
Paul Moore014ab192008-10-10 10:16:33 -04005434static void selinux_inet_conn_established(struct sock *sk, struct sk_buff *skb)
Venkat Yekkirala6b877692006-11-08 17:04:09 -06005435{
Paul Mooreaa862902008-10-10 10:16:29 -04005436 u16 family = sk->sk_family;
Venkat Yekkirala6b877692006-11-08 17:04:09 -06005437 struct sk_security_struct *sksec = sk->sk_security;
5438
Paul Mooreaa862902008-10-10 10:16:29 -04005439 /* handle mapped IPv4 packets arriving via IPv6 sockets */
5440 if (family == PF_INET6 && skb->protocol == htons(ETH_P_IP))
5441 family = PF_INET;
5442
5443 selinux_skb_peerlbl_sid(skb, family, &sksec->peer_sid);
Venkat Yekkirala6b877692006-11-08 17:04:09 -06005444}
5445
Eric Paris2606fd12010-10-13 16:24:41 -04005446static int selinux_secmark_relabel_packet(u32 sid)
5447{
5448 const struct task_security_struct *__tsec;
5449 u32 tsid;
5450
5451 __tsec = current_security();
5452 tsid = __tsec->sid;
5453
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005454 return avc_has_perm(&selinux_state,
5455 tsid, sid, SECCLASS_PACKET, PACKET__RELABELTO,
5456 NULL);
Eric Paris2606fd12010-10-13 16:24:41 -04005457}
5458
5459static void selinux_secmark_refcount_inc(void)
5460{
5461 atomic_inc(&selinux_secmark_refcount);
5462}
5463
5464static void selinux_secmark_refcount_dec(void)
5465{
5466 atomic_dec(&selinux_secmark_refcount);
5467}
5468
Adrian Bunk9a673e52006-08-15 00:03:53 -07005469static void selinux_req_classify_flow(const struct request_sock *req,
5470 struct flowi *fl)
Venkat Yekkirala4237c752006-07-24 23:32:50 -07005471{
David S. Miller1d28f422011-03-12 00:29:39 -05005472 fl->flowi_secid = req->secid;
Venkat Yekkirala4237c752006-07-24 23:32:50 -07005473}
5474
Paul Moore5dbbaf22013-01-14 07:12:19 +00005475static int selinux_tun_dev_alloc_security(void **security)
5476{
5477 struct tun_security_struct *tunsec;
5478
5479 tunsec = kzalloc(sizeof(*tunsec), GFP_KERNEL);
5480 if (!tunsec)
5481 return -ENOMEM;
5482 tunsec->sid = current_sid();
5483
5484 *security = tunsec;
5485 return 0;
5486}
5487
5488static void selinux_tun_dev_free_security(void *security)
5489{
5490 kfree(security);
5491}
5492
Paul Mooreed6d76e2009-08-28 18:12:49 -04005493static int selinux_tun_dev_create(void)
5494{
5495 u32 sid = current_sid();
5496
5497 /* we aren't taking into account the "sockcreate" SID since the socket
5498 * that is being created here is not a socket in the traditional sense,
5499 * instead it is a private sock, accessible only to the kernel, and
5500 * representing a wide range of network traffic spanning multiple
5501 * connections unlike traditional sockets - check the TUN driver to
5502 * get a better understanding of why this socket is special */
5503
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005504 return avc_has_perm(&selinux_state,
5505 sid, sid, SECCLASS_TUN_SOCKET, TUN_SOCKET__CREATE,
Paul Mooreed6d76e2009-08-28 18:12:49 -04005506 NULL);
5507}
5508
Paul Moore5dbbaf22013-01-14 07:12:19 +00005509static int selinux_tun_dev_attach_queue(void *security)
Paul Mooreed6d76e2009-08-28 18:12:49 -04005510{
Paul Moore5dbbaf22013-01-14 07:12:19 +00005511 struct tun_security_struct *tunsec = security;
5512
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005513 return avc_has_perm(&selinux_state,
5514 current_sid(), tunsec->sid, SECCLASS_TUN_SOCKET,
Paul Moore5dbbaf22013-01-14 07:12:19 +00005515 TUN_SOCKET__ATTACH_QUEUE, NULL);
5516}
5517
5518static int selinux_tun_dev_attach(struct sock *sk, void *security)
5519{
5520 struct tun_security_struct *tunsec = security;
Paul Mooreed6d76e2009-08-28 18:12:49 -04005521 struct sk_security_struct *sksec = sk->sk_security;
5522
5523 /* we don't currently perform any NetLabel based labeling here and it
5524 * isn't clear that we would want to do so anyway; while we could apply
5525 * labeling without the support of the TUN user the resulting labeled
5526 * traffic from the other end of the connection would almost certainly
5527 * cause confusion to the TUN user that had no idea network labeling
5528 * protocols were being used */
5529
Paul Moore5dbbaf22013-01-14 07:12:19 +00005530 sksec->sid = tunsec->sid;
Paul Mooreed6d76e2009-08-28 18:12:49 -04005531 sksec->sclass = SECCLASS_TUN_SOCKET;
Paul Moore5dbbaf22013-01-14 07:12:19 +00005532
5533 return 0;
Paul Mooreed6d76e2009-08-28 18:12:49 -04005534}
5535
Paul Moore5dbbaf22013-01-14 07:12:19 +00005536static int selinux_tun_dev_open(void *security)
Paul Mooreed6d76e2009-08-28 18:12:49 -04005537{
Paul Moore5dbbaf22013-01-14 07:12:19 +00005538 struct tun_security_struct *tunsec = security;
Paul Mooreed6d76e2009-08-28 18:12:49 -04005539 u32 sid = current_sid();
5540 int err;
5541
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005542 err = avc_has_perm(&selinux_state,
5543 sid, tunsec->sid, SECCLASS_TUN_SOCKET,
Paul Mooreed6d76e2009-08-28 18:12:49 -04005544 TUN_SOCKET__RELABELFROM, NULL);
5545 if (err)
5546 return err;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005547 err = avc_has_perm(&selinux_state,
5548 sid, sid, SECCLASS_TUN_SOCKET,
Paul Mooreed6d76e2009-08-28 18:12:49 -04005549 TUN_SOCKET__RELABELTO, NULL);
5550 if (err)
5551 return err;
Paul Moore5dbbaf22013-01-14 07:12:19 +00005552 tunsec->sid = sid;
Paul Mooreed6d76e2009-08-28 18:12:49 -04005553
5554 return 0;
5555}
5556
Linus Torvalds1da177e2005-04-16 15:20:36 -07005557static int selinux_nlmsg_perm(struct sock *sk, struct sk_buff *skb)
5558{
5559 int err = 0;
5560 u32 perm;
5561 struct nlmsghdr *nlh;
Paul Moore253bfae2010-04-22 14:46:19 -04005562 struct sk_security_struct *sksec = sk->sk_security;
Eric Paris828dfe12008-04-17 13:17:49 -04005563
Hong zhi guo77954982013-03-27 06:49:35 +00005564 if (skb->len < NLMSG_HDRLEN) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005565 err = -EINVAL;
5566 goto out;
5567 }
Arnaldo Carvalho de Melob529ccf2007-04-25 19:08:35 -07005568 nlh = nlmsg_hdr(skb);
Eric Paris828dfe12008-04-17 13:17:49 -04005569
Paul Moore253bfae2010-04-22 14:46:19 -04005570 err = selinux_nlmsg_lookup(sksec->sclass, nlh->nlmsg_type, &perm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005571 if (err) {
5572 if (err == -EINVAL) {
Vladis Dronov76319942015-12-24 11:09:41 -05005573 pr_warn_ratelimited("SELinux: unrecognized netlink"
5574 " message: protocol=%hu nlmsg_type=%hu sclass=%s"
5575 " pig=%d comm=%s\n",
Marek Milkoviccded3ff2015-06-04 16:22:16 -04005576 sk->sk_protocol, nlh->nlmsg_type,
Vladis Dronov76319942015-12-24 11:09:41 -05005577 secclass_map[sksec->sclass - 1].name,
5578 task_pid_nr(current), current->comm);
Paul Mooree5a5ca92018-03-01 17:38:30 -05005579 if (!enforcing_enabled(&selinux_state) ||
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05005580 security_get_allow_unknown(&selinux_state))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005581 err = 0;
5582 }
5583
5584 /* Ignore */
5585 if (err == -ENOENT)
5586 err = 0;
5587 goto out;
5588 }
5589
Stephen Smalleybe0554c2017-01-09 10:07:31 -05005590 err = sock_has_perm(sk, perm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005591out:
5592 return err;
5593}
5594
5595#ifdef CONFIG_NETFILTER
5596
Paul Moorecbe0d6e2014-09-10 17:09:57 -04005597static unsigned int selinux_ip_forward(struct sk_buff *skb,
5598 const struct net_device *indev,
Paul Mooreeffad8d2008-01-29 08:49:27 -05005599 u16 family)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005600{
Paul Mooredfaebe92008-10-10 10:16:31 -04005601 int err;
Paul Mooreeffad8d2008-01-29 08:49:27 -05005602 char *addrp;
5603 u32 peer_sid;
Thomas Liu2bf49692009-07-14 12:14:09 -04005604 struct common_audit_data ad;
Eric Paris48c62af2012-04-02 13:15:44 -04005605 struct lsm_network_audit net = {0,};
Paul Mooreeffad8d2008-01-29 08:49:27 -05005606 u8 secmark_active;
Paul Moore948bf852008-10-10 10:16:32 -04005607 u8 netlbl_active;
Paul Mooreeffad8d2008-01-29 08:49:27 -05005608 u8 peerlbl_active;
Venkat Yekkirala4237c752006-07-24 23:32:50 -07005609
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05005610 if (!selinux_policycap_netpeer())
Paul Mooreeffad8d2008-01-29 08:49:27 -05005611 return NF_ACCEPT;
Venkat Yekkirala4237c752006-07-24 23:32:50 -07005612
Paul Mooreeffad8d2008-01-29 08:49:27 -05005613 secmark_active = selinux_secmark_enabled();
Paul Moore948bf852008-10-10 10:16:32 -04005614 netlbl_active = netlbl_enabled();
Chris PeBenito2be4d742013-05-03 09:05:39 -04005615 peerlbl_active = selinux_peerlbl_enabled();
Paul Mooreeffad8d2008-01-29 08:49:27 -05005616 if (!secmark_active && !peerlbl_active)
5617 return NF_ACCEPT;
Venkat Yekkirala4237c752006-07-24 23:32:50 -07005618
Paul Moored8395c82008-10-10 10:16:30 -04005619 if (selinux_skb_peerlbl_sid(skb, family, &peer_sid) != 0)
5620 return NF_DROP;
5621
Eric Paris50c205f2012-04-04 15:01:43 -04005622 ad.type = LSM_AUDIT_DATA_NET;
Eric Paris48c62af2012-04-02 13:15:44 -04005623 ad.u.net = &net;
Paul Moorecbe0d6e2014-09-10 17:09:57 -04005624 ad.u.net->netif = indev->ifindex;
Eric Paris48c62af2012-04-02 13:15:44 -04005625 ad.u.net->family = family;
Paul Mooreeffad8d2008-01-29 08:49:27 -05005626 if (selinux_parse_skb(skb, &ad, &addrp, 1, NULL) != 0)
5627 return NF_DROP;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005628
Paul Mooredfaebe92008-10-10 10:16:31 -04005629 if (peerlbl_active) {
Paul Moorecbe0d6e2014-09-10 17:09:57 -04005630 err = selinux_inet_sys_rcv_skb(dev_net(indev), indev->ifindex,
5631 addrp, family, peer_sid, &ad);
Paul Mooredfaebe92008-10-10 10:16:31 -04005632 if (err) {
Huw Daviesa04e71f2016-06-27 15:06:16 -04005633 selinux_netlbl_err(skb, family, err, 1);
Paul Mooreeffad8d2008-01-29 08:49:27 -05005634 return NF_DROP;
Paul Mooredfaebe92008-10-10 10:16:31 -04005635 }
5636 }
Paul Mooreeffad8d2008-01-29 08:49:27 -05005637
5638 if (secmark_active)
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005639 if (avc_has_perm(&selinux_state,
5640 peer_sid, skb->secmark,
Paul Mooreeffad8d2008-01-29 08:49:27 -05005641 SECCLASS_PACKET, PACKET__FORWARD_IN, &ad))
5642 return NF_DROP;
5643
Paul Moore948bf852008-10-10 10:16:32 -04005644 if (netlbl_active)
5645 /* we do this in the FORWARD path and not the POST_ROUTING
5646 * path because we want to make sure we apply the necessary
5647 * labeling before IPsec is applied so we can leverage AH
5648 * protection */
5649 if (selinux_netlbl_skbuff_setsid(skb, family, peer_sid) != 0)
5650 return NF_DROP;
5651
Paul Mooreeffad8d2008-01-29 08:49:27 -05005652 return NF_ACCEPT;
5653}
5654
Eric W. Biederman06198b32015-09-18 14:33:06 -05005655static unsigned int selinux_ipv4_forward(void *priv,
Paul Mooreeffad8d2008-01-29 08:49:27 -05005656 struct sk_buff *skb,
David S. Miller238e54c2015-04-03 20:32:56 -04005657 const struct nf_hook_state *state)
Paul Mooreeffad8d2008-01-29 08:49:27 -05005658{
David S. Miller238e54c2015-04-03 20:32:56 -04005659 return selinux_ip_forward(skb, state->in, PF_INET);
Paul Mooreeffad8d2008-01-29 08:49:27 -05005660}
5661
Javier Martinez Canillas1a93a6e2016-08-08 13:08:25 -04005662#if IS_ENABLED(CONFIG_IPV6)
Eric W. Biederman06198b32015-09-18 14:33:06 -05005663static unsigned int selinux_ipv6_forward(void *priv,
Paul Mooreeffad8d2008-01-29 08:49:27 -05005664 struct sk_buff *skb,
David S. Miller238e54c2015-04-03 20:32:56 -04005665 const struct nf_hook_state *state)
Paul Mooreeffad8d2008-01-29 08:49:27 -05005666{
David S. Miller238e54c2015-04-03 20:32:56 -04005667 return selinux_ip_forward(skb, state->in, PF_INET6);
Paul Mooreeffad8d2008-01-29 08:49:27 -05005668}
5669#endif /* IPV6 */
5670
Paul Moore948bf852008-10-10 10:16:32 -04005671static unsigned int selinux_ip_output(struct sk_buff *skb,
5672 u16 family)
5673{
Paul Moore47180062013-12-04 16:10:45 -05005674 struct sock *sk;
Paul Moore948bf852008-10-10 10:16:32 -04005675 u32 sid;
5676
5677 if (!netlbl_enabled())
5678 return NF_ACCEPT;
5679
5680 /* we do this in the LOCAL_OUT path and not the POST_ROUTING path
5681 * because we want to make sure we apply the necessary labeling
5682 * before IPsec is applied so we can leverage AH protection */
Paul Moore47180062013-12-04 16:10:45 -05005683 sk = skb->sk;
5684 if (sk) {
5685 struct sk_security_struct *sksec;
5686
Eric Dumazete446f9d2015-10-08 05:01:55 -07005687 if (sk_listener(sk))
Paul Moore47180062013-12-04 16:10:45 -05005688 /* if the socket is the listening state then this
5689 * packet is a SYN-ACK packet which means it needs to
5690 * be labeled based on the connection/request_sock and
5691 * not the parent socket. unfortunately, we can't
5692 * lookup the request_sock yet as it isn't queued on
5693 * the parent socket until after the SYN-ACK is sent.
5694 * the "solution" is to simply pass the packet as-is
5695 * as any IP option based labeling should be copied
5696 * from the initial connection request (in the IP
5697 * layer). it is far from ideal, but until we get a
5698 * security label in the packet itself this is the
5699 * best we can do. */
5700 return NF_ACCEPT;
5701
5702 /* standard practice, label using the parent socket */
5703 sksec = sk->sk_security;
Paul Moore948bf852008-10-10 10:16:32 -04005704 sid = sksec->sid;
5705 } else
5706 sid = SECINITSID_KERNEL;
5707 if (selinux_netlbl_skbuff_setsid(skb, family, sid) != 0)
5708 return NF_DROP;
5709
5710 return NF_ACCEPT;
5711}
5712
Eric W. Biederman06198b32015-09-18 14:33:06 -05005713static unsigned int selinux_ipv4_output(void *priv,
Paul Moore948bf852008-10-10 10:16:32 -04005714 struct sk_buff *skb,
David S. Miller238e54c2015-04-03 20:32:56 -04005715 const struct nf_hook_state *state)
Paul Moore948bf852008-10-10 10:16:32 -04005716{
5717 return selinux_ip_output(skb, PF_INET);
5718}
5719
Javier Martinez Canillas1a93a6e2016-08-08 13:08:25 -04005720#if IS_ENABLED(CONFIG_IPV6)
Huw Davies2917f572016-06-27 15:06:15 -04005721static unsigned int selinux_ipv6_output(void *priv,
5722 struct sk_buff *skb,
5723 const struct nf_hook_state *state)
5724{
5725 return selinux_ip_output(skb, PF_INET6);
5726}
5727#endif /* IPV6 */
5728
Paul Mooreeffad8d2008-01-29 08:49:27 -05005729static unsigned int selinux_ip_postroute_compat(struct sk_buff *skb,
5730 int ifindex,
Paul Moored8395c82008-10-10 10:16:30 -04005731 u16 family)
James Morris4e5ab4c2006-06-09 00:33:33 -07005732{
Eric Dumazet54abc682015-11-08 10:54:07 -08005733 struct sock *sk = skb_to_full_sk(skb);
Venkat Yekkirala4237c752006-07-24 23:32:50 -07005734 struct sk_security_struct *sksec;
Thomas Liu2bf49692009-07-14 12:14:09 -04005735 struct common_audit_data ad;
Eric Paris48c62af2012-04-02 13:15:44 -04005736 struct lsm_network_audit net = {0,};
Paul Moored8395c82008-10-10 10:16:30 -04005737 char *addrp;
5738 u8 proto;
James Morris4e5ab4c2006-06-09 00:33:33 -07005739
Paul Mooreeffad8d2008-01-29 08:49:27 -05005740 if (sk == NULL)
5741 return NF_ACCEPT;
Venkat Yekkirala4237c752006-07-24 23:32:50 -07005742 sksec = sk->sk_security;
James Morris4e5ab4c2006-06-09 00:33:33 -07005743
Eric Paris50c205f2012-04-04 15:01:43 -04005744 ad.type = LSM_AUDIT_DATA_NET;
Eric Paris48c62af2012-04-02 13:15:44 -04005745 ad.u.net = &net;
5746 ad.u.net->netif = ifindex;
5747 ad.u.net->family = family;
Paul Moored8395c82008-10-10 10:16:30 -04005748 if (selinux_parse_skb(skb, &ad, &addrp, 0, &proto))
5749 return NF_DROP;
5750
Paul Moore58bfbb52009-03-27 17:10:41 -04005751 if (selinux_secmark_enabled())
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005752 if (avc_has_perm(&selinux_state,
5753 sksec->sid, skb->secmark,
Paul Moored8395c82008-10-10 10:16:30 -04005754 SECCLASS_PACKET, PACKET__SEND, &ad))
Eric Paris2fe66ec2010-11-23 06:28:08 +00005755 return NF_DROP_ERR(-ECONNREFUSED);
James Morris4e5ab4c2006-06-09 00:33:33 -07005756
Steffen Klassertb9679a72011-02-23 12:55:21 +01005757 if (selinux_xfrm_postroute_last(sksec->sid, skb, &ad, proto))
5758 return NF_DROP_ERR(-ECONNREFUSED);
James Morris4e5ab4c2006-06-09 00:33:33 -07005759
Paul Mooreeffad8d2008-01-29 08:49:27 -05005760 return NF_ACCEPT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005761}
5762
Paul Moorecbe0d6e2014-09-10 17:09:57 -04005763static unsigned int selinux_ip_postroute(struct sk_buff *skb,
5764 const struct net_device *outdev,
Paul Mooreeffad8d2008-01-29 08:49:27 -05005765 u16 family)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005766{
Paul Mooreeffad8d2008-01-29 08:49:27 -05005767 u32 secmark_perm;
5768 u32 peer_sid;
Paul Moorecbe0d6e2014-09-10 17:09:57 -04005769 int ifindex = outdev->ifindex;
Paul Mooreeffad8d2008-01-29 08:49:27 -05005770 struct sock *sk;
Thomas Liu2bf49692009-07-14 12:14:09 -04005771 struct common_audit_data ad;
Eric Paris48c62af2012-04-02 13:15:44 -04005772 struct lsm_network_audit net = {0,};
Paul Mooreeffad8d2008-01-29 08:49:27 -05005773 char *addrp;
Paul Mooreeffad8d2008-01-29 08:49:27 -05005774 u8 secmark_active;
5775 u8 peerlbl_active;
5776
Paul Mooreeffad8d2008-01-29 08:49:27 -05005777 /* If any sort of compatibility mode is enabled then handoff processing
5778 * to the selinux_ip_postroute_compat() function to deal with the
5779 * special handling. We do this in an attempt to keep this function
5780 * as fast and as clean as possible. */
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05005781 if (!selinux_policycap_netpeer())
Paul Moored8395c82008-10-10 10:16:30 -04005782 return selinux_ip_postroute_compat(skb, ifindex, family);
Paul Moorec0828e52013-12-10 14:58:01 -05005783
Paul Mooreeffad8d2008-01-29 08:49:27 -05005784 secmark_active = selinux_secmark_enabled();
Chris PeBenito2be4d742013-05-03 09:05:39 -04005785 peerlbl_active = selinux_peerlbl_enabled();
Paul Mooreeffad8d2008-01-29 08:49:27 -05005786 if (!secmark_active && !peerlbl_active)
5787 return NF_ACCEPT;
5788
Eric Dumazet54abc682015-11-08 10:54:07 -08005789 sk = skb_to_full_sk(skb);
Paul Moorec0828e52013-12-10 14:58:01 -05005790
Paul Mooreeffad8d2008-01-29 08:49:27 -05005791#ifdef CONFIG_XFRM
5792 /* If skb->dst->xfrm is non-NULL then the packet is undergoing an IPsec
5793 * packet transformation so allow the packet to pass without any checks
5794 * since we'll have another chance to perform access control checks
5795 * when the packet is on it's final way out.
5796 * NOTE: there appear to be some IPv6 multicast cases where skb->dst
Paul Moorec0828e52013-12-10 14:58:01 -05005797 * is NULL, in this case go ahead and apply access control.
5798 * NOTE: if this is a local socket (skb->sk != NULL) that is in the
5799 * TCP listening state we cannot wait until the XFRM processing
5800 * is done as we will miss out on the SA label if we do;
5801 * unfortunately, this means more work, but it is only once per
5802 * connection. */
5803 if (skb_dst(skb) != NULL && skb_dst(skb)->xfrm != NULL &&
Eric Dumazete446f9d2015-10-08 05:01:55 -07005804 !(sk && sk_listener(sk)))
Paul Mooreeffad8d2008-01-29 08:49:27 -05005805 return NF_ACCEPT;
5806#endif
Paul Mooreeffad8d2008-01-29 08:49:27 -05005807
Paul Moored8395c82008-10-10 10:16:30 -04005808 if (sk == NULL) {
Paul Moore446b8022013-12-04 16:10:51 -05005809 /* Without an associated socket the packet is either coming
5810 * from the kernel or it is being forwarded; check the packet
5811 * to determine which and if the packet is being forwarded
5812 * query the packet directly to determine the security label. */
Steffen Klassert4a7ab3d2011-02-23 12:56:23 +01005813 if (skb->skb_iif) {
5814 secmark_perm = PACKET__FORWARD_OUT;
Paul Moored8395c82008-10-10 10:16:30 -04005815 if (selinux_skb_peerlbl_sid(skb, family, &peer_sid))
Eric Paris04f6d702010-11-23 06:28:02 +00005816 return NF_DROP;
Steffen Klassert4a7ab3d2011-02-23 12:56:23 +01005817 } else {
5818 secmark_perm = PACKET__SEND;
Paul Moored8395c82008-10-10 10:16:30 -04005819 peer_sid = SECINITSID_KERNEL;
Steffen Klassert4a7ab3d2011-02-23 12:56:23 +01005820 }
Eric Dumazete446f9d2015-10-08 05:01:55 -07005821 } else if (sk_listener(sk)) {
Paul Moore446b8022013-12-04 16:10:51 -05005822 /* Locally generated packet but the associated socket is in the
5823 * listening state which means this is a SYN-ACK packet. In
5824 * this particular case the correct security label is assigned
5825 * to the connection/request_sock but unfortunately we can't
5826 * query the request_sock as it isn't queued on the parent
5827 * socket until after the SYN-ACK packet is sent; the only
5828 * viable choice is to regenerate the label like we do in
5829 * selinux_inet_conn_request(). See also selinux_ip_output()
5830 * for similar problems. */
5831 u32 skb_sid;
Eric Dumazete446f9d2015-10-08 05:01:55 -07005832 struct sk_security_struct *sksec;
5833
Eric Dumazete446f9d2015-10-08 05:01:55 -07005834 sksec = sk->sk_security;
Paul Moore446b8022013-12-04 16:10:51 -05005835 if (selinux_skb_peerlbl_sid(skb, family, &skb_sid))
5836 return NF_DROP;
Paul Moorec0828e52013-12-10 14:58:01 -05005837 /* At this point, if the returned skb peerlbl is SECSID_NULL
5838 * and the packet has been through at least one XFRM
5839 * transformation then we must be dealing with the "final"
5840 * form of labeled IPsec packet; since we've already applied
5841 * all of our access controls on this packet we can safely
5842 * pass the packet. */
5843 if (skb_sid == SECSID_NULL) {
5844 switch (family) {
5845 case PF_INET:
5846 if (IPCB(skb)->flags & IPSKB_XFRM_TRANSFORMED)
5847 return NF_ACCEPT;
5848 break;
5849 case PF_INET6:
5850 if (IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED)
5851 return NF_ACCEPT;
Paul Moorea7a91a12014-09-03 10:51:59 -04005852 break;
Paul Moorec0828e52013-12-10 14:58:01 -05005853 default:
5854 return NF_DROP_ERR(-ECONNREFUSED);
5855 }
5856 }
Paul Moore446b8022013-12-04 16:10:51 -05005857 if (selinux_conn_sid(sksec->sid, skb_sid, &peer_sid))
5858 return NF_DROP;
5859 secmark_perm = PACKET__SEND;
Paul Moored8395c82008-10-10 10:16:30 -04005860 } else {
Paul Moore446b8022013-12-04 16:10:51 -05005861 /* Locally generated packet, fetch the security label from the
5862 * associated socket. */
Paul Mooreeffad8d2008-01-29 08:49:27 -05005863 struct sk_security_struct *sksec = sk->sk_security;
5864 peer_sid = sksec->sid;
5865 secmark_perm = PACKET__SEND;
Paul Mooreeffad8d2008-01-29 08:49:27 -05005866 }
5867
Eric Paris50c205f2012-04-04 15:01:43 -04005868 ad.type = LSM_AUDIT_DATA_NET;
Eric Paris48c62af2012-04-02 13:15:44 -04005869 ad.u.net = &net;
5870 ad.u.net->netif = ifindex;
5871 ad.u.net->family = family;
Paul Moored8395c82008-10-10 10:16:30 -04005872 if (selinux_parse_skb(skb, &ad, &addrp, 0, NULL))
Eric Paris04f6d702010-11-23 06:28:02 +00005873 return NF_DROP;
Paul Moored8395c82008-10-10 10:16:30 -04005874
Paul Mooreeffad8d2008-01-29 08:49:27 -05005875 if (secmark_active)
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005876 if (avc_has_perm(&selinux_state,
5877 peer_sid, skb->secmark,
Paul Mooreeffad8d2008-01-29 08:49:27 -05005878 SECCLASS_PACKET, secmark_perm, &ad))
Eric Paris1f1aaf82010-11-16 11:52:57 +00005879 return NF_DROP_ERR(-ECONNREFUSED);
Paul Mooreeffad8d2008-01-29 08:49:27 -05005880
5881 if (peerlbl_active) {
5882 u32 if_sid;
5883 u32 node_sid;
5884
Paul Moorecbe0d6e2014-09-10 17:09:57 -04005885 if (sel_netif_sid(dev_net(outdev), ifindex, &if_sid))
Eric Paris04f6d702010-11-23 06:28:02 +00005886 return NF_DROP;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005887 if (avc_has_perm(&selinux_state,
5888 peer_sid, if_sid,
Paul Mooreeffad8d2008-01-29 08:49:27 -05005889 SECCLASS_NETIF, NETIF__EGRESS, &ad))
Eric Paris1f1aaf82010-11-16 11:52:57 +00005890 return NF_DROP_ERR(-ECONNREFUSED);
Paul Mooreeffad8d2008-01-29 08:49:27 -05005891
5892 if (sel_netnode_sid(addrp, family, &node_sid))
Eric Paris04f6d702010-11-23 06:28:02 +00005893 return NF_DROP;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005894 if (avc_has_perm(&selinux_state,
5895 peer_sid, node_sid,
Paul Mooreeffad8d2008-01-29 08:49:27 -05005896 SECCLASS_NODE, NODE__SENDTO, &ad))
Eric Paris1f1aaf82010-11-16 11:52:57 +00005897 return NF_DROP_ERR(-ECONNREFUSED);
Paul Mooreeffad8d2008-01-29 08:49:27 -05005898 }
5899
5900 return NF_ACCEPT;
5901}
5902
Eric W. Biederman06198b32015-09-18 14:33:06 -05005903static unsigned int selinux_ipv4_postroute(void *priv,
Paul Mooreeffad8d2008-01-29 08:49:27 -05005904 struct sk_buff *skb,
David S. Miller238e54c2015-04-03 20:32:56 -04005905 const struct nf_hook_state *state)
Paul Mooreeffad8d2008-01-29 08:49:27 -05005906{
David S. Miller238e54c2015-04-03 20:32:56 -04005907 return selinux_ip_postroute(skb, state->out, PF_INET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005908}
5909
Javier Martinez Canillas1a93a6e2016-08-08 13:08:25 -04005910#if IS_ENABLED(CONFIG_IPV6)
Eric W. Biederman06198b32015-09-18 14:33:06 -05005911static unsigned int selinux_ipv6_postroute(void *priv,
Paul Mooreeffad8d2008-01-29 08:49:27 -05005912 struct sk_buff *skb,
David S. Miller238e54c2015-04-03 20:32:56 -04005913 const struct nf_hook_state *state)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005914{
David S. Miller238e54c2015-04-03 20:32:56 -04005915 return selinux_ip_postroute(skb, state->out, PF_INET6);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005916}
Linus Torvalds1da177e2005-04-16 15:20:36 -07005917#endif /* IPV6 */
5918
5919#endif /* CONFIG_NETFILTER */
5920
Linus Torvalds1da177e2005-04-16 15:20:36 -07005921static int selinux_netlink_send(struct sock *sk, struct sk_buff *skb)
5922{
Stephen Smalley941fc5b2009-10-01 14:48:23 -04005923 return selinux_nlmsg_perm(sk, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005924}
5925
Stephen Smalleybe0554c2017-01-09 10:07:31 -05005926static int ipc_alloc_security(struct kern_ipc_perm *perm,
Linus Torvalds1da177e2005-04-16 15:20:36 -07005927 u16 sclass)
5928{
Linus Torvalds1da177e2005-04-16 15:20:36 -07005929 struct ipc_security_struct *isec;
5930
James Morris89d155e2005-10-30 14:59:21 -08005931 isec = kzalloc(sizeof(struct ipc_security_struct), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005932 if (!isec)
5933 return -ENOMEM;
5934
Linus Torvalds1da177e2005-04-16 15:20:36 -07005935 isec->sclass = sclass;
Stephen Smalleybe0554c2017-01-09 10:07:31 -05005936 isec->sid = current_sid();
Linus Torvalds1da177e2005-04-16 15:20:36 -07005937 perm->security = isec;
5938
5939 return 0;
5940}
5941
5942static void ipc_free_security(struct kern_ipc_perm *perm)
5943{
5944 struct ipc_security_struct *isec = perm->security;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005945 perm->security = NULL;
5946 kfree(isec);
5947}
5948
5949static int msg_msg_alloc_security(struct msg_msg *msg)
5950{
5951 struct msg_security_struct *msec;
5952
James Morris89d155e2005-10-30 14:59:21 -08005953 msec = kzalloc(sizeof(struct msg_security_struct), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005954 if (!msec)
5955 return -ENOMEM;
5956
Linus Torvalds1da177e2005-04-16 15:20:36 -07005957 msec->sid = SECINITSID_UNLABELED;
5958 msg->security = msec;
5959
5960 return 0;
5961}
5962
5963static void msg_msg_free_security(struct msg_msg *msg)
5964{
5965 struct msg_security_struct *msec = msg->security;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005966
5967 msg->security = NULL;
5968 kfree(msec);
5969}
5970
5971static int ipc_has_perm(struct kern_ipc_perm *ipc_perms,
Stephen Smalley6af963f2005-05-01 08:58:39 -07005972 u32 perms)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005973{
Linus Torvalds1da177e2005-04-16 15:20:36 -07005974 struct ipc_security_struct *isec;
Thomas Liu2bf49692009-07-14 12:14:09 -04005975 struct common_audit_data ad;
David Howells275bb412008-11-14 10:39:19 +11005976 u32 sid = current_sid();
Linus Torvalds1da177e2005-04-16 15:20:36 -07005977
Linus Torvalds1da177e2005-04-16 15:20:36 -07005978 isec = ipc_perms->security;
5979
Eric Paris50c205f2012-04-04 15:01:43 -04005980 ad.type = LSM_AUDIT_DATA_IPC;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005981 ad.u.ipc_id = ipc_perms->key;
5982
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005983 return avc_has_perm(&selinux_state,
5984 sid, isec->sid, isec->sclass, perms, &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005985}
5986
5987static int selinux_msg_msg_alloc_security(struct msg_msg *msg)
5988{
5989 return msg_msg_alloc_security(msg);
5990}
5991
5992static void selinux_msg_msg_free_security(struct msg_msg *msg)
5993{
5994 msg_msg_free_security(msg);
5995}
5996
5997/* message queue security operations */
Eric W. Biedermand8c6e852018-03-22 21:22:26 -05005998static int selinux_msg_queue_alloc_security(struct kern_ipc_perm *msq)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005999{
Linus Torvalds1da177e2005-04-16 15:20:36 -07006000 struct ipc_security_struct *isec;
Thomas Liu2bf49692009-07-14 12:14:09 -04006001 struct common_audit_data ad;
David Howells275bb412008-11-14 10:39:19 +11006002 u32 sid = current_sid();
Linus Torvalds1da177e2005-04-16 15:20:36 -07006003 int rc;
6004
Eric W. Biedermand8c6e852018-03-22 21:22:26 -05006005 rc = ipc_alloc_security(msq, SECCLASS_MSGQ);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006006 if (rc)
6007 return rc;
6008
Eric W. Biedermand8c6e852018-03-22 21:22:26 -05006009 isec = msq->security;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006010
Eric Paris50c205f2012-04-04 15:01:43 -04006011 ad.type = LSM_AUDIT_DATA_IPC;
Eric W. Biedermand8c6e852018-03-22 21:22:26 -05006012 ad.u.ipc_id = msq->key;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006013
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006014 rc = avc_has_perm(&selinux_state,
6015 sid, isec->sid, SECCLASS_MSGQ,
Linus Torvalds1da177e2005-04-16 15:20:36 -07006016 MSGQ__CREATE, &ad);
6017 if (rc) {
Eric W. Biedermand8c6e852018-03-22 21:22:26 -05006018 ipc_free_security(msq);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006019 return rc;
6020 }
6021 return 0;
6022}
6023
Eric W. Biedermand8c6e852018-03-22 21:22:26 -05006024static void selinux_msg_queue_free_security(struct kern_ipc_perm *msq)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006025{
Eric W. Biedermand8c6e852018-03-22 21:22:26 -05006026 ipc_free_security(msq);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006027}
6028
Eric W. Biedermand8c6e852018-03-22 21:22:26 -05006029static int selinux_msg_queue_associate(struct kern_ipc_perm *msq, int msqflg)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006030{
Linus Torvalds1da177e2005-04-16 15:20:36 -07006031 struct ipc_security_struct *isec;
Thomas Liu2bf49692009-07-14 12:14:09 -04006032 struct common_audit_data ad;
David Howells275bb412008-11-14 10:39:19 +11006033 u32 sid = current_sid();
Linus Torvalds1da177e2005-04-16 15:20:36 -07006034
Eric W. Biedermand8c6e852018-03-22 21:22:26 -05006035 isec = msq->security;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006036
Eric Paris50c205f2012-04-04 15:01:43 -04006037 ad.type = LSM_AUDIT_DATA_IPC;
Eric W. Biedermand8c6e852018-03-22 21:22:26 -05006038 ad.u.ipc_id = msq->key;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006039
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006040 return avc_has_perm(&selinux_state,
6041 sid, isec->sid, SECCLASS_MSGQ,
Linus Torvalds1da177e2005-04-16 15:20:36 -07006042 MSGQ__ASSOCIATE, &ad);
6043}
6044
Eric W. Biedermand8c6e852018-03-22 21:22:26 -05006045static int selinux_msg_queue_msgctl(struct kern_ipc_perm *msq, int cmd)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006046{
6047 int err;
6048 int perms;
6049
Eric Paris828dfe12008-04-17 13:17:49 -04006050 switch (cmd) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07006051 case IPC_INFO:
6052 case MSG_INFO:
6053 /* No specific object, just general system-wide information. */
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006054 return avc_has_perm(&selinux_state,
6055 current_sid(), SECINITSID_KERNEL,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05006056 SECCLASS_SYSTEM, SYSTEM__IPC_INFO, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006057 case IPC_STAT:
6058 case MSG_STAT:
Davidlohr Bueso23c8cec2018-04-10 16:35:30 -07006059 case MSG_STAT_ANY:
Linus Torvalds1da177e2005-04-16 15:20:36 -07006060 perms = MSGQ__GETATTR | MSGQ__ASSOCIATE;
6061 break;
6062 case IPC_SET:
6063 perms = MSGQ__SETATTR;
6064 break;
6065 case IPC_RMID:
6066 perms = MSGQ__DESTROY;
6067 break;
6068 default:
6069 return 0;
6070 }
6071
Eric W. Biedermand8c6e852018-03-22 21:22:26 -05006072 err = ipc_has_perm(msq, perms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006073 return err;
6074}
6075
Eric W. Biedermand8c6e852018-03-22 21:22:26 -05006076static int selinux_msg_queue_msgsnd(struct kern_ipc_perm *msq, struct msg_msg *msg, int msqflg)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006077{
Linus Torvalds1da177e2005-04-16 15:20:36 -07006078 struct ipc_security_struct *isec;
6079 struct msg_security_struct *msec;
Thomas Liu2bf49692009-07-14 12:14:09 -04006080 struct common_audit_data ad;
David Howells275bb412008-11-14 10:39:19 +11006081 u32 sid = current_sid();
Linus Torvalds1da177e2005-04-16 15:20:36 -07006082 int rc;
6083
Eric W. Biedermand8c6e852018-03-22 21:22:26 -05006084 isec = msq->security;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006085 msec = msg->security;
6086
6087 /*
6088 * First time through, need to assign label to the message
6089 */
6090 if (msec->sid == SECINITSID_UNLABELED) {
6091 /*
6092 * Compute new sid based on current process and
6093 * message queue this message will be stored in
6094 */
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05006095 rc = security_transition_sid(&selinux_state, sid, isec->sid,
6096 SECCLASS_MSG, NULL, &msec->sid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006097 if (rc)
6098 return rc;
6099 }
6100
Eric Paris50c205f2012-04-04 15:01:43 -04006101 ad.type = LSM_AUDIT_DATA_IPC;
Eric W. Biedermand8c6e852018-03-22 21:22:26 -05006102 ad.u.ipc_id = msq->key;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006103
6104 /* Can this process write to the queue? */
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006105 rc = avc_has_perm(&selinux_state,
6106 sid, isec->sid, SECCLASS_MSGQ,
Linus Torvalds1da177e2005-04-16 15:20:36 -07006107 MSGQ__WRITE, &ad);
6108 if (!rc)
6109 /* Can this process send the message */
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006110 rc = avc_has_perm(&selinux_state,
6111 sid, msec->sid, SECCLASS_MSG,
David Howells275bb412008-11-14 10:39:19 +11006112 MSG__SEND, &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006113 if (!rc)
6114 /* Can the message be put in the queue? */
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006115 rc = avc_has_perm(&selinux_state,
6116 msec->sid, isec->sid, SECCLASS_MSGQ,
David Howells275bb412008-11-14 10:39:19 +11006117 MSGQ__ENQUEUE, &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006118
6119 return rc;
6120}
6121
Eric W. Biedermand8c6e852018-03-22 21:22:26 -05006122static int selinux_msg_queue_msgrcv(struct kern_ipc_perm *msq, struct msg_msg *msg,
Linus Torvalds1da177e2005-04-16 15:20:36 -07006123 struct task_struct *target,
6124 long type, int mode)
6125{
Linus Torvalds1da177e2005-04-16 15:20:36 -07006126 struct ipc_security_struct *isec;
6127 struct msg_security_struct *msec;
Thomas Liu2bf49692009-07-14 12:14:09 -04006128 struct common_audit_data ad;
David Howells275bb412008-11-14 10:39:19 +11006129 u32 sid = task_sid(target);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006130 int rc;
6131
Eric W. Biedermand8c6e852018-03-22 21:22:26 -05006132 isec = msq->security;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006133 msec = msg->security;
6134
Eric Paris50c205f2012-04-04 15:01:43 -04006135 ad.type = LSM_AUDIT_DATA_IPC;
Eric W. Biedermand8c6e852018-03-22 21:22:26 -05006136 ad.u.ipc_id = msq->key;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006137
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006138 rc = avc_has_perm(&selinux_state,
6139 sid, isec->sid,
Linus Torvalds1da177e2005-04-16 15:20:36 -07006140 SECCLASS_MSGQ, MSGQ__READ, &ad);
6141 if (!rc)
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006142 rc = avc_has_perm(&selinux_state,
6143 sid, msec->sid,
Linus Torvalds1da177e2005-04-16 15:20:36 -07006144 SECCLASS_MSG, MSG__RECEIVE, &ad);
6145 return rc;
6146}
6147
6148/* Shared Memory security operations */
Eric W. Biederman7191adf2018-03-22 21:08:27 -05006149static int selinux_shm_alloc_security(struct kern_ipc_perm *shp)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006150{
Linus Torvalds1da177e2005-04-16 15:20:36 -07006151 struct ipc_security_struct *isec;
Thomas Liu2bf49692009-07-14 12:14:09 -04006152 struct common_audit_data ad;
David Howells275bb412008-11-14 10:39:19 +11006153 u32 sid = current_sid();
Linus Torvalds1da177e2005-04-16 15:20:36 -07006154 int rc;
6155
Eric W. Biederman7191adf2018-03-22 21:08:27 -05006156 rc = ipc_alloc_security(shp, SECCLASS_SHM);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006157 if (rc)
6158 return rc;
6159
Eric W. Biederman7191adf2018-03-22 21:08:27 -05006160 isec = shp->security;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006161
Eric Paris50c205f2012-04-04 15:01:43 -04006162 ad.type = LSM_AUDIT_DATA_IPC;
Eric W. Biederman7191adf2018-03-22 21:08:27 -05006163 ad.u.ipc_id = shp->key;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006164
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006165 rc = avc_has_perm(&selinux_state,
6166 sid, isec->sid, SECCLASS_SHM,
Linus Torvalds1da177e2005-04-16 15:20:36 -07006167 SHM__CREATE, &ad);
6168 if (rc) {
Eric W. Biederman7191adf2018-03-22 21:08:27 -05006169 ipc_free_security(shp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006170 return rc;
6171 }
6172 return 0;
6173}
6174
Eric W. Biederman7191adf2018-03-22 21:08:27 -05006175static void selinux_shm_free_security(struct kern_ipc_perm *shp)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006176{
Eric W. Biederman7191adf2018-03-22 21:08:27 -05006177 ipc_free_security(shp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006178}
6179
Eric W. Biederman7191adf2018-03-22 21:08:27 -05006180static int selinux_shm_associate(struct kern_ipc_perm *shp, int shmflg)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006181{
Linus Torvalds1da177e2005-04-16 15:20:36 -07006182 struct ipc_security_struct *isec;
Thomas Liu2bf49692009-07-14 12:14:09 -04006183 struct common_audit_data ad;
David Howells275bb412008-11-14 10:39:19 +11006184 u32 sid = current_sid();
Linus Torvalds1da177e2005-04-16 15:20:36 -07006185
Eric W. Biederman7191adf2018-03-22 21:08:27 -05006186 isec = shp->security;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006187
Eric Paris50c205f2012-04-04 15:01:43 -04006188 ad.type = LSM_AUDIT_DATA_IPC;
Eric W. Biederman7191adf2018-03-22 21:08:27 -05006189 ad.u.ipc_id = shp->key;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006190
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006191 return avc_has_perm(&selinux_state,
6192 sid, isec->sid, SECCLASS_SHM,
Linus Torvalds1da177e2005-04-16 15:20:36 -07006193 SHM__ASSOCIATE, &ad);
6194}
6195
6196/* Note, at this point, shp is locked down */
Eric W. Biederman7191adf2018-03-22 21:08:27 -05006197static int selinux_shm_shmctl(struct kern_ipc_perm *shp, int cmd)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006198{
6199 int perms;
6200 int err;
6201
Eric Paris828dfe12008-04-17 13:17:49 -04006202 switch (cmd) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07006203 case IPC_INFO:
6204 case SHM_INFO:
6205 /* No specific object, just general system-wide information. */
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006206 return avc_has_perm(&selinux_state,
6207 current_sid(), SECINITSID_KERNEL,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05006208 SECCLASS_SYSTEM, SYSTEM__IPC_INFO, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006209 case IPC_STAT:
6210 case SHM_STAT:
Davidlohr Buesoc21a6972018-04-10 16:35:23 -07006211 case SHM_STAT_ANY:
Linus Torvalds1da177e2005-04-16 15:20:36 -07006212 perms = SHM__GETATTR | SHM__ASSOCIATE;
6213 break;
6214 case IPC_SET:
6215 perms = SHM__SETATTR;
6216 break;
6217 case SHM_LOCK:
6218 case SHM_UNLOCK:
6219 perms = SHM__LOCK;
6220 break;
6221 case IPC_RMID:
6222 perms = SHM__DESTROY;
6223 break;
6224 default:
6225 return 0;
6226 }
6227
Eric W. Biederman7191adf2018-03-22 21:08:27 -05006228 err = ipc_has_perm(shp, perms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006229 return err;
6230}
6231
Eric W. Biederman7191adf2018-03-22 21:08:27 -05006232static int selinux_shm_shmat(struct kern_ipc_perm *shp,
Linus Torvalds1da177e2005-04-16 15:20:36 -07006233 char __user *shmaddr, int shmflg)
6234{
6235 u32 perms;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006236
6237 if (shmflg & SHM_RDONLY)
6238 perms = SHM__READ;
6239 else
6240 perms = SHM__READ | SHM__WRITE;
6241
Eric W. Biederman7191adf2018-03-22 21:08:27 -05006242 return ipc_has_perm(shp, perms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006243}
6244
6245/* Semaphore security operations */
Eric W. Biedermanaefad952018-03-22 20:52:43 -05006246static int selinux_sem_alloc_security(struct kern_ipc_perm *sma)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006247{
Linus Torvalds1da177e2005-04-16 15:20:36 -07006248 struct ipc_security_struct *isec;
Thomas Liu2bf49692009-07-14 12:14:09 -04006249 struct common_audit_data ad;
David Howells275bb412008-11-14 10:39:19 +11006250 u32 sid = current_sid();
Linus Torvalds1da177e2005-04-16 15:20:36 -07006251 int rc;
6252
Eric W. Biedermanaefad952018-03-22 20:52:43 -05006253 rc = ipc_alloc_security(sma, SECCLASS_SEM);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006254 if (rc)
6255 return rc;
6256
Eric W. Biedermanaefad952018-03-22 20:52:43 -05006257 isec = sma->security;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006258
Eric Paris50c205f2012-04-04 15:01:43 -04006259 ad.type = LSM_AUDIT_DATA_IPC;
Eric W. Biedermanaefad952018-03-22 20:52:43 -05006260 ad.u.ipc_id = sma->key;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006261
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006262 rc = avc_has_perm(&selinux_state,
6263 sid, isec->sid, SECCLASS_SEM,
Linus Torvalds1da177e2005-04-16 15:20:36 -07006264 SEM__CREATE, &ad);
6265 if (rc) {
Eric W. Biedermanaefad952018-03-22 20:52:43 -05006266 ipc_free_security(sma);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006267 return rc;
6268 }
6269 return 0;
6270}
6271
Eric W. Biedermanaefad952018-03-22 20:52:43 -05006272static void selinux_sem_free_security(struct kern_ipc_perm *sma)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006273{
Eric W. Biedermanaefad952018-03-22 20:52:43 -05006274 ipc_free_security(sma);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006275}
6276
Eric W. Biedermanaefad952018-03-22 20:52:43 -05006277static int selinux_sem_associate(struct kern_ipc_perm *sma, int semflg)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006278{
Linus Torvalds1da177e2005-04-16 15:20:36 -07006279 struct ipc_security_struct *isec;
Thomas Liu2bf49692009-07-14 12:14:09 -04006280 struct common_audit_data ad;
David Howells275bb412008-11-14 10:39:19 +11006281 u32 sid = current_sid();
Linus Torvalds1da177e2005-04-16 15:20:36 -07006282
Eric W. Biedermanaefad952018-03-22 20:52:43 -05006283 isec = sma->security;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006284
Eric Paris50c205f2012-04-04 15:01:43 -04006285 ad.type = LSM_AUDIT_DATA_IPC;
Eric W. Biedermanaefad952018-03-22 20:52:43 -05006286 ad.u.ipc_id = sma->key;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006287
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006288 return avc_has_perm(&selinux_state,
6289 sid, isec->sid, SECCLASS_SEM,
Linus Torvalds1da177e2005-04-16 15:20:36 -07006290 SEM__ASSOCIATE, &ad);
6291}
6292
6293/* Note, at this point, sma is locked down */
Eric W. Biedermanaefad952018-03-22 20:52:43 -05006294static int selinux_sem_semctl(struct kern_ipc_perm *sma, int cmd)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006295{
6296 int err;
6297 u32 perms;
6298
Eric Paris828dfe12008-04-17 13:17:49 -04006299 switch (cmd) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07006300 case IPC_INFO:
6301 case SEM_INFO:
6302 /* No specific object, just general system-wide information. */
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006303 return avc_has_perm(&selinux_state,
6304 current_sid(), SECINITSID_KERNEL,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05006305 SECCLASS_SYSTEM, SYSTEM__IPC_INFO, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006306 case GETPID:
6307 case GETNCNT:
6308 case GETZCNT:
6309 perms = SEM__GETATTR;
6310 break;
6311 case GETVAL:
6312 case GETALL:
6313 perms = SEM__READ;
6314 break;
6315 case SETVAL:
6316 case SETALL:
6317 perms = SEM__WRITE;
6318 break;
6319 case IPC_RMID:
6320 perms = SEM__DESTROY;
6321 break;
6322 case IPC_SET:
6323 perms = SEM__SETATTR;
6324 break;
6325 case IPC_STAT:
6326 case SEM_STAT:
Davidlohr Buesoa280d6d2018-04-10 16:35:26 -07006327 case SEM_STAT_ANY:
Linus Torvalds1da177e2005-04-16 15:20:36 -07006328 perms = SEM__GETATTR | SEM__ASSOCIATE;
6329 break;
6330 default:
6331 return 0;
6332 }
6333
Eric W. Biedermanaefad952018-03-22 20:52:43 -05006334 err = ipc_has_perm(sma, perms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006335 return err;
6336}
6337
Eric W. Biedermanaefad952018-03-22 20:52:43 -05006338static int selinux_sem_semop(struct kern_ipc_perm *sma,
Linus Torvalds1da177e2005-04-16 15:20:36 -07006339 struct sembuf *sops, unsigned nsops, int alter)
6340{
6341 u32 perms;
6342
6343 if (alter)
6344 perms = SEM__READ | SEM__WRITE;
6345 else
6346 perms = SEM__READ;
6347
Eric W. Biedermanaefad952018-03-22 20:52:43 -05006348 return ipc_has_perm(sma, perms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006349}
6350
6351static int selinux_ipc_permission(struct kern_ipc_perm *ipcp, short flag)
6352{
Linus Torvalds1da177e2005-04-16 15:20:36 -07006353 u32 av = 0;
6354
Linus Torvalds1da177e2005-04-16 15:20:36 -07006355 av = 0;
6356 if (flag & S_IRUGO)
6357 av |= IPC__UNIX_READ;
6358 if (flag & S_IWUGO)
6359 av |= IPC__UNIX_WRITE;
6360
6361 if (av == 0)
6362 return 0;
6363
Stephen Smalley6af963f2005-05-01 08:58:39 -07006364 return ipc_has_perm(ipcp, av);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006365}
6366
Ahmed S. Darwish713a04ae2008-03-01 21:52:30 +02006367static void selinux_ipc_getsecid(struct kern_ipc_perm *ipcp, u32 *secid)
6368{
6369 struct ipc_security_struct *isec = ipcp->security;
6370 *secid = isec->sid;
6371}
6372
Eric Paris828dfe12008-04-17 13:17:49 -04006373static void selinux_d_instantiate(struct dentry *dentry, struct inode *inode)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006374{
6375 if (inode)
6376 inode_doinit_with_dentry(inode, dentry);
6377}
6378
6379static int selinux_getprocattr(struct task_struct *p,
Al Viro04ff9702007-03-12 16:17:58 +00006380 char *name, char **value)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006381{
David Howells275bb412008-11-14 10:39:19 +11006382 const struct task_security_struct *__tsec;
Dustin Kirkland8c8570f2005-11-03 17:15:16 +00006383 u32 sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006384 int error;
Al Viro04ff9702007-03-12 16:17:58 +00006385 unsigned len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006386
David Howells275bb412008-11-14 10:39:19 +11006387 rcu_read_lock();
6388 __tsec = __task_cred(p)->security;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006389
Stephen Smalleybe0554c2017-01-09 10:07:31 -05006390 if (current != p) {
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006391 error = avc_has_perm(&selinux_state,
6392 current_sid(), __tsec->sid,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05006393 SECCLASS_PROCESS, PROCESS__GETATTR, NULL);
6394 if (error)
6395 goto bad;
6396 }
6397
Linus Torvalds1da177e2005-04-16 15:20:36 -07006398 if (!strcmp(name, "current"))
David Howells275bb412008-11-14 10:39:19 +11006399 sid = __tsec->sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006400 else if (!strcmp(name, "prev"))
David Howells275bb412008-11-14 10:39:19 +11006401 sid = __tsec->osid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006402 else if (!strcmp(name, "exec"))
David Howells275bb412008-11-14 10:39:19 +11006403 sid = __tsec->exec_sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006404 else if (!strcmp(name, "fscreate"))
David Howells275bb412008-11-14 10:39:19 +11006405 sid = __tsec->create_sid;
Michael LeMay4eb582c2006-06-26 00:24:57 -07006406 else if (!strcmp(name, "keycreate"))
David Howells275bb412008-11-14 10:39:19 +11006407 sid = __tsec->keycreate_sid;
Eric Paris42c3e032006-06-26 00:26:03 -07006408 else if (!strcmp(name, "sockcreate"))
David Howells275bb412008-11-14 10:39:19 +11006409 sid = __tsec->sockcreate_sid;
Stephen Smalleybe0554c2017-01-09 10:07:31 -05006410 else {
6411 error = -EINVAL;
6412 goto bad;
6413 }
David Howells275bb412008-11-14 10:39:19 +11006414 rcu_read_unlock();
Linus Torvalds1da177e2005-04-16 15:20:36 -07006415
6416 if (!sid)
6417 return 0;
6418
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05006419 error = security_sid_to_context(&selinux_state, sid, value, &len);
Al Viro04ff9702007-03-12 16:17:58 +00006420 if (error)
6421 return error;
6422 return len;
David Howells275bb412008-11-14 10:39:19 +11006423
Stephen Smalleybe0554c2017-01-09 10:07:31 -05006424bad:
David Howells275bb412008-11-14 10:39:19 +11006425 rcu_read_unlock();
Stephen Smalleybe0554c2017-01-09 10:07:31 -05006426 return error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006427}
6428
Stephen Smalleyb21507e2017-01-09 10:07:31 -05006429static int selinux_setprocattr(const char *name, void *value, size_t size)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006430{
6431 struct task_security_struct *tsec;
David Howellsd84f4f92008-11-14 10:39:23 +11006432 struct cred *new;
Stephen Smalleybe0554c2017-01-09 10:07:31 -05006433 u32 mysid = current_sid(), sid = 0, ptsid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006434 int error;
6435 char *str = value;
6436
Linus Torvalds1da177e2005-04-16 15:20:36 -07006437 /*
6438 * Basic control over ability to set these attributes at all.
Linus Torvalds1da177e2005-04-16 15:20:36 -07006439 */
6440 if (!strcmp(name, "exec"))
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006441 error = avc_has_perm(&selinux_state,
6442 mysid, mysid, SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05006443 PROCESS__SETEXEC, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006444 else if (!strcmp(name, "fscreate"))
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006445 error = avc_has_perm(&selinux_state,
6446 mysid, mysid, SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05006447 PROCESS__SETFSCREATE, NULL);
Michael LeMay4eb582c2006-06-26 00:24:57 -07006448 else if (!strcmp(name, "keycreate"))
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006449 error = avc_has_perm(&selinux_state,
6450 mysid, mysid, SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05006451 PROCESS__SETKEYCREATE, NULL);
Eric Paris42c3e032006-06-26 00:26:03 -07006452 else if (!strcmp(name, "sockcreate"))
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006453 error = avc_has_perm(&selinux_state,
6454 mysid, mysid, SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05006455 PROCESS__SETSOCKCREATE, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006456 else if (!strcmp(name, "current"))
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006457 error = avc_has_perm(&selinux_state,
6458 mysid, mysid, SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05006459 PROCESS__SETCURRENT, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006460 else
6461 error = -EINVAL;
6462 if (error)
6463 return error;
6464
6465 /* Obtain a SID for the context, if one was specified. */
Stephen Smalleya050a572017-01-31 11:54:04 -05006466 if (size && str[0] && str[0] != '\n') {
Linus Torvalds1da177e2005-04-16 15:20:36 -07006467 if (str[size-1] == '\n') {
6468 str[size-1] = 0;
6469 size--;
6470 }
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05006471 error = security_context_to_sid(&selinux_state, value, size,
6472 &sid, GFP_KERNEL);
Stephen Smalley12b29f32008-05-07 13:03:20 -04006473 if (error == -EINVAL && !strcmp(name, "fscreate")) {
Stephen Smalleydb590002017-04-20 11:31:30 -04006474 if (!has_cap_mac_admin(true)) {
Eric Parisd6ea83e2012-04-04 13:45:49 -04006475 struct audit_buffer *ab;
6476 size_t audit_size;
6477
6478 /* We strip a nul only if it is at the end, otherwise the
6479 * context contains a nul and we should audit that */
6480 if (str[size - 1] == '\0')
6481 audit_size = size - 1;
6482 else
6483 audit_size = size;
Richard Guy Briggscdfb6b32018-05-12 21:58:20 -04006484 ab = audit_log_start(audit_context(),
6485 GFP_ATOMIC,
6486 AUDIT_SELINUX_ERR);
Eric Parisd6ea83e2012-04-04 13:45:49 -04006487 audit_log_format(ab, "op=fscreate invalid_context=");
6488 audit_log_n_untrustedstring(ab, value, audit_size);
6489 audit_log_end(ab);
6490
Stephen Smalley12b29f32008-05-07 13:03:20 -04006491 return error;
Eric Parisd6ea83e2012-04-04 13:45:49 -04006492 }
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05006493 error = security_context_to_sid_force(
6494 &selinux_state,
6495 value, size, &sid);
Stephen Smalley12b29f32008-05-07 13:03:20 -04006496 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006497 if (error)
6498 return error;
6499 }
6500
David Howellsd84f4f92008-11-14 10:39:23 +11006501 new = prepare_creds();
6502 if (!new)
6503 return -ENOMEM;
6504
Linus Torvalds1da177e2005-04-16 15:20:36 -07006505 /* Permission checking based on the specified context is
6506 performed during the actual operation (execve,
6507 open/mkdir/...), when we know the full context of the
David Howellsd84f4f92008-11-14 10:39:23 +11006508 operation. See selinux_bprm_set_creds for the execve
Linus Torvalds1da177e2005-04-16 15:20:36 -07006509 checks and may_create for the file creation checks. The
6510 operation will then fail if the context is not permitted. */
David Howellsd84f4f92008-11-14 10:39:23 +11006511 tsec = new->security;
6512 if (!strcmp(name, "exec")) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07006513 tsec->exec_sid = sid;
David Howellsd84f4f92008-11-14 10:39:23 +11006514 } else if (!strcmp(name, "fscreate")) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07006515 tsec->create_sid = sid;
David Howellsd84f4f92008-11-14 10:39:23 +11006516 } else if (!strcmp(name, "keycreate")) {
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006517 error = avc_has_perm(&selinux_state,
6518 mysid, sid, SECCLASS_KEY, KEY__CREATE,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05006519 NULL);
Michael LeMay4eb582c2006-06-26 00:24:57 -07006520 if (error)
David Howellsd84f4f92008-11-14 10:39:23 +11006521 goto abort_change;
Michael LeMay4eb582c2006-06-26 00:24:57 -07006522 tsec->keycreate_sid = sid;
David Howellsd84f4f92008-11-14 10:39:23 +11006523 } else if (!strcmp(name, "sockcreate")) {
Eric Paris42c3e032006-06-26 00:26:03 -07006524 tsec->sockcreate_sid = sid;
David Howellsd84f4f92008-11-14 10:39:23 +11006525 } else if (!strcmp(name, "current")) {
6526 error = -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006527 if (sid == 0)
David Howellsd84f4f92008-11-14 10:39:23 +11006528 goto abort_change;
KaiGai Koheid9250de2008-08-28 16:35:57 +09006529
David Howellsd84f4f92008-11-14 10:39:23 +11006530 /* Only allow single threaded processes to change context */
6531 error = -EPERM;
Oleg Nesterov5bb459b2009-07-10 03:48:23 +02006532 if (!current_is_single_threaded()) {
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05006533 error = security_bounded_transition(&selinux_state,
6534 tsec->sid, sid);
David Howellsd84f4f92008-11-14 10:39:23 +11006535 if (error)
6536 goto abort_change;
Eric Paris828dfe12008-04-17 13:17:49 -04006537 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006538
6539 /* Check permissions for the transition. */
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006540 error = avc_has_perm(&selinux_state,
6541 tsec->sid, sid, SECCLASS_PROCESS,
Eric Paris828dfe12008-04-17 13:17:49 -04006542 PROCESS__DYNTRANSITION, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006543 if (error)
David Howellsd84f4f92008-11-14 10:39:23 +11006544 goto abort_change;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006545
6546 /* Check for ptracing, and update the task SID if ok.
6547 Otherwise, leave SID unchanged and fail. */
Stephen Smalleybe0554c2017-01-09 10:07:31 -05006548 ptsid = ptrace_parent_sid();
Paul Moore0c6181c2016-03-30 21:41:21 -04006549 if (ptsid != 0) {
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006550 error = avc_has_perm(&selinux_state,
6551 ptsid, sid, SECCLASS_PROCESS,
David Howellsd84f4f92008-11-14 10:39:23 +11006552 PROCESS__PTRACE, NULL);
6553 if (error)
6554 goto abort_change;
6555 }
6556
6557 tsec->sid = sid;
6558 } else {
6559 error = -EINVAL;
6560 goto abort_change;
6561 }
6562
6563 commit_creds(new);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006564 return size;
David Howellsd84f4f92008-11-14 10:39:23 +11006565
6566abort_change:
6567 abort_creds(new);
6568 return error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006569}
6570
David Quigley746df9b2013-05-22 12:50:35 -04006571static int selinux_ismaclabel(const char *name)
6572{
6573 return (strcmp(name, XATTR_SELINUX_SUFFIX) == 0);
6574}
6575
Catherine Zhangdc49c1f2006-08-02 14:12:06 -07006576static int selinux_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
6577{
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05006578 return security_sid_to_context(&selinux_state, secid,
6579 secdata, seclen);
Catherine Zhangdc49c1f2006-08-02 14:12:06 -07006580}
6581
David Howells7bf570d2008-04-29 20:52:51 +01006582static int selinux_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid)
David Howells63cb3442008-01-15 23:47:35 +00006583{
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05006584 return security_context_to_sid(&selinux_state, secdata, seclen,
6585 secid, GFP_KERNEL);
David Howells63cb3442008-01-15 23:47:35 +00006586}
6587
Catherine Zhangdc49c1f2006-08-02 14:12:06 -07006588static void selinux_release_secctx(char *secdata, u32 seclen)
6589{
Paul Moore088999e2007-08-01 11:12:58 -04006590 kfree(secdata);
Catherine Zhangdc49c1f2006-08-02 14:12:06 -07006591}
6592
Andreas Gruenbacher6f3be9f2015-12-24 11:09:40 -05006593static void selinux_inode_invalidate_secctx(struct inode *inode)
6594{
6595 struct inode_security_struct *isec = inode->i_security;
6596
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01006597 spin_lock(&isec->lock);
Andreas Gruenbacher6f3be9f2015-12-24 11:09:40 -05006598 isec->initialized = LABEL_INVALID;
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01006599 spin_unlock(&isec->lock);
Andreas Gruenbacher6f3be9f2015-12-24 11:09:40 -05006600}
6601
David P. Quigley1ee65e32009-09-03 14:25:57 -04006602/*
6603 * called with inode->i_mutex locked
6604 */
6605static int selinux_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen)
6606{
6607 return selinux_inode_setsecurity(inode, XATTR_SELINUX_SUFFIX, ctx, ctxlen, 0);
6608}
6609
6610/*
6611 * called with inode->i_mutex locked
6612 */
6613static int selinux_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen)
6614{
6615 return __vfs_setxattr_noperm(dentry, XATTR_NAME_SELINUX, ctx, ctxlen, 0);
6616}
6617
6618static int selinux_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen)
6619{
6620 int len = 0;
6621 len = selinux_inode_getsecurity(inode, XATTR_SELINUX_SUFFIX,
6622 ctx, true);
6623 if (len < 0)
6624 return len;
6625 *ctxlen = len;
6626 return 0;
6627}
Michael LeMayd7200242006-06-22 14:47:17 -07006628#ifdef CONFIG_KEYS
6629
David Howellsd84f4f92008-11-14 10:39:23 +11006630static int selinux_key_alloc(struct key *k, const struct cred *cred,
David Howells7e047ef2006-06-26 00:24:50 -07006631 unsigned long flags)
Michael LeMayd7200242006-06-22 14:47:17 -07006632{
David Howellsd84f4f92008-11-14 10:39:23 +11006633 const struct task_security_struct *tsec;
Michael LeMayd7200242006-06-22 14:47:17 -07006634 struct key_security_struct *ksec;
6635
6636 ksec = kzalloc(sizeof(struct key_security_struct), GFP_KERNEL);
6637 if (!ksec)
6638 return -ENOMEM;
6639
David Howellsd84f4f92008-11-14 10:39:23 +11006640 tsec = cred->security;
6641 if (tsec->keycreate_sid)
6642 ksec->sid = tsec->keycreate_sid;
Michael LeMay4eb582c2006-06-26 00:24:57 -07006643 else
David Howellsd84f4f92008-11-14 10:39:23 +11006644 ksec->sid = tsec->sid;
Michael LeMayd7200242006-06-22 14:47:17 -07006645
David Howells275bb412008-11-14 10:39:19 +11006646 k->security = ksec;
Michael LeMayd7200242006-06-22 14:47:17 -07006647 return 0;
6648}
6649
6650static void selinux_key_free(struct key *k)
6651{
6652 struct key_security_struct *ksec = k->security;
6653
6654 k->security = NULL;
6655 kfree(ksec);
6656}
6657
6658static int selinux_key_permission(key_ref_t key_ref,
David Howellsd84f4f92008-11-14 10:39:23 +11006659 const struct cred *cred,
David Howellsf5895942014-03-14 17:44:49 +00006660 unsigned perm)
Michael LeMayd7200242006-06-22 14:47:17 -07006661{
6662 struct key *key;
Michael LeMayd7200242006-06-22 14:47:17 -07006663 struct key_security_struct *ksec;
David Howells275bb412008-11-14 10:39:19 +11006664 u32 sid;
Michael LeMayd7200242006-06-22 14:47:17 -07006665
6666 /* if no specific permissions are requested, we skip the
6667 permission check. No serious, additional covert channels
6668 appear to be created. */
6669 if (perm == 0)
6670 return 0;
6671
David Howellsd84f4f92008-11-14 10:39:23 +11006672 sid = cred_sid(cred);
David Howells275bb412008-11-14 10:39:19 +11006673
6674 key = key_ref_to_ptr(key_ref);
6675 ksec = key->security;
6676
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006677 return avc_has_perm(&selinux_state,
6678 sid, ksec->sid, SECCLASS_KEY, perm, NULL);
Michael LeMayd7200242006-06-22 14:47:17 -07006679}
6680
David Howells70a5bb72008-04-29 01:01:26 -07006681static int selinux_key_getsecurity(struct key *key, char **_buffer)
6682{
6683 struct key_security_struct *ksec = key->security;
6684 char *context = NULL;
6685 unsigned len;
6686 int rc;
6687
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05006688 rc = security_sid_to_context(&selinux_state, ksec->sid,
6689 &context, &len);
David Howells70a5bb72008-04-29 01:01:26 -07006690 if (!rc)
6691 rc = len;
6692 *_buffer = context;
6693 return rc;
6694}
Daniel Jurgens3a976fa2017-05-19 15:48:56 +03006695#endif
David Howells70a5bb72008-04-29 01:01:26 -07006696
Daniel Jurgens3a976fa2017-05-19 15:48:56 +03006697#ifdef CONFIG_SECURITY_INFINIBAND
Daniel Jurgenscfc4d882017-05-19 15:48:57 +03006698static int selinux_ib_pkey_access(void *ib_sec, u64 subnet_prefix, u16 pkey_val)
6699{
6700 struct common_audit_data ad;
6701 int err;
6702 u32 sid = 0;
6703 struct ib_security_struct *sec = ib_sec;
6704 struct lsm_ibpkey_audit ibpkey;
6705
Daniel Jurgens409dcf32017-05-19 15:48:59 +03006706 err = sel_ib_pkey_sid(subnet_prefix, pkey_val, &sid);
Daniel Jurgenscfc4d882017-05-19 15:48:57 +03006707 if (err)
6708 return err;
6709
6710 ad.type = LSM_AUDIT_DATA_IBPKEY;
6711 ibpkey.subnet_prefix = subnet_prefix;
6712 ibpkey.pkey = pkey_val;
6713 ad.u.ibpkey = &ibpkey;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006714 return avc_has_perm(&selinux_state,
6715 sec->sid, sid,
Daniel Jurgenscfc4d882017-05-19 15:48:57 +03006716 SECCLASS_INFINIBAND_PKEY,
6717 INFINIBAND_PKEY__ACCESS, &ad);
6718}
6719
Daniel Jurgensab861df2017-05-19 15:48:58 +03006720static int selinux_ib_endport_manage_subnet(void *ib_sec, const char *dev_name,
6721 u8 port_num)
6722{
6723 struct common_audit_data ad;
6724 int err;
6725 u32 sid = 0;
6726 struct ib_security_struct *sec = ib_sec;
6727 struct lsm_ibendport_audit ibendport;
6728
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05006729 err = security_ib_endport_sid(&selinux_state, dev_name, port_num,
6730 &sid);
Daniel Jurgensab861df2017-05-19 15:48:58 +03006731
6732 if (err)
6733 return err;
6734
6735 ad.type = LSM_AUDIT_DATA_IBENDPORT;
6736 strncpy(ibendport.dev_name, dev_name, sizeof(ibendport.dev_name));
6737 ibendport.port = port_num;
6738 ad.u.ibendport = &ibendport;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006739 return avc_has_perm(&selinux_state,
6740 sec->sid, sid,
Daniel Jurgensab861df2017-05-19 15:48:58 +03006741 SECCLASS_INFINIBAND_ENDPORT,
6742 INFINIBAND_ENDPORT__MANAGE_SUBNET, &ad);
6743}
6744
Daniel Jurgens3a976fa2017-05-19 15:48:56 +03006745static int selinux_ib_alloc_security(void **ib_sec)
6746{
6747 struct ib_security_struct *sec;
6748
6749 sec = kzalloc(sizeof(*sec), GFP_KERNEL);
6750 if (!sec)
6751 return -ENOMEM;
6752 sec->sid = current_sid();
6753
6754 *ib_sec = sec;
6755 return 0;
6756}
6757
6758static void selinux_ib_free_security(void *ib_sec)
6759{
6760 kfree(ib_sec);
6761}
Michael LeMayd7200242006-06-22 14:47:17 -07006762#endif
6763
Chenbo Fengec27c352017-10-18 13:00:25 -07006764#ifdef CONFIG_BPF_SYSCALL
6765static int selinux_bpf(int cmd, union bpf_attr *attr,
6766 unsigned int size)
6767{
6768 u32 sid = current_sid();
6769 int ret;
6770
6771 switch (cmd) {
6772 case BPF_MAP_CREATE:
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006773 ret = avc_has_perm(&selinux_state,
6774 sid, sid, SECCLASS_BPF, BPF__MAP_CREATE,
Chenbo Fengec27c352017-10-18 13:00:25 -07006775 NULL);
6776 break;
6777 case BPF_PROG_LOAD:
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006778 ret = avc_has_perm(&selinux_state,
6779 sid, sid, SECCLASS_BPF, BPF__PROG_LOAD,
Chenbo Fengec27c352017-10-18 13:00:25 -07006780 NULL);
6781 break;
6782 default:
6783 ret = 0;
6784 break;
6785 }
6786
6787 return ret;
6788}
6789
6790static u32 bpf_map_fmode_to_av(fmode_t fmode)
6791{
6792 u32 av = 0;
6793
6794 if (fmode & FMODE_READ)
6795 av |= BPF__MAP_READ;
6796 if (fmode & FMODE_WRITE)
6797 av |= BPF__MAP_WRITE;
6798 return av;
6799}
6800
Chenbo Fengf66e4482017-10-18 13:00:26 -07006801/* This function will check the file pass through unix socket or binder to see
6802 * if it is a bpf related object. And apply correspinding checks on the bpf
6803 * object based on the type. The bpf maps and programs, not like other files and
6804 * socket, are using a shared anonymous inode inside the kernel as their inode.
6805 * So checking that inode cannot identify if the process have privilege to
6806 * access the bpf object and that's why we have to add this additional check in
6807 * selinux_file_receive and selinux_binder_transfer_files.
6808 */
6809static int bpf_fd_pass(struct file *file, u32 sid)
6810{
6811 struct bpf_security_struct *bpfsec;
6812 struct bpf_prog *prog;
6813 struct bpf_map *map;
6814 int ret;
6815
6816 if (file->f_op == &bpf_map_fops) {
6817 map = file->private_data;
6818 bpfsec = map->security;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006819 ret = avc_has_perm(&selinux_state,
6820 sid, bpfsec->sid, SECCLASS_BPF,
Chenbo Fengf66e4482017-10-18 13:00:26 -07006821 bpf_map_fmode_to_av(file->f_mode), NULL);
6822 if (ret)
6823 return ret;
6824 } else if (file->f_op == &bpf_prog_fops) {
6825 prog = file->private_data;
6826 bpfsec = prog->aux->security;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006827 ret = avc_has_perm(&selinux_state,
6828 sid, bpfsec->sid, SECCLASS_BPF,
Chenbo Fengf66e4482017-10-18 13:00:26 -07006829 BPF__PROG_RUN, NULL);
6830 if (ret)
6831 return ret;
6832 }
6833 return 0;
6834}
6835
Chenbo Fengec27c352017-10-18 13:00:25 -07006836static int selinux_bpf_map(struct bpf_map *map, fmode_t fmode)
6837{
6838 u32 sid = current_sid();
6839 struct bpf_security_struct *bpfsec;
6840
6841 bpfsec = map->security;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006842 return avc_has_perm(&selinux_state,
6843 sid, bpfsec->sid, SECCLASS_BPF,
Chenbo Fengec27c352017-10-18 13:00:25 -07006844 bpf_map_fmode_to_av(fmode), NULL);
6845}
6846
6847static int selinux_bpf_prog(struct bpf_prog *prog)
6848{
6849 u32 sid = current_sid();
6850 struct bpf_security_struct *bpfsec;
6851
6852 bpfsec = prog->aux->security;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006853 return avc_has_perm(&selinux_state,
6854 sid, bpfsec->sid, SECCLASS_BPF,
Chenbo Fengec27c352017-10-18 13:00:25 -07006855 BPF__PROG_RUN, NULL);
6856}
6857
6858static int selinux_bpf_map_alloc(struct bpf_map *map)
6859{
6860 struct bpf_security_struct *bpfsec;
6861
6862 bpfsec = kzalloc(sizeof(*bpfsec), GFP_KERNEL);
6863 if (!bpfsec)
6864 return -ENOMEM;
6865
6866 bpfsec->sid = current_sid();
6867 map->security = bpfsec;
6868
6869 return 0;
6870}
6871
6872static void selinux_bpf_map_free(struct bpf_map *map)
6873{
6874 struct bpf_security_struct *bpfsec = map->security;
6875
6876 map->security = NULL;
6877 kfree(bpfsec);
6878}
6879
6880static int selinux_bpf_prog_alloc(struct bpf_prog_aux *aux)
6881{
6882 struct bpf_security_struct *bpfsec;
6883
6884 bpfsec = kzalloc(sizeof(*bpfsec), GFP_KERNEL);
6885 if (!bpfsec)
6886 return -ENOMEM;
6887
6888 bpfsec->sid = current_sid();
6889 aux->security = bpfsec;
6890
6891 return 0;
6892}
6893
6894static void selinux_bpf_prog_free(struct bpf_prog_aux *aux)
6895{
6896 struct bpf_security_struct *bpfsec = aux->security;
6897
6898 aux->security = NULL;
6899 kfree(bpfsec);
6900}
6901#endif
6902
James Morrisca97d932017-02-15 00:18:51 +11006903static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = {
Casey Schauflere20b0432015-05-02 15:11:36 -07006904 LSM_HOOK_INIT(binder_set_context_mgr, selinux_binder_set_context_mgr),
6905 LSM_HOOK_INIT(binder_transaction, selinux_binder_transaction),
6906 LSM_HOOK_INIT(binder_transfer_binder, selinux_binder_transfer_binder),
6907 LSM_HOOK_INIT(binder_transfer_file, selinux_binder_transfer_file),
Ahmed S. Darwish076c54c2008-03-06 18:09:10 +02006908
Casey Schauflere20b0432015-05-02 15:11:36 -07006909 LSM_HOOK_INIT(ptrace_access_check, selinux_ptrace_access_check),
6910 LSM_HOOK_INIT(ptrace_traceme, selinux_ptrace_traceme),
6911 LSM_HOOK_INIT(capget, selinux_capget),
6912 LSM_HOOK_INIT(capset, selinux_capset),
6913 LSM_HOOK_INIT(capable, selinux_capable),
6914 LSM_HOOK_INIT(quotactl, selinux_quotactl),
6915 LSM_HOOK_INIT(quota_on, selinux_quota_on),
6916 LSM_HOOK_INIT(syslog, selinux_syslog),
6917 LSM_HOOK_INIT(vm_enough_memory, selinux_vm_enough_memory),
Stephen Smalley79af7302015-01-21 10:54:10 -05006918
Casey Schauflere20b0432015-05-02 15:11:36 -07006919 LSM_HOOK_INIT(netlink_send, selinux_netlink_send),
Linus Torvalds1da177e2005-04-16 15:20:36 -07006920
Casey Schauflere20b0432015-05-02 15:11:36 -07006921 LSM_HOOK_INIT(bprm_set_creds, selinux_bprm_set_creds),
6922 LSM_HOOK_INIT(bprm_committing_creds, selinux_bprm_committing_creds),
6923 LSM_HOOK_INIT(bprm_committed_creds, selinux_bprm_committed_creds),
Linus Torvalds1da177e2005-04-16 15:20:36 -07006924
Casey Schauflere20b0432015-05-02 15:11:36 -07006925 LSM_HOOK_INIT(sb_alloc_security, selinux_sb_alloc_security),
6926 LSM_HOOK_INIT(sb_free_security, selinux_sb_free_security),
6927 LSM_HOOK_INIT(sb_copy_data, selinux_sb_copy_data),
6928 LSM_HOOK_INIT(sb_remount, selinux_sb_remount),
6929 LSM_HOOK_INIT(sb_kern_mount, selinux_sb_kern_mount),
6930 LSM_HOOK_INIT(sb_show_options, selinux_sb_show_options),
6931 LSM_HOOK_INIT(sb_statfs, selinux_sb_statfs),
6932 LSM_HOOK_INIT(sb_mount, selinux_mount),
6933 LSM_HOOK_INIT(sb_umount, selinux_umount),
6934 LSM_HOOK_INIT(sb_set_mnt_opts, selinux_set_mnt_opts),
6935 LSM_HOOK_INIT(sb_clone_mnt_opts, selinux_sb_clone_mnt_opts),
6936 LSM_HOOK_INIT(sb_parse_opts_str, selinux_parse_opts_str),
Linus Torvalds1da177e2005-04-16 15:20:36 -07006937
Casey Schauflere20b0432015-05-02 15:11:36 -07006938 LSM_HOOK_INIT(dentry_init_security, selinux_dentry_init_security),
Vivek Goyala518b0a2016-07-13 10:44:53 -04006939 LSM_HOOK_INIT(dentry_create_files_as, selinux_dentry_create_files_as),
Eric Parise0007522008-03-05 10:31:54 -05006940
Casey Schauflere20b0432015-05-02 15:11:36 -07006941 LSM_HOOK_INIT(inode_alloc_security, selinux_inode_alloc_security),
6942 LSM_HOOK_INIT(inode_free_security, selinux_inode_free_security),
6943 LSM_HOOK_INIT(inode_init_security, selinux_inode_init_security),
6944 LSM_HOOK_INIT(inode_create, selinux_inode_create),
6945 LSM_HOOK_INIT(inode_link, selinux_inode_link),
6946 LSM_HOOK_INIT(inode_unlink, selinux_inode_unlink),
6947 LSM_HOOK_INIT(inode_symlink, selinux_inode_symlink),
6948 LSM_HOOK_INIT(inode_mkdir, selinux_inode_mkdir),
6949 LSM_HOOK_INIT(inode_rmdir, selinux_inode_rmdir),
6950 LSM_HOOK_INIT(inode_mknod, selinux_inode_mknod),
6951 LSM_HOOK_INIT(inode_rename, selinux_inode_rename),
6952 LSM_HOOK_INIT(inode_readlink, selinux_inode_readlink),
6953 LSM_HOOK_INIT(inode_follow_link, selinux_inode_follow_link),
6954 LSM_HOOK_INIT(inode_permission, selinux_inode_permission),
6955 LSM_HOOK_INIT(inode_setattr, selinux_inode_setattr),
6956 LSM_HOOK_INIT(inode_getattr, selinux_inode_getattr),
6957 LSM_HOOK_INIT(inode_setxattr, selinux_inode_setxattr),
6958 LSM_HOOK_INIT(inode_post_setxattr, selinux_inode_post_setxattr),
6959 LSM_HOOK_INIT(inode_getxattr, selinux_inode_getxattr),
6960 LSM_HOOK_INIT(inode_listxattr, selinux_inode_listxattr),
6961 LSM_HOOK_INIT(inode_removexattr, selinux_inode_removexattr),
6962 LSM_HOOK_INIT(inode_getsecurity, selinux_inode_getsecurity),
6963 LSM_HOOK_INIT(inode_setsecurity, selinux_inode_setsecurity),
6964 LSM_HOOK_INIT(inode_listsecurity, selinux_inode_listsecurity),
6965 LSM_HOOK_INIT(inode_getsecid, selinux_inode_getsecid),
Vivek Goyal56909eb2016-07-13 10:44:48 -04006966 LSM_HOOK_INIT(inode_copy_up, selinux_inode_copy_up),
Vivek Goyal19472b62016-07-13 10:44:50 -04006967 LSM_HOOK_INIT(inode_copy_up_xattr, selinux_inode_copy_up_xattr),
Linus Torvalds1da177e2005-04-16 15:20:36 -07006968
Casey Schauflere20b0432015-05-02 15:11:36 -07006969 LSM_HOOK_INIT(file_permission, selinux_file_permission),
6970 LSM_HOOK_INIT(file_alloc_security, selinux_file_alloc_security),
6971 LSM_HOOK_INIT(file_free_security, selinux_file_free_security),
6972 LSM_HOOK_INIT(file_ioctl, selinux_file_ioctl),
6973 LSM_HOOK_INIT(mmap_file, selinux_mmap_file),
6974 LSM_HOOK_INIT(mmap_addr, selinux_mmap_addr),
6975 LSM_HOOK_INIT(file_mprotect, selinux_file_mprotect),
6976 LSM_HOOK_INIT(file_lock, selinux_file_lock),
6977 LSM_HOOK_INIT(file_fcntl, selinux_file_fcntl),
6978 LSM_HOOK_INIT(file_set_fowner, selinux_file_set_fowner),
6979 LSM_HOOK_INIT(file_send_sigiotask, selinux_file_send_sigiotask),
6980 LSM_HOOK_INIT(file_receive, selinux_file_receive),
Linus Torvalds1da177e2005-04-16 15:20:36 -07006981
Casey Schauflere20b0432015-05-02 15:11:36 -07006982 LSM_HOOK_INIT(file_open, selinux_file_open),
Linus Torvalds1da177e2005-04-16 15:20:36 -07006983
Tetsuo Handaa79be232017-03-28 23:08:45 +09006984 LSM_HOOK_INIT(task_alloc, selinux_task_alloc),
Casey Schauflere20b0432015-05-02 15:11:36 -07006985 LSM_HOOK_INIT(cred_alloc_blank, selinux_cred_alloc_blank),
6986 LSM_HOOK_INIT(cred_free, selinux_cred_free),
6987 LSM_HOOK_INIT(cred_prepare, selinux_cred_prepare),
6988 LSM_HOOK_INIT(cred_transfer, selinux_cred_transfer),
Matthew Garrett3ec30112018-01-08 13:36:19 -08006989 LSM_HOOK_INIT(cred_getsecid, selinux_cred_getsecid),
Casey Schauflere20b0432015-05-02 15:11:36 -07006990 LSM_HOOK_INIT(kernel_act_as, selinux_kernel_act_as),
6991 LSM_HOOK_INIT(kernel_create_files_as, selinux_kernel_create_files_as),
6992 LSM_HOOK_INIT(kernel_module_request, selinux_kernel_module_request),
Mimi Zoharc77b8cd2018-07-13 14:06:02 -04006993 LSM_HOOK_INIT(kernel_load_data, selinux_kernel_load_data),
Jeff Vander Stoep61d612ea2016-04-05 13:06:27 -07006994 LSM_HOOK_INIT(kernel_read_file, selinux_kernel_read_file),
Casey Schauflere20b0432015-05-02 15:11:36 -07006995 LSM_HOOK_INIT(task_setpgid, selinux_task_setpgid),
6996 LSM_HOOK_INIT(task_getpgid, selinux_task_getpgid),
6997 LSM_HOOK_INIT(task_getsid, selinux_task_getsid),
6998 LSM_HOOK_INIT(task_getsecid, selinux_task_getsecid),
6999 LSM_HOOK_INIT(task_setnice, selinux_task_setnice),
7000 LSM_HOOK_INIT(task_setioprio, selinux_task_setioprio),
7001 LSM_HOOK_INIT(task_getioprio, selinux_task_getioprio),
Stephen Smalley791ec492017-02-17 07:57:00 -05007002 LSM_HOOK_INIT(task_prlimit, selinux_task_prlimit),
Casey Schauflere20b0432015-05-02 15:11:36 -07007003 LSM_HOOK_INIT(task_setrlimit, selinux_task_setrlimit),
7004 LSM_HOOK_INIT(task_setscheduler, selinux_task_setscheduler),
7005 LSM_HOOK_INIT(task_getscheduler, selinux_task_getscheduler),
7006 LSM_HOOK_INIT(task_movememory, selinux_task_movememory),
7007 LSM_HOOK_INIT(task_kill, selinux_task_kill),
Casey Schauflere20b0432015-05-02 15:11:36 -07007008 LSM_HOOK_INIT(task_to_inode, selinux_task_to_inode),
Yuichi Nakamura788e7dd2007-09-14 09:27:07 +09007009
Casey Schauflere20b0432015-05-02 15:11:36 -07007010 LSM_HOOK_INIT(ipc_permission, selinux_ipc_permission),
7011 LSM_HOOK_INIT(ipc_getsecid, selinux_ipc_getsecid),
Linus Torvalds1da177e2005-04-16 15:20:36 -07007012
Casey Schauflere20b0432015-05-02 15:11:36 -07007013 LSM_HOOK_INIT(msg_msg_alloc_security, selinux_msg_msg_alloc_security),
7014 LSM_HOOK_INIT(msg_msg_free_security, selinux_msg_msg_free_security),
Linus Torvalds1da177e2005-04-16 15:20:36 -07007015
Casey Schauflere20b0432015-05-02 15:11:36 -07007016 LSM_HOOK_INIT(msg_queue_alloc_security,
7017 selinux_msg_queue_alloc_security),
7018 LSM_HOOK_INIT(msg_queue_free_security, selinux_msg_queue_free_security),
7019 LSM_HOOK_INIT(msg_queue_associate, selinux_msg_queue_associate),
7020 LSM_HOOK_INIT(msg_queue_msgctl, selinux_msg_queue_msgctl),
7021 LSM_HOOK_INIT(msg_queue_msgsnd, selinux_msg_queue_msgsnd),
7022 LSM_HOOK_INIT(msg_queue_msgrcv, selinux_msg_queue_msgrcv),
Linus Torvalds1da177e2005-04-16 15:20:36 -07007023
Casey Schauflere20b0432015-05-02 15:11:36 -07007024 LSM_HOOK_INIT(shm_alloc_security, selinux_shm_alloc_security),
7025 LSM_HOOK_INIT(shm_free_security, selinux_shm_free_security),
7026 LSM_HOOK_INIT(shm_associate, selinux_shm_associate),
7027 LSM_HOOK_INIT(shm_shmctl, selinux_shm_shmctl),
7028 LSM_HOOK_INIT(shm_shmat, selinux_shm_shmat),
Linus Torvalds1da177e2005-04-16 15:20:36 -07007029
Casey Schauflere20b0432015-05-02 15:11:36 -07007030 LSM_HOOK_INIT(sem_alloc_security, selinux_sem_alloc_security),
7031 LSM_HOOK_INIT(sem_free_security, selinux_sem_free_security),
7032 LSM_HOOK_INIT(sem_associate, selinux_sem_associate),
7033 LSM_HOOK_INIT(sem_semctl, selinux_sem_semctl),
7034 LSM_HOOK_INIT(sem_semop, selinux_sem_semop),
Linus Torvalds1da177e2005-04-16 15:20:36 -07007035
Casey Schauflere20b0432015-05-02 15:11:36 -07007036 LSM_HOOK_INIT(d_instantiate, selinux_d_instantiate),
Linus Torvalds1da177e2005-04-16 15:20:36 -07007037
Casey Schauflere20b0432015-05-02 15:11:36 -07007038 LSM_HOOK_INIT(getprocattr, selinux_getprocattr),
7039 LSM_HOOK_INIT(setprocattr, selinux_setprocattr),
Linus Torvalds1da177e2005-04-16 15:20:36 -07007040
Casey Schauflere20b0432015-05-02 15:11:36 -07007041 LSM_HOOK_INIT(ismaclabel, selinux_ismaclabel),
7042 LSM_HOOK_INIT(secid_to_secctx, selinux_secid_to_secctx),
7043 LSM_HOOK_INIT(secctx_to_secid, selinux_secctx_to_secid),
7044 LSM_HOOK_INIT(release_secctx, selinux_release_secctx),
Andreas Gruenbacher6f3be9f2015-12-24 11:09:40 -05007045 LSM_HOOK_INIT(inode_invalidate_secctx, selinux_inode_invalidate_secctx),
Casey Schauflere20b0432015-05-02 15:11:36 -07007046 LSM_HOOK_INIT(inode_notifysecctx, selinux_inode_notifysecctx),
7047 LSM_HOOK_INIT(inode_setsecctx, selinux_inode_setsecctx),
7048 LSM_HOOK_INIT(inode_getsecctx, selinux_inode_getsecctx),
Linus Torvalds1da177e2005-04-16 15:20:36 -07007049
Casey Schauflere20b0432015-05-02 15:11:36 -07007050 LSM_HOOK_INIT(unix_stream_connect, selinux_socket_unix_stream_connect),
7051 LSM_HOOK_INIT(unix_may_send, selinux_socket_unix_may_send),
Catherine Zhangdc49c1f2006-08-02 14:12:06 -07007052
Casey Schauflere20b0432015-05-02 15:11:36 -07007053 LSM_HOOK_INIT(socket_create, selinux_socket_create),
7054 LSM_HOOK_INIT(socket_post_create, selinux_socket_post_create),
David Herrmann0b811db2018-05-04 16:28:21 +02007055 LSM_HOOK_INIT(socket_socketpair, selinux_socket_socketpair),
Casey Schauflere20b0432015-05-02 15:11:36 -07007056 LSM_HOOK_INIT(socket_bind, selinux_socket_bind),
7057 LSM_HOOK_INIT(socket_connect, selinux_socket_connect),
7058 LSM_HOOK_INIT(socket_listen, selinux_socket_listen),
7059 LSM_HOOK_INIT(socket_accept, selinux_socket_accept),
7060 LSM_HOOK_INIT(socket_sendmsg, selinux_socket_sendmsg),
7061 LSM_HOOK_INIT(socket_recvmsg, selinux_socket_recvmsg),
7062 LSM_HOOK_INIT(socket_getsockname, selinux_socket_getsockname),
7063 LSM_HOOK_INIT(socket_getpeername, selinux_socket_getpeername),
7064 LSM_HOOK_INIT(socket_getsockopt, selinux_socket_getsockopt),
7065 LSM_HOOK_INIT(socket_setsockopt, selinux_socket_setsockopt),
7066 LSM_HOOK_INIT(socket_shutdown, selinux_socket_shutdown),
7067 LSM_HOOK_INIT(socket_sock_rcv_skb, selinux_socket_sock_rcv_skb),
7068 LSM_HOOK_INIT(socket_getpeersec_stream,
7069 selinux_socket_getpeersec_stream),
7070 LSM_HOOK_INIT(socket_getpeersec_dgram, selinux_socket_getpeersec_dgram),
7071 LSM_HOOK_INIT(sk_alloc_security, selinux_sk_alloc_security),
7072 LSM_HOOK_INIT(sk_free_security, selinux_sk_free_security),
7073 LSM_HOOK_INIT(sk_clone_security, selinux_sk_clone_security),
7074 LSM_HOOK_INIT(sk_getsecid, selinux_sk_getsecid),
7075 LSM_HOOK_INIT(sock_graft, selinux_sock_graft),
Richard Hainesd4529302018-02-13 20:57:18 +00007076 LSM_HOOK_INIT(sctp_assoc_request, selinux_sctp_assoc_request),
7077 LSM_HOOK_INIT(sctp_sk_clone, selinux_sctp_sk_clone),
7078 LSM_HOOK_INIT(sctp_bind_connect, selinux_sctp_bind_connect),
Casey Schauflere20b0432015-05-02 15:11:36 -07007079 LSM_HOOK_INIT(inet_conn_request, selinux_inet_conn_request),
7080 LSM_HOOK_INIT(inet_csk_clone, selinux_inet_csk_clone),
7081 LSM_HOOK_INIT(inet_conn_established, selinux_inet_conn_established),
7082 LSM_HOOK_INIT(secmark_relabel_packet, selinux_secmark_relabel_packet),
7083 LSM_HOOK_INIT(secmark_refcount_inc, selinux_secmark_refcount_inc),
7084 LSM_HOOK_INIT(secmark_refcount_dec, selinux_secmark_refcount_dec),
7085 LSM_HOOK_INIT(req_classify_flow, selinux_req_classify_flow),
7086 LSM_HOOK_INIT(tun_dev_alloc_security, selinux_tun_dev_alloc_security),
7087 LSM_HOOK_INIT(tun_dev_free_security, selinux_tun_dev_free_security),
7088 LSM_HOOK_INIT(tun_dev_create, selinux_tun_dev_create),
7089 LSM_HOOK_INIT(tun_dev_attach_queue, selinux_tun_dev_attach_queue),
7090 LSM_HOOK_INIT(tun_dev_attach, selinux_tun_dev_attach),
7091 LSM_HOOK_INIT(tun_dev_open, selinux_tun_dev_open),
Daniel Jurgens3a976fa2017-05-19 15:48:56 +03007092#ifdef CONFIG_SECURITY_INFINIBAND
Daniel Jurgenscfc4d882017-05-19 15:48:57 +03007093 LSM_HOOK_INIT(ib_pkey_access, selinux_ib_pkey_access),
Daniel Jurgensab861df2017-05-19 15:48:58 +03007094 LSM_HOOK_INIT(ib_endport_manage_subnet,
7095 selinux_ib_endport_manage_subnet),
Daniel Jurgens3a976fa2017-05-19 15:48:56 +03007096 LSM_HOOK_INIT(ib_alloc_security, selinux_ib_alloc_security),
7097 LSM_HOOK_INIT(ib_free_security, selinux_ib_free_security),
7098#endif
Trent Jaegerd28d1e02005-12-13 23:12:40 -08007099#ifdef CONFIG_SECURITY_NETWORK_XFRM
Casey Schauflere20b0432015-05-02 15:11:36 -07007100 LSM_HOOK_INIT(xfrm_policy_alloc_security, selinux_xfrm_policy_alloc),
7101 LSM_HOOK_INIT(xfrm_policy_clone_security, selinux_xfrm_policy_clone),
7102 LSM_HOOK_INIT(xfrm_policy_free_security, selinux_xfrm_policy_free),
7103 LSM_HOOK_INIT(xfrm_policy_delete_security, selinux_xfrm_policy_delete),
7104 LSM_HOOK_INIT(xfrm_state_alloc, selinux_xfrm_state_alloc),
7105 LSM_HOOK_INIT(xfrm_state_alloc_acquire,
7106 selinux_xfrm_state_alloc_acquire),
7107 LSM_HOOK_INIT(xfrm_state_free_security, selinux_xfrm_state_free),
7108 LSM_HOOK_INIT(xfrm_state_delete_security, selinux_xfrm_state_delete),
7109 LSM_HOOK_INIT(xfrm_policy_lookup, selinux_xfrm_policy_lookup),
7110 LSM_HOOK_INIT(xfrm_state_pol_flow_match,
7111 selinux_xfrm_state_pol_flow_match),
7112 LSM_HOOK_INIT(xfrm_decode_session, selinux_xfrm_decode_session),
Linus Torvalds1da177e2005-04-16 15:20:36 -07007113#endif
Michael LeMayd7200242006-06-22 14:47:17 -07007114
7115#ifdef CONFIG_KEYS
Casey Schauflere20b0432015-05-02 15:11:36 -07007116 LSM_HOOK_INIT(key_alloc, selinux_key_alloc),
7117 LSM_HOOK_INIT(key_free, selinux_key_free),
7118 LSM_HOOK_INIT(key_permission, selinux_key_permission),
7119 LSM_HOOK_INIT(key_getsecurity, selinux_key_getsecurity),
Michael LeMayd7200242006-06-22 14:47:17 -07007120#endif
Ahmed S. Darwish9d57a7f2008-03-01 22:03:14 +02007121
7122#ifdef CONFIG_AUDIT
Casey Schauflere20b0432015-05-02 15:11:36 -07007123 LSM_HOOK_INIT(audit_rule_init, selinux_audit_rule_init),
7124 LSM_HOOK_INIT(audit_rule_known, selinux_audit_rule_known),
7125 LSM_HOOK_INIT(audit_rule_match, selinux_audit_rule_match),
7126 LSM_HOOK_INIT(audit_rule_free, selinux_audit_rule_free),
Ahmed S. Darwish9d57a7f2008-03-01 22:03:14 +02007127#endif
Chenbo Fengec27c352017-10-18 13:00:25 -07007128
7129#ifdef CONFIG_BPF_SYSCALL
7130 LSM_HOOK_INIT(bpf, selinux_bpf),
7131 LSM_HOOK_INIT(bpf_map, selinux_bpf_map),
7132 LSM_HOOK_INIT(bpf_prog, selinux_bpf_prog),
7133 LSM_HOOK_INIT(bpf_map_alloc_security, selinux_bpf_map_alloc),
7134 LSM_HOOK_INIT(bpf_prog_alloc_security, selinux_bpf_prog_alloc),
7135 LSM_HOOK_INIT(bpf_map_free_security, selinux_bpf_map_free),
7136 LSM_HOOK_INIT(bpf_prog_free_security, selinux_bpf_prog_free),
7137#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07007138};
7139
7140static __init int selinux_init(void)
7141{
Casey Schauflerb1d9e6b2015-05-02 15:11:42 -07007142 if (!security_module_enable("selinux")) {
Ahmed S. Darwish076c54c2008-03-06 18:09:10 +02007143 selinux_enabled = 0;
7144 return 0;
7145 }
7146
Linus Torvalds1da177e2005-04-16 15:20:36 -07007147 if (!selinux_enabled) {
peter enderborgc103a912018-06-12 10:09:03 +02007148 pr_info("SELinux: Disabled at boot.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07007149 return 0;
7150 }
7151
peter enderborgc103a912018-06-12 10:09:03 +02007152 pr_info("SELinux: Initializing.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07007153
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05007154 memset(&selinux_state, 0, sizeof(selinux_state));
Paul Mooree5a5ca92018-03-01 17:38:30 -05007155 enforcing_set(&selinux_state, selinux_enforcing_boot);
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05007156 selinux_state.checkreqprot = selinux_checkreqprot_boot;
7157 selinux_ss_init(&selinux_state.ss);
Stephen Smalley6b6bc622018-03-05 11:47:56 -05007158 selinux_avc_init(&selinux_state.avc);
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05007159
Linus Torvalds1da177e2005-04-16 15:20:36 -07007160 /* Set the security state for the initial task. */
David Howellsd84f4f92008-11-14 10:39:23 +11007161 cred_init_security();
Linus Torvalds1da177e2005-04-16 15:20:36 -07007162
Stephen Smalleyfcaaade2010-04-28 15:57:57 -04007163 default_noexec = !(VM_DATA_DEFAULT_FLAGS & VM_EXEC);
7164
James Morris7cae7e22006-03-22 00:09:22 -08007165 sel_inode_cache = kmem_cache_create("selinux_inode_security",
7166 sizeof(struct inode_security_struct),
Paul Mundt20c2df82007-07-20 10:11:58 +09007167 0, SLAB_PANIC, NULL);
Sangwoo63205652015-10-21 17:44:30 -04007168 file_security_cache = kmem_cache_create("selinux_file_security",
7169 sizeof(struct file_security_struct),
7170 0, SLAB_PANIC, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007171 avc_init();
7172
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05007173 avtab_cache_init();
7174
7175 ebitmap_cache_init();
7176
7177 hashtab_cache_init();
7178
Casey Schauflerd69dece52017-01-18 17:09:05 -08007179 security_add_hooks(selinux_hooks, ARRAY_SIZE(selinux_hooks), "selinux");
Linus Torvalds1da177e2005-04-16 15:20:36 -07007180
Paul Moore615e51f2014-06-26 14:33:56 -04007181 if (avc_add_callback(selinux_netcache_avc_callback, AVC_CALLBACK_RESET))
7182 panic("SELinux: Unable to register AVC netcache callback\n");
7183
Daniel Jurgens8f408ab2017-05-19 15:48:53 +03007184 if (avc_add_callback(selinux_lsm_notifier_avc_callback, AVC_CALLBACK_RESET))
7185 panic("SELinux: Unable to register AVC LSM notifier callback\n");
7186
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05007187 if (selinux_enforcing_boot)
peter enderborgc103a912018-06-12 10:09:03 +02007188 pr_debug("SELinux: Starting in enforcing mode\n");
Eric Paris828dfe12008-04-17 13:17:49 -04007189 else
peter enderborgc103a912018-06-12 10:09:03 +02007190 pr_debug("SELinux: Starting in permissive mode\n");
Michael LeMayd7200242006-06-22 14:47:17 -07007191
Linus Torvalds1da177e2005-04-16 15:20:36 -07007192 return 0;
7193}
7194
Al Viroe8c26252010-03-23 06:36:54 -04007195static void delayed_superblock_init(struct super_block *sb, void *unused)
7196{
7197 superblock_doinit(sb, NULL);
7198}
7199
Linus Torvalds1da177e2005-04-16 15:20:36 -07007200void selinux_complete_init(void)
7201{
peter enderborgc103a912018-06-12 10:09:03 +02007202 pr_debug("SELinux: Completing initialization.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07007203
7204 /* Set up any superblocks initialized prior to the policy load. */
peter enderborgc103a912018-06-12 10:09:03 +02007205 pr_debug("SELinux: Setting up existing superblocks.\n");
Al Viroe8c26252010-03-23 06:36:54 -04007206 iterate_supers(delayed_superblock_init, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007207}
7208
7209/* SELinux requires early initialization in order to label
7210 all processes and objects when they are created. */
Kees Cook3d6e5f62018-10-10 17:18:23 -07007211DEFINE_LSM(selinux) = {
Kees Cook07aed2f2018-10-10 17:18:24 -07007212 .name = "selinux",
Kees Cook3d6e5f62018-10-10 17:18:23 -07007213 .init = selinux_init,
7214};
Linus Torvalds1da177e2005-04-16 15:20:36 -07007215
Stephen Smalleyc2b507f2006-02-04 23:27:50 -08007216#if defined(CONFIG_NETFILTER)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007217
Florian Westphal591bb272017-07-26 11:40:52 +02007218static const struct nf_hook_ops selinux_nf_ops[] = {
Paul Mooreeffad8d2008-01-29 08:49:27 -05007219 {
7220 .hook = selinux_ipv4_postroute,
Alban Crequy2597a832012-05-14 03:56:39 +00007221 .pf = NFPROTO_IPV4,
Paul Mooreeffad8d2008-01-29 08:49:27 -05007222 .hooknum = NF_INET_POST_ROUTING,
7223 .priority = NF_IP_PRI_SELINUX_LAST,
7224 },
7225 {
7226 .hook = selinux_ipv4_forward,
Alban Crequy2597a832012-05-14 03:56:39 +00007227 .pf = NFPROTO_IPV4,
Paul Mooreeffad8d2008-01-29 08:49:27 -05007228 .hooknum = NF_INET_FORWARD,
7229 .priority = NF_IP_PRI_SELINUX_FIRST,
Paul Moore948bf852008-10-10 10:16:32 -04007230 },
7231 {
7232 .hook = selinux_ipv4_output,
Alban Crequy2597a832012-05-14 03:56:39 +00007233 .pf = NFPROTO_IPV4,
Paul Moore948bf852008-10-10 10:16:32 -04007234 .hooknum = NF_INET_LOCAL_OUT,
7235 .priority = NF_IP_PRI_SELINUX_FIRST,
Jiri Pirko25db6be2014-09-03 17:42:13 +02007236 },
Javier Martinez Canillas1a93a6e2016-08-08 13:08:25 -04007237#if IS_ENABLED(CONFIG_IPV6)
Paul Mooreeffad8d2008-01-29 08:49:27 -05007238 {
7239 .hook = selinux_ipv6_postroute,
Alban Crequy2597a832012-05-14 03:56:39 +00007240 .pf = NFPROTO_IPV6,
Paul Mooreeffad8d2008-01-29 08:49:27 -05007241 .hooknum = NF_INET_POST_ROUTING,
7242 .priority = NF_IP6_PRI_SELINUX_LAST,
7243 },
7244 {
7245 .hook = selinux_ipv6_forward,
Alban Crequy2597a832012-05-14 03:56:39 +00007246 .pf = NFPROTO_IPV6,
Paul Mooreeffad8d2008-01-29 08:49:27 -05007247 .hooknum = NF_INET_FORWARD,
7248 .priority = NF_IP6_PRI_SELINUX_FIRST,
Jiri Pirko25db6be2014-09-03 17:42:13 +02007249 },
Huw Davies2917f572016-06-27 15:06:15 -04007250 {
7251 .hook = selinux_ipv6_output,
7252 .pf = NFPROTO_IPV6,
7253 .hooknum = NF_INET_LOCAL_OUT,
7254 .priority = NF_IP6_PRI_SELINUX_FIRST,
7255 },
Linus Torvalds1da177e2005-04-16 15:20:36 -07007256#endif /* IPV6 */
Jiri Pirko25db6be2014-09-03 17:42:13 +02007257};
Linus Torvalds1da177e2005-04-16 15:20:36 -07007258
Florian Westphal8e71bf72017-04-21 11:49:09 +02007259static int __net_init selinux_nf_register(struct net *net)
7260{
7261 return nf_register_net_hooks(net, selinux_nf_ops,
7262 ARRAY_SIZE(selinux_nf_ops));
7263}
7264
7265static void __net_exit selinux_nf_unregister(struct net *net)
7266{
7267 nf_unregister_net_hooks(net, selinux_nf_ops,
7268 ARRAY_SIZE(selinux_nf_ops));
7269}
7270
7271static struct pernet_operations selinux_net_ops = {
7272 .init = selinux_nf_register,
7273 .exit = selinux_nf_unregister,
7274};
7275
Linus Torvalds1da177e2005-04-16 15:20:36 -07007276static int __init selinux_nf_ip_init(void)
7277{
Jiri Pirko25db6be2014-09-03 17:42:13 +02007278 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007279
7280 if (!selinux_enabled)
Jiri Pirko25db6be2014-09-03 17:42:13 +02007281 return 0;
Eric Parisfadcdb42007-02-22 18:11:31 -05007282
peter enderborgc103a912018-06-12 10:09:03 +02007283 pr_debug("SELinux: Registering netfilter hooks\n");
Eric Parisfadcdb42007-02-22 18:11:31 -05007284
Florian Westphal8e71bf72017-04-21 11:49:09 +02007285 err = register_pernet_subsys(&selinux_net_ops);
Alexey Dobriyan6c5a9d22008-07-26 17:48:15 -07007286 if (err)
Florian Westphal8e71bf72017-04-21 11:49:09 +02007287 panic("SELinux: register_pernet_subsys: error %d\n", err);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007288
Jiri Pirko25db6be2014-09-03 17:42:13 +02007289 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007290}
Linus Torvalds1da177e2005-04-16 15:20:36 -07007291__initcall(selinux_nf_ip_init);
7292
7293#ifdef CONFIG_SECURITY_SELINUX_DISABLE
7294static void selinux_nf_ip_exit(void)
7295{
peter enderborgc103a912018-06-12 10:09:03 +02007296 pr_debug("SELinux: Unregistering netfilter hooks\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07007297
Florian Westphal8e71bf72017-04-21 11:49:09 +02007298 unregister_pernet_subsys(&selinux_net_ops);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007299}
7300#endif
7301
Stephen Smalleyc2b507f2006-02-04 23:27:50 -08007302#else /* CONFIG_NETFILTER */
Linus Torvalds1da177e2005-04-16 15:20:36 -07007303
7304#ifdef CONFIG_SECURITY_SELINUX_DISABLE
7305#define selinux_nf_ip_exit()
7306#endif
7307
Stephen Smalleyc2b507f2006-02-04 23:27:50 -08007308#endif /* CONFIG_NETFILTER */
Linus Torvalds1da177e2005-04-16 15:20:36 -07007309
7310#ifdef CONFIG_SECURITY_SELINUX_DISABLE
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05007311int selinux_disable(struct selinux_state *state)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007312{
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05007313 if (state->initialized) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07007314 /* Not permitted after initial policy load. */
7315 return -EINVAL;
7316 }
7317
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05007318 if (state->disabled) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07007319 /* Only do this once. */
7320 return -EINVAL;
7321 }
7322
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05007323 state->disabled = 1;
7324
peter enderborgc103a912018-06-12 10:09:03 +02007325 pr_info("SELinux: Disabled at runtime.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07007326
Stephen Smalley30d55282006-05-03 10:52:36 -04007327 selinux_enabled = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007328
Casey Schauflerb1d9e6b2015-05-02 15:11:42 -07007329 security_delete_hooks(selinux_hooks, ARRAY_SIZE(selinux_hooks));
Linus Torvalds1da177e2005-04-16 15:20:36 -07007330
Eric Parisaf8ff042009-09-20 21:23:01 -04007331 /* Try to destroy the avc node cache */
7332 avc_disable();
7333
Linus Torvalds1da177e2005-04-16 15:20:36 -07007334 /* Unregister netfilter hooks. */
7335 selinux_nf_ip_exit();
7336
7337 /* Unregister selinuxfs. */
7338 exit_sel_fs();
7339
7340 return 0;
7341}
7342#endif