blob: 5d92167dbe0530edc1406c52e1fc28b665bb622f [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 Parisf52697102008-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>
Eric Paris23970742006-09-25 23:32:01 -070082#include <linux/mutex.h>
Frank Mayharf06febc2008-09-12 09:54:39 -070083#include <linux/posix-timers.h>
Kees Cook00234592010-02-03 15:36:43 -080084#include <linux/syslog.h>
Serge E. Hallyn34867402011-03-23 16:43:17 -070085#include <linux/user_namespace.h>
Paul Gortmaker44fc7ea2011-05-26 20:52:10 -040086#include <linux/export.h>
Al Viro40401532012-02-13 03:58:52 +000087#include <linux/msg.h>
88#include <linux/shm.h>
Chenbo Fengec27c352017-10-18 13:00:25 -070089#include <linux/bpf.h>
David Howellse262e32d2018-11-01 23:07:23 +000090#include <uapi/linux/mount.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070091
92#include "avc.h"
93#include "objsec.h"
94#include "netif.h"
Paul Moore224dfbd2008-01-29 08:38:13 -050095#include "netnode.h"
Paul Moore3e112172008-04-10 10:48:14 -040096#include "netport.h"
Daniel Jurgens409dcf32017-05-19 15:48:59 +030097#include "ibpkey.h"
Trent Jaegerd28d1e02005-12-13 23:12:40 -080098#include "xfrm.h"
Paul Moorec60475b2007-02-28 15:14:23 -050099#include "netlabel.h"
Ahmed S. Darwish9d57a7f2008-03-01 22:03:14 +0200100#include "audit.h"
James Morris7b98a582011-08-30 12:52:32 +1000101#include "avc_ss.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -0700102
Stephen Smalleyaa8e7122018-03-01 18:48:02 -0500103struct selinux_state selinux_state;
104
Paul Moored621d352008-01-29 08:43:36 -0500105/* SECMARK reference count */
James Morris56a4ca92011-08-17 11:08:43 +1000106static atomic_t selinux_secmark_refcount = ATOMIC_INIT(0);
Paul Moored621d352008-01-29 08:43:36 -0500107
Linus Torvalds1da177e2005-04-16 15:20:36 -0700108#ifdef CONFIG_SECURITY_SELINUX_DEVELOP
Stephen Smalleyaa8e7122018-03-01 18:48:02 -0500109static int selinux_enforcing_boot;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700110
111static int __init enforcing_setup(char *str)
112{
Eric Parisf52697102008-05-14 11:27:45 -0400113 unsigned long enforcing;
Jingoo Han29707b22014-02-05 15:13:14 +0900114 if (!kstrtoul(str, 0, &enforcing))
Stephen Smalleyaa8e7122018-03-01 18:48:02 -0500115 selinux_enforcing_boot = enforcing ? 1 : 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700116 return 1;
117}
118__setup("enforcing=", enforcing_setup);
Stephen Smalleyaa8e7122018-03-01 18:48:02 -0500119#else
120#define selinux_enforcing_boot 1
Linus Torvalds1da177e2005-04-16 15:20:36 -0700121#endif
122
Kees Cookbe6ec882018-10-01 17:08:57 -0700123int selinux_enabled __lsm_ro_after_init = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700124#ifdef CONFIG_SECURITY_SELINUX_BOOTPARAM
Linus Torvalds1da177e2005-04-16 15:20:36 -0700125static int __init selinux_enabled_setup(char *str)
126{
Eric Parisf52697102008-05-14 11:27:45 -0400127 unsigned long enabled;
Jingoo Han29707b22014-02-05 15:13:14 +0900128 if (!kstrtoul(str, 0, &enabled))
Eric Parisf52697102008-05-14 11:27:45 -0400129 selinux_enabled = enabled ? 1 : 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700130 return 1;
131}
132__setup("selinux=", selinux_enabled_setup);
133#endif
134
Stephen Smalleyaa8e7122018-03-01 18:48:02 -0500135static unsigned int selinux_checkreqprot_boot =
136 CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE;
137
138static int __init checkreqprot_setup(char *str)
139{
140 unsigned long checkreqprot;
141
142 if (!kstrtoul(str, 0, &checkreqprot))
143 selinux_checkreqprot_boot = checkreqprot ? 1 : 0;
144 return 1;
145}
146__setup("checkreqprot=", checkreqprot_setup);
147
Paul Moored621d352008-01-29 08:43:36 -0500148/**
149 * selinux_secmark_enabled - Check to see if SECMARK is currently enabled
150 *
151 * Description:
152 * This function checks the SECMARK reference counter to see if any SECMARK
153 * targets are currently configured, if the reference counter is greater than
154 * zero SECMARK is considered to be enabled. Returns true (1) if SECMARK is
Chris PeBenito2be4d742013-05-03 09:05:39 -0400155 * enabled, false (0) if SECMARK is disabled. If the always_check_network
156 * policy capability is enabled, SECMARK is always considered enabled.
Paul Moored621d352008-01-29 08:43:36 -0500157 *
158 */
159static int selinux_secmark_enabled(void)
160{
Stephen Smalleyaa8e7122018-03-01 18:48:02 -0500161 return (selinux_policycap_alwaysnetwork() ||
162 atomic_read(&selinux_secmark_refcount));
Chris PeBenito2be4d742013-05-03 09:05:39 -0400163}
164
165/**
166 * selinux_peerlbl_enabled - Check to see if peer labeling is currently enabled
167 *
168 * Description:
169 * This function checks if NetLabel or labeled IPSEC is enabled. Returns true
170 * (1) if any are enabled or false (0) if neither are enabled. If the
171 * always_check_network policy capability is enabled, peer labeling
172 * is always considered enabled.
173 *
174 */
175static int selinux_peerlbl_enabled(void)
176{
Stephen Smalleyaa8e7122018-03-01 18:48:02 -0500177 return (selinux_policycap_alwaysnetwork() ||
178 netlbl_enabled() || selinux_xfrm_enabled());
Paul Moored621d352008-01-29 08:43:36 -0500179}
180
Paul Moore615e51f2014-06-26 14:33:56 -0400181static int selinux_netcache_avc_callback(u32 event)
182{
183 if (event == AVC_CALLBACK_RESET) {
184 sel_netif_flush();
185 sel_netnode_flush();
186 sel_netport_flush();
187 synchronize_net();
188 }
189 return 0;
190}
191
Daniel Jurgens8f408ab2017-05-19 15:48:53 +0300192static int selinux_lsm_notifier_avc_callback(u32 event)
193{
Daniel Jurgens409dcf32017-05-19 15:48:59 +0300194 if (event == AVC_CALLBACK_RESET) {
195 sel_ib_pkey_flush();
Daniel Jurgens8f408ab2017-05-19 15:48:53 +0300196 call_lsm_notifier(LSM_POLICY_CHANGE, NULL);
Daniel Jurgens409dcf32017-05-19 15:48:59 +0300197 }
Daniel Jurgens8f408ab2017-05-19 15:48:53 +0300198
199 return 0;
200}
201
David Howellsd84f4f92008-11-14 10:39:23 +1100202/*
203 * initialise the security for the init task
204 */
205static void cred_init_security(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700206{
David Howells3b11a1d2008-11-14 10:39:26 +1100207 struct cred *cred = (struct cred *) current->real_cred;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700208 struct task_security_struct *tsec;
209
Casey Schauflerbbd36622018-11-12 09:30:56 -0800210 tsec = selinux_cred(cred);
David Howellsd84f4f92008-11-14 10:39:23 +1100211 tsec->osid = tsec->sid = SECINITSID_KERNEL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700212}
213
David Howells275bb412008-11-14 10:39:19 +1100214/*
David Howells88e67f32008-11-14 10:39:21 +1100215 * get the security ID of a set of credentials
216 */
217static inline u32 cred_sid(const struct cred *cred)
218{
219 const struct task_security_struct *tsec;
220
Casey Schaufler0c6cfa62018-09-21 17:17:16 -0700221 tsec = selinux_cred(cred);
David Howells88e67f32008-11-14 10:39:21 +1100222 return tsec->sid;
223}
224
225/*
David Howells3b11a1d2008-11-14 10:39:26 +1100226 * get the objective security ID of a task
David Howells275bb412008-11-14 10:39:19 +1100227 */
228static inline u32 task_sid(const struct task_struct *task)
229{
David Howells275bb412008-11-14 10:39:19 +1100230 u32 sid;
231
232 rcu_read_lock();
David Howells88e67f32008-11-14 10:39:21 +1100233 sid = cred_sid(__task_cred(task));
David Howells275bb412008-11-14 10:39:19 +1100234 rcu_read_unlock();
235 return sid;
236}
237
David Howells88e67f32008-11-14 10:39:21 +1100238/* Allocate and free functions for each kind of security blob. */
239
Linus Torvalds1da177e2005-04-16 15:20:36 -0700240static int inode_alloc_security(struct inode *inode)
241{
Casey Schauflerafb1cbe32018-09-21 17:19:29 -0700242 struct inode_security_struct *isec = selinux_inode(inode);
David Howells275bb412008-11-14 10:39:19 +1100243 u32 sid = current_sid();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700244
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +0100245 spin_lock_init(&isec->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700246 INIT_LIST_HEAD(&isec->list);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700247 isec->inode = inode;
248 isec->sid = SECINITSID_UNLABELED;
249 isec->sclass = SECCLASS_FILE;
David Howells275bb412008-11-14 10:39:19 +1100250 isec->task_sid = sid;
Andreas Gruenbacher42059112016-11-10 22:18:27 +0100251 isec->initialized = LABEL_INVALID;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700252
253 return 0;
254}
255
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -0500256static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dentry);
257
258/*
259 * Try reloading inode security labels that have been marked as invalid. The
260 * @may_sleep parameter indicates when sleeping and thus reloading labels is
Andreas Gruenbacher42059112016-11-10 22:18:27 +0100261 * allowed; when set to false, returns -ECHILD when the label is
Al Viroe9193282018-04-24 21:31:02 -0400262 * invalid. The @dentry parameter should be set to a dentry of the inode.
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -0500263 */
264static int __inode_security_revalidate(struct inode *inode,
Al Viroe9193282018-04-24 21:31:02 -0400265 struct dentry *dentry,
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -0500266 bool may_sleep)
267{
Casey Schaufler80788c22018-09-21 17:19:11 -0700268 struct inode_security_struct *isec = selinux_inode(inode);
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -0500269
270 might_sleep_if(may_sleep);
271
Stephen Smalleyaa8e7122018-03-01 18:48:02 -0500272 if (selinux_state.initialized &&
273 isec->initialized != LABEL_INITIALIZED) {
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -0500274 if (!may_sleep)
275 return -ECHILD;
276
277 /*
278 * Try reloading the inode security label. This will fail if
279 * @opt_dentry is NULL and no dentry for this inode can be
280 * found; in that case, continue using the old label.
281 */
Al Viroe9193282018-04-24 21:31:02 -0400282 inode_doinit_with_dentry(inode, dentry);
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -0500283 }
284 return 0;
285}
286
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -0500287static struct inode_security_struct *inode_security_novalidate(struct inode *inode)
288{
Casey Schaufler80788c22018-09-21 17:19:11 -0700289 return selinux_inode(inode);
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -0500290}
291
292static struct inode_security_struct *inode_security_rcu(struct inode *inode, bool rcu)
293{
294 int error;
295
296 error = __inode_security_revalidate(inode, NULL, !rcu);
297 if (error)
298 return ERR_PTR(error);
Casey Schaufler80788c22018-09-21 17:19:11 -0700299 return selinux_inode(inode);
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -0500300}
301
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -0500302/*
303 * Get the security label of an inode.
304 */
305static struct inode_security_struct *inode_security(struct inode *inode)
306{
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -0500307 __inode_security_revalidate(inode, NULL, true);
Casey Schaufler80788c22018-09-21 17:19:11 -0700308 return selinux_inode(inode);
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -0500309}
310
Paul Moore2c971652016-04-19 16:36:28 -0400311static struct inode_security_struct *backing_inode_security_novalidate(struct dentry *dentry)
312{
313 struct inode *inode = d_backing_inode(dentry);
314
Casey Schaufler80788c22018-09-21 17:19:11 -0700315 return selinux_inode(inode);
Paul Moore2c971652016-04-19 16:36:28 -0400316}
317
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -0500318/*
319 * Get the security label of a dentry's backing inode.
320 */
321static struct inode_security_struct *backing_inode_security(struct dentry *dentry)
322{
323 struct inode *inode = d_backing_inode(dentry);
324
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -0500325 __inode_security_revalidate(inode, dentry, true);
Casey Schaufler80788c22018-09-21 17:19:11 -0700326 return selinux_inode(inode);
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -0500327}
328
Linus Torvalds1da177e2005-04-16 15:20:36 -0700329static void inode_free_security(struct inode *inode)
330{
Casey Schaufler80788c22018-09-21 17:19:11 -0700331 struct inode_security_struct *isec = selinux_inode(inode);
Casey Schauflerafb1cbe32018-09-21 17:19:29 -0700332 struct superblock_security_struct *sbsec;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700333
Casey Schauflerafb1cbe32018-09-21 17:19:29 -0700334 if (!isec)
335 return;
336 sbsec = inode->i_sb->s_security;
Waiman Long9629d042015-07-10 17:19:56 -0400337 /*
338 * As not all inode security structures are in a list, we check for
339 * empty list outside of the lock to make sure that we won't waste
340 * time taking a lock doing nothing.
341 *
342 * The list_del_init() function can be safely called more than once.
343 * It should not be possible for this function to be called with
344 * concurrent list_add(), but for better safety against future changes
345 * in the code, we use list_empty_careful() here.
346 */
347 if (!list_empty_careful(&isec->list)) {
348 spin_lock(&sbsec->isec_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700349 list_del_init(&isec->list);
Waiman Long9629d042015-07-10 17:19:56 -0400350 spin_unlock(&sbsec->isec_lock);
351 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700352}
353
354static int file_alloc_security(struct file *file)
355{
Casey Schaufler33bf60c2018-11-12 12:02:49 -0800356 struct file_security_struct *fsec = selinux_file(file);
David Howells275bb412008-11-14 10:39:19 +1100357 u32 sid = current_sid();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700358
David Howells275bb412008-11-14 10:39:19 +1100359 fsec->sid = sid;
360 fsec->fown_sid = sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700361
362 return 0;
363}
364
Linus Torvalds1da177e2005-04-16 15:20:36 -0700365static int superblock_alloc_security(struct super_block *sb)
366{
367 struct superblock_security_struct *sbsec;
368
James Morris89d155e2005-10-30 14:59:21 -0800369 sbsec = kzalloc(sizeof(struct superblock_security_struct), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700370 if (!sbsec)
371 return -ENOMEM;
372
Eric Parisbc7e9822006-09-25 23:32:02 -0700373 mutex_init(&sbsec->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700374 INIT_LIST_HEAD(&sbsec->isec_head);
375 spin_lock_init(&sbsec->isec_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700376 sbsec->sb = sb;
377 sbsec->sid = SECINITSID_UNLABELED;
378 sbsec->def_sid = SECINITSID_FILE;
Eric Parisc312feb2006-07-10 04:43:53 -0700379 sbsec->mntpoint_sid = SECINITSID_UNLABELED;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700380 sb->s_security = sbsec;
381
382 return 0;
383}
384
385static void superblock_free_security(struct super_block *sb)
386{
387 struct superblock_security_struct *sbsec = sb->s_security;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700388 sb->s_security = NULL;
389 kfree(sbsec);
390}
391
Al Virobd323652018-12-13 15:04:59 -0500392struct selinux_mnt_opts {
393 const char *fscontext, *context, *rootcontext, *defcontext;
394};
395
Al Viro204cc0c2018-12-13 13:41:47 -0500396static void selinux_free_mnt_opts(void *mnt_opts)
397{
Al Virobd323652018-12-13 15:04:59 -0500398 struct selinux_mnt_opts *opts = mnt_opts;
399 kfree(opts->fscontext);
400 kfree(opts->context);
401 kfree(opts->rootcontext);
402 kfree(opts->defcontext);
Al Viro204cc0c2018-12-13 13:41:47 -0500403 kfree(opts);
404}
405
Linus Torvalds1da177e2005-04-16 15:20:36 -0700406static inline int inode_doinit(struct inode *inode)
407{
408 return inode_doinit_with_dentry(inode, NULL);
409}
410
411enum {
Eric Paris31e87932007-09-19 17:19:12 -0400412 Opt_error = -1,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700413 Opt_context = 1,
414 Opt_fscontext = 2,
Eric Parisc9180a52007-11-30 13:00:35 -0500415 Opt_defcontext = 3,
416 Opt_rootcontext = 4,
Al Viroda3d76a2018-12-17 10:14:16 -0500417 Opt_seclabel = 5,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700418};
419
Al Viroda3d76a2018-12-17 10:14:16 -0500420#define A(s, has_arg) {#s, sizeof(#s) - 1, Opt_##s, has_arg}
Al Viro169d68efb2018-12-14 22:44:50 -0500421static struct {
422 const char *name;
423 int len;
424 int opt;
425 bool has_arg;
426} tokens[] = {
Al Viroda3d76a2018-12-17 10:14:16 -0500427 A(context, true),
428 A(fscontext, true),
429 A(defcontext, true),
430 A(rootcontext, true),
431 A(seclabel, false),
Linus Torvalds1da177e2005-04-16 15:20:36 -0700432};
Al Viro169d68efb2018-12-14 22:44:50 -0500433#undef A
434
435static int match_opt_prefix(char *s, int l, char **arg)
436{
437 int i;
438
439 for (i = 0; i < ARRAY_SIZE(tokens); i++) {
440 size_t len = tokens[i].len;
441 if (len > l || memcmp(s, tokens[i].name, len))
442 continue;
443 if (tokens[i].has_arg) {
444 if (len == l || s[len] != '=')
445 continue;
446 *arg = s + len + 1;
447 } else if (len != l)
448 continue;
449 return tokens[i].opt;
450 }
451 return Opt_error;
452}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700453
454#define SEL_MOUNT_FAIL_MSG "SELinux: duplicate or incompatible mount options\n"
455
Eric Parisc312feb2006-07-10 04:43:53 -0700456static int may_context_mount_sb_relabel(u32 sid,
457 struct superblock_security_struct *sbsec,
David Howells275bb412008-11-14 10:39:19 +1100458 const struct cred *cred)
Eric Parisc312feb2006-07-10 04:43:53 -0700459{
Casey Schaufler0c6cfa62018-09-21 17:17:16 -0700460 const struct task_security_struct *tsec = selinux_cred(cred);
Eric Parisc312feb2006-07-10 04:43:53 -0700461 int rc;
462
Stephen Smalley6b6bc622018-03-05 11:47:56 -0500463 rc = avc_has_perm(&selinux_state,
464 tsec->sid, sbsec->sid, SECCLASS_FILESYSTEM,
Eric Parisc312feb2006-07-10 04:43:53 -0700465 FILESYSTEM__RELABELFROM, NULL);
466 if (rc)
467 return rc;
468
Stephen Smalley6b6bc622018-03-05 11:47:56 -0500469 rc = avc_has_perm(&selinux_state,
470 tsec->sid, sid, SECCLASS_FILESYSTEM,
Eric Parisc312feb2006-07-10 04:43:53 -0700471 FILESYSTEM__RELABELTO, NULL);
472 return rc;
473}
474
Eric Paris08089252006-07-10 04:43:55 -0700475static int may_context_mount_inode_relabel(u32 sid,
476 struct superblock_security_struct *sbsec,
David Howells275bb412008-11-14 10:39:19 +1100477 const struct cred *cred)
Eric Paris08089252006-07-10 04:43:55 -0700478{
Casey Schaufler0c6cfa62018-09-21 17:17:16 -0700479 const struct task_security_struct *tsec = selinux_cred(cred);
Eric Paris08089252006-07-10 04:43:55 -0700480 int rc;
Stephen Smalley6b6bc622018-03-05 11:47:56 -0500481 rc = avc_has_perm(&selinux_state,
482 tsec->sid, sbsec->sid, SECCLASS_FILESYSTEM,
Eric Paris08089252006-07-10 04:43:55 -0700483 FILESYSTEM__RELABELFROM, NULL);
484 if (rc)
485 return rc;
486
Stephen Smalley6b6bc622018-03-05 11:47:56 -0500487 rc = avc_has_perm(&selinux_state,
488 sid, sbsec->sid, SECCLASS_FILESYSTEM,
Eric Paris08089252006-07-10 04:43:55 -0700489 FILESYSTEM__ASSOCIATE, NULL);
490 return rc;
491}
492
Eric Parisb43e7252012-10-10 14:27:35 -0400493static int selinux_is_sblabel_mnt(struct super_block *sb)
494{
495 struct superblock_security_struct *sbsec = sb->s_security;
496
Mark Salyzynd5f3a5f2015-02-04 11:34:30 -0500497 return sbsec->behavior == SECURITY_FS_USE_XATTR ||
498 sbsec->behavior == SECURITY_FS_USE_TRANS ||
499 sbsec->behavior == SECURITY_FS_USE_TASK ||
J. Bruce Fields9fc2b4b2015-06-04 15:57:25 -0400500 sbsec->behavior == SECURITY_FS_USE_NATIVE ||
Mark Salyzynd5f3a5f2015-02-04 11:34:30 -0500501 /* Special handling. Genfs but also in-core setxattr handler */
502 !strcmp(sb->s_type->name, "sysfs") ||
503 !strcmp(sb->s_type->name, "pstore") ||
504 !strcmp(sb->s_type->name, "debugfs") ||
Yongqin Liua2c7c6fb2017-01-09 10:07:30 -0500505 !strcmp(sb->s_type->name, "tracefs") ||
Stephen Smalley2651225b2017-02-28 10:35:56 -0500506 !strcmp(sb->s_type->name, "rootfs") ||
Stephen Smalleyaa8e7122018-03-01 18:48:02 -0500507 (selinux_policycap_cgroupseclabel() &&
Stephen Smalley2651225b2017-02-28 10:35:56 -0500508 (!strcmp(sb->s_type->name, "cgroup") ||
509 !strcmp(sb->s_type->name, "cgroup2")));
Eric Parisb43e7252012-10-10 14:27:35 -0400510}
511
Eric Parisc9180a52007-11-30 13:00:35 -0500512static int sb_finish_set_opts(struct super_block *sb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700513{
514 struct superblock_security_struct *sbsec = sb->s_security;
515 struct dentry *root = sb->s_root;
David Howellsc6f493d2015-03-17 22:26:22 +0000516 struct inode *root_inode = d_backing_inode(root);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700517 int rc = 0;
518
Linus Torvalds1da177e2005-04-16 15:20:36 -0700519 if (sbsec->behavior == SECURITY_FS_USE_XATTR) {
520 /* Make sure that the xattr handler exists and that no
521 error other than -ENODATA is returned by getxattr on
522 the root directory. -ENODATA is ok, as this may be
523 the first boot of the SELinux kernel before we have
524 assigned xattr values to the filesystem. */
Andreas Gruenbacher5d6c3192016-09-29 17:48:42 +0200525 if (!(root_inode->i_opflags & IOP_XATTR)) {
peter enderborgc103a912018-06-12 10:09:03 +0200526 pr_warn("SELinux: (dev %s, type %s) has no "
Linus Torvalds29b1deb2013-12-15 11:17:45 -0800527 "xattr support\n", sb->s_id, sb->s_type->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700528 rc = -EOPNOTSUPP;
529 goto out;
530 }
Andreas Gruenbacher5d6c3192016-09-29 17:48:42 +0200531
532 rc = __vfs_getxattr(root, root_inode, XATTR_NAME_SELINUX, NULL, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700533 if (rc < 0 && rc != -ENODATA) {
534 if (rc == -EOPNOTSUPP)
peter enderborgc103a912018-06-12 10:09:03 +0200535 pr_warn("SELinux: (dev %s, type "
Linus Torvalds29b1deb2013-12-15 11:17:45 -0800536 "%s) has no security xattr handler\n",
537 sb->s_id, sb->s_type->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700538 else
peter enderborgc103a912018-06-12 10:09:03 +0200539 pr_warn("SELinux: (dev %s, type "
Linus Torvalds29b1deb2013-12-15 11:17:45 -0800540 "%s) getxattr errno %d\n", sb->s_id,
541 sb->s_type->name, -rc);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700542 goto out;
543 }
544 }
545
Eric Pariseadcabc2012-08-24 15:59:14 -0400546 sbsec->flags |= SE_SBINITIALIZED;
Scott Mayhew0b4d3452017-06-05 11:45:04 -0400547
548 /*
549 * Explicitly set or clear SBLABEL_MNT. It's not sufficient to simply
550 * leave the flag untouched because sb_clone_mnt_opts might be handing
551 * us a superblock that needs the flag to be cleared.
552 */
Eric Parisb43e7252012-10-10 14:27:35 -0400553 if (selinux_is_sblabel_mnt(sb))
Eric Paris12f348b2012-10-09 10:56:25 -0400554 sbsec->flags |= SBLABEL_MNT;
Scott Mayhew0b4d3452017-06-05 11:45:04 -0400555 else
556 sbsec->flags &= ~SBLABEL_MNT;
David P. Quigleyddd29ec2009-09-09 14:25:37 -0400557
Linus Torvalds1da177e2005-04-16 15:20:36 -0700558 /* Initialize the root inode. */
Eric Parisc9180a52007-11-30 13:00:35 -0500559 rc = inode_doinit_with_dentry(root_inode, root);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700560
561 /* Initialize any other inodes associated with the superblock, e.g.
562 inodes created prior to initial policy load or inodes created
563 during get_sb by a pseudo filesystem that directly
564 populates itself. */
565 spin_lock(&sbsec->isec_lock);
Al Viro8d641242018-12-10 15:34:12 -0500566 while (!list_empty(&sbsec->isec_head)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700567 struct inode_security_struct *isec =
Al Viro8d641242018-12-10 15:34:12 -0500568 list_first_entry(&sbsec->isec_head,
Eric Parisc9180a52007-11-30 13:00:35 -0500569 struct inode_security_struct, list);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700570 struct inode *inode = isec->inode;
Stephen Smalley923190d32014-10-06 16:32:52 -0400571 list_del_init(&isec->list);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700572 spin_unlock(&sbsec->isec_lock);
573 inode = igrab(inode);
574 if (inode) {
Eric Parisc9180a52007-11-30 13:00:35 -0500575 if (!IS_PRIVATE(inode))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700576 inode_doinit(inode);
577 iput(inode);
578 }
579 spin_lock(&sbsec->isec_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700580 }
581 spin_unlock(&sbsec->isec_lock);
582out:
Eric Parisc9180a52007-11-30 13:00:35 -0500583 return rc;
584}
585
Eric Parisc9180a52007-11-30 13:00:35 -0500586static int bad_option(struct superblock_security_struct *sbsec, char flag,
587 u32 old_sid, u32 new_sid)
588{
David P. Quigley0d90a7e2009-01-16 09:22:02 -0500589 char mnt_flags = sbsec->flags & SE_MNTMASK;
590
Eric Parisc9180a52007-11-30 13:00:35 -0500591 /* check if the old mount command had the same options */
David P. Quigley0d90a7e2009-01-16 09:22:02 -0500592 if (sbsec->flags & SE_SBINITIALIZED)
Eric Parisc9180a52007-11-30 13:00:35 -0500593 if (!(sbsec->flags & flag) ||
594 (old_sid != new_sid))
595 return 1;
596
597 /* check if we were passed the same options twice,
598 * aka someone passed context=a,context=b
599 */
David P. Quigley0d90a7e2009-01-16 09:22:02 -0500600 if (!(sbsec->flags & SE_SBINITIALIZED))
601 if (mnt_flags & flag)
Eric Parisc9180a52007-11-30 13:00:35 -0500602 return 1;
603 return 0;
604}
Eric Parise0007522008-03-05 10:31:54 -0500605
Al Virobd323652018-12-13 15:04:59 -0500606static int parse_sid(struct super_block *sb, const char *s, u32 *sid)
607{
608 int rc = security_context_str_to_sid(&selinux_state, s,
609 sid, GFP_KERNEL);
610 if (rc)
611 pr_warn("SELinux: security_context_str_to_sid"
612 "(%s) failed for (dev %s, type %s) errno=%d\n",
613 s, sb->s_id, sb->s_type->name, rc);
614 return rc;
615}
616
Eric Parisc9180a52007-11-30 13:00:35 -0500617/*
618 * Allow filesystems with binary mount data to explicitly set mount point
619 * labeling information.
620 */
Eric Parise0007522008-03-05 10:31:54 -0500621static int selinux_set_mnt_opts(struct super_block *sb,
Al Viro204cc0c2018-12-13 13:41:47 -0500622 void *mnt_opts,
David Quigley649f6e72013-05-22 12:50:36 -0400623 unsigned long kern_flags,
624 unsigned long *set_kern_flags)
Eric Parisc9180a52007-11-30 13:00:35 -0500625{
David Howells275bb412008-11-14 10:39:19 +1100626 const struct cred *cred = current_cred();
Eric Parisc9180a52007-11-30 13:00:35 -0500627 struct superblock_security_struct *sbsec = sb->s_security;
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -0500628 struct dentry *root = sbsec->sb->s_root;
Al Virobd323652018-12-13 15:04:59 -0500629 struct selinux_mnt_opts *opts = mnt_opts;
Paul Moore2c971652016-04-19 16:36:28 -0400630 struct inode_security_struct *root_isec;
Eric Parisc9180a52007-11-30 13:00:35 -0500631 u32 fscontext_sid = 0, context_sid = 0, rootcontext_sid = 0;
632 u32 defcontext_sid = 0;
Al Virobd323652018-12-13 15:04:59 -0500633 int rc = 0;
Eric Parisc9180a52007-11-30 13:00:35 -0500634
635 mutex_lock(&sbsec->lock);
636
Stephen Smalleyaa8e7122018-03-01 18:48:02 -0500637 if (!selinux_state.initialized) {
Al Virobd323652018-12-13 15:04:59 -0500638 if (!opts) {
Eric Parisc9180a52007-11-30 13:00:35 -0500639 /* Defer initialization until selinux_complete_init,
640 after the initial policy is loaded and the security
641 server is ready to handle calls. */
Eric Parisc9180a52007-11-30 13:00:35 -0500642 goto out;
643 }
644 rc = -EINVAL;
peter enderborgc103a912018-06-12 10:09:03 +0200645 pr_warn("SELinux: Unable to set superblock options "
Eric Paris744ba352008-04-17 11:52:44 -0400646 "before the security server is initialized\n");
Eric Parisc9180a52007-11-30 13:00:35 -0500647 goto out;
648 }
David Quigley649f6e72013-05-22 12:50:36 -0400649 if (kern_flags && !set_kern_flags) {
650 /* Specifying internal flags without providing a place to
651 * place the results is not allowed */
652 rc = -EINVAL;
653 goto out;
654 }
Eric Parisc9180a52007-11-30 13:00:35 -0500655
656 /*
Eric Parise0007522008-03-05 10:31:54 -0500657 * Binary mount data FS will come through this function twice. Once
658 * from an explicit call and once from the generic calls from the vfs.
659 * Since the generic VFS calls will not contain any security mount data
660 * we need to skip the double mount verification.
661 *
662 * This does open a hole in which we will not notice if the first
663 * mount using this sb set explict options and a second mount using
664 * this sb does not set any security options. (The first options
665 * will be used for both mounts)
666 */
David P. Quigley0d90a7e2009-01-16 09:22:02 -0500667 if ((sbsec->flags & SE_SBINITIALIZED) && (sb->s_type->fs_flags & FS_BINARY_MOUNTDATA)
Al Virobd323652018-12-13 15:04:59 -0500668 && !opts)
Eric Parisf52697102008-05-14 11:27:45 -0400669 goto out;
Eric Parise0007522008-03-05 10:31:54 -0500670
Paul Moore2c971652016-04-19 16:36:28 -0400671 root_isec = backing_inode_security_novalidate(root);
672
Eric Parise0007522008-03-05 10:31:54 -0500673 /*
Eric Parisc9180a52007-11-30 13:00:35 -0500674 * parse the mount options, check if they are valid sids.
675 * also check if someone is trying to mount the same sb more
676 * than once with different security options.
677 */
Al Virobd323652018-12-13 15:04:59 -0500678 if (opts) {
679 if (opts->fscontext) {
680 rc = parse_sid(sb, opts->fscontext, &fscontext_sid);
681 if (rc)
682 goto out;
Eric Parisc9180a52007-11-30 13:00:35 -0500683 if (bad_option(sbsec, FSCONTEXT_MNT, sbsec->sid,
684 fscontext_sid))
685 goto out_double_mount;
Eric Parisc9180a52007-11-30 13:00:35 -0500686 sbsec->flags |= FSCONTEXT_MNT;
Al Virobd323652018-12-13 15:04:59 -0500687 }
688 if (opts->context) {
689 rc = parse_sid(sb, opts->context, &context_sid);
690 if (rc)
691 goto out;
Eric Parisc9180a52007-11-30 13:00:35 -0500692 if (bad_option(sbsec, CONTEXT_MNT, sbsec->mntpoint_sid,
693 context_sid))
694 goto out_double_mount;
Eric Parisc9180a52007-11-30 13:00:35 -0500695 sbsec->flags |= CONTEXT_MNT;
Al Virobd323652018-12-13 15:04:59 -0500696 }
697 if (opts->rootcontext) {
698 rc = parse_sid(sb, opts->rootcontext, &rootcontext_sid);
699 if (rc)
700 goto out;
Eric Parisc9180a52007-11-30 13:00:35 -0500701 if (bad_option(sbsec, ROOTCONTEXT_MNT, root_isec->sid,
702 rootcontext_sid))
703 goto out_double_mount;
Eric Parisc9180a52007-11-30 13:00:35 -0500704 sbsec->flags |= ROOTCONTEXT_MNT;
Al Virobd323652018-12-13 15:04:59 -0500705 }
706 if (opts->defcontext) {
707 rc = parse_sid(sb, opts->defcontext, &defcontext_sid);
708 if (rc)
709 goto out;
Eric Parisc9180a52007-11-30 13:00:35 -0500710 if (bad_option(sbsec, DEFCONTEXT_MNT, sbsec->def_sid,
711 defcontext_sid))
712 goto out_double_mount;
Eric Parisc9180a52007-11-30 13:00:35 -0500713 sbsec->flags |= DEFCONTEXT_MNT;
Eric Parisc9180a52007-11-30 13:00:35 -0500714 }
715 }
716
David P. Quigley0d90a7e2009-01-16 09:22:02 -0500717 if (sbsec->flags & SE_SBINITIALIZED) {
Eric Parisc9180a52007-11-30 13:00:35 -0500718 /* previously mounted with options, but not on this attempt? */
Al Virobd323652018-12-13 15:04:59 -0500719 if ((sbsec->flags & SE_MNTMASK) && !opts)
Eric Parisc9180a52007-11-30 13:00:35 -0500720 goto out_double_mount;
721 rc = 0;
722 goto out;
723 }
724
James Morris089be432008-07-15 18:32:49 +1000725 if (strcmp(sb->s_type->name, "proc") == 0)
Stephen Smalley134509d2015-06-04 16:22:17 -0400726 sbsec->flags |= SE_SBPROC | SE_SBGENFS;
727
Stephen Smalley8e014722015-06-04 16:22:17 -0400728 if (!strcmp(sb->s_type->name, "debugfs") ||
Jeff Vander Stoep6a391182017-06-20 09:35:33 -0700729 !strcmp(sb->s_type->name, "tracefs") ||
Stephen Smalley8e014722015-06-04 16:22:17 -0400730 !strcmp(sb->s_type->name, "sysfs") ||
Antonio Murdaca901ef842017-02-09 17:02:42 +0100731 !strcmp(sb->s_type->name, "pstore") ||
732 !strcmp(sb->s_type->name, "cgroup") ||
733 !strcmp(sb->s_type->name, "cgroup2"))
Stephen Smalley134509d2015-06-04 16:22:17 -0400734 sbsec->flags |= SE_SBGENFS;
Eric Parisc9180a52007-11-30 13:00:35 -0500735
David Quigleyeb9ae682013-05-22 12:50:37 -0400736 if (!sbsec->behavior) {
737 /*
738 * Determine the labeling behavior to use for this
739 * filesystem type.
740 */
Stephen Smalleyaa8e7122018-03-01 18:48:02 -0500741 rc = security_fs_use(&selinux_state, sb);
David Quigleyeb9ae682013-05-22 12:50:37 -0400742 if (rc) {
peter enderborgc103a912018-06-12 10:09:03 +0200743 pr_warn("%s: security_fs_use(%s) returned %d\n",
David Quigleyeb9ae682013-05-22 12:50:37 -0400744 __func__, sb->s_type->name, rc);
745 goto out;
746 }
Eric Parisc9180a52007-11-30 13:00:35 -0500747 }
Seth Forsheeaad82892016-04-26 14:36:20 -0500748
749 /*
Stephen Smalley01593d32017-01-09 10:07:31 -0500750 * If this is a user namespace mount and the filesystem type is not
751 * explicitly whitelisted, then no contexts are allowed on the command
752 * line and security labels must be ignored.
Seth Forsheeaad82892016-04-26 14:36:20 -0500753 */
Stephen Smalley01593d32017-01-09 10:07:31 -0500754 if (sb->s_user_ns != &init_user_ns &&
755 strcmp(sb->s_type->name, "tmpfs") &&
756 strcmp(sb->s_type->name, "ramfs") &&
757 strcmp(sb->s_type->name, "devpts")) {
Seth Forsheeaad82892016-04-26 14:36:20 -0500758 if (context_sid || fscontext_sid || rootcontext_sid ||
759 defcontext_sid) {
760 rc = -EACCES;
761 goto out;
762 }
763 if (sbsec->behavior == SECURITY_FS_USE_XATTR) {
764 sbsec->behavior = SECURITY_FS_USE_MNTPOINT;
Stephen Smalleyaa8e7122018-03-01 18:48:02 -0500765 rc = security_transition_sid(&selinux_state,
766 current_sid(),
767 current_sid(),
Seth Forsheeaad82892016-04-26 14:36:20 -0500768 SECCLASS_FILE, NULL,
769 &sbsec->mntpoint_sid);
770 if (rc)
771 goto out;
772 }
773 goto out_set_opts;
774 }
775
Eric Parisc9180a52007-11-30 13:00:35 -0500776 /* sets the context of the superblock for the fs being mounted. */
777 if (fscontext_sid) {
David Howells275bb412008-11-14 10:39:19 +1100778 rc = may_context_mount_sb_relabel(fscontext_sid, sbsec, cred);
Eric Parisc9180a52007-11-30 13:00:35 -0500779 if (rc)
780 goto out;
781
782 sbsec->sid = fscontext_sid;
783 }
784
785 /*
786 * Switch to using mount point labeling behavior.
787 * sets the label used on all file below the mountpoint, and will set
788 * the superblock context if not already set.
789 */
David Quigleyeb9ae682013-05-22 12:50:37 -0400790 if (kern_flags & SECURITY_LSM_NATIVE_LABELS && !context_sid) {
791 sbsec->behavior = SECURITY_FS_USE_NATIVE;
792 *set_kern_flags |= SECURITY_LSM_NATIVE_LABELS;
793 }
794
Eric Parisc9180a52007-11-30 13:00:35 -0500795 if (context_sid) {
796 if (!fscontext_sid) {
David Howells275bb412008-11-14 10:39:19 +1100797 rc = may_context_mount_sb_relabel(context_sid, sbsec,
798 cred);
Eric Parisc9180a52007-11-30 13:00:35 -0500799 if (rc)
800 goto out;
801 sbsec->sid = context_sid;
802 } else {
David Howells275bb412008-11-14 10:39:19 +1100803 rc = may_context_mount_inode_relabel(context_sid, sbsec,
804 cred);
Eric Parisc9180a52007-11-30 13:00:35 -0500805 if (rc)
806 goto out;
807 }
808 if (!rootcontext_sid)
809 rootcontext_sid = context_sid;
810
811 sbsec->mntpoint_sid = context_sid;
812 sbsec->behavior = SECURITY_FS_USE_MNTPOINT;
813 }
814
815 if (rootcontext_sid) {
David Howells275bb412008-11-14 10:39:19 +1100816 rc = may_context_mount_inode_relabel(rootcontext_sid, sbsec,
817 cred);
Eric Parisc9180a52007-11-30 13:00:35 -0500818 if (rc)
819 goto out;
820
821 root_isec->sid = rootcontext_sid;
Andreas Gruenbacher6f3be9f2015-12-24 11:09:40 -0500822 root_isec->initialized = LABEL_INITIALIZED;
Eric Parisc9180a52007-11-30 13:00:35 -0500823 }
824
825 if (defcontext_sid) {
David Quigleyeb9ae682013-05-22 12:50:37 -0400826 if (sbsec->behavior != SECURITY_FS_USE_XATTR &&
827 sbsec->behavior != SECURITY_FS_USE_NATIVE) {
Eric Parisc9180a52007-11-30 13:00:35 -0500828 rc = -EINVAL;
peter enderborgc103a912018-06-12 10:09:03 +0200829 pr_warn("SELinux: defcontext option is "
Eric Parisc9180a52007-11-30 13:00:35 -0500830 "invalid for this filesystem type\n");
831 goto out;
832 }
833
834 if (defcontext_sid != sbsec->def_sid) {
835 rc = may_context_mount_inode_relabel(defcontext_sid,
David Howells275bb412008-11-14 10:39:19 +1100836 sbsec, cred);
Eric Parisc9180a52007-11-30 13:00:35 -0500837 if (rc)
838 goto out;
839 }
840
841 sbsec->def_sid = defcontext_sid;
842 }
843
Seth Forsheeaad82892016-04-26 14:36:20 -0500844out_set_opts:
Eric Parisc9180a52007-11-30 13:00:35 -0500845 rc = sb_finish_set_opts(sb);
846out:
Eric Parisbc7e9822006-09-25 23:32:02 -0700847 mutex_unlock(&sbsec->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700848 return rc;
Eric Parisc9180a52007-11-30 13:00:35 -0500849out_double_mount:
850 rc = -EINVAL;
peter enderborgc103a912018-06-12 10:09:03 +0200851 pr_warn("SELinux: mount invalid. Same superblock, different "
Al Virobd323652018-12-13 15:04:59 -0500852 "security settings for (dev %s, type %s)\n", sb->s_id,
853 sb->s_type->name);
Eric Parisc9180a52007-11-30 13:00:35 -0500854 goto out;
855}
856
Jeff Layton094f7b62013-04-01 08:14:24 -0400857static int selinux_cmp_sb_context(const struct super_block *oldsb,
858 const struct super_block *newsb)
859{
860 struct superblock_security_struct *old = oldsb->s_security;
861 struct superblock_security_struct *new = newsb->s_security;
862 char oldflags = old->flags & SE_MNTMASK;
863 char newflags = new->flags & SE_MNTMASK;
864
865 if (oldflags != newflags)
866 goto mismatch;
867 if ((oldflags & FSCONTEXT_MNT) && old->sid != new->sid)
868 goto mismatch;
869 if ((oldflags & CONTEXT_MNT) && old->mntpoint_sid != new->mntpoint_sid)
870 goto mismatch;
871 if ((oldflags & DEFCONTEXT_MNT) && old->def_sid != new->def_sid)
872 goto mismatch;
873 if (oldflags & ROOTCONTEXT_MNT) {
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -0500874 struct inode_security_struct *oldroot = backing_inode_security(oldsb->s_root);
875 struct inode_security_struct *newroot = backing_inode_security(newsb->s_root);
Jeff Layton094f7b62013-04-01 08:14:24 -0400876 if (oldroot->sid != newroot->sid)
877 goto mismatch;
878 }
879 return 0;
880mismatch:
peter enderborgc103a912018-06-12 10:09:03 +0200881 pr_warn("SELinux: mount invalid. Same superblock, "
Jeff Layton094f7b62013-04-01 08:14:24 -0400882 "different security settings for (dev %s, "
883 "type %s)\n", newsb->s_id, newsb->s_type->name);
884 return -EBUSY;
885}
886
887static int selinux_sb_clone_mnt_opts(const struct super_block *oldsb,
Scott Mayhew0b4d3452017-06-05 11:45:04 -0400888 struct super_block *newsb,
889 unsigned long kern_flags,
890 unsigned long *set_kern_flags)
Eric Parisc9180a52007-11-30 13:00:35 -0500891{
Scott Mayhew0b4d3452017-06-05 11:45:04 -0400892 int rc = 0;
Eric Parisc9180a52007-11-30 13:00:35 -0500893 const struct superblock_security_struct *oldsbsec = oldsb->s_security;
894 struct superblock_security_struct *newsbsec = newsb->s_security;
895
896 int set_fscontext = (oldsbsec->flags & FSCONTEXT_MNT);
897 int set_context = (oldsbsec->flags & CONTEXT_MNT);
898 int set_rootcontext = (oldsbsec->flags & ROOTCONTEXT_MNT);
899
Eric Paris0f5e6422008-04-21 16:24:11 -0400900 /*
901 * if the parent was able to be mounted it clearly had no special lsm
Al Viroe8c26252010-03-23 06:36:54 -0400902 * mount options. thus we can safely deal with this superblock later
Eric Paris0f5e6422008-04-21 16:24:11 -0400903 */
Stephen Smalleyaa8e7122018-03-01 18:48:02 -0500904 if (!selinux_state.initialized)
Jeff Layton094f7b62013-04-01 08:14:24 -0400905 return 0;
Eric Parisc9180a52007-11-30 13:00:35 -0500906
Scott Mayhew0b4d3452017-06-05 11:45:04 -0400907 /*
908 * Specifying internal flags without providing a place to
909 * place the results is not allowed.
910 */
911 if (kern_flags && !set_kern_flags)
912 return -EINVAL;
913
Eric Parisc9180a52007-11-30 13:00:35 -0500914 /* how can we clone if the old one wasn't set up?? */
David P. Quigley0d90a7e2009-01-16 09:22:02 -0500915 BUG_ON(!(oldsbsec->flags & SE_SBINITIALIZED));
Eric Parisc9180a52007-11-30 13:00:35 -0500916
Jeff Layton094f7b62013-04-01 08:14:24 -0400917 /* if fs is reusing a sb, make sure that the contexts match */
David P. Quigley0d90a7e2009-01-16 09:22:02 -0500918 if (newsbsec->flags & SE_SBINITIALIZED)
Jeff Layton094f7b62013-04-01 08:14:24 -0400919 return selinux_cmp_sb_context(oldsb, newsb);
Eric Paris5a552612008-04-09 14:08:35 -0400920
Eric Parisc9180a52007-11-30 13:00:35 -0500921 mutex_lock(&newsbsec->lock);
922
923 newsbsec->flags = oldsbsec->flags;
924
925 newsbsec->sid = oldsbsec->sid;
926 newsbsec->def_sid = oldsbsec->def_sid;
927 newsbsec->behavior = oldsbsec->behavior;
928
Scott Mayhew0b4d3452017-06-05 11:45:04 -0400929 if (newsbsec->behavior == SECURITY_FS_USE_NATIVE &&
930 !(kern_flags & SECURITY_LSM_NATIVE_LABELS) && !set_context) {
Stephen Smalleyaa8e7122018-03-01 18:48:02 -0500931 rc = security_fs_use(&selinux_state, newsb);
Scott Mayhew0b4d3452017-06-05 11:45:04 -0400932 if (rc)
933 goto out;
934 }
935
936 if (kern_flags & SECURITY_LSM_NATIVE_LABELS && !set_context) {
937 newsbsec->behavior = SECURITY_FS_USE_NATIVE;
938 *set_kern_flags |= SECURITY_LSM_NATIVE_LABELS;
939 }
940
Eric Parisc9180a52007-11-30 13:00:35 -0500941 if (set_context) {
942 u32 sid = oldsbsec->mntpoint_sid;
943
944 if (!set_fscontext)
945 newsbsec->sid = sid;
946 if (!set_rootcontext) {
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -0500947 struct inode_security_struct *newisec = backing_inode_security(newsb->s_root);
Eric Parisc9180a52007-11-30 13:00:35 -0500948 newisec->sid = sid;
949 }
950 newsbsec->mntpoint_sid = sid;
951 }
952 if (set_rootcontext) {
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -0500953 const struct inode_security_struct *oldisec = backing_inode_security(oldsb->s_root);
954 struct inode_security_struct *newisec = backing_inode_security(newsb->s_root);
Eric Parisc9180a52007-11-30 13:00:35 -0500955
956 newisec->sid = oldisec->sid;
957 }
958
959 sb_finish_set_opts(newsb);
Scott Mayhew0b4d3452017-06-05 11:45:04 -0400960out:
Eric Parisc9180a52007-11-30 13:00:35 -0500961 mutex_unlock(&newsbsec->lock);
Scott Mayhew0b4d3452017-06-05 11:45:04 -0400962 return rc;
Eric Parisc9180a52007-11-30 13:00:35 -0500963}
964
Al Viroba641862018-12-14 20:28:15 -0500965static int selinux_add_opt(int token, const char *s, void **mnt_opts)
Eric Parisc9180a52007-11-30 13:00:35 -0500966{
Al Viroba641862018-12-14 20:28:15 -0500967 struct selinux_mnt_opts *opts = *mnt_opts;
Eric Parisc9180a52007-11-30 13:00:35 -0500968
Al Viroda3d76a2018-12-17 10:14:16 -0500969 if (token == Opt_seclabel) /* eaten and completely ignored */
Al Viro169d68efb2018-12-14 22:44:50 -0500970 return 0;
Eric Parisc9180a52007-11-30 13:00:35 -0500971
Al Viroba641862018-12-14 20:28:15 -0500972 if (!opts) {
973 opts = kzalloc(sizeof(struct selinux_mnt_opts), GFP_KERNEL);
974 if (!opts)
975 return -ENOMEM;
976 *mnt_opts = opts;
977 }
978 if (!s)
979 return -ENOMEM;
980 switch (token) {
981 case Opt_context:
982 if (opts->context || opts->defcontext)
983 goto Einval;
984 opts->context = s;
985 break;
986 case Opt_fscontext:
987 if (opts->fscontext)
988 goto Einval;
989 opts->fscontext = s;
990 break;
991 case Opt_rootcontext:
992 if (opts->rootcontext)
993 goto Einval;
994 opts->rootcontext = s;
995 break;
996 case Opt_defcontext:
997 if (opts->context || opts->defcontext)
998 goto Einval;
999 opts->defcontext = s;
1000 break;
1001 }
1002 return 0;
1003Einval:
1004 pr_warn(SEL_MOUNT_FAIL_MSG);
Al Viroba641862018-12-14 20:28:15 -05001005 return -EINVAL;
1006}
Eric Parisc9180a52007-11-30 13:00:35 -05001007
Al Viro757cbe52018-12-14 23:42:21 -05001008static int selinux_add_mnt_opt(const char *option, const char *val, int len,
1009 void **mnt_opts)
Eric Parisc9180a52007-11-30 13:00:35 -05001010{
Al Viro757cbe52018-12-14 23:42:21 -05001011 int token = Opt_error;
1012 int rc, i;
Eric Parisc9180a52007-11-30 13:00:35 -05001013
Al Viro757cbe52018-12-14 23:42:21 -05001014 for (i = 0; i < ARRAY_SIZE(tokens); i++) {
1015 if (strcmp(option, tokens[i].name) == 0) {
1016 token = tokens[i].opt;
Eric Parisc9180a52007-11-30 13:00:35 -05001017 break;
Eric Parisc9180a52007-11-30 13:00:35 -05001018 }
1019 }
1020
Al Viro757cbe52018-12-14 23:42:21 -05001021 if (token == Opt_error)
1022 return -EINVAL;
Eric Parise0007522008-03-05 10:31:54 -05001023
Al Viro757cbe52018-12-14 23:42:21 -05001024 if (token != Opt_seclabel)
1025 val = kmemdup_nul(val, len, GFP_KERNEL);
1026 rc = selinux_add_opt(token, val, mnt_opts);
1027 if (unlikely(rc)) {
1028 kfree(val);
1029 if (*mnt_opts) {
1030 selinux_free_mnt_opts(*mnt_opts);
1031 *mnt_opts = NULL;
1032 }
1033 }
1034 return rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001035}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001036
Al Viroe3489f82018-12-13 00:24:36 -05001037static int show_sid(struct seq_file *m, u32 sid)
Eric Paris2069f452008-07-04 09:47:13 +10001038{
Al Viroe3489f82018-12-13 00:24:36 -05001039 char *context = NULL;
1040 u32 len;
1041 int rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001042
Al Viroe3489f82018-12-13 00:24:36 -05001043 rc = security_sid_to_context(&selinux_state, sid,
1044 &context, &len);
1045 if (!rc) {
1046 bool has_comma = context && strchr(context, ',');
Linus Torvalds1da177e2005-04-16 15:20:36 -07001047
Eric Paris2069f452008-07-04 09:47:13 +10001048 if (has_comma)
1049 seq_putc(m, '\"');
Al Viroe3489f82018-12-13 00:24:36 -05001050 seq_escape(m, context, "\"\n\\");
Eric Paris2069f452008-07-04 09:47:13 +10001051 if (has_comma)
1052 seq_putc(m, '\"');
1053 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001054 kfree(context);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001055 return rc;
1056}
Eric Paris2069f452008-07-04 09:47:13 +10001057
1058static int selinux_sb_show_options(struct seq_file *m, struct super_block *sb)
1059{
Al Viroe3489f82018-12-13 00:24:36 -05001060 struct superblock_security_struct *sbsec = sb->s_security;
Eric Paris2069f452008-07-04 09:47:13 +10001061 int rc;
1062
Al Viroe3489f82018-12-13 00:24:36 -05001063 if (!(sbsec->flags & SE_SBINITIALIZED))
1064 return 0;
1065
1066 if (!selinux_state.initialized)
1067 return 0;
1068
1069 if (sbsec->flags & FSCONTEXT_MNT) {
1070 seq_putc(m, ',');
1071 seq_puts(m, FSCONTEXT_STR);
1072 rc = show_sid(m, sbsec->sid);
1073 if (rc)
1074 return rc;
Eric Paris383795c2008-07-29 17:07:26 -04001075 }
Al Viroe3489f82018-12-13 00:24:36 -05001076 if (sbsec->flags & CONTEXT_MNT) {
1077 seq_putc(m, ',');
1078 seq_puts(m, CONTEXT_STR);
1079 rc = show_sid(m, sbsec->mntpoint_sid);
1080 if (rc)
1081 return rc;
1082 }
1083 if (sbsec->flags & DEFCONTEXT_MNT) {
1084 seq_putc(m, ',');
1085 seq_puts(m, DEFCONTEXT_STR);
1086 rc = show_sid(m, sbsec->def_sid);
1087 if (rc)
1088 return rc;
1089 }
1090 if (sbsec->flags & ROOTCONTEXT_MNT) {
1091 struct dentry *root = sbsec->sb->s_root;
1092 struct inode_security_struct *isec = backing_inode_security(root);
1093 seq_putc(m, ',');
1094 seq_puts(m, ROOTCONTEXT_STR);
1095 rc = show_sid(m, isec->sid);
1096 if (rc)
1097 return rc;
1098 }
1099 if (sbsec->flags & SBLABEL_MNT) {
1100 seq_putc(m, ',');
1101 seq_puts(m, LABELSUPP_STR);
1102 }
1103 return 0;
Eric Paris2069f452008-07-04 09:47:13 +10001104}
1105
Linus Torvalds1da177e2005-04-16 15:20:36 -07001106static inline u16 inode_mode_to_security_class(umode_t mode)
1107{
1108 switch (mode & S_IFMT) {
1109 case S_IFSOCK:
1110 return SECCLASS_SOCK_FILE;
1111 case S_IFLNK:
1112 return SECCLASS_LNK_FILE;
1113 case S_IFREG:
1114 return SECCLASS_FILE;
1115 case S_IFBLK:
1116 return SECCLASS_BLK_FILE;
1117 case S_IFDIR:
1118 return SECCLASS_DIR;
1119 case S_IFCHR:
1120 return SECCLASS_CHR_FILE;
1121 case S_IFIFO:
1122 return SECCLASS_FIFO_FILE;
1123
1124 }
1125
1126 return SECCLASS_FILE;
1127}
1128
James Morris13402582005-09-30 14:24:34 -04001129static inline int default_protocol_stream(int protocol)
1130{
1131 return (protocol == IPPROTO_IP || protocol == IPPROTO_TCP);
1132}
1133
1134static inline int default_protocol_dgram(int protocol)
1135{
1136 return (protocol == IPPROTO_IP || protocol == IPPROTO_UDP);
1137}
1138
Linus Torvalds1da177e2005-04-16 15:20:36 -07001139static inline u16 socket_type_to_security_class(int family, int type, int protocol)
1140{
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05001141 int extsockclass = selinux_policycap_extsockclass();
Stephen Smalleyda69a532017-01-09 10:07:30 -05001142
Linus Torvalds1da177e2005-04-16 15:20:36 -07001143 switch (family) {
1144 case PF_UNIX:
1145 switch (type) {
1146 case SOCK_STREAM:
1147 case SOCK_SEQPACKET:
1148 return SECCLASS_UNIX_STREAM_SOCKET;
1149 case SOCK_DGRAM:
Luis Ressel2a764b52017-07-25 15:13:41 -04001150 case SOCK_RAW:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001151 return SECCLASS_UNIX_DGRAM_SOCKET;
1152 }
1153 break;
1154 case PF_INET:
1155 case PF_INET6:
1156 switch (type) {
1157 case SOCK_STREAM:
Stephen Smalleyda69a532017-01-09 10:07:30 -05001158 case SOCK_SEQPACKET:
James Morris13402582005-09-30 14:24:34 -04001159 if (default_protocol_stream(protocol))
1160 return SECCLASS_TCP_SOCKET;
Stephen Smalleyda69a532017-01-09 10:07:30 -05001161 else if (extsockclass && protocol == IPPROTO_SCTP)
1162 return SECCLASS_SCTP_SOCKET;
James Morris13402582005-09-30 14:24:34 -04001163 else
1164 return SECCLASS_RAWIP_SOCKET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001165 case SOCK_DGRAM:
James Morris13402582005-09-30 14:24:34 -04001166 if (default_protocol_dgram(protocol))
1167 return SECCLASS_UDP_SOCKET;
Stephen Smalleyef379792017-01-09 10:07:31 -05001168 else if (extsockclass && (protocol == IPPROTO_ICMP ||
1169 protocol == IPPROTO_ICMPV6))
Stephen Smalleyda69a532017-01-09 10:07:30 -05001170 return SECCLASS_ICMP_SOCKET;
James Morris13402582005-09-30 14:24:34 -04001171 else
1172 return SECCLASS_RAWIP_SOCKET;
James Morris2ee92d42006-11-13 16:09:01 -08001173 case SOCK_DCCP:
1174 return SECCLASS_DCCP_SOCKET;
James Morris13402582005-09-30 14:24:34 -04001175 default:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001176 return SECCLASS_RAWIP_SOCKET;
1177 }
1178 break;
1179 case PF_NETLINK:
1180 switch (protocol) {
1181 case NETLINK_ROUTE:
1182 return SECCLASS_NETLINK_ROUTE_SOCKET;
Pavel Emelyanov7f1fb602011-12-06 07:56:43 +00001183 case NETLINK_SOCK_DIAG:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001184 return SECCLASS_NETLINK_TCPDIAG_SOCKET;
1185 case NETLINK_NFLOG:
1186 return SECCLASS_NETLINK_NFLOG_SOCKET;
1187 case NETLINK_XFRM:
1188 return SECCLASS_NETLINK_XFRM_SOCKET;
1189 case NETLINK_SELINUX:
1190 return SECCLASS_NETLINK_SELINUX_SOCKET;
Stephen Smalley6c6d2e92015-06-04 16:22:16 -04001191 case NETLINK_ISCSI:
1192 return SECCLASS_NETLINK_ISCSI_SOCKET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001193 case NETLINK_AUDIT:
1194 return SECCLASS_NETLINK_AUDIT_SOCKET;
Stephen Smalley6c6d2e92015-06-04 16:22:16 -04001195 case NETLINK_FIB_LOOKUP:
1196 return SECCLASS_NETLINK_FIB_LOOKUP_SOCKET;
1197 case NETLINK_CONNECTOR:
1198 return SECCLASS_NETLINK_CONNECTOR_SOCKET;
1199 case NETLINK_NETFILTER:
1200 return SECCLASS_NETLINK_NETFILTER_SOCKET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001201 case NETLINK_DNRTMSG:
1202 return SECCLASS_NETLINK_DNRT_SOCKET;
James Morris0c9b7942005-04-16 15:24:13 -07001203 case NETLINK_KOBJECT_UEVENT:
1204 return SECCLASS_NETLINK_KOBJECT_UEVENT_SOCKET;
Stephen Smalley6c6d2e92015-06-04 16:22:16 -04001205 case NETLINK_GENERIC:
1206 return SECCLASS_NETLINK_GENERIC_SOCKET;
1207 case NETLINK_SCSITRANSPORT:
1208 return SECCLASS_NETLINK_SCSITRANSPORT_SOCKET;
1209 case NETLINK_RDMA:
1210 return SECCLASS_NETLINK_RDMA_SOCKET;
1211 case NETLINK_CRYPTO:
1212 return SECCLASS_NETLINK_CRYPTO_SOCKET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001213 default:
1214 return SECCLASS_NETLINK_SOCKET;
1215 }
1216 case PF_PACKET:
1217 return SECCLASS_PACKET_SOCKET;
1218 case PF_KEY:
1219 return SECCLASS_KEY_SOCKET;
Christopher J. PeBenito3e3ff152006-06-09 00:25:03 -07001220 case PF_APPLETALK:
1221 return SECCLASS_APPLETALK_SOCKET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001222 }
1223
Stephen Smalleyda69a532017-01-09 10:07:30 -05001224 if (extsockclass) {
1225 switch (family) {
1226 case PF_AX25:
1227 return SECCLASS_AX25_SOCKET;
1228 case PF_IPX:
1229 return SECCLASS_IPX_SOCKET;
1230 case PF_NETROM:
1231 return SECCLASS_NETROM_SOCKET;
Stephen Smalleyda69a532017-01-09 10:07:30 -05001232 case PF_ATMPVC:
1233 return SECCLASS_ATMPVC_SOCKET;
1234 case PF_X25:
1235 return SECCLASS_X25_SOCKET;
1236 case PF_ROSE:
1237 return SECCLASS_ROSE_SOCKET;
1238 case PF_DECnet:
1239 return SECCLASS_DECNET_SOCKET;
1240 case PF_ATMSVC:
1241 return SECCLASS_ATMSVC_SOCKET;
1242 case PF_RDS:
1243 return SECCLASS_RDS_SOCKET;
1244 case PF_IRDA:
1245 return SECCLASS_IRDA_SOCKET;
1246 case PF_PPPOX:
1247 return SECCLASS_PPPOX_SOCKET;
1248 case PF_LLC:
1249 return SECCLASS_LLC_SOCKET;
Stephen Smalleyda69a532017-01-09 10:07:30 -05001250 case PF_CAN:
1251 return SECCLASS_CAN_SOCKET;
1252 case PF_TIPC:
1253 return SECCLASS_TIPC_SOCKET;
1254 case PF_BLUETOOTH:
1255 return SECCLASS_BLUETOOTH_SOCKET;
1256 case PF_IUCV:
1257 return SECCLASS_IUCV_SOCKET;
1258 case PF_RXRPC:
1259 return SECCLASS_RXRPC_SOCKET;
1260 case PF_ISDN:
1261 return SECCLASS_ISDN_SOCKET;
1262 case PF_PHONET:
1263 return SECCLASS_PHONET_SOCKET;
1264 case PF_IEEE802154:
1265 return SECCLASS_IEEE802154_SOCKET;
1266 case PF_CAIF:
1267 return SECCLASS_CAIF_SOCKET;
1268 case PF_ALG:
1269 return SECCLASS_ALG_SOCKET;
1270 case PF_NFC:
1271 return SECCLASS_NFC_SOCKET;
1272 case PF_VSOCK:
1273 return SECCLASS_VSOCK_SOCKET;
1274 case PF_KCM:
1275 return SECCLASS_KCM_SOCKET;
1276 case PF_QIPCRTR:
1277 return SECCLASS_QIPCRTR_SOCKET;
Linus Torvalds3051bf32017-02-22 10:15:09 -08001278 case PF_SMC:
1279 return SECCLASS_SMC_SOCKET;
Björn Töpel68e8b842018-05-02 13:01:22 +02001280 case PF_XDP:
1281 return SECCLASS_XDP_SOCKET;
1282#if PF_MAX > 45
Stephen Smalleyda69a532017-01-09 10:07:30 -05001283#error New address family defined, please update this function.
1284#endif
1285 }
1286 }
1287
Linus Torvalds1da177e2005-04-16 15:20:36 -07001288 return SECCLASS_SOCKET;
1289}
1290
Stephen Smalley134509d2015-06-04 16:22:17 -04001291static int selinux_genfs_get_sid(struct dentry *dentry,
1292 u16 tclass,
1293 u16 flags,
1294 u32 *sid)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001295{
Lucian Adrian Grijincu8e6c9692011-02-01 18:42:22 +02001296 int rc;
Al Virofc640052016-04-10 01:33:30 -04001297 struct super_block *sb = dentry->d_sb;
Lucian Adrian Grijincu8e6c9692011-02-01 18:42:22 +02001298 char *buffer, *path;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001299
Eric Paris828dfe12008-04-17 13:17:49 -04001300 buffer = (char *)__get_free_page(GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001301 if (!buffer)
1302 return -ENOMEM;
1303
Lucian Adrian Grijincu8e6c9692011-02-01 18:42:22 +02001304 path = dentry_path_raw(dentry, buffer, PAGE_SIZE);
1305 if (IS_ERR(path))
1306 rc = PTR_ERR(path);
1307 else {
Stephen Smalley134509d2015-06-04 16:22:17 -04001308 if (flags & SE_SBPROC) {
1309 /* each process gets a /proc/PID/ entry. Strip off the
1310 * PID part to get a valid selinux labeling.
1311 * e.g. /proc/1/net/rpc/nfs -> /net/rpc/nfs */
1312 while (path[1] >= '0' && path[1] <= '9') {
1313 path[1] = '/';
1314 path++;
1315 }
Lucian Adrian Grijincu8e6c9692011-02-01 18:42:22 +02001316 }
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05001317 rc = security_genfs_sid(&selinux_state, sb->s_type->name,
1318 path, tclass, sid);
Stephen Smalley7bb185e2018-09-04 16:51:36 -04001319 if (rc == -ENOENT) {
1320 /* No match in policy, mark as unlabeled. */
1321 *sid = SECINITSID_UNLABELED;
1322 rc = 0;
1323 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001324 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001325 free_page((unsigned long)buffer);
1326 return rc;
1327}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001328
1329/* The inode's security attributes must be initialized before first use. */
1330static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dentry)
1331{
1332 struct superblock_security_struct *sbsec = NULL;
Casey Schaufler80788c22018-09-21 17:19:11 -07001333 struct inode_security_struct *isec = selinux_inode(inode);
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001334 u32 task_sid, sid = 0;
1335 u16 sclass;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001336 struct dentry *dentry;
1337#define INITCONTEXTLEN 255
1338 char *context = NULL;
1339 unsigned len = 0;
1340 int rc = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001341
Andreas Gruenbacher6f3be9f2015-12-24 11:09:40 -05001342 if (isec->initialized == LABEL_INITIALIZED)
Andreas Gruenbacher13457d02016-11-10 22:18:29 +01001343 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001344
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001345 spin_lock(&isec->lock);
Andreas Gruenbacher6f3be9f2015-12-24 11:09:40 -05001346 if (isec->initialized == LABEL_INITIALIZED)
Eric Paris23970742006-09-25 23:32:01 -07001347 goto out_unlock;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001348
Andreas Gruenbacher13457d02016-11-10 22:18:29 +01001349 if (isec->sclass == SECCLASS_FILE)
1350 isec->sclass = inode_mode_to_security_class(inode->i_mode);
1351
Linus Torvalds1da177e2005-04-16 15:20:36 -07001352 sbsec = inode->i_sb->s_security;
David P. Quigley0d90a7e2009-01-16 09:22:02 -05001353 if (!(sbsec->flags & SE_SBINITIALIZED)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001354 /* Defer initialization until selinux_complete_init,
1355 after the initial policy is loaded and the security
1356 server is ready to handle calls. */
1357 spin_lock(&sbsec->isec_lock);
1358 if (list_empty(&isec->list))
1359 list_add(&isec->list, &sbsec->isec_head);
1360 spin_unlock(&sbsec->isec_lock);
Eric Paris23970742006-09-25 23:32:01 -07001361 goto out_unlock;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001362 }
1363
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001364 sclass = isec->sclass;
1365 task_sid = isec->task_sid;
1366 sid = isec->sid;
1367 isec->initialized = LABEL_PENDING;
1368 spin_unlock(&isec->lock);
1369
Linus Torvalds1da177e2005-04-16 15:20:36 -07001370 switch (sbsec->behavior) {
David Quigleyeb9ae682013-05-22 12:50:37 -04001371 case SECURITY_FS_USE_NATIVE:
1372 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001373 case SECURITY_FS_USE_XATTR:
Andreas Gruenbacher5d6c3192016-09-29 17:48:42 +02001374 if (!(inode->i_opflags & IOP_XATTR)) {
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001375 sid = sbsec->def_sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001376 break;
1377 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001378 /* Need a dentry, since the xattr API requires one.
1379 Life would be simpler if we could just pass the inode. */
1380 if (opt_dentry) {
1381 /* Called from d_instantiate or d_splice_alias. */
1382 dentry = dget(opt_dentry);
1383 } else {
Al Virob1271252018-04-25 10:28:38 -04001384 /*
1385 * Called from selinux_complete_init, try to find a dentry.
1386 * Some filesystems really want a connected one, so try
1387 * that first. We could split SECURITY_FS_USE_XATTR in
1388 * two, depending upon that...
1389 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001390 dentry = d_find_alias(inode);
Al Virob1271252018-04-25 10:28:38 -04001391 if (!dentry)
1392 dentry = d_find_any_alias(inode);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001393 }
1394 if (!dentry) {
Eric Parisdf7f54c2009-03-09 14:35:58 -04001395 /*
1396 * this is can be hit on boot when a file is accessed
1397 * before the policy is loaded. When we load policy we
1398 * may find inodes that have no dentry on the
1399 * sbsec->isec_head list. No reason to complain as these
1400 * will get fixed up the next time we go through
1401 * inode_doinit with a dentry, before these inodes could
1402 * be used again by userspace.
1403 */
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001404 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001405 }
1406
1407 len = INITCONTEXTLEN;
Eric Paris4cb912f2009-02-12 14:50:05 -05001408 context = kmalloc(len+1, GFP_NOFS);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001409 if (!context) {
1410 rc = -ENOMEM;
1411 dput(dentry);
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001412 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001413 }
Eric Paris4cb912f2009-02-12 14:50:05 -05001414 context[len] = '\0';
Andreas Gruenbacher5d6c3192016-09-29 17:48:42 +02001415 rc = __vfs_getxattr(dentry, inode, XATTR_NAME_SELINUX, context, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001416 if (rc == -ERANGE) {
James Morris314dabb2009-08-10 22:00:13 +10001417 kfree(context);
1418
Linus Torvalds1da177e2005-04-16 15:20:36 -07001419 /* Need a larger buffer. Query for the right size. */
Andreas Gruenbacher5d6c3192016-09-29 17:48:42 +02001420 rc = __vfs_getxattr(dentry, inode, XATTR_NAME_SELINUX, NULL, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001421 if (rc < 0) {
1422 dput(dentry);
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001423 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001424 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001425 len = rc;
Eric Paris4cb912f2009-02-12 14:50:05 -05001426 context = kmalloc(len+1, GFP_NOFS);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001427 if (!context) {
1428 rc = -ENOMEM;
1429 dput(dentry);
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001430 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001431 }
Eric Paris4cb912f2009-02-12 14:50:05 -05001432 context[len] = '\0';
Andreas Gruenbacher5d6c3192016-09-29 17:48:42 +02001433 rc = __vfs_getxattr(dentry, inode, XATTR_NAME_SELINUX, context, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001434 }
1435 dput(dentry);
1436 if (rc < 0) {
1437 if (rc != -ENODATA) {
peter enderborgc103a912018-06-12 10:09:03 +02001438 pr_warn("SELinux: %s: getxattr returned "
Harvey Harrisondd6f9532008-03-06 10:03:59 +11001439 "%d for dev=%s ino=%ld\n", __func__,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001440 -rc, inode->i_sb->s_id, inode->i_ino);
1441 kfree(context);
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001442 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001443 }
1444 /* Map ENODATA to the default file SID */
1445 sid = sbsec->def_sid;
1446 rc = 0;
1447 } else {
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05001448 rc = security_context_to_sid_default(&selinux_state,
1449 context, rc, &sid,
Stephen Smalley869ab512008-04-04 08:46:05 -04001450 sbsec->def_sid,
1451 GFP_NOFS);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001452 if (rc) {
Eric Paris4ba0a8a2009-02-12 15:01:10 -05001453 char *dev = inode->i_sb->s_id;
1454 unsigned long ino = inode->i_ino;
1455
1456 if (rc == -EINVAL) {
1457 if (printk_ratelimit())
peter enderborgc103a912018-06-12 10:09:03 +02001458 pr_notice("SELinux: inode=%lu on dev=%s was found to have an invalid "
Eric Paris4ba0a8a2009-02-12 15:01:10 -05001459 "context=%s. This indicates you may need to relabel the inode or the "
1460 "filesystem in question.\n", ino, dev, context);
1461 } else {
peter enderborgc103a912018-06-12 10:09:03 +02001462 pr_warn("SELinux: %s: context_to_sid(%s) "
Eric Paris4ba0a8a2009-02-12 15:01:10 -05001463 "returned %d for dev=%s ino=%ld\n",
1464 __func__, context, -rc, dev, ino);
1465 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001466 kfree(context);
1467 /* Leave with the unlabeled SID */
1468 rc = 0;
1469 break;
1470 }
1471 }
1472 kfree(context);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001473 break;
1474 case SECURITY_FS_USE_TASK:
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001475 sid = task_sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001476 break;
1477 case SECURITY_FS_USE_TRANS:
1478 /* Default to the fs SID. */
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001479 sid = sbsec->sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001480
1481 /* Try to obtain a transition SID. */
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05001482 rc = security_transition_sid(&selinux_state, task_sid, sid,
1483 sclass, NULL, &sid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001484 if (rc)
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001485 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001486 break;
Eric Parisc312feb2006-07-10 04:43:53 -07001487 case SECURITY_FS_USE_MNTPOINT:
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001488 sid = sbsec->mntpoint_sid;
Eric Parisc312feb2006-07-10 04:43:53 -07001489 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001490 default:
Eric Parisc312feb2006-07-10 04:43:53 -07001491 /* Default to the fs superblock SID. */
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001492 sid = sbsec->sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001493
Stephen Smalley134509d2015-06-04 16:22:17 -04001494 if ((sbsec->flags & SE_SBGENFS) && !S_ISLNK(inode->i_mode)) {
Paul Mooref64410e2014-03-19 16:46:18 -04001495 /* We must have a dentry to determine the label on
1496 * procfs inodes */
Al Virob1271252018-04-25 10:28:38 -04001497 if (opt_dentry) {
Paul Mooref64410e2014-03-19 16:46:18 -04001498 /* Called from d_instantiate or
1499 * d_splice_alias. */
1500 dentry = dget(opt_dentry);
Al Virob1271252018-04-25 10:28:38 -04001501 } else {
Paul Mooref64410e2014-03-19 16:46:18 -04001502 /* Called from selinux_complete_init, try to
Al Virob1271252018-04-25 10:28:38 -04001503 * find a dentry. Some filesystems really want
1504 * a connected one, so try that first.
1505 */
Paul Mooref64410e2014-03-19 16:46:18 -04001506 dentry = d_find_alias(inode);
Al Virob1271252018-04-25 10:28:38 -04001507 if (!dentry)
1508 dentry = d_find_any_alias(inode);
1509 }
Paul Mooref64410e2014-03-19 16:46:18 -04001510 /*
1511 * This can be hit on boot when a file is accessed
1512 * before the policy is loaded. When we load policy we
1513 * may find inodes that have no dentry on the
1514 * sbsec->isec_head list. No reason to complain as
1515 * these will get fixed up the next time we go through
1516 * inode_doinit() with a dentry, before these inodes
1517 * could be used again by userspace.
1518 */
1519 if (!dentry)
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001520 goto out;
1521 rc = selinux_genfs_get_sid(dentry, sclass,
Stephen Smalley134509d2015-06-04 16:22:17 -04001522 sbsec->flags, &sid);
Paul Mooref64410e2014-03-19 16:46:18 -04001523 dput(dentry);
1524 if (rc)
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001525 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001526 }
1527 break;
1528 }
1529
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001530out:
1531 spin_lock(&isec->lock);
1532 if (isec->initialized == LABEL_PENDING) {
1533 if (!sid || rc) {
1534 isec->initialized = LABEL_INVALID;
1535 goto out_unlock;
1536 }
1537
1538 isec->initialized = LABEL_INITIALIZED;
1539 isec->sid = sid;
1540 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001541
Eric Paris23970742006-09-25 23:32:01 -07001542out_unlock:
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001543 spin_unlock(&isec->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001544 return rc;
1545}
1546
1547/* Convert a Linux signal to an access vector. */
1548static inline u32 signal_to_av(int sig)
1549{
1550 u32 perm = 0;
1551
1552 switch (sig) {
1553 case SIGCHLD:
1554 /* Commonly granted from child to parent. */
1555 perm = PROCESS__SIGCHLD;
1556 break;
1557 case SIGKILL:
1558 /* Cannot be caught or ignored */
1559 perm = PROCESS__SIGKILL;
1560 break;
1561 case SIGSTOP:
1562 /* Cannot be caught or ignored */
1563 perm = PROCESS__SIGSTOP;
1564 break;
1565 default:
1566 /* All other signals. */
1567 perm = PROCESS__SIGNAL;
1568 break;
1569 }
1570
1571 return perm;
1572}
1573
Stephen Smalleyb68e4182008-02-07 11:21:04 -05001574#if CAP_LAST_CAP > 63
1575#error Fix SELinux to handle capabilities > 63.
1576#endif
1577
Linus Torvalds1da177e2005-04-16 15:20:36 -07001578/* Check whether a task is allowed to use a capability. */
Eric Paris6a9de492012-01-03 12:25:14 -05001579static int cred_has_capability(const struct cred *cred,
Micah Mortonc1a85a02019-01-07 16:10:53 -08001580 int cap, unsigned int opts, bool initns)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001581{
Thomas Liu2bf49692009-07-14 12:14:09 -04001582 struct common_audit_data ad;
Eric Paris06112162008-11-11 22:02:50 +11001583 struct av_decision avd;
Stephen Smalleyb68e4182008-02-07 11:21:04 -05001584 u16 sclass;
David Howells3699c532009-01-06 22:27:01 +00001585 u32 sid = cred_sid(cred);
Stephen Smalleyb68e4182008-02-07 11:21:04 -05001586 u32 av = CAP_TO_MASK(cap);
Eric Paris06112162008-11-11 22:02:50 +11001587 int rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001588
Eric Paris50c205f2012-04-04 15:01:43 -04001589 ad.type = LSM_AUDIT_DATA_CAP;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001590 ad.u.cap = cap;
1591
Stephen Smalleyb68e4182008-02-07 11:21:04 -05001592 switch (CAP_TO_INDEX(cap)) {
1593 case 0:
Stephen Smalley8e4ff6f2016-04-08 13:52:00 -04001594 sclass = initns ? SECCLASS_CAPABILITY : SECCLASS_CAP_USERNS;
Stephen Smalleyb68e4182008-02-07 11:21:04 -05001595 break;
1596 case 1:
Stephen Smalley8e4ff6f2016-04-08 13:52:00 -04001597 sclass = initns ? SECCLASS_CAPABILITY2 : SECCLASS_CAP2_USERNS;
Stephen Smalleyb68e4182008-02-07 11:21:04 -05001598 break;
1599 default:
peter enderborgc103a912018-06-12 10:09:03 +02001600 pr_err("SELinux: out of range capability %d\n", cap);
Stephen Smalleyb68e4182008-02-07 11:21:04 -05001601 BUG();
Eric Parisa35c6c832011-04-20 10:21:28 -04001602 return -EINVAL;
Stephen Smalleyb68e4182008-02-07 11:21:04 -05001603 }
Eric Paris06112162008-11-11 22:02:50 +11001604
Stephen Smalley6b6bc622018-03-05 11:47:56 -05001605 rc = avc_has_perm_noaudit(&selinux_state,
1606 sid, sid, sclass, av, 0, &avd);
Micah Mortonc1a85a02019-01-07 16:10:53 -08001607 if (!(opts & CAP_OPT_NOAUDIT)) {
Stephen Smalley6b6bc622018-03-05 11:47:56 -05001608 int rc2 = avc_audit(&selinux_state,
1609 sid, sid, sclass, av, &avd, rc, &ad, 0);
Eric Paris9ade0cf2011-04-25 16:26:29 -04001610 if (rc2)
1611 return rc2;
1612 }
Eric Paris06112162008-11-11 22:02:50 +11001613 return rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001614}
1615
Linus Torvalds1da177e2005-04-16 15:20:36 -07001616/* Check whether a task has a particular permission to an inode.
1617 The 'adp' parameter is optional and allows other audit
1618 data to be passed (e.g. the dentry). */
David Howells88e67f32008-11-14 10:39:21 +11001619static int inode_has_perm(const struct cred *cred,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001620 struct inode *inode,
1621 u32 perms,
Linus Torvalds19e49832013-10-04 12:54:11 -07001622 struct common_audit_data *adp)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001623{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001624 struct inode_security_struct *isec;
David Howells275bb412008-11-14 10:39:19 +11001625 u32 sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001626
David Howellse0e81732009-09-02 09:13:40 +01001627 validate_creds(cred);
1628
Eric Paris828dfe12008-04-17 13:17:49 -04001629 if (unlikely(IS_PRIVATE(inode)))
Stephen Smalleybbaca6c2007-02-14 00:34:16 -08001630 return 0;
1631
David Howells88e67f32008-11-14 10:39:21 +11001632 sid = cred_sid(cred);
Casey Schaufler80788c22018-09-21 17:19:11 -07001633 isec = selinux_inode(inode);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001634
Stephen Smalley6b6bc622018-03-05 11:47:56 -05001635 return avc_has_perm(&selinux_state,
1636 sid, isec->sid, isec->sclass, perms, adp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001637}
1638
1639/* Same as inode_has_perm, but pass explicit audit data containing
1640 the dentry to help the auditing code to more easily generate the
1641 pathname if needed. */
David Howells88e67f32008-11-14 10:39:21 +11001642static inline int dentry_has_perm(const struct cred *cred,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001643 struct dentry *dentry,
1644 u32 av)
1645{
David Howellsc6f493d2015-03-17 22:26:22 +00001646 struct inode *inode = d_backing_inode(dentry);
Thomas Liu2bf49692009-07-14 12:14:09 -04001647 struct common_audit_data ad;
David Howells88e67f32008-11-14 10:39:21 +11001648
Eric Paris50c205f2012-04-04 15:01:43 -04001649 ad.type = LSM_AUDIT_DATA_DENTRY;
Eric Paris2875fa02011-04-28 16:04:24 -04001650 ad.u.dentry = dentry;
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -05001651 __inode_security_revalidate(inode, dentry, true);
Linus Torvalds19e49832013-10-04 12:54:11 -07001652 return inode_has_perm(cred, inode, av, &ad);
Eric Paris2875fa02011-04-28 16:04:24 -04001653}
1654
1655/* Same as inode_has_perm, but pass explicit audit data containing
1656 the path to help the auditing code to more easily generate the
1657 pathname if needed. */
1658static inline int path_has_perm(const struct cred *cred,
Al Viro3f7036a2015-03-08 19:28:30 -04001659 const struct path *path,
Eric Paris2875fa02011-04-28 16:04:24 -04001660 u32 av)
1661{
David Howellsc6f493d2015-03-17 22:26:22 +00001662 struct inode *inode = d_backing_inode(path->dentry);
Eric Paris2875fa02011-04-28 16:04:24 -04001663 struct common_audit_data ad;
1664
Eric Paris50c205f2012-04-04 15:01:43 -04001665 ad.type = LSM_AUDIT_DATA_PATH;
Eric Paris2875fa02011-04-28 16:04:24 -04001666 ad.u.path = *path;
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -05001667 __inode_security_revalidate(inode, path->dentry, true);
Linus Torvalds19e49832013-10-04 12:54:11 -07001668 return inode_has_perm(cred, inode, av, &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001669}
1670
David Howells13f8e982013-06-13 23:37:55 +01001671/* Same as path_has_perm, but uses the inode from the file struct. */
1672static inline int file_path_has_perm(const struct cred *cred,
1673 struct file *file,
1674 u32 av)
1675{
1676 struct common_audit_data ad;
1677
Vivek Goyal43af5de2016-09-09 11:37:49 -04001678 ad.type = LSM_AUDIT_DATA_FILE;
1679 ad.u.file = file;
Linus Torvalds19e49832013-10-04 12:54:11 -07001680 return inode_has_perm(cred, file_inode(file), av, &ad);
David Howells13f8e982013-06-13 23:37:55 +01001681}
1682
Chenbo Fengf66e4482017-10-18 13:00:26 -07001683#ifdef CONFIG_BPF_SYSCALL
1684static int bpf_fd_pass(struct file *file, u32 sid);
1685#endif
1686
Linus Torvalds1da177e2005-04-16 15:20:36 -07001687/* Check whether a task can use an open file descriptor to
1688 access an inode in a given way. Check access to the
1689 descriptor itself, and then use dentry_has_perm to
1690 check a particular permission to the file.
1691 Access to the descriptor is implicitly granted if it
1692 has the same SID as the process. If av is zero, then
1693 access to the file is not checked, e.g. for cases
1694 where only the descriptor is affected like seek. */
David Howells88e67f32008-11-14 10:39:21 +11001695static int file_has_perm(const struct cred *cred,
1696 struct file *file,
1697 u32 av)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001698{
Casey Schauflerbb6c6b02018-09-21 17:22:32 -07001699 struct file_security_struct *fsec = selinux_file(file);
Al Viro496ad9a2013-01-23 17:07:38 -05001700 struct inode *inode = file_inode(file);
Thomas Liu2bf49692009-07-14 12:14:09 -04001701 struct common_audit_data ad;
David Howells88e67f32008-11-14 10:39:21 +11001702 u32 sid = cred_sid(cred);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001703 int rc;
1704
Vivek Goyal43af5de2016-09-09 11:37:49 -04001705 ad.type = LSM_AUDIT_DATA_FILE;
1706 ad.u.file = file;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001707
David Howells275bb412008-11-14 10:39:19 +11001708 if (sid != fsec->sid) {
Stephen Smalley6b6bc622018-03-05 11:47:56 -05001709 rc = avc_has_perm(&selinux_state,
1710 sid, fsec->sid,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001711 SECCLASS_FD,
1712 FD__USE,
1713 &ad);
1714 if (rc)
David Howells88e67f32008-11-14 10:39:21 +11001715 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001716 }
1717
Chenbo Fengf66e4482017-10-18 13:00:26 -07001718#ifdef CONFIG_BPF_SYSCALL
1719 rc = bpf_fd_pass(file, cred_sid(cred));
1720 if (rc)
1721 return rc;
1722#endif
1723
Linus Torvalds1da177e2005-04-16 15:20:36 -07001724 /* av is zero if only checking access to the descriptor. */
David Howells88e67f32008-11-14 10:39:21 +11001725 rc = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001726 if (av)
Linus Torvalds19e49832013-10-04 12:54:11 -07001727 rc = inode_has_perm(cred, inode, av, &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001728
David Howells88e67f32008-11-14 10:39:21 +11001729out:
1730 return rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001731}
1732
David Howellsc3c188b2015-07-10 17:19:58 -04001733/*
1734 * Determine the label for an inode that might be unioned.
1735 */
Vivek Goyalc957f6d2016-07-13 10:44:51 -04001736static int
1737selinux_determine_inode_label(const struct task_security_struct *tsec,
1738 struct inode *dir,
1739 const struct qstr *name, u16 tclass,
1740 u32 *_new_isid)
David Howellsc3c188b2015-07-10 17:19:58 -04001741{
1742 const struct superblock_security_struct *sbsec = dir->i_sb->s_security;
David Howellsc3c188b2015-07-10 17:19:58 -04001743
1744 if ((sbsec->flags & SE_SBINITIALIZED) &&
1745 (sbsec->behavior == SECURITY_FS_USE_MNTPOINT)) {
1746 *_new_isid = sbsec->mntpoint_sid;
1747 } else if ((sbsec->flags & SBLABEL_MNT) &&
1748 tsec->create_sid) {
1749 *_new_isid = tsec->create_sid;
1750 } else {
Paul Moore20cdef82016-04-04 14:14:42 -04001751 const struct inode_security_struct *dsec = inode_security(dir);
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05001752 return security_transition_sid(&selinux_state, tsec->sid,
1753 dsec->sid, tclass,
David Howellsc3c188b2015-07-10 17:19:58 -04001754 name, _new_isid);
1755 }
1756
1757 return 0;
1758}
1759
Linus Torvalds1da177e2005-04-16 15:20:36 -07001760/* Check whether a task can create a file. */
1761static int may_create(struct inode *dir,
1762 struct dentry *dentry,
1763 u16 tclass)
1764{
Casey Schaufler0c6cfa62018-09-21 17:17:16 -07001765 const struct task_security_struct *tsec = selinux_cred(current_cred());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001766 struct inode_security_struct *dsec;
1767 struct superblock_security_struct *sbsec;
David Howells275bb412008-11-14 10:39:19 +11001768 u32 sid, newsid;
Thomas Liu2bf49692009-07-14 12:14:09 -04001769 struct common_audit_data ad;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001770 int rc;
1771
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -05001772 dsec = inode_security(dir);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001773 sbsec = dir->i_sb->s_security;
1774
David Howells275bb412008-11-14 10:39:19 +11001775 sid = tsec->sid;
David Howells275bb412008-11-14 10:39:19 +11001776
Eric Paris50c205f2012-04-04 15:01:43 -04001777 ad.type = LSM_AUDIT_DATA_DENTRY;
Eric Parisa2694342011-04-25 13:10:27 -04001778 ad.u.dentry = dentry;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001779
Stephen Smalley6b6bc622018-03-05 11:47:56 -05001780 rc = avc_has_perm(&selinux_state,
1781 sid, dsec->sid, SECCLASS_DIR,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001782 DIR__ADD_NAME | DIR__SEARCH,
1783 &ad);
1784 if (rc)
1785 return rc;
1786
Casey Schaufler0c6cfa62018-09-21 17:17:16 -07001787 rc = selinux_determine_inode_label(selinux_cred(current_cred()), dir,
Vivek Goyalc957f6d2016-07-13 10:44:51 -04001788 &dentry->d_name, tclass, &newsid);
David Howellsc3c188b2015-07-10 17:19:58 -04001789 if (rc)
1790 return rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001791
Stephen Smalley6b6bc622018-03-05 11:47:56 -05001792 rc = avc_has_perm(&selinux_state,
1793 sid, newsid, tclass, FILE__CREATE, &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001794 if (rc)
1795 return rc;
1796
Stephen Smalley6b6bc622018-03-05 11:47:56 -05001797 return avc_has_perm(&selinux_state,
1798 newsid, sbsec->sid,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001799 SECCLASS_FILESYSTEM,
1800 FILESYSTEM__ASSOCIATE, &ad);
1801}
1802
Eric Paris828dfe12008-04-17 13:17:49 -04001803#define MAY_LINK 0
1804#define MAY_UNLINK 1
1805#define MAY_RMDIR 2
Linus Torvalds1da177e2005-04-16 15:20:36 -07001806
1807/* Check whether a task can link, unlink, or rmdir a file/directory. */
1808static int may_link(struct inode *dir,
1809 struct dentry *dentry,
1810 int kind)
1811
1812{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001813 struct inode_security_struct *dsec, *isec;
Thomas Liu2bf49692009-07-14 12:14:09 -04001814 struct common_audit_data ad;
David Howells275bb412008-11-14 10:39:19 +11001815 u32 sid = current_sid();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001816 u32 av;
1817 int rc;
1818
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -05001819 dsec = inode_security(dir);
1820 isec = backing_inode_security(dentry);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001821
Eric Paris50c205f2012-04-04 15:01:43 -04001822 ad.type = LSM_AUDIT_DATA_DENTRY;
Eric Parisa2694342011-04-25 13:10:27 -04001823 ad.u.dentry = dentry;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001824
1825 av = DIR__SEARCH;
1826 av |= (kind ? DIR__REMOVE_NAME : DIR__ADD_NAME);
Stephen Smalley6b6bc622018-03-05 11:47:56 -05001827 rc = avc_has_perm(&selinux_state,
1828 sid, dsec->sid, SECCLASS_DIR, av, &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001829 if (rc)
1830 return rc;
1831
1832 switch (kind) {
1833 case MAY_LINK:
1834 av = FILE__LINK;
1835 break;
1836 case MAY_UNLINK:
1837 av = FILE__UNLINK;
1838 break;
1839 case MAY_RMDIR:
1840 av = DIR__RMDIR;
1841 break;
1842 default:
peter enderborgc103a912018-06-12 10:09:03 +02001843 pr_warn("SELinux: %s: unrecognized kind %d\n",
Eric Paris744ba352008-04-17 11:52:44 -04001844 __func__, kind);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001845 return 0;
1846 }
1847
Stephen Smalley6b6bc622018-03-05 11:47:56 -05001848 rc = avc_has_perm(&selinux_state,
1849 sid, isec->sid, isec->sclass, av, &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001850 return rc;
1851}
1852
1853static inline int may_rename(struct inode *old_dir,
1854 struct dentry *old_dentry,
1855 struct inode *new_dir,
1856 struct dentry *new_dentry)
1857{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001858 struct inode_security_struct *old_dsec, *new_dsec, *old_isec, *new_isec;
Thomas Liu2bf49692009-07-14 12:14:09 -04001859 struct common_audit_data ad;
David Howells275bb412008-11-14 10:39:19 +11001860 u32 sid = current_sid();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001861 u32 av;
1862 int old_is_dir, new_is_dir;
1863 int rc;
1864
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -05001865 old_dsec = inode_security(old_dir);
1866 old_isec = backing_inode_security(old_dentry);
David Howellse36cb0b2015-01-29 12:02:35 +00001867 old_is_dir = d_is_dir(old_dentry);
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -05001868 new_dsec = inode_security(new_dir);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001869
Eric Paris50c205f2012-04-04 15:01:43 -04001870 ad.type = LSM_AUDIT_DATA_DENTRY;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001871
Eric Parisa2694342011-04-25 13:10:27 -04001872 ad.u.dentry = old_dentry;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05001873 rc = avc_has_perm(&selinux_state,
1874 sid, old_dsec->sid, SECCLASS_DIR,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001875 DIR__REMOVE_NAME | DIR__SEARCH, &ad);
1876 if (rc)
1877 return rc;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05001878 rc = avc_has_perm(&selinux_state,
1879 sid, old_isec->sid,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001880 old_isec->sclass, FILE__RENAME, &ad);
1881 if (rc)
1882 return rc;
1883 if (old_is_dir && new_dir != old_dir) {
Stephen Smalley6b6bc622018-03-05 11:47:56 -05001884 rc = avc_has_perm(&selinux_state,
1885 sid, old_isec->sid,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001886 old_isec->sclass, DIR__REPARENT, &ad);
1887 if (rc)
1888 return rc;
1889 }
1890
Eric Parisa2694342011-04-25 13:10:27 -04001891 ad.u.dentry = new_dentry;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001892 av = DIR__ADD_NAME | DIR__SEARCH;
David Howells2c616d42015-01-29 12:02:33 +00001893 if (d_is_positive(new_dentry))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001894 av |= DIR__REMOVE_NAME;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05001895 rc = avc_has_perm(&selinux_state,
1896 sid, new_dsec->sid, SECCLASS_DIR, av, &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001897 if (rc)
1898 return rc;
David Howells2c616d42015-01-29 12:02:33 +00001899 if (d_is_positive(new_dentry)) {
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -05001900 new_isec = backing_inode_security(new_dentry);
David Howellse36cb0b2015-01-29 12:02:35 +00001901 new_is_dir = d_is_dir(new_dentry);
Stephen Smalley6b6bc622018-03-05 11:47:56 -05001902 rc = avc_has_perm(&selinux_state,
1903 sid, new_isec->sid,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001904 new_isec->sclass,
1905 (new_is_dir ? DIR__RMDIR : FILE__UNLINK), &ad);
1906 if (rc)
1907 return rc;
1908 }
1909
1910 return 0;
1911}
1912
1913/* Check whether a task can perform a filesystem operation. */
David Howells88e67f32008-11-14 10:39:21 +11001914static int superblock_has_perm(const struct cred *cred,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001915 struct super_block *sb,
1916 u32 perms,
Thomas Liu2bf49692009-07-14 12:14:09 -04001917 struct common_audit_data *ad)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001918{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001919 struct superblock_security_struct *sbsec;
David Howells88e67f32008-11-14 10:39:21 +11001920 u32 sid = cred_sid(cred);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001921
Linus Torvalds1da177e2005-04-16 15:20:36 -07001922 sbsec = sb->s_security;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05001923 return avc_has_perm(&selinux_state,
1924 sid, sbsec->sid, SECCLASS_FILESYSTEM, perms, ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001925}
1926
1927/* Convert a Linux mode and permission mask to an access vector. */
1928static inline u32 file_mask_to_av(int mode, int mask)
1929{
1930 u32 av = 0;
1931
Al Virodba19c62011-07-25 20:49:29 -04001932 if (!S_ISDIR(mode)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001933 if (mask & MAY_EXEC)
1934 av |= FILE__EXECUTE;
1935 if (mask & MAY_READ)
1936 av |= FILE__READ;
1937
1938 if (mask & MAY_APPEND)
1939 av |= FILE__APPEND;
1940 else if (mask & MAY_WRITE)
1941 av |= FILE__WRITE;
1942
1943 } else {
1944 if (mask & MAY_EXEC)
1945 av |= DIR__SEARCH;
1946 if (mask & MAY_WRITE)
1947 av |= DIR__WRITE;
1948 if (mask & MAY_READ)
1949 av |= DIR__READ;
1950 }
1951
1952 return av;
1953}
1954
1955/* Convert a Linux file to an access vector. */
1956static inline u32 file_to_av(struct file *file)
1957{
1958 u32 av = 0;
1959
1960 if (file->f_mode & FMODE_READ)
1961 av |= FILE__READ;
1962 if (file->f_mode & FMODE_WRITE) {
1963 if (file->f_flags & O_APPEND)
1964 av |= FILE__APPEND;
1965 else
1966 av |= FILE__WRITE;
1967 }
Stephen Smalley0794c662008-03-17 08:55:18 -04001968 if (!av) {
1969 /*
1970 * Special file opened with flags 3 for ioctl-only use.
1971 */
1972 av = FILE__IOCTL;
1973 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001974
1975 return av;
1976}
1977
Eric Paris8b6a5a32008-10-29 17:06:46 -04001978/*
1979 * Convert a file to an access vector and include the correct open
1980 * open permission.
1981 */
1982static inline u32 open_file_to_av(struct file *file)
1983{
1984 u32 av = file_to_av(file);
Stephen Smalleyccb54472017-05-12 12:41:24 -04001985 struct inode *inode = file_inode(file);
Eric Paris8b6a5a32008-10-29 17:06:46 -04001986
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05001987 if (selinux_policycap_openperm() &&
1988 inode->i_sb->s_magic != SOCKFS_MAGIC)
Eric Paris49b7b8d2010-07-23 11:44:09 -04001989 av |= FILE__OPEN;
1990
Eric Paris8b6a5a32008-10-29 17:06:46 -04001991 return av;
1992}
1993
Linus Torvalds1da177e2005-04-16 15:20:36 -07001994/* Hook functions begin here. */
1995
Stephen Smalley79af7302015-01-21 10:54:10 -05001996static int selinux_binder_set_context_mgr(struct task_struct *mgr)
1997{
1998 u32 mysid = current_sid();
1999 u32 mgrsid = task_sid(mgr);
2000
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002001 return avc_has_perm(&selinux_state,
2002 mysid, mgrsid, SECCLASS_BINDER,
Stephen Smalley79af7302015-01-21 10:54:10 -05002003 BINDER__SET_CONTEXT_MGR, NULL);
2004}
2005
2006static int selinux_binder_transaction(struct task_struct *from,
2007 struct task_struct *to)
2008{
2009 u32 mysid = current_sid();
2010 u32 fromsid = task_sid(from);
2011 u32 tosid = task_sid(to);
2012 int rc;
2013
2014 if (mysid != fromsid) {
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002015 rc = avc_has_perm(&selinux_state,
2016 mysid, fromsid, SECCLASS_BINDER,
Stephen Smalley79af7302015-01-21 10:54:10 -05002017 BINDER__IMPERSONATE, NULL);
2018 if (rc)
2019 return rc;
2020 }
2021
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002022 return avc_has_perm(&selinux_state,
2023 fromsid, tosid, SECCLASS_BINDER, BINDER__CALL,
Stephen Smalley79af7302015-01-21 10:54:10 -05002024 NULL);
2025}
2026
2027static int selinux_binder_transfer_binder(struct task_struct *from,
2028 struct task_struct *to)
2029{
2030 u32 fromsid = task_sid(from);
2031 u32 tosid = task_sid(to);
2032
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002033 return avc_has_perm(&selinux_state,
2034 fromsid, tosid, SECCLASS_BINDER, BINDER__TRANSFER,
Stephen Smalley79af7302015-01-21 10:54:10 -05002035 NULL);
2036}
2037
2038static int selinux_binder_transfer_file(struct task_struct *from,
2039 struct task_struct *to,
2040 struct file *file)
2041{
2042 u32 sid = task_sid(to);
Casey Schauflerbb6c6b02018-09-21 17:22:32 -07002043 struct file_security_struct *fsec = selinux_file(file);
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -05002044 struct dentry *dentry = file->f_path.dentry;
Paul Moore20cdef82016-04-04 14:14:42 -04002045 struct inode_security_struct *isec;
Stephen Smalley79af7302015-01-21 10:54:10 -05002046 struct common_audit_data ad;
2047 int rc;
2048
2049 ad.type = LSM_AUDIT_DATA_PATH;
2050 ad.u.path = file->f_path;
2051
2052 if (sid != fsec->sid) {
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002053 rc = avc_has_perm(&selinux_state,
2054 sid, fsec->sid,
Stephen Smalley79af7302015-01-21 10:54:10 -05002055 SECCLASS_FD,
2056 FD__USE,
2057 &ad);
2058 if (rc)
2059 return rc;
2060 }
2061
Chenbo Fengf66e4482017-10-18 13:00:26 -07002062#ifdef CONFIG_BPF_SYSCALL
2063 rc = bpf_fd_pass(file, sid);
2064 if (rc)
2065 return rc;
2066#endif
2067
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -05002068 if (unlikely(IS_PRIVATE(d_backing_inode(dentry))))
Stephen Smalley79af7302015-01-21 10:54:10 -05002069 return 0;
2070
Paul Moore20cdef82016-04-04 14:14:42 -04002071 isec = backing_inode_security(dentry);
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002072 return avc_has_perm(&selinux_state,
2073 sid, isec->sid, isec->sclass, file_to_av(file),
Stephen Smalley79af7302015-01-21 10:54:10 -05002074 &ad);
2075}
2076
Ingo Molnar9e488582009-05-07 19:26:19 +10002077static int selinux_ptrace_access_check(struct task_struct *child,
David Howells5cd9c582008-08-14 11:37:28 +01002078 unsigned int mode)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002079{
Stephen Smalleybe0554c2017-01-09 10:07:31 -05002080 u32 sid = current_sid();
2081 u32 csid = task_sid(child);
Stephen Smalley006ebb42008-05-19 08:32:49 -04002082
Stephen Smalleybe0554c2017-01-09 10:07:31 -05002083 if (mode & PTRACE_MODE_READ)
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002084 return avc_has_perm(&selinux_state,
2085 sid, csid, SECCLASS_FILE, FILE__READ, NULL);
Stephen Smalleybe0554c2017-01-09 10:07:31 -05002086
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002087 return avc_has_perm(&selinux_state,
2088 sid, csid, SECCLASS_PROCESS, PROCESS__PTRACE, NULL);
David Howells5cd9c582008-08-14 11:37:28 +01002089}
2090
2091static int selinux_ptrace_traceme(struct task_struct *parent)
2092{
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002093 return avc_has_perm(&selinux_state,
2094 task_sid(parent), current_sid(), SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05002095 PROCESS__PTRACE, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002096}
2097
2098static int selinux_capget(struct task_struct *target, kernel_cap_t *effective,
Eric Paris828dfe12008-04-17 13:17:49 -04002099 kernel_cap_t *inheritable, kernel_cap_t *permitted)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002100{
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002101 return avc_has_perm(&selinux_state,
2102 current_sid(), task_sid(target), SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05002103 PROCESS__GETCAP, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002104}
2105
David Howellsd84f4f92008-11-14 10:39:23 +11002106static int selinux_capset(struct cred *new, const struct cred *old,
2107 const kernel_cap_t *effective,
2108 const kernel_cap_t *inheritable,
2109 const kernel_cap_t *permitted)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002110{
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002111 return avc_has_perm(&selinux_state,
2112 cred_sid(old), cred_sid(new), SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05002113 PROCESS__SETCAP, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002114}
2115
James Morris5626d3e2009-01-30 10:05:06 +11002116/*
2117 * (This comment used to live with the selinux_task_setuid hook,
2118 * which was removed).
2119 *
2120 * Since setuid only affects the current process, and since the SELinux
2121 * controls are not based on the Linux identity attributes, SELinux does not
2122 * need to control this operation. However, SELinux does control the use of
2123 * the CAP_SETUID and CAP_SETGID capabilities using the capable hook.
2124 */
2125
Eric Paris6a9de492012-01-03 12:25:14 -05002126static int selinux_capable(const struct cred *cred, struct user_namespace *ns,
Micah Mortonc1a85a02019-01-07 16:10:53 -08002127 int cap, unsigned int opts)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002128{
Micah Mortonc1a85a02019-01-07 16:10:53 -08002129 return cred_has_capability(cred, cap, opts, ns == &init_user_ns);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002130}
2131
Linus Torvalds1da177e2005-04-16 15:20:36 -07002132static int selinux_quotactl(int cmds, int type, int id, struct super_block *sb)
2133{
David Howells88e67f32008-11-14 10:39:21 +11002134 const struct cred *cred = current_cred();
Linus Torvalds1da177e2005-04-16 15:20:36 -07002135 int rc = 0;
2136
2137 if (!sb)
2138 return 0;
2139
2140 switch (cmds) {
Eric Paris828dfe12008-04-17 13:17:49 -04002141 case Q_SYNC:
2142 case Q_QUOTAON:
2143 case Q_QUOTAOFF:
2144 case Q_SETINFO:
2145 case Q_SETQUOTA:
David Howells88e67f32008-11-14 10:39:21 +11002146 rc = superblock_has_perm(cred, sb, FILESYSTEM__QUOTAMOD, NULL);
Eric Paris828dfe12008-04-17 13:17:49 -04002147 break;
2148 case Q_GETFMT:
2149 case Q_GETINFO:
2150 case Q_GETQUOTA:
David Howells88e67f32008-11-14 10:39:21 +11002151 rc = superblock_has_perm(cred, sb, FILESYSTEM__QUOTAGET, NULL);
Eric Paris828dfe12008-04-17 13:17:49 -04002152 break;
2153 default:
2154 rc = 0; /* let the kernel handle invalid cmds */
2155 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002156 }
2157 return rc;
2158}
2159
2160static int selinux_quota_on(struct dentry *dentry)
2161{
David Howells88e67f32008-11-14 10:39:21 +11002162 const struct cred *cred = current_cred();
2163
Eric Paris2875fa02011-04-28 16:04:24 -04002164 return dentry_has_perm(cred, dentry, FILE__QUOTAON);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002165}
2166
Eric Paris12b30522010-11-15 18:36:29 -05002167static int selinux_syslog(int type)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002168{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002169 switch (type) {
Kees Cookd78ca3c2010-02-03 15:37:13 -08002170 case SYSLOG_ACTION_READ_ALL: /* Read last kernel messages */
2171 case SYSLOG_ACTION_SIZE_BUFFER: /* Return size of the log buffer */
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002172 return avc_has_perm(&selinux_state,
2173 current_sid(), SECINITSID_KERNEL,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05002174 SECCLASS_SYSTEM, SYSTEM__SYSLOG_READ, NULL);
Kees Cookd78ca3c2010-02-03 15:37:13 -08002175 case SYSLOG_ACTION_CONSOLE_OFF: /* Disable logging to console */
2176 case SYSLOG_ACTION_CONSOLE_ON: /* Enable logging to console */
2177 /* Set level of messages printed to console */
2178 case SYSLOG_ACTION_CONSOLE_LEVEL:
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002179 return avc_has_perm(&selinux_state,
2180 current_sid(), SECINITSID_KERNEL,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05002181 SECCLASS_SYSTEM, SYSTEM__SYSLOG_CONSOLE,
2182 NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002183 }
Stephen Smalleybe0554c2017-01-09 10:07:31 -05002184 /* All other syslog types */
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002185 return avc_has_perm(&selinux_state,
2186 current_sid(), SECINITSID_KERNEL,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05002187 SECCLASS_SYSTEM, SYSTEM__SYSLOG_MOD, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002188}
2189
2190/*
2191 * Check that a process has enough memory to allocate a new virtual
2192 * mapping. 0 means there is enough memory for the allocation to
2193 * succeed and -ENOMEM implies there is not.
2194 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07002195 * Do not audit the selinux permission check, as this is applied to all
2196 * processes that allocate mappings.
2197 */
Alan Cox34b4e4a2007-08-22 14:01:28 -07002198static int selinux_vm_enough_memory(struct mm_struct *mm, long pages)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002199{
2200 int rc, cap_sys_admin = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002201
Casey Schauflerb1d9e6b2015-05-02 15:11:42 -07002202 rc = cred_has_capability(current_cred(), CAP_SYS_ADMIN,
Micah Mortonc1a85a02019-01-07 16:10:53 -08002203 CAP_OPT_NOAUDIT, true);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002204 if (rc == 0)
2205 cap_sys_admin = 1;
2206
Casey Schauflerb1d9e6b2015-05-02 15:11:42 -07002207 return cap_sys_admin;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002208}
2209
2210/* binprm security operations */
2211
Stephen Smalleybe0554c2017-01-09 10:07:31 -05002212static u32 ptrace_parent_sid(void)
Paul Moore0c6181c2016-03-30 21:41:21 -04002213{
2214 u32 sid = 0;
2215 struct task_struct *tracer;
2216
2217 rcu_read_lock();
Stephen Smalleybe0554c2017-01-09 10:07:31 -05002218 tracer = ptrace_parent(current);
Paul Moore0c6181c2016-03-30 21:41:21 -04002219 if (tracer)
2220 sid = task_sid(tracer);
2221 rcu_read_unlock();
2222
2223 return sid;
2224}
2225
Stephen Smalley7b0d0b42014-08-04 13:36:49 -04002226static int check_nnp_nosuid(const struct linux_binprm *bprm,
2227 const struct task_security_struct *old_tsec,
2228 const struct task_security_struct *new_tsec)
2229{
2230 int nnp = (bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS);
Andy Lutomirski380cf5b2016-06-23 16:41:05 -05002231 int nosuid = !mnt_may_suid(bprm->file->f_path.mnt);
Stephen Smalley7b0d0b42014-08-04 13:36:49 -04002232 int rc;
Stephen Smalleyaf63f412017-07-31 10:12:46 -04002233 u32 av;
Stephen Smalley7b0d0b42014-08-04 13:36:49 -04002234
2235 if (!nnp && !nosuid)
2236 return 0; /* neither NNP nor nosuid */
2237
2238 if (new_tsec->sid == old_tsec->sid)
2239 return 0; /* No change in credentials */
2240
2241 /*
Stephen Smalleyaf63f412017-07-31 10:12:46 -04002242 * If the policy enables the nnp_nosuid_transition policy capability,
2243 * then we permit transitions under NNP or nosuid if the
2244 * policy allows the corresponding permission between
2245 * the old and new contexts.
2246 */
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05002247 if (selinux_policycap_nnp_nosuid_transition()) {
Stephen Smalleyaf63f412017-07-31 10:12:46 -04002248 av = 0;
2249 if (nnp)
2250 av |= PROCESS2__NNP_TRANSITION;
2251 if (nosuid)
2252 av |= PROCESS2__NOSUID_TRANSITION;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002253 rc = avc_has_perm(&selinux_state,
2254 old_tsec->sid, new_tsec->sid,
Stephen Smalleyaf63f412017-07-31 10:12:46 -04002255 SECCLASS_PROCESS2, av, NULL);
2256 if (!rc)
2257 return 0;
2258 }
2259
2260 /*
2261 * We also permit NNP or nosuid transitions to bounded SIDs,
2262 * i.e. SIDs that are guaranteed to only be allowed a subset
2263 * of the permissions of the current SID.
Stephen Smalley7b0d0b42014-08-04 13:36:49 -04002264 */
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05002265 rc = security_bounded_transition(&selinux_state, old_tsec->sid,
2266 new_tsec->sid);
Stephen Smalleyaf63f412017-07-31 10:12:46 -04002267 if (!rc)
2268 return 0;
2269
2270 /*
2271 * On failure, preserve the errno values for NNP vs nosuid.
2272 * NNP: Operation not permitted for caller.
2273 * nosuid: Permission denied to file.
2274 */
2275 if (nnp)
2276 return -EPERM;
2277 return -EACCES;
Stephen Smalley7b0d0b42014-08-04 13:36:49 -04002278}
2279
David Howellsa6f76f22008-11-14 10:39:24 +11002280static int selinux_bprm_set_creds(struct linux_binprm *bprm)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002281{
David Howellsa6f76f22008-11-14 10:39:24 +11002282 const struct task_security_struct *old_tsec;
2283 struct task_security_struct *new_tsec;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002284 struct inode_security_struct *isec;
Thomas Liu2bf49692009-07-14 12:14:09 -04002285 struct common_audit_data ad;
Al Viro496ad9a2013-01-23 17:07:38 -05002286 struct inode *inode = file_inode(bprm->file);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002287 int rc;
2288
David Howellsa6f76f22008-11-14 10:39:24 +11002289 /* SELinux context only depends on initial program or script and not
2290 * the script interpreter */
Kees Cookddb4a142017-07-18 15:25:23 -07002291 if (bprm->called_set_creds)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002292 return 0;
2293
Casey Schaufler0c6cfa62018-09-21 17:17:16 -07002294 old_tsec = selinux_cred(current_cred());
2295 new_tsec = selinux_cred(bprm->cred);
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -05002296 isec = inode_security(inode);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002297
2298 /* Default to the current task SID. */
David Howellsa6f76f22008-11-14 10:39:24 +11002299 new_tsec->sid = old_tsec->sid;
2300 new_tsec->osid = old_tsec->sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002301
Michael LeMay28eba5b2006-06-27 02:53:42 -07002302 /* Reset fs, key, and sock SIDs on execve. */
David Howellsa6f76f22008-11-14 10:39:24 +11002303 new_tsec->create_sid = 0;
2304 new_tsec->keycreate_sid = 0;
2305 new_tsec->sockcreate_sid = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002306
David Howellsa6f76f22008-11-14 10:39:24 +11002307 if (old_tsec->exec_sid) {
2308 new_tsec->sid = old_tsec->exec_sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002309 /* Reset exec SID on execve. */
David Howellsa6f76f22008-11-14 10:39:24 +11002310 new_tsec->exec_sid = 0;
Andy Lutomirski259e5e62012-04-12 16:47:50 -05002311
Stephen Smalley7b0d0b42014-08-04 13:36:49 -04002312 /* Fail on NNP or nosuid if not an allowed transition. */
2313 rc = check_nnp_nosuid(bprm, old_tsec, new_tsec);
2314 if (rc)
2315 return rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002316 } else {
2317 /* Check for a default transition on this program. */
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05002318 rc = security_transition_sid(&selinux_state, old_tsec->sid,
2319 isec->sid, SECCLASS_PROCESS, NULL,
Eric Paris652bb9b2011-02-01 11:05:40 -05002320 &new_tsec->sid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002321 if (rc)
2322 return rc;
Stephen Smalley7b0d0b42014-08-04 13:36:49 -04002323
2324 /*
2325 * Fallback to old SID on NNP or nosuid if not an allowed
2326 * transition.
2327 */
2328 rc = check_nnp_nosuid(bprm, old_tsec, new_tsec);
2329 if (rc)
2330 new_tsec->sid = old_tsec->sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002331 }
2332
Vivek Goyal43af5de2016-09-09 11:37:49 -04002333 ad.type = LSM_AUDIT_DATA_FILE;
2334 ad.u.file = bprm->file;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002335
David Howellsa6f76f22008-11-14 10:39:24 +11002336 if (new_tsec->sid == old_tsec->sid) {
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002337 rc = avc_has_perm(&selinux_state,
2338 old_tsec->sid, isec->sid,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002339 SECCLASS_FILE, FILE__EXECUTE_NO_TRANS, &ad);
2340 if (rc)
2341 return rc;
2342 } else {
2343 /* Check permissions for the transition. */
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002344 rc = avc_has_perm(&selinux_state,
2345 old_tsec->sid, new_tsec->sid,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002346 SECCLASS_PROCESS, PROCESS__TRANSITION, &ad);
2347 if (rc)
2348 return rc;
2349
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002350 rc = avc_has_perm(&selinux_state,
2351 new_tsec->sid, isec->sid,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002352 SECCLASS_FILE, FILE__ENTRYPOINT, &ad);
2353 if (rc)
2354 return rc;
2355
David Howellsa6f76f22008-11-14 10:39:24 +11002356 /* Check for shared state */
2357 if (bprm->unsafe & LSM_UNSAFE_SHARE) {
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002358 rc = avc_has_perm(&selinux_state,
2359 old_tsec->sid, new_tsec->sid,
David Howellsa6f76f22008-11-14 10:39:24 +11002360 SECCLASS_PROCESS, PROCESS__SHARE,
2361 NULL);
2362 if (rc)
2363 return -EPERM;
2364 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002365
David Howellsa6f76f22008-11-14 10:39:24 +11002366 /* Make sure that anyone attempting to ptrace over a task that
2367 * changes its SID has the appropriate permit */
Eric W. Biederman9227dd22017-01-23 17:26:31 +13002368 if (bprm->unsafe & LSM_UNSAFE_PTRACE) {
Stephen Smalleybe0554c2017-01-09 10:07:31 -05002369 u32 ptsid = ptrace_parent_sid();
David Howellsa6f76f22008-11-14 10:39:24 +11002370 if (ptsid != 0) {
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002371 rc = avc_has_perm(&selinux_state,
2372 ptsid, new_tsec->sid,
David Howellsa6f76f22008-11-14 10:39:24 +11002373 SECCLASS_PROCESS,
2374 PROCESS__PTRACE, NULL);
2375 if (rc)
2376 return -EPERM;
2377 }
2378 }
2379
2380 /* Clear any possibly unsafe personality bits on exec: */
2381 bprm->per_clear |= PER_CLEAR_ON_SETID;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002382
Linus Torvalds1da177e2005-04-16 15:20:36 -07002383 /* Enable secure mode for SIDs transitions unless
2384 the noatsecure permission is granted between
2385 the two SIDs, i.e. ahp returns 0. */
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002386 rc = avc_has_perm(&selinux_state,
2387 old_tsec->sid, new_tsec->sid,
Kees Cook62874c32017-07-18 15:25:25 -07002388 SECCLASS_PROCESS, PROCESS__NOATSECURE,
2389 NULL);
2390 bprm->secureexec |= !!rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002391 }
2392
Kees Cook62874c32017-07-18 15:25:25 -07002393 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002394}
2395
Al Viroc3c073f2012-08-21 22:32:06 -04002396static int match_file(const void *p, struct file *file, unsigned fd)
2397{
2398 return file_has_perm(p, file, file_to_av(file)) ? fd + 1 : 0;
2399}
2400
Linus Torvalds1da177e2005-04-16 15:20:36 -07002401/* Derived from fs/exec.c:flush_old_files. */
David Howells745ca242008-11-14 10:39:22 +11002402static inline void flush_unauthorized_files(const struct cred *cred,
2403 struct files_struct *files)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002404{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002405 struct file *file, *devnull = NULL;
Stephen Smalleyb20c8122006-09-25 23:32:03 -07002406 struct tty_struct *tty;
Peter Zijlstra24ec8392006-12-08 02:36:04 -08002407 int drop_tty = 0;
Al Viroc3c073f2012-08-21 22:32:06 -04002408 unsigned n;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002409
Peter Zijlstra24ec8392006-12-08 02:36:04 -08002410 tty = get_current_tty();
Linus Torvalds1da177e2005-04-16 15:20:36 -07002411 if (tty) {
Peter Hurley4a510962016-01-09 21:35:23 -08002412 spin_lock(&tty->files_lock);
Eric Paris37dd0bd2008-10-31 17:40:00 -04002413 if (!list_empty(&tty->tty_files)) {
Nick Piggind996b622010-08-18 04:37:36 +10002414 struct tty_file_private *file_priv;
Eric Paris37dd0bd2008-10-31 17:40:00 -04002415
Linus Torvalds1da177e2005-04-16 15:20:36 -07002416 /* Revalidate access to controlling tty.
David Howells13f8e982013-06-13 23:37:55 +01002417 Use file_path_has_perm on the tty path directly
2418 rather than using file_has_perm, as this particular
2419 open file may belong to another process and we are
2420 only interested in the inode-based check here. */
Nick Piggind996b622010-08-18 04:37:36 +10002421 file_priv = list_first_entry(&tty->tty_files,
2422 struct tty_file_private, list);
2423 file = file_priv->file;
David Howells13f8e982013-06-13 23:37:55 +01002424 if (file_path_has_perm(cred, file, FILE__READ | FILE__WRITE))
Peter Zijlstra24ec8392006-12-08 02:36:04 -08002425 drop_tty = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002426 }
Peter Hurley4a510962016-01-09 21:35:23 -08002427 spin_unlock(&tty->files_lock);
Alan Cox452a00d2008-10-13 10:39:13 +01002428 tty_kref_put(tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002429 }
Eric W. Biederman98a27ba2007-05-08 00:26:56 -07002430 /* Reset controlling tty. */
2431 if (drop_tty)
2432 no_tty();
Linus Torvalds1da177e2005-04-16 15:20:36 -07002433
2434 /* Revalidate access to inherited open files. */
Al Viroc3c073f2012-08-21 22:32:06 -04002435 n = iterate_fd(files, 0, match_file, cred);
2436 if (!n) /* none found? */
2437 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002438
Al Viroc3c073f2012-08-21 22:32:06 -04002439 devnull = dentry_open(&selinux_null, O_RDWR, cred);
Al Viro45525b22012-10-16 13:30:07 -04002440 if (IS_ERR(devnull))
2441 devnull = NULL;
2442 /* replace all the matching ones with this */
2443 do {
2444 replace_fd(n - 1, devnull, 0);
2445 } while ((n = iterate_fd(files, n, match_file, cred)) != 0);
2446 if (devnull)
Al Viroc3c073f2012-08-21 22:32:06 -04002447 fput(devnull);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002448}
2449
Linus Torvalds1da177e2005-04-16 15:20:36 -07002450/*
David Howellsa6f76f22008-11-14 10:39:24 +11002451 * Prepare a process for imminent new credential changes due to exec
Linus Torvalds1da177e2005-04-16 15:20:36 -07002452 */
David Howellsa6f76f22008-11-14 10:39:24 +11002453static void selinux_bprm_committing_creds(struct linux_binprm *bprm)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002454{
David Howellsa6f76f22008-11-14 10:39:24 +11002455 struct task_security_struct *new_tsec;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002456 struct rlimit *rlim, *initrlim;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002457 int rc, i;
2458
Casey Schaufler0c6cfa62018-09-21 17:17:16 -07002459 new_tsec = selinux_cred(bprm->cred);
David Howellsa6f76f22008-11-14 10:39:24 +11002460 if (new_tsec->sid == new_tsec->osid)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002461 return;
2462
2463 /* Close files for which the new task SID is not authorized. */
David Howellsa6f76f22008-11-14 10:39:24 +11002464 flush_unauthorized_files(bprm->cred, current->files);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002465
David Howellsa6f76f22008-11-14 10:39:24 +11002466 /* Always clear parent death signal on SID transitions. */
2467 current->pdeath_signal = 0;
2468
2469 /* Check whether the new SID can inherit resource limits from the old
2470 * SID. If not, reset all soft limits to the lower of the current
2471 * task's hard limit and the init task's soft limit.
2472 *
2473 * Note that the setting of hard limits (even to lower them) can be
2474 * controlled by the setrlimit check. The inclusion of the init task's
2475 * soft limit into the computation is to avoid resetting soft limits
2476 * higher than the default soft limit for cases where the default is
2477 * lower than the hard limit, e.g. RLIMIT_CORE or RLIMIT_STACK.
2478 */
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002479 rc = avc_has_perm(&selinux_state,
2480 new_tsec->osid, new_tsec->sid, SECCLASS_PROCESS,
David Howellsa6f76f22008-11-14 10:39:24 +11002481 PROCESS__RLIMITINH, NULL);
2482 if (rc) {
Oleg Nesteroveb2d55a2010-06-23 22:43:32 +02002483 /* protect against do_prlimit() */
2484 task_lock(current);
David Howellsa6f76f22008-11-14 10:39:24 +11002485 for (i = 0; i < RLIM_NLIMITS; i++) {
2486 rlim = current->signal->rlim + i;
2487 initrlim = init_task.signal->rlim + i;
2488 rlim->rlim_cur = min(rlim->rlim_max, initrlim->rlim_cur);
2489 }
Oleg Nesteroveb2d55a2010-06-23 22:43:32 +02002490 task_unlock(current);
Nicolas Pitrebaa73d92016-11-11 00:10:10 -05002491 if (IS_ENABLED(CONFIG_POSIX_TIMERS))
2492 update_rlimit_cpu(current, rlimit(RLIMIT_CPU));
David Howellsa6f76f22008-11-14 10:39:24 +11002493 }
2494}
2495
2496/*
2497 * Clean up the process immediately after the installation of new credentials
2498 * due to exec
2499 */
2500static void selinux_bprm_committed_creds(struct linux_binprm *bprm)
2501{
Casey Schaufler0c6cfa62018-09-21 17:17:16 -07002502 const struct task_security_struct *tsec = selinux_cred(current_cred());
David Howellsa6f76f22008-11-14 10:39:24 +11002503 struct itimerval itimer;
David Howellsa6f76f22008-11-14 10:39:24 +11002504 u32 osid, sid;
2505 int rc, i;
David Howellsa6f76f22008-11-14 10:39:24 +11002506
David Howellsa6f76f22008-11-14 10:39:24 +11002507 osid = tsec->osid;
2508 sid = tsec->sid;
2509
2510 if (sid == osid)
2511 return;
2512
2513 /* Check whether the new SID can inherit signal state from the old SID.
2514 * If not, clear itimers to avoid subsequent signal generation and
2515 * flush and unblock signals.
2516 *
2517 * This must occur _after_ the task SID has been updated so that any
2518 * kill done after the flush will be checked against the new SID.
2519 */
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002520 rc = avc_has_perm(&selinux_state,
2521 osid, sid, SECCLASS_PROCESS, PROCESS__SIGINH, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002522 if (rc) {
Nicolas Pitrebaa73d92016-11-11 00:10:10 -05002523 if (IS_ENABLED(CONFIG_POSIX_TIMERS)) {
2524 memset(&itimer, 0, sizeof itimer);
2525 for (i = 0; i < 3; i++)
2526 do_setitimer(i, &itimer, NULL);
2527 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002528 spin_lock_irq(&current->sighand->siglock);
Oleg Nesterov9e7c8f82015-06-04 16:22:16 -04002529 if (!fatal_signal_pending(current)) {
2530 flush_sigqueue(&current->pending);
2531 flush_sigqueue(&current->signal->shared_pending);
David Howells3bcac022009-04-29 13:45:05 +01002532 flush_signal_handlers(current, 1);
2533 sigemptyset(&current->blocked);
Oleg Nesterov9e7c8f82015-06-04 16:22:16 -04002534 recalc_sigpending();
David Howells3bcac022009-04-29 13:45:05 +01002535 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002536 spin_unlock_irq(&current->sighand->siglock);
2537 }
2538
David Howellsa6f76f22008-11-14 10:39:24 +11002539 /* Wake up the parent if it is waiting so that it can recheck
2540 * wait permission to the new task SID. */
Oleg Nesterovecd6de32009-04-29 16:02:24 +02002541 read_lock(&tasklist_lock);
Oleg Nesterov0b7570e2009-09-23 15:56:46 -07002542 __wake_up_parent(current, current->real_parent);
Oleg Nesterovecd6de32009-04-29 16:02:24 +02002543 read_unlock(&tasklist_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002544}
2545
2546/* superblock security operations */
2547
2548static int selinux_sb_alloc_security(struct super_block *sb)
2549{
2550 return superblock_alloc_security(sb);
2551}
2552
2553static void selinux_sb_free_security(struct super_block *sb)
2554{
2555 superblock_free_security(sb);
2556}
2557
Al Viro99dbbb52018-12-14 21:56:23 -05002558static inline int opt_len(const char *s)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002559{
Al Viro99dbbb52018-12-14 21:56:23 -05002560 bool open_quote = false;
2561 int len;
2562 char c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002563
Al Viro99dbbb52018-12-14 21:56:23 -05002564 for (len = 0; (c = s[len]) != '\0'; len++) {
2565 if (c == '"')
Cory Olmo3528a952006-09-29 01:58:44 -07002566 open_quote = !open_quote;
Al Viro99dbbb52018-12-14 21:56:23 -05002567 if (c == ',' && !open_quote)
2568 break;
2569 }
2570 return len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002571}
2572
Al Viro204cc0c2018-12-13 13:41:47 -05002573static int selinux_sb_eat_lsm_opts(char *options, void **mnt_opts)
Eric Paris026eb162011-03-03 16:09:14 -05002574{
Al Viro99dbbb52018-12-14 21:56:23 -05002575 char *from = options;
2576 char *to = options;
2577 bool first = true;
Al Viro5b400232018-12-12 20:13:29 -05002578
Al Viro99dbbb52018-12-14 21:56:23 -05002579 while (1) {
2580 int len = opt_len(from);
2581 int token, rc;
2582 char *arg = NULL;
2583
2584 token = match_opt_prefix(from, len, &arg);
2585
2586 if (token != Opt_error) {
2587 char *p, *q;
2588
2589 /* strip quotes */
2590 if (arg) {
2591 for (p = q = arg; p < from + len; p++) {
2592 char c = *p;
2593 if (c != '"')
2594 *q++ = c;
2595 }
2596 arg = kmemdup_nul(arg, q - arg, GFP_KERNEL);
2597 }
2598 rc = selinux_add_opt(token, arg, mnt_opts);
2599 if (unlikely(rc)) {
2600 kfree(arg);
2601 if (*mnt_opts) {
2602 selinux_free_mnt_opts(*mnt_opts);
2603 *mnt_opts = NULL;
2604 }
2605 return rc;
2606 }
2607 } else {
2608 if (!first) { // copy with preceding comma
2609 from--;
2610 len++;
2611 }
2612 if (to != from)
2613 memmove(to, from, len);
2614 to += len;
2615 first = false;
2616 }
2617 if (!from[len])
2618 break;
2619 from += len + 1;
2620 }
2621 *to = '\0';
2622 return 0;
Al Viro5b400232018-12-12 20:13:29 -05002623}
2624
Al Viro204cc0c2018-12-13 13:41:47 -05002625static int selinux_sb_remount(struct super_block *sb, void *mnt_opts)
Eric Paris026eb162011-03-03 16:09:14 -05002626{
Al Virobd323652018-12-13 15:04:59 -05002627 struct selinux_mnt_opts *opts = mnt_opts;
Eric Paris026eb162011-03-03 16:09:14 -05002628 struct superblock_security_struct *sbsec = sb->s_security;
Al Virobd323652018-12-13 15:04:59 -05002629 u32 sid;
2630 int rc;
Eric Paris026eb162011-03-03 16:09:14 -05002631
2632 if (!(sbsec->flags & SE_SBINITIALIZED))
2633 return 0;
2634
Al Viro204cc0c2018-12-13 13:41:47 -05002635 if (!opts)
Eric Paris026eb162011-03-03 16:09:14 -05002636 return 0;
2637
Al Virobd323652018-12-13 15:04:59 -05002638 if (opts->fscontext) {
2639 rc = parse_sid(sb, opts->fscontext, &sid);
2640 if (rc)
Al Viroc039bc32018-12-01 23:06:57 -05002641 return rc;
Al Virobd323652018-12-13 15:04:59 -05002642 if (bad_option(sbsec, FSCONTEXT_MNT, sbsec->sid, sid))
2643 goto out_bad_option;
Eric Paris026eb162011-03-03 16:09:14 -05002644 }
Al Virobd323652018-12-13 15:04:59 -05002645 if (opts->context) {
2646 rc = parse_sid(sb, opts->context, &sid);
2647 if (rc)
2648 return rc;
2649 if (bad_option(sbsec, CONTEXT_MNT, sbsec->mntpoint_sid, sid))
2650 goto out_bad_option;
2651 }
2652 if (opts->rootcontext) {
2653 struct inode_security_struct *root_isec;
2654 root_isec = backing_inode_security(sb->s_root);
2655 rc = parse_sid(sb, opts->rootcontext, &sid);
2656 if (rc)
2657 return rc;
2658 if (bad_option(sbsec, ROOTCONTEXT_MNT, root_isec->sid, sid))
2659 goto out_bad_option;
2660 }
2661 if (opts->defcontext) {
2662 rc = parse_sid(sb, opts->defcontext, &sid);
2663 if (rc)
2664 return rc;
2665 if (bad_option(sbsec, DEFCONTEXT_MNT, sbsec->def_sid, sid))
2666 goto out_bad_option;
Eric Paris026eb162011-03-03 16:09:14 -05002667 }
Al Viroc039bc32018-12-01 23:06:57 -05002668 return 0;
Eric Paris026eb162011-03-03 16:09:14 -05002669
Eric Paris026eb162011-03-03 16:09:14 -05002670out_bad_option:
peter enderborgc103a912018-06-12 10:09:03 +02002671 pr_warn("SELinux: unable to change security options "
Linus Torvalds29b1deb2013-12-15 11:17:45 -08002672 "during remount (dev %s, type=%s)\n", sb->s_id,
2673 sb->s_type->name);
Al Viroc039bc32018-12-01 23:06:57 -05002674 return -EINVAL;
Eric Paris026eb162011-03-03 16:09:14 -05002675}
2676
Al Viroa10d7c22018-12-05 11:58:35 -05002677static int selinux_sb_kern_mount(struct super_block *sb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002678{
David Howells88e67f32008-11-14 10:39:21 +11002679 const struct cred *cred = current_cred();
Thomas Liu2bf49692009-07-14 12:14:09 -04002680 struct common_audit_data ad;
James Morris74192242008-12-19 11:41:10 +11002681
Eric Paris50c205f2012-04-04 15:01:43 -04002682 ad.type = LSM_AUDIT_DATA_DENTRY;
Eric Parisa2694342011-04-25 13:10:27 -04002683 ad.u.dentry = sb->s_root;
David Howells88e67f32008-11-14 10:39:21 +11002684 return superblock_has_perm(cred, sb, FILESYSTEM__MOUNT, &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002685}
2686
David Howells726c3342006-06-23 02:02:58 -07002687static int selinux_sb_statfs(struct dentry *dentry)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002688{
David Howells88e67f32008-11-14 10:39:21 +11002689 const struct cred *cred = current_cred();
Thomas Liu2bf49692009-07-14 12:14:09 -04002690 struct common_audit_data ad;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002691
Eric Paris50c205f2012-04-04 15:01:43 -04002692 ad.type = LSM_AUDIT_DATA_DENTRY;
Eric Parisa2694342011-04-25 13:10:27 -04002693 ad.u.dentry = dentry->d_sb->s_root;
David Howells88e67f32008-11-14 10:39:21 +11002694 return superblock_has_perm(cred, dentry->d_sb, FILESYSTEM__GETATTR, &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002695}
2696
Al Viro808d4e32012-10-11 11:42:01 -04002697static int selinux_mount(const char *dev_name,
Al Viro8a04c432016-03-25 14:52:53 -04002698 const struct path *path,
Al Viro808d4e32012-10-11 11:42:01 -04002699 const char *type,
Eric Paris828dfe12008-04-17 13:17:49 -04002700 unsigned long flags,
2701 void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002702{
David Howells88e67f32008-11-14 10:39:21 +11002703 const struct cred *cred = current_cred();
Linus Torvalds1da177e2005-04-16 15:20:36 -07002704
2705 if (flags & MS_REMOUNT)
Al Virod8c95842011-12-07 18:16:57 -05002706 return superblock_has_perm(cred, path->dentry->d_sb,
Eric Paris828dfe12008-04-17 13:17:49 -04002707 FILESYSTEM__REMOUNT, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002708 else
Eric Paris2875fa02011-04-28 16:04:24 -04002709 return path_has_perm(cred, path, FILE__MOUNTON);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002710}
2711
2712static int selinux_umount(struct vfsmount *mnt, int flags)
2713{
David Howells88e67f32008-11-14 10:39:21 +11002714 const struct cred *cred = current_cred();
Linus Torvalds1da177e2005-04-16 15:20:36 -07002715
David Howells88e67f32008-11-14 10:39:21 +11002716 return superblock_has_perm(cred, mnt->mnt_sb,
Eric Paris828dfe12008-04-17 13:17:49 -04002717 FILESYSTEM__UNMOUNT, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002718}
2719
2720/* inode security operations */
2721
2722static int selinux_inode_alloc_security(struct inode *inode)
2723{
2724 return inode_alloc_security(inode);
2725}
2726
2727static void selinux_inode_free_security(struct inode *inode)
2728{
2729 inode_free_security(inode);
2730}
2731
David Quigleyd47be3d2013-05-22 12:50:34 -04002732static int selinux_dentry_init_security(struct dentry *dentry, int mode,
Al Viro4f3ccd72016-07-20 16:06:15 -04002733 const struct qstr *name, void **ctx,
David Quigleyd47be3d2013-05-22 12:50:34 -04002734 u32 *ctxlen)
2735{
David Quigleyd47be3d2013-05-22 12:50:34 -04002736 u32 newsid;
2737 int rc;
2738
Casey Schaufler0c6cfa62018-09-21 17:17:16 -07002739 rc = selinux_determine_inode_label(selinux_cred(current_cred()),
Vivek Goyalc957f6d2016-07-13 10:44:51 -04002740 d_inode(dentry->d_parent), name,
David Howellsc3c188b2015-07-10 17:19:58 -04002741 inode_mode_to_security_class(mode),
2742 &newsid);
2743 if (rc)
2744 return rc;
David Quigleyd47be3d2013-05-22 12:50:34 -04002745
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05002746 return security_sid_to_context(&selinux_state, newsid, (char **)ctx,
2747 ctxlen);
David Quigleyd47be3d2013-05-22 12:50:34 -04002748}
2749
Vivek Goyala518b0a2016-07-13 10:44:53 -04002750static int selinux_dentry_create_files_as(struct dentry *dentry, int mode,
2751 struct qstr *name,
2752 const struct cred *old,
2753 struct cred *new)
2754{
2755 u32 newsid;
2756 int rc;
2757 struct task_security_struct *tsec;
2758
Casey Schaufler0c6cfa62018-09-21 17:17:16 -07002759 rc = selinux_determine_inode_label(selinux_cred(old),
Vivek Goyala518b0a2016-07-13 10:44:53 -04002760 d_inode(dentry->d_parent), name,
2761 inode_mode_to_security_class(mode),
2762 &newsid);
2763 if (rc)
2764 return rc;
2765
Casey Schaufler0c6cfa62018-09-21 17:17:16 -07002766 tsec = selinux_cred(new);
Vivek Goyala518b0a2016-07-13 10:44:53 -04002767 tsec->create_sid = newsid;
2768 return 0;
2769}
2770
Stephen Smalley5e41ff92005-09-09 13:01:35 -07002771static int selinux_inode_init_security(struct inode *inode, struct inode *dir,
Tetsuo Handa95489062013-07-25 05:44:02 +09002772 const struct qstr *qstr,
2773 const char **name,
Eric Paris2a7dba32011-02-01 11:05:39 -05002774 void **value, size_t *len)
Stephen Smalley5e41ff92005-09-09 13:01:35 -07002775{
Casey Schaufler0c6cfa62018-09-21 17:17:16 -07002776 const struct task_security_struct *tsec = selinux_cred(current_cred());
Stephen Smalley5e41ff92005-09-09 13:01:35 -07002777 struct superblock_security_struct *sbsec;
Corentin LABBEc0d4f462017-10-04 20:32:17 +02002778 u32 newsid, clen;
Stephen Smalley5e41ff92005-09-09 13:01:35 -07002779 int rc;
Tetsuo Handa95489062013-07-25 05:44:02 +09002780 char *context;
Stephen Smalley5e41ff92005-09-09 13:01:35 -07002781
Stephen Smalley5e41ff92005-09-09 13:01:35 -07002782 sbsec = dir->i_sb->s_security;
Stephen Smalley5e41ff92005-09-09 13:01:35 -07002783
David Howells275bb412008-11-14 10:39:19 +11002784 newsid = tsec->create_sid;
2785
Casey Schaufler0c6cfa62018-09-21 17:17:16 -07002786 rc = selinux_determine_inode_label(selinux_cred(current_cred()),
David Howellsc3c188b2015-07-10 17:19:58 -04002787 dir, qstr,
2788 inode_mode_to_security_class(inode->i_mode),
2789 &newsid);
2790 if (rc)
2791 return rc;
Stephen Smalley5e41ff92005-09-09 13:01:35 -07002792
Eric Paris296fddf2006-09-25 23:32:00 -07002793 /* Possibly defer initialization to selinux_complete_init. */
David P. Quigley0d90a7e2009-01-16 09:22:02 -05002794 if (sbsec->flags & SE_SBINITIALIZED) {
Casey Schaufler80788c22018-09-21 17:19:11 -07002795 struct inode_security_struct *isec = selinux_inode(inode);
Eric Paris296fddf2006-09-25 23:32:00 -07002796 isec->sclass = inode_mode_to_security_class(inode->i_mode);
2797 isec->sid = newsid;
Andreas Gruenbacher6f3be9f2015-12-24 11:09:40 -05002798 isec->initialized = LABEL_INITIALIZED;
Eric Paris296fddf2006-09-25 23:32:00 -07002799 }
Stephen Smalley5e41ff92005-09-09 13:01:35 -07002800
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05002801 if (!selinux_state.initialized || !(sbsec->flags & SBLABEL_MNT))
Stephen Smalley25a74f32005-11-08 21:34:33 -08002802 return -EOPNOTSUPP;
2803
Tetsuo Handa95489062013-07-25 05:44:02 +09002804 if (name)
2805 *name = XATTR_SELINUX_SUFFIX;
Stephen Smalley570bc1c2005-09-09 13:01:43 -07002806
2807 if (value && len) {
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05002808 rc = security_sid_to_context_force(&selinux_state, newsid,
2809 &context, &clen);
Tetsuo Handa95489062013-07-25 05:44:02 +09002810 if (rc)
Stephen Smalley570bc1c2005-09-09 13:01:43 -07002811 return rc;
Stephen Smalley570bc1c2005-09-09 13:01:43 -07002812 *value = context;
2813 *len = clen;
2814 }
Stephen Smalley5e41ff92005-09-09 13:01:35 -07002815
Stephen Smalley5e41ff92005-09-09 13:01:35 -07002816 return 0;
2817}
2818
Al Viro4acdaf22011-07-26 01:42:34 -04002819static int selinux_inode_create(struct inode *dir, struct dentry *dentry, umode_t mode)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002820{
2821 return may_create(dir, dentry, SECCLASS_FILE);
2822}
2823
Linus Torvalds1da177e2005-04-16 15:20:36 -07002824static int selinux_inode_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry)
2825{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002826 return may_link(dir, old_dentry, MAY_LINK);
2827}
2828
Linus Torvalds1da177e2005-04-16 15:20:36 -07002829static int selinux_inode_unlink(struct inode *dir, struct dentry *dentry)
2830{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002831 return may_link(dir, dentry, MAY_UNLINK);
2832}
2833
2834static int selinux_inode_symlink(struct inode *dir, struct dentry *dentry, const char *name)
2835{
2836 return may_create(dir, dentry, SECCLASS_LNK_FILE);
2837}
2838
Al Viro18bb1db2011-07-26 01:41:39 -04002839static int selinux_inode_mkdir(struct inode *dir, struct dentry *dentry, umode_t mask)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002840{
2841 return may_create(dir, dentry, SECCLASS_DIR);
2842}
2843
Linus Torvalds1da177e2005-04-16 15:20:36 -07002844static int selinux_inode_rmdir(struct inode *dir, struct dentry *dentry)
2845{
2846 return may_link(dir, dentry, MAY_RMDIR);
2847}
2848
Al Viro1a67aaf2011-07-26 01:52:52 -04002849static int selinux_inode_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002850{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002851 return may_create(dir, dentry, inode_mode_to_security_class(mode));
2852}
2853
Linus Torvalds1da177e2005-04-16 15:20:36 -07002854static int selinux_inode_rename(struct inode *old_inode, struct dentry *old_dentry,
Eric Paris828dfe12008-04-17 13:17:49 -04002855 struct inode *new_inode, struct dentry *new_dentry)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002856{
2857 return may_rename(old_inode, old_dentry, new_inode, new_dentry);
2858}
2859
Linus Torvalds1da177e2005-04-16 15:20:36 -07002860static int selinux_inode_readlink(struct dentry *dentry)
2861{
David Howells88e67f32008-11-14 10:39:21 +11002862 const struct cred *cred = current_cred();
2863
Eric Paris2875fa02011-04-28 16:04:24 -04002864 return dentry_has_perm(cred, dentry, FILE__READ);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002865}
2866
NeilBrownbda0be72015-03-23 13:37:39 +11002867static int selinux_inode_follow_link(struct dentry *dentry, struct inode *inode,
2868 bool rcu)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002869{
David Howells88e67f32008-11-14 10:39:21 +11002870 const struct cred *cred = current_cred();
NeilBrownbda0be72015-03-23 13:37:39 +11002871 struct common_audit_data ad;
2872 struct inode_security_struct *isec;
2873 u32 sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002874
NeilBrownbda0be72015-03-23 13:37:39 +11002875 validate_creds(cred);
2876
2877 ad.type = LSM_AUDIT_DATA_DENTRY;
2878 ad.u.dentry = dentry;
2879 sid = cred_sid(cred);
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -05002880 isec = inode_security_rcu(inode, rcu);
2881 if (IS_ERR(isec))
2882 return PTR_ERR(isec);
NeilBrownbda0be72015-03-23 13:37:39 +11002883
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002884 return avc_has_perm_flags(&selinux_state,
2885 sid, isec->sid, isec->sclass, FILE__READ, &ad,
NeilBrownbda0be72015-03-23 13:37:39 +11002886 rcu ? MAY_NOT_BLOCK : 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002887}
2888
Eric Parisd4cf970d2012-04-04 15:01:42 -04002889static noinline int audit_inode_permission(struct inode *inode,
2890 u32 perms, u32 audited, u32 denied,
Stephen Smalley626b9742014-04-29 11:29:04 -07002891 int result,
Eric Parisd4cf970d2012-04-04 15:01:42 -04002892 unsigned flags)
2893{
2894 struct common_audit_data ad;
Casey Schaufler80788c22018-09-21 17:19:11 -07002895 struct inode_security_struct *isec = selinux_inode(inode);
Eric Parisd4cf970d2012-04-04 15:01:42 -04002896 int rc;
2897
Eric Paris50c205f2012-04-04 15:01:43 -04002898 ad.type = LSM_AUDIT_DATA_INODE;
Eric Parisd4cf970d2012-04-04 15:01:42 -04002899 ad.u.inode = inode;
2900
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002901 rc = slow_avc_audit(&selinux_state,
2902 current_sid(), isec->sid, isec->sclass, perms,
Stephen Smalley626b9742014-04-29 11:29:04 -07002903 audited, denied, result, &ad, flags);
Eric Parisd4cf970d2012-04-04 15:01:42 -04002904 if (rc)
2905 return rc;
2906 return 0;
2907}
2908
Al Viroe74f71e2011-06-20 19:38:15 -04002909static int selinux_inode_permission(struct inode *inode, int mask)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002910{
David Howells88e67f32008-11-14 10:39:21 +11002911 const struct cred *cred = current_cred();
Eric Parisb782e0a2010-07-23 11:44:03 -04002912 u32 perms;
2913 bool from_access;
Al Virocf1dd1d2011-06-20 19:44:08 -04002914 unsigned flags = mask & MAY_NOT_BLOCK;
Eric Paris2e3340572012-04-04 15:01:42 -04002915 struct inode_security_struct *isec;
2916 u32 sid;
2917 struct av_decision avd;
2918 int rc, rc2;
2919 u32 audited, denied;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002920
Eric Parisb782e0a2010-07-23 11:44:03 -04002921 from_access = mask & MAY_ACCESS;
Eric Parisd09ca732010-07-23 11:43:57 -04002922 mask &= (MAY_READ|MAY_WRITE|MAY_EXEC|MAY_APPEND);
2923
Eric Parisb782e0a2010-07-23 11:44:03 -04002924 /* No permission to check. Existence test. */
2925 if (!mask)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002926 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002927
Eric Paris2e3340572012-04-04 15:01:42 -04002928 validate_creds(cred);
Eric Parisb782e0a2010-07-23 11:44:03 -04002929
Eric Paris2e3340572012-04-04 15:01:42 -04002930 if (unlikely(IS_PRIVATE(inode)))
2931 return 0;
Eric Parisb782e0a2010-07-23 11:44:03 -04002932
2933 perms = file_mask_to_av(inode->i_mode, mask);
2934
Eric Paris2e3340572012-04-04 15:01:42 -04002935 sid = cred_sid(cred);
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -05002936 isec = inode_security_rcu(inode, flags & MAY_NOT_BLOCK);
2937 if (IS_ERR(isec))
2938 return PTR_ERR(isec);
Eric Paris2e3340572012-04-04 15:01:42 -04002939
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002940 rc = avc_has_perm_noaudit(&selinux_state,
2941 sid, isec->sid, isec->sclass, perms, 0, &avd);
Eric Paris2e3340572012-04-04 15:01:42 -04002942 audited = avc_audit_required(perms, &avd, rc,
2943 from_access ? FILE__AUDIT_ACCESS : 0,
2944 &denied);
2945 if (likely(!audited))
2946 return rc;
2947
Stephen Smalley626b9742014-04-29 11:29:04 -07002948 rc2 = audit_inode_permission(inode, perms, audited, denied, rc, flags);
Eric Paris2e3340572012-04-04 15:01:42 -04002949 if (rc2)
2950 return rc2;
2951 return rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002952}
2953
2954static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr)
2955{
David Howells88e67f32008-11-14 10:39:21 +11002956 const struct cred *cred = current_cred();
Stephen Smalleyccb54472017-05-12 12:41:24 -04002957 struct inode *inode = d_backing_inode(dentry);
Amerigo Wangbc6a6002009-08-20 19:29:02 -07002958 unsigned int ia_valid = iattr->ia_valid;
Eric Paris95dbf732012-04-04 13:45:34 -04002959 __u32 av = FILE__WRITE;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002960
Amerigo Wangbc6a6002009-08-20 19:29:02 -07002961 /* ATTR_FORCE is just used for ATTR_KILL_S[UG]ID. */
2962 if (ia_valid & ATTR_FORCE) {
2963 ia_valid &= ~(ATTR_KILL_SUID | ATTR_KILL_SGID | ATTR_MODE |
2964 ATTR_FORCE);
2965 if (!ia_valid)
2966 return 0;
2967 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002968
Amerigo Wangbc6a6002009-08-20 19:29:02 -07002969 if (ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID |
2970 ATTR_ATIME_SET | ATTR_MTIME_SET | ATTR_TIMES_SET))
Eric Paris2875fa02011-04-28 16:04:24 -04002971 return dentry_has_perm(cred, dentry, FILE__SETATTR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002972
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05002973 if (selinux_policycap_openperm() &&
Stephen Smalleyccb54472017-05-12 12:41:24 -04002974 inode->i_sb->s_magic != SOCKFS_MAGIC &&
2975 (ia_valid & ATTR_SIZE) &&
2976 !(ia_valid & ATTR_FILE))
Eric Paris95dbf732012-04-04 13:45:34 -04002977 av |= FILE__OPEN;
2978
2979 return dentry_has_perm(cred, dentry, av);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002980}
2981
Al Viro3f7036a2015-03-08 19:28:30 -04002982static int selinux_inode_getattr(const struct path *path)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002983{
Al Viro3f7036a2015-03-08 19:28:30 -04002984 return path_has_perm(current_cred(), path, FILE__GETATTR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002985}
2986
Stephen Smalleydb590002017-04-20 11:31:30 -04002987static bool has_cap_mac_admin(bool audit)
2988{
2989 const struct cred *cred = current_cred();
Micah Mortonc1a85a02019-01-07 16:10:53 -08002990 unsigned int opts = audit ? CAP_OPT_NONE : CAP_OPT_NOAUDIT;
Stephen Smalleydb590002017-04-20 11:31:30 -04002991
Micah Mortonc1a85a02019-01-07 16:10:53 -08002992 if (cap_capable(cred, &init_user_ns, CAP_MAC_ADMIN, opts))
Stephen Smalleydb590002017-04-20 11:31:30 -04002993 return false;
Micah Mortonc1a85a02019-01-07 16:10:53 -08002994 if (cred_has_capability(cred, CAP_MAC_ADMIN, opts, true))
Stephen Smalleydb590002017-04-20 11:31:30 -04002995 return false;
2996 return true;
2997}
2998
David Howells8f0cfa52008-04-29 00:59:41 -07002999static int selinux_inode_setxattr(struct dentry *dentry, const char *name,
3000 const void *value, size_t size, int flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003001{
David Howellsc6f493d2015-03-17 22:26:22 +00003002 struct inode *inode = d_backing_inode(dentry);
Paul Moore20cdef82016-04-04 14:14:42 -04003003 struct inode_security_struct *isec;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003004 struct superblock_security_struct *sbsec;
Thomas Liu2bf49692009-07-14 12:14:09 -04003005 struct common_audit_data ad;
David Howells275bb412008-11-14 10:39:19 +11003006 u32 newsid, sid = current_sid();
Linus Torvalds1da177e2005-04-16 15:20:36 -07003007 int rc = 0;
3008
Eric W. Biederman6b240302017-10-02 09:38:20 -05003009 if (strcmp(name, XATTR_NAME_SELINUX)) {
3010 rc = cap_inode_setxattr(dentry, name, value, size, flags);
3011 if (rc)
3012 return rc;
3013
3014 /* Not an attribute we recognize, so just check the
3015 ordinary setattr permission. */
3016 return dentry_has_perm(current_cred(), dentry, FILE__SETATTR);
3017 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003018
3019 sbsec = inode->i_sb->s_security;
Eric Paris12f348b2012-10-09 10:56:25 -04003020 if (!(sbsec->flags & SBLABEL_MNT))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003021 return -EOPNOTSUPP;
3022
Serge E. Hallyn2e149672011-03-23 16:43:26 -07003023 if (!inode_owner_or_capable(inode))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003024 return -EPERM;
3025
Eric Paris50c205f2012-04-04 15:01:43 -04003026 ad.type = LSM_AUDIT_DATA_DENTRY;
Eric Parisa2694342011-04-25 13:10:27 -04003027 ad.u.dentry = dentry;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003028
Paul Moore20cdef82016-04-04 14:14:42 -04003029 isec = backing_inode_security(dentry);
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003030 rc = avc_has_perm(&selinux_state,
3031 sid, isec->sid, isec->sclass,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003032 FILE__RELABELFROM, &ad);
3033 if (rc)
3034 return rc;
3035
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05003036 rc = security_context_to_sid(&selinux_state, value, size, &newsid,
3037 GFP_KERNEL);
Stephen Smalley12b29f32008-05-07 13:03:20 -04003038 if (rc == -EINVAL) {
Stephen Smalleydb590002017-04-20 11:31:30 -04003039 if (!has_cap_mac_admin(true)) {
Eric Parisd6ea83e2012-04-04 13:45:49 -04003040 struct audit_buffer *ab;
3041 size_t audit_size;
Eric Parisd6ea83e2012-04-04 13:45:49 -04003042
3043 /* We strip a nul only if it is at the end, otherwise the
3044 * context contains a nul and we should audit that */
Al Viroe3fea3f2012-06-09 08:15:16 +01003045 if (value) {
Colin Ian Kingadd24372017-10-14 13:46:55 +01003046 const char *str = value;
3047
Al Viroe3fea3f2012-06-09 08:15:16 +01003048 if (str[size - 1] == '\0')
3049 audit_size = size - 1;
3050 else
3051 audit_size = size;
3052 } else {
Al Viroe3fea3f2012-06-09 08:15:16 +01003053 audit_size = 0;
3054 }
Richard Guy Briggscdfb6b32018-05-12 21:58:20 -04003055 ab = audit_log_start(audit_context(),
3056 GFP_ATOMIC, AUDIT_SELINUX_ERR);
Eric Parisd6ea83e2012-04-04 13:45:49 -04003057 audit_log_format(ab, "op=setxattr invalid_context=");
3058 audit_log_n_untrustedstring(ab, value, audit_size);
3059 audit_log_end(ab);
3060
Stephen Smalley12b29f32008-05-07 13:03:20 -04003061 return rc;
Eric Parisd6ea83e2012-04-04 13:45:49 -04003062 }
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05003063 rc = security_context_to_sid_force(&selinux_state, value,
3064 size, &newsid);
Stephen Smalley12b29f32008-05-07 13:03:20 -04003065 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003066 if (rc)
3067 return rc;
3068
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003069 rc = avc_has_perm(&selinux_state,
3070 sid, newsid, isec->sclass,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003071 FILE__RELABELTO, &ad);
3072 if (rc)
3073 return rc;
3074
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05003075 rc = security_validate_transition(&selinux_state, isec->sid, newsid,
3076 sid, isec->sclass);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003077 if (rc)
3078 return rc;
3079
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003080 return avc_has_perm(&selinux_state,
3081 newsid,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003082 sbsec->sid,
3083 SECCLASS_FILESYSTEM,
3084 FILESYSTEM__ASSOCIATE,
3085 &ad);
3086}
3087
David Howells8f0cfa52008-04-29 00:59:41 -07003088static void selinux_inode_post_setxattr(struct dentry *dentry, const char *name,
Eric Parisf52697102008-05-14 11:27:45 -04003089 const void *value, size_t size,
David Howells8f0cfa52008-04-29 00:59:41 -07003090 int flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003091{
David Howellsc6f493d2015-03-17 22:26:22 +00003092 struct inode *inode = d_backing_inode(dentry);
Paul Moore20cdef82016-04-04 14:14:42 -04003093 struct inode_security_struct *isec;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003094 u32 newsid;
3095 int rc;
3096
3097 if (strcmp(name, XATTR_NAME_SELINUX)) {
3098 /* Not an attribute we recognize, so nothing to do. */
3099 return;
3100 }
3101
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05003102 rc = security_context_to_sid_force(&selinux_state, value, size,
3103 &newsid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003104 if (rc) {
peter enderborgc103a912018-06-12 10:09:03 +02003105 pr_err("SELinux: unable to map context to SID"
Stephen Smalley12b29f32008-05-07 13:03:20 -04003106 "for (%s, %lu), rc=%d\n",
3107 inode->i_sb->s_id, inode->i_ino, -rc);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003108 return;
3109 }
3110
Paul Moore20cdef82016-04-04 14:14:42 -04003111 isec = backing_inode_security(dentry);
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01003112 spin_lock(&isec->lock);
David Quigleyaa9c2662013-05-22 12:50:44 -04003113 isec->sclass = inode_mode_to_security_class(inode->i_mode);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003114 isec->sid = newsid;
Andreas Gruenbacher6f3be9f2015-12-24 11:09:40 -05003115 isec->initialized = LABEL_INITIALIZED;
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01003116 spin_unlock(&isec->lock);
David Quigleyaa9c2662013-05-22 12:50:44 -04003117
Linus Torvalds1da177e2005-04-16 15:20:36 -07003118 return;
3119}
3120
David Howells8f0cfa52008-04-29 00:59:41 -07003121static int selinux_inode_getxattr(struct dentry *dentry, const char *name)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003122{
David Howells88e67f32008-11-14 10:39:21 +11003123 const struct cred *cred = current_cred();
3124
Eric Paris2875fa02011-04-28 16:04:24 -04003125 return dentry_has_perm(cred, dentry, FILE__GETATTR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003126}
3127
Eric Paris828dfe12008-04-17 13:17:49 -04003128static int selinux_inode_listxattr(struct dentry *dentry)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003129{
David Howells88e67f32008-11-14 10:39:21 +11003130 const struct cred *cred = current_cred();
3131
Eric Paris2875fa02011-04-28 16:04:24 -04003132 return dentry_has_perm(cred, dentry, FILE__GETATTR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003133}
3134
David Howells8f0cfa52008-04-29 00:59:41 -07003135static int selinux_inode_removexattr(struct dentry *dentry, const char *name)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003136{
Eric W. Biederman6b240302017-10-02 09:38:20 -05003137 if (strcmp(name, XATTR_NAME_SELINUX)) {
3138 int rc = cap_inode_removexattr(dentry, name);
3139 if (rc)
3140 return rc;
3141
3142 /* Not an attribute we recognize, so just check the
3143 ordinary setattr permission. */
3144 return dentry_has_perm(current_cred(), dentry, FILE__SETATTR);
3145 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003146
3147 /* No one is allowed to remove a SELinux security label.
3148 You can change the label, but all data must be labeled. */
3149 return -EACCES;
3150}
3151
James Morrisd381d8a2005-10-30 14:59:22 -08003152/*
Stephen Smalleyabc69bb2008-05-21 14:16:12 -04003153 * Copy the inode security context value to the user.
James Morrisd381d8a2005-10-30 14:59:22 -08003154 *
3155 * Permission check is handled by selinux_inode_getxattr hook.
3156 */
Andreas Gruenbacherea861dfd2015-12-24 11:09:39 -05003157static int selinux_inode_getsecurity(struct inode *inode, const char *name, void **buffer, bool alloc)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003158{
David P. Quigley42492592008-02-04 22:29:39 -08003159 u32 size;
3160 int error;
3161 char *context = NULL;
Paul Moore20cdef82016-04-04 14:14:42 -04003162 struct inode_security_struct *isec;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003163
Dustin Kirkland8c8570f2005-11-03 17:15:16 +00003164 if (strcmp(name, XATTR_SELINUX_SUFFIX))
3165 return -EOPNOTSUPP;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003166
Stephen Smalleyabc69bb2008-05-21 14:16:12 -04003167 /*
3168 * If the caller has CAP_MAC_ADMIN, then get the raw context
3169 * value even if it is not defined by current policy; otherwise,
3170 * use the in-core value under current policy.
3171 * Use the non-auditing forms of the permission checks since
3172 * getxattr may be called by unprivileged processes commonly
3173 * and lack of permission just means that we fall back to the
3174 * in-core context value, not a denial.
3175 */
Paul Moore20cdef82016-04-04 14:14:42 -04003176 isec = inode_security(inode);
Stephen Smalleydb590002017-04-20 11:31:30 -04003177 if (has_cap_mac_admin(false))
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05003178 error = security_sid_to_context_force(&selinux_state,
3179 isec->sid, &context,
Stephen Smalleyabc69bb2008-05-21 14:16:12 -04003180 &size);
3181 else
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05003182 error = security_sid_to_context(&selinux_state, isec->sid,
3183 &context, &size);
David P. Quigley42492592008-02-04 22:29:39 -08003184 if (error)
3185 return error;
3186 error = size;
3187 if (alloc) {
3188 *buffer = context;
3189 goto out_nofree;
3190 }
3191 kfree(context);
3192out_nofree:
3193 return error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003194}
3195
3196static int selinux_inode_setsecurity(struct inode *inode, const char *name,
Eric Paris828dfe12008-04-17 13:17:49 -04003197 const void *value, size_t size, int flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003198{
Paul Moore2c971652016-04-19 16:36:28 -04003199 struct inode_security_struct *isec = inode_security_novalidate(inode);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003200 u32 newsid;
3201 int rc;
3202
3203 if (strcmp(name, XATTR_SELINUX_SUFFIX))
3204 return -EOPNOTSUPP;
3205
3206 if (!value || !size)
3207 return -EACCES;
3208
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05003209 rc = security_context_to_sid(&selinux_state, value, size, &newsid,
3210 GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003211 if (rc)
3212 return rc;
3213
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01003214 spin_lock(&isec->lock);
David Quigleyaa9c2662013-05-22 12:50:44 -04003215 isec->sclass = inode_mode_to_security_class(inode->i_mode);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003216 isec->sid = newsid;
Andreas Gruenbacher6f3be9f2015-12-24 11:09:40 -05003217 isec->initialized = LABEL_INITIALIZED;
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01003218 spin_unlock(&isec->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003219 return 0;
3220}
3221
3222static int selinux_inode_listsecurity(struct inode *inode, char *buffer, size_t buffer_size)
3223{
3224 const int len = sizeof(XATTR_NAME_SELINUX);
3225 if (buffer && len <= buffer_size)
3226 memcpy(buffer, XATTR_NAME_SELINUX, len);
3227 return len;
3228}
3229
Andreas Gruenbacherd6335d72015-12-24 11:09:39 -05003230static void selinux_inode_getsecid(struct inode *inode, u32 *secid)
Ahmed S. Darwish713a04ae2008-03-01 21:52:30 +02003231{
Andreas Gruenbachere817c2f2016-02-18 12:04:08 +01003232 struct inode_security_struct *isec = inode_security_novalidate(inode);
Ahmed S. Darwish713a04ae2008-03-01 21:52:30 +02003233 *secid = isec->sid;
3234}
3235
Vivek Goyal56909eb2016-07-13 10:44:48 -04003236static int selinux_inode_copy_up(struct dentry *src, struct cred **new)
3237{
3238 u32 sid;
3239 struct task_security_struct *tsec;
3240 struct cred *new_creds = *new;
3241
3242 if (new_creds == NULL) {
3243 new_creds = prepare_creds();
3244 if (!new_creds)
3245 return -ENOMEM;
3246 }
3247
Casey Schaufler0c6cfa62018-09-21 17:17:16 -07003248 tsec = selinux_cred(new_creds);
Vivek Goyal56909eb2016-07-13 10:44:48 -04003249 /* Get label from overlay inode and set it in create_sid */
3250 selinux_inode_getsecid(d_inode(src), &sid);
3251 tsec->create_sid = sid;
3252 *new = new_creds;
3253 return 0;
3254}
3255
Vivek Goyal19472b62016-07-13 10:44:50 -04003256static int selinux_inode_copy_up_xattr(const char *name)
3257{
3258 /* The copy_up hook above sets the initial context on an inode, but we
3259 * don't then want to overwrite it by blindly copying all the lower
3260 * xattrs up. Instead, we have to filter out SELinux-related xattrs.
3261 */
3262 if (strcmp(name, XATTR_NAME_SELINUX) == 0)
3263 return 1; /* Discard */
3264 /*
3265 * Any other attribute apart from SELINUX is not claimed, supported
3266 * by selinux.
3267 */
3268 return -EOPNOTSUPP;
3269}
3270
Linus Torvalds1da177e2005-04-16 15:20:36 -07003271/* file security operations */
3272
Yuichi Nakamura788e7dd2007-09-14 09:27:07 +09003273static int selinux_revalidate_file_permission(struct file *file, int mask)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003274{
David Howells88e67f32008-11-14 10:39:21 +11003275 const struct cred *cred = current_cred();
Al Viro496ad9a2013-01-23 17:07:38 -05003276 struct inode *inode = file_inode(file);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003277
Linus Torvalds1da177e2005-04-16 15:20:36 -07003278 /* file_mask_to_av won't add FILE__WRITE if MAY_APPEND is set */
3279 if ((file->f_flags & O_APPEND) && (mask & MAY_WRITE))
3280 mask |= MAY_APPEND;
3281
Paul Moore389fb8002009-03-27 17:10:34 -04003282 return file_has_perm(cred, file,
3283 file_mask_to_av(inode->i_mode, mask));
Linus Torvalds1da177e2005-04-16 15:20:36 -07003284}
3285
Yuichi Nakamura788e7dd2007-09-14 09:27:07 +09003286static int selinux_file_permission(struct file *file, int mask)
3287{
Al Viro496ad9a2013-01-23 17:07:38 -05003288 struct inode *inode = file_inode(file);
Casey Schauflerbb6c6b02018-09-21 17:22:32 -07003289 struct file_security_struct *fsec = selinux_file(file);
Andreas Gruenbacherb1973672016-01-05 23:12:33 +01003290 struct inode_security_struct *isec;
Stephen Smalley20dda182009-06-22 14:54:53 -04003291 u32 sid = current_sid();
3292
Paul Moore389fb8002009-03-27 17:10:34 -04003293 if (!mask)
Yuichi Nakamura788e7dd2007-09-14 09:27:07 +09003294 /* No permission to check. Existence test. */
3295 return 0;
Yuichi Nakamura788e7dd2007-09-14 09:27:07 +09003296
Andreas Gruenbacherb1973672016-01-05 23:12:33 +01003297 isec = inode_security(inode);
Stephen Smalley20dda182009-06-22 14:54:53 -04003298 if (sid == fsec->sid && fsec->isid == isec->sid &&
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003299 fsec->pseqno == avc_policy_seqno(&selinux_state))
Eric Paris83d49852012-04-04 13:45:40 -04003300 /* No change since file_open check. */
Stephen Smalley20dda182009-06-22 14:54:53 -04003301 return 0;
3302
Yuichi Nakamura788e7dd2007-09-14 09:27:07 +09003303 return selinux_revalidate_file_permission(file, mask);
3304}
3305
Linus Torvalds1da177e2005-04-16 15:20:36 -07003306static int selinux_file_alloc_security(struct file *file)
3307{
3308 return file_alloc_security(file);
3309}
3310
Jeff Vander Stoepfa1aa142015-07-10 17:19:56 -04003311/*
3312 * Check whether a task has the ioctl permission and cmd
3313 * operation to an inode.
3314 */
Geliang Tang1d2a1682015-10-21 17:44:27 -04003315static int ioctl_has_perm(const struct cred *cred, struct file *file,
Jeff Vander Stoepfa1aa142015-07-10 17:19:56 -04003316 u32 requested, u16 cmd)
3317{
3318 struct common_audit_data ad;
Casey Schauflerbb6c6b02018-09-21 17:22:32 -07003319 struct file_security_struct *fsec = selinux_file(file);
Jeff Vander Stoepfa1aa142015-07-10 17:19:56 -04003320 struct inode *inode = file_inode(file);
Paul Moore20cdef82016-04-04 14:14:42 -04003321 struct inode_security_struct *isec;
Jeff Vander Stoepfa1aa142015-07-10 17:19:56 -04003322 struct lsm_ioctlop_audit ioctl;
3323 u32 ssid = cred_sid(cred);
3324 int rc;
3325 u8 driver = cmd >> 8;
3326 u8 xperm = cmd & 0xff;
3327
3328 ad.type = LSM_AUDIT_DATA_IOCTL_OP;
3329 ad.u.op = &ioctl;
3330 ad.u.op->cmd = cmd;
3331 ad.u.op->path = file->f_path;
3332
3333 if (ssid != fsec->sid) {
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003334 rc = avc_has_perm(&selinux_state,
3335 ssid, fsec->sid,
Jeff Vander Stoepfa1aa142015-07-10 17:19:56 -04003336 SECCLASS_FD,
3337 FD__USE,
3338 &ad);
3339 if (rc)
3340 goto out;
3341 }
3342
3343 if (unlikely(IS_PRIVATE(inode)))
3344 return 0;
3345
Paul Moore20cdef82016-04-04 14:14:42 -04003346 isec = inode_security(inode);
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003347 rc = avc_has_extended_perms(&selinux_state,
3348 ssid, isec->sid, isec->sclass,
3349 requested, driver, xperm, &ad);
Jeff Vander Stoepfa1aa142015-07-10 17:19:56 -04003350out:
3351 return rc;
3352}
3353
Linus Torvalds1da177e2005-04-16 15:20:36 -07003354static int selinux_file_ioctl(struct file *file, unsigned int cmd,
3355 unsigned long arg)
3356{
David Howells88e67f32008-11-14 10:39:21 +11003357 const struct cred *cred = current_cred();
Eric Paris0b24dcb2011-02-25 15:39:20 -05003358 int error = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003359
Eric Paris0b24dcb2011-02-25 15:39:20 -05003360 switch (cmd) {
3361 case FIONREAD:
3362 /* fall through */
3363 case FIBMAP:
3364 /* fall through */
3365 case FIGETBSZ:
3366 /* fall through */
Al Viro2f99c362012-03-23 16:04:05 -04003367 case FS_IOC_GETFLAGS:
Eric Paris0b24dcb2011-02-25 15:39:20 -05003368 /* fall through */
Al Viro2f99c362012-03-23 16:04:05 -04003369 case FS_IOC_GETVERSION:
Eric Paris0b24dcb2011-02-25 15:39:20 -05003370 error = file_has_perm(cred, file, FILE__GETATTR);
3371 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003372
Al Viro2f99c362012-03-23 16:04:05 -04003373 case FS_IOC_SETFLAGS:
Eric Paris0b24dcb2011-02-25 15:39:20 -05003374 /* fall through */
Al Viro2f99c362012-03-23 16:04:05 -04003375 case FS_IOC_SETVERSION:
Eric Paris0b24dcb2011-02-25 15:39:20 -05003376 error = file_has_perm(cred, file, FILE__SETATTR);
3377 break;
3378
3379 /* sys_ioctl() checks */
3380 case FIONBIO:
3381 /* fall through */
3382 case FIOASYNC:
3383 error = file_has_perm(cred, file, 0);
3384 break;
3385
3386 case KDSKBENT:
3387 case KDSKBSENT:
Eric Paris6a9de492012-01-03 12:25:14 -05003388 error = cred_has_capability(cred, CAP_SYS_TTY_CONFIG,
Micah Mortonc1a85a02019-01-07 16:10:53 -08003389 CAP_OPT_NONE, true);
Eric Paris0b24dcb2011-02-25 15:39:20 -05003390 break;
3391
3392 /* default case assumes that the command will go
3393 * to the file's ioctl() function.
3394 */
3395 default:
Jeff Vander Stoepfa1aa142015-07-10 17:19:56 -04003396 error = ioctl_has_perm(cred, file, FILE__IOCTL, (u16) cmd);
Eric Paris0b24dcb2011-02-25 15:39:20 -05003397 }
3398 return error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003399}
3400
Stephen Smalleyfcaaade2010-04-28 15:57:57 -04003401static int default_noexec;
3402
Linus Torvalds1da177e2005-04-16 15:20:36 -07003403static int file_map_prot_check(struct file *file, unsigned long prot, int shared)
3404{
David Howells88e67f32008-11-14 10:39:21 +11003405 const struct cred *cred = current_cred();
Stephen Smalleybe0554c2017-01-09 10:07:31 -05003406 u32 sid = cred_sid(cred);
David Howellsd84f4f92008-11-14 10:39:23 +11003407 int rc = 0;
David Howells88e67f32008-11-14 10:39:21 +11003408
Stephen Smalleyfcaaade2010-04-28 15:57:57 -04003409 if (default_noexec &&
Stephen Smalley892e8ca2015-07-10 09:40:59 -04003410 (prot & PROT_EXEC) && (!file || IS_PRIVATE(file_inode(file)) ||
3411 (!shared && (prot & PROT_WRITE)))) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003412 /*
3413 * We are making executable an anonymous mapping or a
3414 * private file mapping that will also be writable.
3415 * This has an additional check.
3416 */
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003417 rc = avc_has_perm(&selinux_state,
3418 sid, sid, SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05003419 PROCESS__EXECMEM, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003420 if (rc)
David Howellsd84f4f92008-11-14 10:39:23 +11003421 goto error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003422 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003423
3424 if (file) {
3425 /* read access is always possible with a mapping */
3426 u32 av = FILE__READ;
3427
3428 /* write access only matters if the mapping is shared */
3429 if (shared && (prot & PROT_WRITE))
3430 av |= FILE__WRITE;
3431
3432 if (prot & PROT_EXEC)
3433 av |= FILE__EXECUTE;
3434
David Howells88e67f32008-11-14 10:39:21 +11003435 return file_has_perm(cred, file, av);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003436 }
David Howellsd84f4f92008-11-14 10:39:23 +11003437
3438error:
3439 return rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003440}
3441
Al Viroe5467852012-05-30 13:30:51 -04003442static int selinux_mmap_addr(unsigned long addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003443{
Casey Schauflerb1d9e6b2015-05-02 15:11:42 -07003444 int rc = 0;
Paul Moore98883bf2014-03-19 16:46:11 -04003445
3446 if (addr < CONFIG_LSM_MMAP_MIN_ADDR) {
3447 u32 sid = current_sid();
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003448 rc = avc_has_perm(&selinux_state,
3449 sid, sid, SECCLASS_MEMPROTECT,
Paul Moore98883bf2014-03-19 16:46:11 -04003450 MEMPROTECT__MMAP_ZERO, NULL);
3451 }
3452
3453 return rc;
Al Viroe5467852012-05-30 13:30:51 -04003454}
Linus Torvalds1da177e2005-04-16 15:20:36 -07003455
Al Viroe5467852012-05-30 13:30:51 -04003456static int selinux_mmap_file(struct file *file, unsigned long reqprot,
3457 unsigned long prot, unsigned long flags)
3458{
Stephen Smalley3ba4bf52017-05-05 09:14:48 -04003459 struct common_audit_data ad;
3460 int rc;
3461
3462 if (file) {
3463 ad.type = LSM_AUDIT_DATA_FILE;
3464 ad.u.file = file;
3465 rc = inode_has_perm(current_cred(), file_inode(file),
3466 FILE__MAP, &ad);
3467 if (rc)
3468 return rc;
3469 }
3470
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05003471 if (selinux_state.checkreqprot)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003472 prot = reqprot;
3473
3474 return file_map_prot_check(file, prot,
3475 (flags & MAP_TYPE) == MAP_SHARED);
3476}
3477
3478static int selinux_file_mprotect(struct vm_area_struct *vma,
3479 unsigned long reqprot,
3480 unsigned long prot)
3481{
David Howells88e67f32008-11-14 10:39:21 +11003482 const struct cred *cred = current_cred();
Stephen Smalleybe0554c2017-01-09 10:07:31 -05003483 u32 sid = cred_sid(cred);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003484
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05003485 if (selinux_state.checkreqprot)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003486 prot = reqprot;
3487
Stephen Smalleyfcaaade2010-04-28 15:57:57 -04003488 if (default_noexec &&
3489 (prot & PROT_EXEC) && !(vma->vm_flags & VM_EXEC)) {
James Morrisd541bbe2009-01-29 12:19:51 +11003490 int rc = 0;
Stephen Smalleydb4c96412006-02-01 03:05:54 -08003491 if (vma->vm_start >= vma->vm_mm->start_brk &&
3492 vma->vm_end <= vma->vm_mm->brk) {
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003493 rc = avc_has_perm(&selinux_state,
3494 sid, sid, SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05003495 PROCESS__EXECHEAP, NULL);
Stephen Smalleydb4c96412006-02-01 03:05:54 -08003496 } else if (!vma->vm_file &&
Stephen Smalleyc2316db2016-04-08 13:55:03 -04003497 ((vma->vm_start <= vma->vm_mm->start_stack &&
3498 vma->vm_end >= vma->vm_mm->start_stack) ||
Andy Lutomirskid17af502016-09-30 10:58:58 -07003499 vma_is_stack_for_current(vma))) {
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003500 rc = avc_has_perm(&selinux_state,
3501 sid, sid, SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05003502 PROCESS__EXECSTACK, NULL);
Stephen Smalleydb4c96412006-02-01 03:05:54 -08003503 } else if (vma->vm_file && vma->anon_vma) {
3504 /*
3505 * We are making executable a file mapping that has
3506 * had some COW done. Since pages might have been
3507 * written, check ability to execute the possibly
3508 * modified content. This typically should only
3509 * occur for text relocations.
3510 */
David Howellsd84f4f92008-11-14 10:39:23 +11003511 rc = file_has_perm(cred, vma->vm_file, FILE__EXECMOD);
Stephen Smalleydb4c96412006-02-01 03:05:54 -08003512 }
Lorenzo Hernandez García-Hierro6b992192005-06-25 14:54:34 -07003513 if (rc)
3514 return rc;
3515 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003516
3517 return file_map_prot_check(vma->vm_file, prot, vma->vm_flags&VM_SHARED);
3518}
3519
3520static int selinux_file_lock(struct file *file, unsigned int cmd)
3521{
David Howells88e67f32008-11-14 10:39:21 +11003522 const struct cred *cred = current_cred();
3523
3524 return file_has_perm(cred, file, FILE__LOCK);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003525}
3526
3527static int selinux_file_fcntl(struct file *file, unsigned int cmd,
3528 unsigned long arg)
3529{
David Howells88e67f32008-11-14 10:39:21 +11003530 const struct cred *cred = current_cred();
Linus Torvalds1da177e2005-04-16 15:20:36 -07003531 int err = 0;
3532
3533 switch (cmd) {
Eric Paris828dfe12008-04-17 13:17:49 -04003534 case F_SETFL:
Eric Paris828dfe12008-04-17 13:17:49 -04003535 if ((file->f_flags & O_APPEND) && !(arg & O_APPEND)) {
David Howells88e67f32008-11-14 10:39:21 +11003536 err = file_has_perm(cred, file, FILE__WRITE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003537 break;
Eric Paris828dfe12008-04-17 13:17:49 -04003538 }
3539 /* fall through */
3540 case F_SETOWN:
3541 case F_SETSIG:
3542 case F_GETFL:
3543 case F_GETOWN:
3544 case F_GETSIG:
Cyrill Gorcunov1d151c32012-07-30 14:43:00 -07003545 case F_GETOWNER_UIDS:
Eric Paris828dfe12008-04-17 13:17:49 -04003546 /* Just check FD__USE permission */
David Howells88e67f32008-11-14 10:39:21 +11003547 err = file_has_perm(cred, file, 0);
Eric Paris828dfe12008-04-17 13:17:49 -04003548 break;
3549 case F_GETLK:
3550 case F_SETLK:
3551 case F_SETLKW:
Jeff Layton0d3f7a22014-04-22 08:23:58 -04003552 case F_OFD_GETLK:
3553 case F_OFD_SETLK:
3554 case F_OFD_SETLKW:
Linus Torvalds1da177e2005-04-16 15:20:36 -07003555#if BITS_PER_LONG == 32
Eric Paris828dfe12008-04-17 13:17:49 -04003556 case F_GETLK64:
3557 case F_SETLK64:
3558 case F_SETLKW64:
Linus Torvalds1da177e2005-04-16 15:20:36 -07003559#endif
David Howells88e67f32008-11-14 10:39:21 +11003560 err = file_has_perm(cred, file, FILE__LOCK);
Eric Paris828dfe12008-04-17 13:17:49 -04003561 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003562 }
3563
3564 return err;
3565}
3566
Jeff Laytone0b93ed2014-08-22 11:27:32 -04003567static void selinux_file_set_fowner(struct file *file)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003568{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003569 struct file_security_struct *fsec;
3570
Casey Schauflerbb6c6b02018-09-21 17:22:32 -07003571 fsec = selinux_file(file);
David Howells275bb412008-11-14 10:39:19 +11003572 fsec->fown_sid = current_sid();
Linus Torvalds1da177e2005-04-16 15:20:36 -07003573}
3574
3575static int selinux_file_send_sigiotask(struct task_struct *tsk,
3576 struct fown_struct *fown, int signum)
3577{
Eric Paris828dfe12008-04-17 13:17:49 -04003578 struct file *file;
Stephen Smalley65c90bc2009-05-04 15:43:18 -04003579 u32 sid = task_sid(tsk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003580 u32 perm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003581 struct file_security_struct *fsec;
3582
3583 /* struct fown_struct is never outside the context of a struct file */
Eric Paris828dfe12008-04-17 13:17:49 -04003584 file = container_of(fown, struct file, f_owner);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003585
Casey Schauflerbb6c6b02018-09-21 17:22:32 -07003586 fsec = selinux_file(file);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003587
3588 if (!signum)
3589 perm = signal_to_av(SIGIO); /* as per send_sigio_to_task */
3590 else
3591 perm = signal_to_av(signum);
3592
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003593 return avc_has_perm(&selinux_state,
3594 fsec->fown_sid, sid,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003595 SECCLASS_PROCESS, perm, NULL);
3596}
3597
3598static int selinux_file_receive(struct file *file)
3599{
David Howells88e67f32008-11-14 10:39:21 +11003600 const struct cred *cred = current_cred();
3601
3602 return file_has_perm(cred, file, file_to_av(file));
Linus Torvalds1da177e2005-04-16 15:20:36 -07003603}
3604
Al Viro94817692018-07-10 14:13:18 -04003605static int selinux_file_open(struct file *file)
Yuichi Nakamura788e7dd2007-09-14 09:27:07 +09003606{
3607 struct file_security_struct *fsec;
Yuichi Nakamura788e7dd2007-09-14 09:27:07 +09003608 struct inode_security_struct *isec;
David Howellsd84f4f92008-11-14 10:39:23 +11003609
Casey Schauflerbb6c6b02018-09-21 17:22:32 -07003610 fsec = selinux_file(file);
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -05003611 isec = inode_security(file_inode(file));
Yuichi Nakamura788e7dd2007-09-14 09:27:07 +09003612 /*
3613 * Save inode label and policy sequence number
3614 * at open-time so that selinux_file_permission
3615 * can determine whether revalidation is necessary.
3616 * Task label is already saved in the file security
3617 * struct as its SID.
3618 */
3619 fsec->isid = isec->sid;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003620 fsec->pseqno = avc_policy_seqno(&selinux_state);
Yuichi Nakamura788e7dd2007-09-14 09:27:07 +09003621 /*
3622 * Since the inode label or policy seqno may have changed
3623 * between the selinux_inode_permission check and the saving
3624 * of state above, recheck that access is still permitted.
3625 * Otherwise, access might never be revalidated against the
3626 * new inode label or new policy.
3627 * This check is not redundant - do not remove.
3628 */
Al Viro94817692018-07-10 14:13:18 -04003629 return file_path_has_perm(file->f_cred, file, open_file_to_av(file));
Yuichi Nakamura788e7dd2007-09-14 09:27:07 +09003630}
3631
Linus Torvalds1da177e2005-04-16 15:20:36 -07003632/* task security operations */
3633
Tetsuo Handaa79be232017-03-28 23:08:45 +09003634static int selinux_task_alloc(struct task_struct *task,
3635 unsigned long clone_flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003636{
Stephen Smalleybe0554c2017-01-09 10:07:31 -05003637 u32 sid = current_sid();
3638
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003639 return avc_has_perm(&selinux_state,
3640 sid, sid, SECCLASS_PROCESS, PROCESS__FORK, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003641}
3642
David Howellsf1752ee2008-11-14 10:39:17 +11003643/*
David Howellsd84f4f92008-11-14 10:39:23 +11003644 * prepare a new set of credentials for modification
3645 */
3646static int selinux_cred_prepare(struct cred *new, const struct cred *old,
3647 gfp_t gfp)
3648{
Casey Schauflerbbd36622018-11-12 09:30:56 -08003649 const struct task_security_struct *old_tsec = selinux_cred(old);
3650 struct task_security_struct *tsec = selinux_cred(new);
David Howellsd84f4f92008-11-14 10:39:23 +11003651
Casey Schauflerbbd36622018-11-12 09:30:56 -08003652 *tsec = *old_tsec;
David Howellsd84f4f92008-11-14 10:39:23 +11003653 return 0;
3654}
3655
3656/*
David Howellsee18d642009-09-02 09:14:21 +01003657 * transfer the SELinux data to a blank set of creds
3658 */
3659static void selinux_cred_transfer(struct cred *new, const struct cred *old)
3660{
Casey Schaufler0c6cfa62018-09-21 17:17:16 -07003661 const struct task_security_struct *old_tsec = selinux_cred(old);
3662 struct task_security_struct *tsec = selinux_cred(new);
David Howellsee18d642009-09-02 09:14:21 +01003663
3664 *tsec = *old_tsec;
3665}
3666
Matthew Garrett3ec30112018-01-08 13:36:19 -08003667static void selinux_cred_getsecid(const struct cred *c, u32 *secid)
3668{
3669 *secid = cred_sid(c);
3670}
3671
David Howellsee18d642009-09-02 09:14:21 +01003672/*
David Howells3a3b7ce2008-11-14 10:39:28 +11003673 * set the security data for a kernel service
3674 * - all the creation contexts are set to unlabelled
3675 */
3676static int selinux_kernel_act_as(struct cred *new, u32 secid)
3677{
Casey Schaufler0c6cfa62018-09-21 17:17:16 -07003678 struct task_security_struct *tsec = selinux_cred(new);
David Howells3a3b7ce2008-11-14 10:39:28 +11003679 u32 sid = current_sid();
3680 int ret;
3681
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003682 ret = avc_has_perm(&selinux_state,
3683 sid, secid,
David Howells3a3b7ce2008-11-14 10:39:28 +11003684 SECCLASS_KERNEL_SERVICE,
3685 KERNEL_SERVICE__USE_AS_OVERRIDE,
3686 NULL);
3687 if (ret == 0) {
3688 tsec->sid = secid;
3689 tsec->create_sid = 0;
3690 tsec->keycreate_sid = 0;
3691 tsec->sockcreate_sid = 0;
3692 }
3693 return ret;
3694}
3695
3696/*
3697 * set the file creation context in a security record to the same as the
3698 * objective context of the specified inode
3699 */
3700static int selinux_kernel_create_files_as(struct cred *new, struct inode *inode)
3701{
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -05003702 struct inode_security_struct *isec = inode_security(inode);
Casey Schaufler0c6cfa62018-09-21 17:17:16 -07003703 struct task_security_struct *tsec = selinux_cred(new);
David Howells3a3b7ce2008-11-14 10:39:28 +11003704 u32 sid = current_sid();
3705 int ret;
3706
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003707 ret = avc_has_perm(&selinux_state,
3708 sid, isec->sid,
David Howells3a3b7ce2008-11-14 10:39:28 +11003709 SECCLASS_KERNEL_SERVICE,
3710 KERNEL_SERVICE__CREATE_FILES_AS,
3711 NULL);
3712
3713 if (ret == 0)
3714 tsec->create_sid = isec->sid;
David Howellsef574712010-02-26 01:56:16 +00003715 return ret;
David Howells3a3b7ce2008-11-14 10:39:28 +11003716}
3717
Eric Parisdd8dbf22009-11-03 16:35:32 +11003718static int selinux_kernel_module_request(char *kmod_name)
Eric Paris25354c42009-08-13 09:45:03 -04003719{
Eric Parisdd8dbf22009-11-03 16:35:32 +11003720 struct common_audit_data ad;
3721
Eric Paris50c205f2012-04-04 15:01:43 -04003722 ad.type = LSM_AUDIT_DATA_KMOD;
Eric Parisdd8dbf22009-11-03 16:35:32 +11003723 ad.u.kmod_name = kmod_name;
3724
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003725 return avc_has_perm(&selinux_state,
3726 current_sid(), SECINITSID_KERNEL, SECCLASS_SYSTEM,
Eric Parisdd8dbf22009-11-03 16:35:32 +11003727 SYSTEM__MODULE_REQUEST, &ad);
Eric Paris25354c42009-08-13 09:45:03 -04003728}
3729
Jeff Vander Stoep61d612ea2016-04-05 13:06:27 -07003730static int selinux_kernel_module_from_file(struct file *file)
3731{
3732 struct common_audit_data ad;
3733 struct inode_security_struct *isec;
3734 struct file_security_struct *fsec;
3735 u32 sid = current_sid();
3736 int rc;
3737
3738 /* init_module */
3739 if (file == NULL)
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003740 return avc_has_perm(&selinux_state,
3741 sid, sid, SECCLASS_SYSTEM,
Jeff Vander Stoep61d612ea2016-04-05 13:06:27 -07003742 SYSTEM__MODULE_LOAD, NULL);
3743
3744 /* finit_module */
Paul Moore20cdef82016-04-04 14:14:42 -04003745
Vivek Goyal43af5de2016-09-09 11:37:49 -04003746 ad.type = LSM_AUDIT_DATA_FILE;
3747 ad.u.file = file;
Jeff Vander Stoep61d612ea2016-04-05 13:06:27 -07003748
Casey Schauflerbb6c6b02018-09-21 17:22:32 -07003749 fsec = selinux_file(file);
Jeff Vander Stoep61d612ea2016-04-05 13:06:27 -07003750 if (sid != fsec->sid) {
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003751 rc = avc_has_perm(&selinux_state,
3752 sid, fsec->sid, SECCLASS_FD, FD__USE, &ad);
Jeff Vander Stoep61d612ea2016-04-05 13:06:27 -07003753 if (rc)
3754 return rc;
3755 }
3756
Paul Moore20cdef82016-04-04 14:14:42 -04003757 isec = inode_security(file_inode(file));
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003758 return avc_has_perm(&selinux_state,
3759 sid, isec->sid, SECCLASS_SYSTEM,
Jeff Vander Stoep61d612ea2016-04-05 13:06:27 -07003760 SYSTEM__MODULE_LOAD, &ad);
3761}
3762
3763static int selinux_kernel_read_file(struct file *file,
3764 enum kernel_read_file_id id)
3765{
3766 int rc = 0;
3767
3768 switch (id) {
3769 case READING_MODULE:
3770 rc = selinux_kernel_module_from_file(file);
3771 break;
3772 default:
3773 break;
3774 }
3775
3776 return rc;
3777}
3778
Mimi Zoharc77b8cd2018-07-13 14:06:02 -04003779static int selinux_kernel_load_data(enum kernel_load_data_id id)
3780{
3781 int rc = 0;
3782
3783 switch (id) {
3784 case LOADING_MODULE:
3785 rc = selinux_kernel_module_from_file(NULL);
3786 default:
3787 break;
3788 }
3789
3790 return rc;
3791}
3792
Linus Torvalds1da177e2005-04-16 15:20:36 -07003793static int selinux_task_setpgid(struct task_struct *p, pid_t pgid)
3794{
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003795 return avc_has_perm(&selinux_state,
3796 current_sid(), task_sid(p), SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05003797 PROCESS__SETPGID, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003798}
3799
3800static int selinux_task_getpgid(struct task_struct *p)
3801{
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003802 return avc_has_perm(&selinux_state,
3803 current_sid(), task_sid(p), SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05003804 PROCESS__GETPGID, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003805}
3806
3807static int selinux_task_getsid(struct task_struct *p)
3808{
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003809 return avc_has_perm(&selinux_state,
3810 current_sid(), task_sid(p), SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05003811 PROCESS__GETSESSION, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003812}
3813
David Quigleyf9008e4c2006-06-30 01:55:46 -07003814static void selinux_task_getsecid(struct task_struct *p, u32 *secid)
3815{
David Howells275bb412008-11-14 10:39:19 +11003816 *secid = task_sid(p);
David Quigleyf9008e4c2006-06-30 01:55:46 -07003817}
3818
Linus Torvalds1da177e2005-04-16 15:20:36 -07003819static int selinux_task_setnice(struct task_struct *p, int nice)
3820{
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003821 return avc_has_perm(&selinux_state,
3822 current_sid(), task_sid(p), SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05003823 PROCESS__SETSCHED, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003824}
3825
James Morris03e68062006-06-23 02:03:58 -07003826static int selinux_task_setioprio(struct task_struct *p, int ioprio)
3827{
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003828 return avc_has_perm(&selinux_state,
3829 current_sid(), task_sid(p), SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05003830 PROCESS__SETSCHED, NULL);
James Morris03e68062006-06-23 02:03:58 -07003831}
3832
David Quigleya1836a42006-06-30 01:55:49 -07003833static int selinux_task_getioprio(struct task_struct *p)
3834{
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003835 return avc_has_perm(&selinux_state,
3836 current_sid(), task_sid(p), SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05003837 PROCESS__GETSCHED, NULL);
David Quigleya1836a42006-06-30 01:55:49 -07003838}
3839
Corentin LABBE42985552017-10-04 20:32:18 +02003840static int selinux_task_prlimit(const struct cred *cred, const struct cred *tcred,
3841 unsigned int flags)
Stephen Smalley791ec492017-02-17 07:57:00 -05003842{
3843 u32 av = 0;
3844
Stephen Smalley84e68852017-02-28 09:35:08 -05003845 if (!flags)
3846 return 0;
Stephen Smalley791ec492017-02-17 07:57:00 -05003847 if (flags & LSM_PRLIMIT_WRITE)
3848 av |= PROCESS__SETRLIMIT;
3849 if (flags & LSM_PRLIMIT_READ)
3850 av |= PROCESS__GETRLIMIT;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003851 return avc_has_perm(&selinux_state,
3852 cred_sid(cred), cred_sid(tcred),
Stephen Smalley791ec492017-02-17 07:57:00 -05003853 SECCLASS_PROCESS, av, NULL);
3854}
3855
Jiri Slaby8fd00b42009-08-26 18:41:16 +02003856static int selinux_task_setrlimit(struct task_struct *p, unsigned int resource,
3857 struct rlimit *new_rlim)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003858{
Jiri Slaby8fd00b42009-08-26 18:41:16 +02003859 struct rlimit *old_rlim = p->signal->rlim + resource;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003860
3861 /* Control the ability to change the hard limit (whether
3862 lowering or raising it), so that the hard limit can
3863 later be used as a safe reset point for the soft limit
David Howellsd84f4f92008-11-14 10:39:23 +11003864 upon context transitions. See selinux_bprm_committing_creds. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07003865 if (old_rlim->rlim_max != new_rlim->rlim_max)
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003866 return avc_has_perm(&selinux_state,
3867 current_sid(), task_sid(p),
Stephen Smalleybe0554c2017-01-09 10:07:31 -05003868 SECCLASS_PROCESS, PROCESS__SETRLIMIT, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003869
3870 return 0;
3871}
3872
KOSAKI Motohirob0ae1982010-10-15 04:21:18 +09003873static int selinux_task_setscheduler(struct task_struct *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003874{
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003875 return avc_has_perm(&selinux_state,
3876 current_sid(), task_sid(p), SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05003877 PROCESS__SETSCHED, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003878}
3879
3880static int selinux_task_getscheduler(struct task_struct *p)
3881{
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003882 return avc_has_perm(&selinux_state,
3883 current_sid(), task_sid(p), SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05003884 PROCESS__GETSCHED, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003885}
3886
David Quigley35601542006-06-23 02:04:01 -07003887static int selinux_task_movememory(struct task_struct *p)
3888{
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003889 return avc_has_perm(&selinux_state,
3890 current_sid(), task_sid(p), SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05003891 PROCESS__SETSCHED, NULL);
David Quigley35601542006-06-23 02:04:01 -07003892}
3893
Eric W. Biedermanae7795b2018-09-25 11:27:20 +02003894static int selinux_task_kill(struct task_struct *p, struct kernel_siginfo *info,
Stephen Smalley6b4f3d02017-09-08 12:40:01 -04003895 int sig, const struct cred *cred)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003896{
Stephen Smalley6b4f3d02017-09-08 12:40:01 -04003897 u32 secid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003898 u32 perm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003899
Linus Torvalds1da177e2005-04-16 15:20:36 -07003900 if (!sig)
3901 perm = PROCESS__SIGNULL; /* null signal; existence test */
3902 else
3903 perm = signal_to_av(sig);
Stephen Smalley6b4f3d02017-09-08 12:40:01 -04003904 if (!cred)
Stephen Smalleybe0554c2017-01-09 10:07:31 -05003905 secid = current_sid();
Stephen Smalley6b4f3d02017-09-08 12:40:01 -04003906 else
3907 secid = cred_sid(cred);
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003908 return avc_has_perm(&selinux_state,
3909 secid, task_sid(p), SECCLASS_PROCESS, perm, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003910}
3911
Linus Torvalds1da177e2005-04-16 15:20:36 -07003912static void selinux_task_to_inode(struct task_struct *p,
3913 struct inode *inode)
3914{
Casey Schaufler80788c22018-09-21 17:19:11 -07003915 struct inode_security_struct *isec = selinux_inode(inode);
David Howells275bb412008-11-14 10:39:19 +11003916 u32 sid = task_sid(p);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003917
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01003918 spin_lock(&isec->lock);
Andreas Gruenbacherdb978da2016-11-10 22:18:28 +01003919 isec->sclass = inode_mode_to_security_class(inode->i_mode);
David Howells275bb412008-11-14 10:39:19 +11003920 isec->sid = sid;
Andreas Gruenbacher6f3be9f2015-12-24 11:09:40 -05003921 isec->initialized = LABEL_INITIALIZED;
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01003922 spin_unlock(&isec->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003923}
3924
Linus Torvalds1da177e2005-04-16 15:20:36 -07003925/* Returns error only if unable to parse addresses */
Venkat Yekkirala67f83cb2006-11-08 17:04:26 -06003926static int selinux_parse_skb_ipv4(struct sk_buff *skb,
Thomas Liu2bf49692009-07-14 12:14:09 -04003927 struct common_audit_data *ad, u8 *proto)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003928{
3929 int offset, ihlen, ret = -EINVAL;
3930 struct iphdr _iph, *ih;
3931
Arnaldo Carvalho de Melobbe735e2007-03-10 22:16:10 -03003932 offset = skb_network_offset(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003933 ih = skb_header_pointer(skb, offset, sizeof(_iph), &_iph);
3934 if (ih == NULL)
3935 goto out;
3936
3937 ihlen = ih->ihl * 4;
3938 if (ihlen < sizeof(_iph))
3939 goto out;
3940
Eric Paris48c62af2012-04-02 13:15:44 -04003941 ad->u.net->v4info.saddr = ih->saddr;
3942 ad->u.net->v4info.daddr = ih->daddr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003943 ret = 0;
3944
Venkat Yekkirala67f83cb2006-11-08 17:04:26 -06003945 if (proto)
3946 *proto = ih->protocol;
3947
Linus Torvalds1da177e2005-04-16 15:20:36 -07003948 switch (ih->protocol) {
Eric Paris828dfe12008-04-17 13:17:49 -04003949 case IPPROTO_TCP: {
3950 struct tcphdr _tcph, *th;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003951
Eric Paris828dfe12008-04-17 13:17:49 -04003952 if (ntohs(ih->frag_off) & IP_OFFSET)
3953 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003954
3955 offset += ihlen;
3956 th = skb_header_pointer(skb, offset, sizeof(_tcph), &_tcph);
3957 if (th == NULL)
3958 break;
3959
Eric Paris48c62af2012-04-02 13:15:44 -04003960 ad->u.net->sport = th->source;
3961 ad->u.net->dport = th->dest;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003962 break;
Eric Paris828dfe12008-04-17 13:17:49 -04003963 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003964
Eric Paris828dfe12008-04-17 13:17:49 -04003965 case IPPROTO_UDP: {
3966 struct udphdr _udph, *uh;
3967
3968 if (ntohs(ih->frag_off) & IP_OFFSET)
3969 break;
3970
3971 offset += ihlen;
3972 uh = skb_header_pointer(skb, offset, sizeof(_udph), &_udph);
3973 if (uh == NULL)
3974 break;
3975
Eric Paris48c62af2012-04-02 13:15:44 -04003976 ad->u.net->sport = uh->source;
3977 ad->u.net->dport = uh->dest;
Eric Paris828dfe12008-04-17 13:17:49 -04003978 break;
3979 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003980
James Morris2ee92d42006-11-13 16:09:01 -08003981 case IPPROTO_DCCP: {
3982 struct dccp_hdr _dccph, *dh;
3983
3984 if (ntohs(ih->frag_off) & IP_OFFSET)
3985 break;
3986
3987 offset += ihlen;
3988 dh = skb_header_pointer(skb, offset, sizeof(_dccph), &_dccph);
3989 if (dh == NULL)
3990 break;
3991
Eric Paris48c62af2012-04-02 13:15:44 -04003992 ad->u.net->sport = dh->dccph_sport;
3993 ad->u.net->dport = dh->dccph_dport;
James Morris2ee92d42006-11-13 16:09:01 -08003994 break;
Eric Paris828dfe12008-04-17 13:17:49 -04003995 }
James Morris2ee92d42006-11-13 16:09:01 -08003996
Richard Hainesd4529302018-02-13 20:57:18 +00003997#if IS_ENABLED(CONFIG_IP_SCTP)
3998 case IPPROTO_SCTP: {
3999 struct sctphdr _sctph, *sh;
4000
4001 if (ntohs(ih->frag_off) & IP_OFFSET)
4002 break;
4003
4004 offset += ihlen;
4005 sh = skb_header_pointer(skb, offset, sizeof(_sctph), &_sctph);
4006 if (sh == NULL)
4007 break;
4008
4009 ad->u.net->sport = sh->source;
4010 ad->u.net->dport = sh->dest;
4011 break;
4012 }
4013#endif
Eric Paris828dfe12008-04-17 13:17:49 -04004014 default:
4015 break;
4016 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004017out:
4018 return ret;
4019}
4020
Javier Martinez Canillas1a93a6e2016-08-08 13:08:25 -04004021#if IS_ENABLED(CONFIG_IPV6)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004022
4023/* Returns error only if unable to parse addresses */
Venkat Yekkirala67f83cb2006-11-08 17:04:26 -06004024static int selinux_parse_skb_ipv6(struct sk_buff *skb,
Thomas Liu2bf49692009-07-14 12:14:09 -04004025 struct common_audit_data *ad, u8 *proto)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004026{
4027 u8 nexthdr;
4028 int ret = -EINVAL, offset;
4029 struct ipv6hdr _ipv6h, *ip6;
Jesse Gross75f28112011-11-30 17:05:51 -08004030 __be16 frag_off;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004031
Arnaldo Carvalho de Melobbe735e2007-03-10 22:16:10 -03004032 offset = skb_network_offset(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004033 ip6 = skb_header_pointer(skb, offset, sizeof(_ipv6h), &_ipv6h);
4034 if (ip6 == NULL)
4035 goto out;
4036
Eric Paris48c62af2012-04-02 13:15:44 -04004037 ad->u.net->v6info.saddr = ip6->saddr;
4038 ad->u.net->v6info.daddr = ip6->daddr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004039 ret = 0;
4040
4041 nexthdr = ip6->nexthdr;
4042 offset += sizeof(_ipv6h);
Jesse Gross75f28112011-11-30 17:05:51 -08004043 offset = ipv6_skip_exthdr(skb, offset, &nexthdr, &frag_off);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004044 if (offset < 0)
4045 goto out;
4046
Venkat Yekkirala67f83cb2006-11-08 17:04:26 -06004047 if (proto)
4048 *proto = nexthdr;
4049
Linus Torvalds1da177e2005-04-16 15:20:36 -07004050 switch (nexthdr) {
4051 case IPPROTO_TCP: {
Eric Paris828dfe12008-04-17 13:17:49 -04004052 struct tcphdr _tcph, *th;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004053
4054 th = skb_header_pointer(skb, offset, sizeof(_tcph), &_tcph);
4055 if (th == NULL)
4056 break;
4057
Eric Paris48c62af2012-04-02 13:15:44 -04004058 ad->u.net->sport = th->source;
4059 ad->u.net->dport = th->dest;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004060 break;
4061 }
4062
4063 case IPPROTO_UDP: {
4064 struct udphdr _udph, *uh;
4065
4066 uh = skb_header_pointer(skb, offset, sizeof(_udph), &_udph);
4067 if (uh == NULL)
4068 break;
4069
Eric Paris48c62af2012-04-02 13:15:44 -04004070 ad->u.net->sport = uh->source;
4071 ad->u.net->dport = uh->dest;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004072 break;
4073 }
4074
James Morris2ee92d42006-11-13 16:09:01 -08004075 case IPPROTO_DCCP: {
4076 struct dccp_hdr _dccph, *dh;
4077
4078 dh = skb_header_pointer(skb, offset, sizeof(_dccph), &_dccph);
4079 if (dh == NULL)
4080 break;
4081
Eric Paris48c62af2012-04-02 13:15:44 -04004082 ad->u.net->sport = dh->dccph_sport;
4083 ad->u.net->dport = dh->dccph_dport;
James Morris2ee92d42006-11-13 16:09:01 -08004084 break;
Eric Paris828dfe12008-04-17 13:17:49 -04004085 }
James Morris2ee92d42006-11-13 16:09:01 -08004086
Richard Hainesd4529302018-02-13 20:57:18 +00004087#if IS_ENABLED(CONFIG_IP_SCTP)
4088 case IPPROTO_SCTP: {
4089 struct sctphdr _sctph, *sh;
4090
4091 sh = skb_header_pointer(skb, offset, sizeof(_sctph), &_sctph);
4092 if (sh == NULL)
4093 break;
4094
4095 ad->u.net->sport = sh->source;
4096 ad->u.net->dport = sh->dest;
4097 break;
4098 }
4099#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07004100 /* includes fragments */
4101 default:
4102 break;
4103 }
4104out:
4105 return ret;
4106}
4107
4108#endif /* IPV6 */
4109
Thomas Liu2bf49692009-07-14 12:14:09 -04004110static int selinux_parse_skb(struct sk_buff *skb, struct common_audit_data *ad,
David Howellscf9481e2008-07-27 21:31:07 +10004111 char **_addrp, int src, u8 *proto)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004112{
David Howellscf9481e2008-07-27 21:31:07 +10004113 char *addrp;
4114 int ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004115
Eric Paris48c62af2012-04-02 13:15:44 -04004116 switch (ad->u.net->family) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004117 case PF_INET:
Venkat Yekkirala67f83cb2006-11-08 17:04:26 -06004118 ret = selinux_parse_skb_ipv4(skb, ad, proto);
David Howellscf9481e2008-07-27 21:31:07 +10004119 if (ret)
4120 goto parse_error;
Eric Paris48c62af2012-04-02 13:15:44 -04004121 addrp = (char *)(src ? &ad->u.net->v4info.saddr :
4122 &ad->u.net->v4info.daddr);
David Howellscf9481e2008-07-27 21:31:07 +10004123 goto okay;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004124
Javier Martinez Canillas1a93a6e2016-08-08 13:08:25 -04004125#if IS_ENABLED(CONFIG_IPV6)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004126 case PF_INET6:
Venkat Yekkirala67f83cb2006-11-08 17:04:26 -06004127 ret = selinux_parse_skb_ipv6(skb, ad, proto);
David Howellscf9481e2008-07-27 21:31:07 +10004128 if (ret)
4129 goto parse_error;
Eric Paris48c62af2012-04-02 13:15:44 -04004130 addrp = (char *)(src ? &ad->u.net->v6info.saddr :
4131 &ad->u.net->v6info.daddr);
David Howellscf9481e2008-07-27 21:31:07 +10004132 goto okay;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004133#endif /* IPV6 */
4134 default:
David Howellscf9481e2008-07-27 21:31:07 +10004135 addrp = NULL;
4136 goto okay;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004137 }
4138
David Howellscf9481e2008-07-27 21:31:07 +10004139parse_error:
peter enderborgc103a912018-06-12 10:09:03 +02004140 pr_warn(
David Howellscf9481e2008-07-27 21:31:07 +10004141 "SELinux: failure in selinux_parse_skb(),"
4142 " unable to parse packet\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07004143 return ret;
David Howellscf9481e2008-07-27 21:31:07 +10004144
4145okay:
4146 if (_addrp)
4147 *_addrp = addrp;
4148 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004149}
4150
Paul Moore4f6a9932007-03-01 14:35:22 -05004151/**
Paul Moore220deb92008-01-29 08:38:23 -05004152 * selinux_skb_peerlbl_sid - Determine the peer label of a packet
Paul Moore4f6a9932007-03-01 14:35:22 -05004153 * @skb: the packet
Paul Moore75e22912008-01-29 08:38:04 -05004154 * @family: protocol family
Paul Moore220deb92008-01-29 08:38:23 -05004155 * @sid: the packet's peer label SID
Paul Moore4f6a9932007-03-01 14:35:22 -05004156 *
4157 * Description:
Paul Moore220deb92008-01-29 08:38:23 -05004158 * Check the various different forms of network peer labeling and determine
4159 * the peer label/SID for the packet; most of the magic actually occurs in
4160 * the security server function security_net_peersid_cmp(). The function
4161 * returns zero if the value in @sid is valid (although it may be SECSID_NULL)
4162 * or -EACCES if @sid is invalid due to inconsistencies with the different
4163 * peer labels.
Paul Moore4f6a9932007-03-01 14:35:22 -05004164 *
4165 */
Paul Moore220deb92008-01-29 08:38:23 -05004166static int selinux_skb_peerlbl_sid(struct sk_buff *skb, u16 family, u32 *sid)
Paul Moore4f6a9932007-03-01 14:35:22 -05004167{
Paul Moore71f1cb02008-01-29 08:51:16 -05004168 int err;
Paul Moore4f6a9932007-03-01 14:35:22 -05004169 u32 xfrm_sid;
4170 u32 nlbl_sid;
Paul Moore220deb92008-01-29 08:38:23 -05004171 u32 nlbl_type;
Paul Moore4f6a9932007-03-01 14:35:22 -05004172
Paul Moore817eff72013-12-10 14:57:54 -05004173 err = selinux_xfrm_skb_sid(skb, &xfrm_sid);
Paul Moorebed4d7e2013-07-23 17:38:40 -04004174 if (unlikely(err))
4175 return -EACCES;
4176 err = selinux_netlbl_skbuff_getsid(skb, family, &nlbl_type, &nlbl_sid);
4177 if (unlikely(err))
4178 return -EACCES;
Paul Moore220deb92008-01-29 08:38:23 -05004179
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05004180 err = security_net_peersid_resolve(&selinux_state, nlbl_sid,
4181 nlbl_type, xfrm_sid, sid);
Paul Moore71f1cb02008-01-29 08:51:16 -05004182 if (unlikely(err)) {
peter enderborgc103a912018-06-12 10:09:03 +02004183 pr_warn(
Paul Moore71f1cb02008-01-29 08:51:16 -05004184 "SELinux: failure in selinux_skb_peerlbl_sid(),"
4185 " unable to determine packet's peer label\n");
Paul Moore220deb92008-01-29 08:38:23 -05004186 return -EACCES;
Paul Moore71f1cb02008-01-29 08:51:16 -05004187 }
Paul Moore220deb92008-01-29 08:38:23 -05004188
4189 return 0;
Paul Moore4f6a9932007-03-01 14:35:22 -05004190}
4191
Paul Moore446b8022013-12-04 16:10:51 -05004192/**
4193 * selinux_conn_sid - Determine the child socket label for a connection
4194 * @sk_sid: the parent socket's SID
4195 * @skb_sid: the packet's SID
4196 * @conn_sid: the resulting connection SID
4197 *
4198 * If @skb_sid is valid then the user:role:type information from @sk_sid is
4199 * combined with the MLS information from @skb_sid in order to create
4200 * @conn_sid. If @skb_sid is not valid then then @conn_sid is simply a copy
4201 * of @sk_sid. Returns zero on success, negative values on failure.
4202 *
4203 */
4204static int selinux_conn_sid(u32 sk_sid, u32 skb_sid, u32 *conn_sid)
4205{
4206 int err = 0;
4207
4208 if (skb_sid != SECSID_NULL)
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05004209 err = security_sid_mls_copy(&selinux_state, sk_sid, skb_sid,
4210 conn_sid);
Paul Moore446b8022013-12-04 16:10:51 -05004211 else
4212 *conn_sid = sk_sid;
4213
4214 return err;
4215}
4216
Linus Torvalds1da177e2005-04-16 15:20:36 -07004217/* socket security operations */
Paul Moored4f2d972010-04-22 14:46:18 -04004218
Harry Ciao2ad18bd2011-03-02 13:32:34 +08004219static int socket_sockcreate_sid(const struct task_security_struct *tsec,
4220 u16 secclass, u32 *socksid)
Paul Moored4f2d972010-04-22 14:46:18 -04004221{
Harry Ciao2ad18bd2011-03-02 13:32:34 +08004222 if (tsec->sockcreate_sid > SECSID_NULL) {
4223 *socksid = tsec->sockcreate_sid;
4224 return 0;
4225 }
4226
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05004227 return security_transition_sid(&selinux_state, tsec->sid, tsec->sid,
4228 secclass, NULL, socksid);
Paul Moored4f2d972010-04-22 14:46:18 -04004229}
4230
Stephen Smalleybe0554c2017-01-09 10:07:31 -05004231static int sock_has_perm(struct sock *sk, u32 perms)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004232{
Paul Moore253bfae2010-04-22 14:46:19 -04004233 struct sk_security_struct *sksec = sk->sk_security;
Thomas Liu2bf49692009-07-14 12:14:09 -04004234 struct common_audit_data ad;
Eric Paris48c62af2012-04-02 13:15:44 -04004235 struct lsm_network_audit net = {0,};
Linus Torvalds1da177e2005-04-16 15:20:36 -07004236
Paul Moore253bfae2010-04-22 14:46:19 -04004237 if (sksec->sid == SECINITSID_KERNEL)
4238 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004239
Eric Paris50c205f2012-04-04 15:01:43 -04004240 ad.type = LSM_AUDIT_DATA_NET;
Eric Paris48c62af2012-04-02 13:15:44 -04004241 ad.u.net = &net;
4242 ad.u.net->sk = sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004243
Stephen Smalley6b6bc622018-03-05 11:47:56 -05004244 return avc_has_perm(&selinux_state,
4245 current_sid(), sksec->sid, sksec->sclass, perms,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05004246 &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004247}
4248
4249static int selinux_socket_create(int family, int type,
4250 int protocol, int kern)
4251{
Casey Schaufler0c6cfa62018-09-21 17:17:16 -07004252 const struct task_security_struct *tsec = selinux_cred(current_cred());
Paul Moored4f2d972010-04-22 14:46:18 -04004253 u32 newsid;
David Howells275bb412008-11-14 10:39:19 +11004254 u16 secclass;
Harry Ciao2ad18bd2011-03-02 13:32:34 +08004255 int rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004256
4257 if (kern)
Paul Moored4f2d972010-04-22 14:46:18 -04004258 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004259
David Howells275bb412008-11-14 10:39:19 +11004260 secclass = socket_type_to_security_class(family, type, protocol);
Harry Ciao2ad18bd2011-03-02 13:32:34 +08004261 rc = socket_sockcreate_sid(tsec, secclass, &newsid);
4262 if (rc)
4263 return rc;
4264
Stephen Smalley6b6bc622018-03-05 11:47:56 -05004265 return avc_has_perm(&selinux_state,
4266 tsec->sid, newsid, secclass, SOCKET__CREATE, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004267}
4268
Venkat Yekkirala7420ed22006-08-04 23:17:57 -07004269static int selinux_socket_post_create(struct socket *sock, int family,
4270 int type, int protocol, int kern)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004271{
Casey Schaufler0c6cfa62018-09-21 17:17:16 -07004272 const struct task_security_struct *tsec = selinux_cred(current_cred());
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -05004273 struct inode_security_struct *isec = inode_security_novalidate(SOCK_INODE(sock));
Venkat Yekkirala892c1412006-08-04 23:08:56 -07004274 struct sk_security_struct *sksec;
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01004275 u16 sclass = socket_type_to_security_class(family, type, protocol);
4276 u32 sid = SECINITSID_KERNEL;
David Howells275bb412008-11-14 10:39:19 +11004277 int err = 0;
4278
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01004279 if (!kern) {
4280 err = socket_sockcreate_sid(tsec, sclass, &sid);
Harry Ciao2ad18bd2011-03-02 13:32:34 +08004281 if (err)
4282 return err;
4283 }
David Howells275bb412008-11-14 10:39:19 +11004284
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01004285 isec->sclass = sclass;
4286 isec->sid = sid;
Andreas Gruenbacher6f3be9f2015-12-24 11:09:40 -05004287 isec->initialized = LABEL_INITIALIZED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004288
Venkat Yekkirala892c1412006-08-04 23:08:56 -07004289 if (sock->sk) {
4290 sksec = sock->sk->sk_security;
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01004291 sksec->sclass = sclass;
4292 sksec->sid = sid;
Richard Hainesd4529302018-02-13 20:57:18 +00004293 /* Allows detection of the first association on this socket */
4294 if (sksec->sclass == SECCLASS_SCTP_SOCKET)
4295 sksec->sctp_assoc_state = SCTP_ASSOC_UNSET;
4296
Paul Moore389fb8002009-03-27 17:10:34 -04004297 err = selinux_netlbl_socket_post_create(sock->sk, family);
Venkat Yekkirala892c1412006-08-04 23:08:56 -07004298 }
4299
Venkat Yekkirala7420ed22006-08-04 23:17:57 -07004300 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004301}
4302
David Herrmann0b811db2018-05-04 16:28:21 +02004303static int selinux_socket_socketpair(struct socket *socka,
4304 struct socket *sockb)
4305{
4306 struct sk_security_struct *sksec_a = socka->sk->sk_security;
4307 struct sk_security_struct *sksec_b = sockb->sk->sk_security;
4308
4309 sksec_a->peer_sid = sksec_b->sid;
4310 sksec_b->peer_sid = sksec_a->sid;
4311
4312 return 0;
4313}
4314
Linus Torvalds1da177e2005-04-16 15:20:36 -07004315/* Range of port numbers used to automatically bind.
4316 Need to determine whether we should perform a name_bind
4317 permission check between the socket and the port number. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07004318
4319static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, int addrlen)
4320{
Paul Moore253bfae2010-04-22 14:46:19 -04004321 struct sock *sk = sock->sk;
Alexey Kodanev0f8db8c2018-05-11 20:15:11 +03004322 struct sk_security_struct *sksec = sk->sk_security;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004323 u16 family;
4324 int err;
4325
Stephen Smalleybe0554c2017-01-09 10:07:31 -05004326 err = sock_has_perm(sk, SOCKET__BIND);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004327 if (err)
4328 goto out;
4329
Richard Hainesd4529302018-02-13 20:57:18 +00004330 /* If PF_INET or PF_INET6, check name_bind permission for the port. */
Paul Moore253bfae2010-04-22 14:46:19 -04004331 family = sk->sk_family;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004332 if (family == PF_INET || family == PF_INET6) {
4333 char *addrp;
Thomas Liu2bf49692009-07-14 12:14:09 -04004334 struct common_audit_data ad;
Eric Paris48c62af2012-04-02 13:15:44 -04004335 struct lsm_network_audit net = {0,};
Linus Torvalds1da177e2005-04-16 15:20:36 -07004336 struct sockaddr_in *addr4 = NULL;
4337 struct sockaddr_in6 *addr6 = NULL;
Alexey Kodanev0f8db8c2018-05-11 20:15:11 +03004338 u16 family_sa = address->sa_family;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004339 unsigned short snum;
James Morrise399f982008-06-12 01:39:58 +10004340 u32 sid, node_perm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004341
Richard Hainesd4529302018-02-13 20:57:18 +00004342 /*
4343 * sctp_bindx(3) calls via selinux_sctp_bind_connect()
4344 * that validates multiple binding addresses. Because of this
4345 * need to check address->sa_family as it is possible to have
4346 * sk->sk_family = PF_INET6 with addr->sa_family = AF_INET.
4347 */
Alexey Kodanev0f8db8c2018-05-11 20:15:11 +03004348 switch (family_sa) {
4349 case AF_UNSPEC:
Richard Haines68741a8a2018-03-02 19:54:34 +00004350 case AF_INET:
4351 if (addrlen < sizeof(struct sockaddr_in))
4352 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004353 addr4 = (struct sockaddr_in *)address;
Alexey Kodanev0f8db8c2018-05-11 20:15:11 +03004354 if (family_sa == AF_UNSPEC) {
4355 /* see __inet_bind(), we only want to allow
4356 * AF_UNSPEC if the address is INADDR_ANY
4357 */
4358 if (addr4->sin_addr.s_addr != htonl(INADDR_ANY))
4359 goto err_af;
4360 family_sa = AF_INET;
4361 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004362 snum = ntohs(addr4->sin_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004363 addrp = (char *)&addr4->sin_addr.s_addr;
Richard Haines68741a8a2018-03-02 19:54:34 +00004364 break;
4365 case AF_INET6:
4366 if (addrlen < SIN6_LEN_RFC2133)
4367 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004368 addr6 = (struct sockaddr_in6 *)address;
4369 snum = ntohs(addr6->sin6_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004370 addrp = (char *)&addr6->sin6_addr.s6_addr;
Richard Haines68741a8a2018-03-02 19:54:34 +00004371 break;
4372 default:
Alexey Kodanev0f8db8c2018-05-11 20:15:11 +03004373 goto err_af;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004374 }
4375
Alexey Kodanev88b7d372018-05-11 20:15:12 +03004376 ad.type = LSM_AUDIT_DATA_NET;
4377 ad.u.net = &net;
4378 ad.u.net->sport = htons(snum);
4379 ad.u.net->family = family_sa;
4380
Stephen Hemminger227b60f2007-10-10 17:30:46 -07004381 if (snum) {
4382 int low, high;
4383
Eric W. Biederman0bbf87d2013-09-28 14:10:59 -07004384 inet_get_local_port_range(sock_net(sk), &low, &high);
Stephen Hemminger227b60f2007-10-10 17:30:46 -07004385
Krister Johansen4548b682017-01-20 17:49:11 -08004386 if (snum < max(inet_prot_sock(sock_net(sk)), low) ||
4387 snum > high) {
Paul Moore3e112172008-04-10 10:48:14 -04004388 err = sel_netport_sid(sk->sk_protocol,
4389 snum, &sid);
Stephen Hemminger227b60f2007-10-10 17:30:46 -07004390 if (err)
4391 goto out;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05004392 err = avc_has_perm(&selinux_state,
4393 sksec->sid, sid,
Paul Moore253bfae2010-04-22 14:46:19 -04004394 sksec->sclass,
Stephen Hemminger227b60f2007-10-10 17:30:46 -07004395 SOCKET__NAME_BIND, &ad);
4396 if (err)
4397 goto out;
4398 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004399 }
Eric Paris828dfe12008-04-17 13:17:49 -04004400
Paul Moore253bfae2010-04-22 14:46:19 -04004401 switch (sksec->sclass) {
James Morris13402582005-09-30 14:24:34 -04004402 case SECCLASS_TCP_SOCKET:
Linus Torvalds1da177e2005-04-16 15:20:36 -07004403 node_perm = TCP_SOCKET__NODE_BIND;
4404 break;
Eric Paris828dfe12008-04-17 13:17:49 -04004405
James Morris13402582005-09-30 14:24:34 -04004406 case SECCLASS_UDP_SOCKET:
Linus Torvalds1da177e2005-04-16 15:20:36 -07004407 node_perm = UDP_SOCKET__NODE_BIND;
4408 break;
James Morris2ee92d42006-11-13 16:09:01 -08004409
4410 case SECCLASS_DCCP_SOCKET:
4411 node_perm = DCCP_SOCKET__NODE_BIND;
4412 break;
4413
Richard Hainesd4529302018-02-13 20:57:18 +00004414 case SECCLASS_SCTP_SOCKET:
4415 node_perm = SCTP_SOCKET__NODE_BIND;
4416 break;
4417
Linus Torvalds1da177e2005-04-16 15:20:36 -07004418 default:
4419 node_perm = RAWIP_SOCKET__NODE_BIND;
4420 break;
4421 }
Eric Paris828dfe12008-04-17 13:17:49 -04004422
Alexey Kodanev88b7d372018-05-11 20:15:12 +03004423 err = sel_netnode_sid(addrp, family_sa, &sid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004424 if (err)
4425 goto out;
Eric Paris828dfe12008-04-17 13:17:49 -04004426
Alexey Kodanev0f8db8c2018-05-11 20:15:11 +03004427 if (family_sa == AF_INET)
Eric Paris48c62af2012-04-02 13:15:44 -04004428 ad.u.net->v4info.saddr = addr4->sin_addr.s_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004429 else
Eric Paris48c62af2012-04-02 13:15:44 -04004430 ad.u.net->v6info.saddr = addr6->sin6_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004431
Stephen Smalley6b6bc622018-03-05 11:47:56 -05004432 err = avc_has_perm(&selinux_state,
4433 sksec->sid, sid,
Paul Moore253bfae2010-04-22 14:46:19 -04004434 sksec->sclass, node_perm, &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004435 if (err)
4436 goto out;
4437 }
4438out:
4439 return err;
Alexey Kodanev0f8db8c2018-05-11 20:15:11 +03004440err_af:
4441 /* Note that SCTP services expect -EINVAL, others -EAFNOSUPPORT. */
4442 if (sksec->sclass == SECCLASS_SCTP_SOCKET)
4443 return -EINVAL;
4444 return -EAFNOSUPPORT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004445}
4446
Richard Hainesd4529302018-02-13 20:57:18 +00004447/* This supports connect(2) and SCTP connect services such as sctp_connectx(3)
Mauro Carvalho Chehab5fb94e92018-05-08 15:14:57 -03004448 * and sctp_sendmsg(3) as described in Documentation/security/LSM-sctp.rst
Richard Hainesd4529302018-02-13 20:57:18 +00004449 */
4450static int selinux_socket_connect_helper(struct socket *sock,
4451 struct sockaddr *address, int addrlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004452{
Paul Moore014ab192008-10-10 10:16:33 -04004453 struct sock *sk = sock->sk;
Paul Moore253bfae2010-04-22 14:46:19 -04004454 struct sk_security_struct *sksec = sk->sk_security;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004455 int err;
4456
Stephen Smalleybe0554c2017-01-09 10:07:31 -05004457 err = sock_has_perm(sk, SOCKET__CONNECT);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004458 if (err)
4459 return err;
4460
4461 /*
Richard Hainesd4529302018-02-13 20:57:18 +00004462 * If a TCP, DCCP or SCTP socket, check name_connect permission
4463 * for the port.
Linus Torvalds1da177e2005-04-16 15:20:36 -07004464 */
Paul Moore253bfae2010-04-22 14:46:19 -04004465 if (sksec->sclass == SECCLASS_TCP_SOCKET ||
Richard Hainesd4529302018-02-13 20:57:18 +00004466 sksec->sclass == SECCLASS_DCCP_SOCKET ||
4467 sksec->sclass == SECCLASS_SCTP_SOCKET) {
Thomas Liu2bf49692009-07-14 12:14:09 -04004468 struct common_audit_data ad;
Eric Paris48c62af2012-04-02 13:15:44 -04004469 struct lsm_network_audit net = {0,};
Linus Torvalds1da177e2005-04-16 15:20:36 -07004470 struct sockaddr_in *addr4 = NULL;
4471 struct sockaddr_in6 *addr6 = NULL;
4472 unsigned short snum;
James Morris2ee92d42006-11-13 16:09:01 -08004473 u32 sid, perm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004474
Richard Hainesd4529302018-02-13 20:57:18 +00004475 /* sctp_connectx(3) calls via selinux_sctp_bind_connect()
4476 * that validates multiple connect addresses. Because of this
4477 * need to check address->sa_family as it is possible to have
4478 * sk->sk_family = PF_INET6 with addr->sa_family = AF_INET.
4479 */
Richard Haines68741a8a2018-03-02 19:54:34 +00004480 switch (address->sa_family) {
4481 case AF_INET:
Linus Torvalds1da177e2005-04-16 15:20:36 -07004482 addr4 = (struct sockaddr_in *)address;
Stephen Smalley911656f2005-07-28 21:16:21 -07004483 if (addrlen < sizeof(struct sockaddr_in))
Linus Torvalds1da177e2005-04-16 15:20:36 -07004484 return -EINVAL;
4485 snum = ntohs(addr4->sin_port);
Richard Haines68741a8a2018-03-02 19:54:34 +00004486 break;
4487 case AF_INET6:
Linus Torvalds1da177e2005-04-16 15:20:36 -07004488 addr6 = (struct sockaddr_in6 *)address;
Stephen Smalley911656f2005-07-28 21:16:21 -07004489 if (addrlen < SIN6_LEN_RFC2133)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004490 return -EINVAL;
4491 snum = ntohs(addr6->sin6_port);
Richard Haines68741a8a2018-03-02 19:54:34 +00004492 break;
4493 default:
4494 /* Note that SCTP services expect -EINVAL, whereas
4495 * others expect -EAFNOSUPPORT.
4496 */
4497 if (sksec->sclass == SECCLASS_SCTP_SOCKET)
4498 return -EINVAL;
4499 else
4500 return -EAFNOSUPPORT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004501 }
4502
Paul Moore3e112172008-04-10 10:48:14 -04004503 err = sel_netport_sid(sk->sk_protocol, snum, &sid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004504 if (err)
Richard Hainesd4529302018-02-13 20:57:18 +00004505 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004506
Richard Hainesd4529302018-02-13 20:57:18 +00004507 switch (sksec->sclass) {
4508 case SECCLASS_TCP_SOCKET:
4509 perm = TCP_SOCKET__NAME_CONNECT;
4510 break;
4511 case SECCLASS_DCCP_SOCKET:
4512 perm = DCCP_SOCKET__NAME_CONNECT;
4513 break;
4514 case SECCLASS_SCTP_SOCKET:
4515 perm = SCTP_SOCKET__NAME_CONNECT;
4516 break;
4517 }
James Morris2ee92d42006-11-13 16:09:01 -08004518
Eric Paris50c205f2012-04-04 15:01:43 -04004519 ad.type = LSM_AUDIT_DATA_NET;
Eric Paris48c62af2012-04-02 13:15:44 -04004520 ad.u.net = &net;
4521 ad.u.net->dport = htons(snum);
Alexey Kodanev88b7d372018-05-11 20:15:12 +03004522 ad.u.net->family = address->sa_family;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05004523 err = avc_has_perm(&selinux_state,
4524 sksec->sid, sid, sksec->sclass, perm, &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004525 if (err)
Richard Hainesd4529302018-02-13 20:57:18 +00004526 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004527 }
4528
Richard Hainesd4529302018-02-13 20:57:18 +00004529 return 0;
4530}
Paul Moore014ab192008-10-10 10:16:33 -04004531
Richard Hainesd4529302018-02-13 20:57:18 +00004532/* Supports connect(2), see comments in selinux_socket_connect_helper() */
4533static int selinux_socket_connect(struct socket *sock,
4534 struct sockaddr *address, int addrlen)
4535{
4536 int err;
4537 struct sock *sk = sock->sk;
4538
4539 err = selinux_socket_connect_helper(sock, address, addrlen);
4540 if (err)
4541 return err;
4542
4543 return selinux_netlbl_socket_connect(sk, address);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004544}
4545
4546static int selinux_socket_listen(struct socket *sock, int backlog)
4547{
Stephen Smalleybe0554c2017-01-09 10:07:31 -05004548 return sock_has_perm(sock->sk, SOCKET__LISTEN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004549}
4550
4551static int selinux_socket_accept(struct socket *sock, struct socket *newsock)
4552{
4553 int err;
4554 struct inode_security_struct *isec;
4555 struct inode_security_struct *newisec;
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01004556 u16 sclass;
4557 u32 sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004558
Stephen Smalleybe0554c2017-01-09 10:07:31 -05004559 err = sock_has_perm(sock->sk, SOCKET__ACCEPT);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004560 if (err)
4561 return err;
4562
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -05004563 isec = inode_security_novalidate(SOCK_INODE(sock));
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01004564 spin_lock(&isec->lock);
4565 sclass = isec->sclass;
4566 sid = isec->sid;
4567 spin_unlock(&isec->lock);
4568
4569 newisec = inode_security_novalidate(SOCK_INODE(newsock));
4570 newisec->sclass = sclass;
4571 newisec->sid = sid;
Andreas Gruenbacher6f3be9f2015-12-24 11:09:40 -05004572 newisec->initialized = LABEL_INITIALIZED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004573
4574 return 0;
4575}
4576
4577static int selinux_socket_sendmsg(struct socket *sock, struct msghdr *msg,
Eric Paris828dfe12008-04-17 13:17:49 -04004578 int size)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004579{
Stephen Smalleybe0554c2017-01-09 10:07:31 -05004580 return sock_has_perm(sock->sk, SOCKET__WRITE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004581}
4582
4583static int selinux_socket_recvmsg(struct socket *sock, struct msghdr *msg,
4584 int size, int flags)
4585{
Stephen Smalleybe0554c2017-01-09 10:07:31 -05004586 return sock_has_perm(sock->sk, SOCKET__READ);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004587}
4588
4589static int selinux_socket_getsockname(struct socket *sock)
4590{
Stephen Smalleybe0554c2017-01-09 10:07:31 -05004591 return sock_has_perm(sock->sk, SOCKET__GETATTR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004592}
4593
4594static int selinux_socket_getpeername(struct socket *sock)
4595{
Stephen Smalleybe0554c2017-01-09 10:07:31 -05004596 return sock_has_perm(sock->sk, SOCKET__GETATTR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004597}
4598
Eric Paris828dfe12008-04-17 13:17:49 -04004599static int selinux_socket_setsockopt(struct socket *sock, int level, int optname)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004600{
Paul Mooref8687af2006-10-30 15:22:15 -08004601 int err;
4602
Stephen Smalleybe0554c2017-01-09 10:07:31 -05004603 err = sock_has_perm(sock->sk, SOCKET__SETOPT);
Paul Mooref8687af2006-10-30 15:22:15 -08004604 if (err)
4605 return err;
4606
4607 return selinux_netlbl_socket_setsockopt(sock, level, optname);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004608}
4609
4610static int selinux_socket_getsockopt(struct socket *sock, int level,
4611 int optname)
4612{
Stephen Smalleybe0554c2017-01-09 10:07:31 -05004613 return sock_has_perm(sock->sk, SOCKET__GETOPT);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004614}
4615
4616static int selinux_socket_shutdown(struct socket *sock, int how)
4617{
Stephen Smalleybe0554c2017-01-09 10:07:31 -05004618 return sock_has_perm(sock->sk, SOCKET__SHUTDOWN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004619}
4620
David S. Miller3610cda2011-01-05 15:38:53 -08004621static int selinux_socket_unix_stream_connect(struct sock *sock,
4622 struct sock *other,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004623 struct sock *newsk)
4624{
David S. Miller3610cda2011-01-05 15:38:53 -08004625 struct sk_security_struct *sksec_sock = sock->sk_security;
4626 struct sk_security_struct *sksec_other = other->sk_security;
Paul Moore4d1e2452010-04-22 14:46:18 -04004627 struct sk_security_struct *sksec_new = newsk->sk_security;
Thomas Liu2bf49692009-07-14 12:14:09 -04004628 struct common_audit_data ad;
Eric Paris48c62af2012-04-02 13:15:44 -04004629 struct lsm_network_audit net = {0,};
Linus Torvalds1da177e2005-04-16 15:20:36 -07004630 int err;
4631
Eric Paris50c205f2012-04-04 15:01:43 -04004632 ad.type = LSM_AUDIT_DATA_NET;
Eric Paris48c62af2012-04-02 13:15:44 -04004633 ad.u.net = &net;
4634 ad.u.net->sk = other;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004635
Stephen Smalley6b6bc622018-03-05 11:47:56 -05004636 err = avc_has_perm(&selinux_state,
4637 sksec_sock->sid, sksec_other->sid,
Paul Moore4d1e2452010-04-22 14:46:18 -04004638 sksec_other->sclass,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004639 UNIX_STREAM_SOCKET__CONNECTTO, &ad);
4640 if (err)
4641 return err;
4642
Linus Torvalds1da177e2005-04-16 15:20:36 -07004643 /* server child socket */
Paul Moore4d1e2452010-04-22 14:46:18 -04004644 sksec_new->peer_sid = sksec_sock->sid;
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05004645 err = security_sid_mls_copy(&selinux_state, sksec_other->sid,
4646 sksec_sock->sid, &sksec_new->sid);
Paul Moore4d1e2452010-04-22 14:46:18 -04004647 if (err)
4648 return err;
Venkat Yekkirala4237c752006-07-24 23:32:50 -07004649
Paul Moore4d1e2452010-04-22 14:46:18 -04004650 /* connecting socket */
4651 sksec_sock->peer_sid = sksec_new->sid;
4652
4653 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004654}
4655
4656static int selinux_socket_unix_may_send(struct socket *sock,
4657 struct socket *other)
4658{
Paul Moore253bfae2010-04-22 14:46:19 -04004659 struct sk_security_struct *ssec = sock->sk->sk_security;
4660 struct sk_security_struct *osec = other->sk->sk_security;
Thomas Liu2bf49692009-07-14 12:14:09 -04004661 struct common_audit_data ad;
Eric Paris48c62af2012-04-02 13:15:44 -04004662 struct lsm_network_audit net = {0,};
Linus Torvalds1da177e2005-04-16 15:20:36 -07004663
Eric Paris50c205f2012-04-04 15:01:43 -04004664 ad.type = LSM_AUDIT_DATA_NET;
Eric Paris48c62af2012-04-02 13:15:44 -04004665 ad.u.net = &net;
4666 ad.u.net->sk = other->sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004667
Stephen Smalley6b6bc622018-03-05 11:47:56 -05004668 return avc_has_perm(&selinux_state,
4669 ssec->sid, osec->sid, osec->sclass, SOCKET__SENDTO,
Paul Moore253bfae2010-04-22 14:46:19 -04004670 &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004671}
4672
Paul Moorecbe0d6e2014-09-10 17:09:57 -04004673static int selinux_inet_sys_rcv_skb(struct net *ns, int ifindex,
4674 char *addrp, u16 family, u32 peer_sid,
Thomas Liu2bf49692009-07-14 12:14:09 -04004675 struct common_audit_data *ad)
Paul Mooreeffad8d2008-01-29 08:49:27 -05004676{
4677 int err;
4678 u32 if_sid;
4679 u32 node_sid;
4680
Paul Moorecbe0d6e2014-09-10 17:09:57 -04004681 err = sel_netif_sid(ns, ifindex, &if_sid);
Paul Mooreeffad8d2008-01-29 08:49:27 -05004682 if (err)
4683 return err;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05004684 err = avc_has_perm(&selinux_state,
4685 peer_sid, if_sid,
Paul Mooreeffad8d2008-01-29 08:49:27 -05004686 SECCLASS_NETIF, NETIF__INGRESS, ad);
4687 if (err)
4688 return err;
4689
4690 err = sel_netnode_sid(addrp, family, &node_sid);
4691 if (err)
4692 return err;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05004693 return avc_has_perm(&selinux_state,
4694 peer_sid, node_sid,
Paul Mooreeffad8d2008-01-29 08:49:27 -05004695 SECCLASS_NODE, NODE__RECVFROM, ad);
4696}
4697
Paul Moore220deb92008-01-29 08:38:23 -05004698static int selinux_sock_rcv_skb_compat(struct sock *sk, struct sk_buff *skb,
Paul Moored8395c82008-10-10 10:16:30 -04004699 u16 family)
Paul Moore220deb92008-01-29 08:38:23 -05004700{
Paul Moore277d3422008-12-31 12:54:11 -05004701 int err = 0;
Paul Moore220deb92008-01-29 08:38:23 -05004702 struct sk_security_struct *sksec = sk->sk_security;
Paul Moore220deb92008-01-29 08:38:23 -05004703 u32 sk_sid = sksec->sid;
Thomas Liu2bf49692009-07-14 12:14:09 -04004704 struct common_audit_data ad;
Eric Paris48c62af2012-04-02 13:15:44 -04004705 struct lsm_network_audit net = {0,};
Paul Moored8395c82008-10-10 10:16:30 -04004706 char *addrp;
4707
Eric Paris50c205f2012-04-04 15:01:43 -04004708 ad.type = LSM_AUDIT_DATA_NET;
Eric Paris48c62af2012-04-02 13:15:44 -04004709 ad.u.net = &net;
4710 ad.u.net->netif = skb->skb_iif;
4711 ad.u.net->family = family;
Paul Moored8395c82008-10-10 10:16:30 -04004712 err = selinux_parse_skb(skb, &ad, &addrp, 1, NULL);
4713 if (err)
4714 return err;
Paul Moore220deb92008-01-29 08:38:23 -05004715
Paul Moore58bfbb52009-03-27 17:10:41 -04004716 if (selinux_secmark_enabled()) {
Stephen Smalley6b6bc622018-03-05 11:47:56 -05004717 err = avc_has_perm(&selinux_state,
4718 sk_sid, skb->secmark, SECCLASS_PACKET,
Paul Moored8395c82008-10-10 10:16:30 -04004719 PACKET__RECV, &ad);
Paul Moore58bfbb52009-03-27 17:10:41 -04004720 if (err)
4721 return err;
4722 }
Paul Moore220deb92008-01-29 08:38:23 -05004723
Steffen Klassertb9679a72011-02-23 12:55:21 +01004724 err = selinux_netlbl_sock_rcv_skb(sksec, skb, family, &ad);
4725 if (err)
4726 return err;
4727 err = selinux_xfrm_sock_rcv_skb(sksec->sid, skb, &ad);
Trent Jaegerd28d1e02005-12-13 23:12:40 -08004728
James Morris4e5ab4c2006-06-09 00:33:33 -07004729 return err;
4730}
Trent Jaegerd28d1e02005-12-13 23:12:40 -08004731
James Morris4e5ab4c2006-06-09 00:33:33 -07004732static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
4733{
Paul Moore220deb92008-01-29 08:38:23 -05004734 int err;
Venkat Yekkirala4237c752006-07-24 23:32:50 -07004735 struct sk_security_struct *sksec = sk->sk_security;
Paul Moore220deb92008-01-29 08:38:23 -05004736 u16 family = sk->sk_family;
4737 u32 sk_sid = sksec->sid;
Thomas Liu2bf49692009-07-14 12:14:09 -04004738 struct common_audit_data ad;
Eric Paris48c62af2012-04-02 13:15:44 -04004739 struct lsm_network_audit net = {0,};
Paul Moore220deb92008-01-29 08:38:23 -05004740 char *addrp;
Paul Moored8395c82008-10-10 10:16:30 -04004741 u8 secmark_active;
4742 u8 peerlbl_active;
James Morris4e5ab4c2006-06-09 00:33:33 -07004743
James Morris4e5ab4c2006-06-09 00:33:33 -07004744 if (family != PF_INET && family != PF_INET6)
Paul Moore220deb92008-01-29 08:38:23 -05004745 return 0;
James Morris4e5ab4c2006-06-09 00:33:33 -07004746
4747 /* Handle mapped IPv4 packets arriving via IPv6 sockets */
Al Viro87fcd702006-12-04 22:00:55 +00004748 if (family == PF_INET6 && skb->protocol == htons(ETH_P_IP))
James Morris4e5ab4c2006-06-09 00:33:33 -07004749 family = PF_INET;
4750
Paul Moored8395c82008-10-10 10:16:30 -04004751 /* If any sort of compatibility mode is enabled then handoff processing
4752 * to the selinux_sock_rcv_skb_compat() function to deal with the
4753 * special handling. We do this in an attempt to keep this function
4754 * as fast and as clean as possible. */
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05004755 if (!selinux_policycap_netpeer())
Paul Moored8395c82008-10-10 10:16:30 -04004756 return selinux_sock_rcv_skb_compat(sk, skb, family);
4757
4758 secmark_active = selinux_secmark_enabled();
Chris PeBenito2be4d742013-05-03 09:05:39 -04004759 peerlbl_active = selinux_peerlbl_enabled();
Paul Moored8395c82008-10-10 10:16:30 -04004760 if (!secmark_active && !peerlbl_active)
4761 return 0;
4762
Eric Paris50c205f2012-04-04 15:01:43 -04004763 ad.type = LSM_AUDIT_DATA_NET;
Eric Paris48c62af2012-04-02 13:15:44 -04004764 ad.u.net = &net;
4765 ad.u.net->netif = skb->skb_iif;
4766 ad.u.net->family = family;
Paul Moore224dfbd2008-01-29 08:38:13 -05004767 err = selinux_parse_skb(skb, &ad, &addrp, 1, NULL);
James Morris4e5ab4c2006-06-09 00:33:33 -07004768 if (err)
Paul Moore220deb92008-01-29 08:38:23 -05004769 return err;
James Morris4e5ab4c2006-06-09 00:33:33 -07004770
Paul Moored8395c82008-10-10 10:16:30 -04004771 if (peerlbl_active) {
Paul Moored621d352008-01-29 08:43:36 -05004772 u32 peer_sid;
4773
4774 err = selinux_skb_peerlbl_sid(skb, family, &peer_sid);
4775 if (err)
4776 return err;
Paul Moorecbe0d6e2014-09-10 17:09:57 -04004777 err = selinux_inet_sys_rcv_skb(sock_net(sk), skb->skb_iif,
4778 addrp, family, peer_sid, &ad);
Paul Mooredfaebe92008-10-10 10:16:31 -04004779 if (err) {
Huw Daviesa04e71f2016-06-27 15:06:16 -04004780 selinux_netlbl_err(skb, family, err, 0);
Paul Mooreeffad8d2008-01-29 08:49:27 -05004781 return err;
Paul Mooredfaebe92008-10-10 10:16:31 -04004782 }
Stephen Smalley6b6bc622018-03-05 11:47:56 -05004783 err = avc_has_perm(&selinux_state,
4784 sk_sid, peer_sid, SECCLASS_PEER,
Paul Moored621d352008-01-29 08:43:36 -05004785 PEER__RECV, &ad);
Chad Hanson46d01d62013-12-23 17:45:01 -05004786 if (err) {
Huw Daviesa04e71f2016-06-27 15:06:16 -04004787 selinux_netlbl_err(skb, family, err, 0);
Chad Hanson46d01d62013-12-23 17:45:01 -05004788 return err;
4789 }
Paul Moored621d352008-01-29 08:43:36 -05004790 }
4791
Paul Moored8395c82008-10-10 10:16:30 -04004792 if (secmark_active) {
Stephen Smalley6b6bc622018-03-05 11:47:56 -05004793 err = avc_has_perm(&selinux_state,
4794 sk_sid, skb->secmark, SECCLASS_PACKET,
Paul Mooreeffad8d2008-01-29 08:49:27 -05004795 PACKET__RECV, &ad);
4796 if (err)
4797 return err;
4798 }
4799
Paul Moored621d352008-01-29 08:43:36 -05004800 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004801}
4802
Catherine Zhang2c7946a2006-03-20 22:41:23 -08004803static int selinux_socket_getpeersec_stream(struct socket *sock, char __user *optval,
4804 int __user *optlen, unsigned len)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004805{
4806 int err = 0;
4807 char *scontext;
4808 u32 scontext_len;
Paul Moore253bfae2010-04-22 14:46:19 -04004809 struct sk_security_struct *sksec = sock->sk->sk_security;
Paul Moore3de4bab2006-11-17 17:38:54 -05004810 u32 peer_sid = SECSID_NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004811
Paul Moore253bfae2010-04-22 14:46:19 -04004812 if (sksec->sclass == SECCLASS_UNIX_STREAM_SOCKET ||
Richard Hainesd4529302018-02-13 20:57:18 +00004813 sksec->sclass == SECCLASS_TCP_SOCKET ||
4814 sksec->sclass == SECCLASS_SCTP_SOCKET)
Eric Parisdd3e7832010-04-07 15:08:46 -04004815 peer_sid = sksec->peer_sid;
Paul Moore253bfae2010-04-22 14:46:19 -04004816 if (peer_sid == SECSID_NULL)
4817 return -ENOPROTOOPT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004818
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05004819 err = security_sid_to_context(&selinux_state, peer_sid, &scontext,
4820 &scontext_len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004821 if (err)
Paul Moore253bfae2010-04-22 14:46:19 -04004822 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004823
4824 if (scontext_len > len) {
4825 err = -ERANGE;
4826 goto out_len;
4827 }
4828
4829 if (copy_to_user(optval, scontext, scontext_len))
4830 err = -EFAULT;
4831
4832out_len:
4833 if (put_user(scontext_len, optlen))
4834 err = -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004835 kfree(scontext);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004836 return err;
4837}
4838
Catherine Zhangdc49c1f2006-08-02 14:12:06 -07004839static int selinux_socket_getpeersec_dgram(struct socket *sock, struct sk_buff *skb, u32 *secid)
Catherine Zhang2c7946a2006-03-20 22:41:23 -08004840{
Catherine Zhangdc49c1f2006-08-02 14:12:06 -07004841 u32 peer_secid = SECSID_NULL;
Paul Moore75e22912008-01-29 08:38:04 -05004842 u16 family;
Paul Moore899134f2016-03-28 15:19:10 -04004843 struct inode_security_struct *isec;
Catherine Zhang877ce7c2006-06-29 12:27:47 -07004844
Paul Mooreaa862902008-10-10 10:16:29 -04004845 if (skb && skb->protocol == htons(ETH_P_IP))
4846 family = PF_INET;
4847 else if (skb && skb->protocol == htons(ETH_P_IPV6))
4848 family = PF_INET6;
4849 else if (sock)
Paul Moore75e22912008-01-29 08:38:04 -05004850 family = sock->sk->sk_family;
Paul Moore75e22912008-01-29 08:38:04 -05004851 else
4852 goto out;
4853
Paul Moore899134f2016-03-28 15:19:10 -04004854 if (sock && family == PF_UNIX) {
4855 isec = inode_security_novalidate(SOCK_INODE(sock));
4856 peer_secid = isec->sid;
4857 } else if (skb)
Paul Moore220deb92008-01-29 08:38:23 -05004858 selinux_skb_peerlbl_sid(skb, family, &peer_secid);
Catherine Zhang2c7946a2006-03-20 22:41:23 -08004859
Paul Moore75e22912008-01-29 08:38:04 -05004860out:
Catherine Zhangdc49c1f2006-08-02 14:12:06 -07004861 *secid = peer_secid;
Paul Moore75e22912008-01-29 08:38:04 -05004862 if (peer_secid == SECSID_NULL)
4863 return -EINVAL;
4864 return 0;
Catherine Zhang2c7946a2006-03-20 22:41:23 -08004865}
4866
Al Viro7d877f32005-10-21 03:20:43 -04004867static int selinux_sk_alloc_security(struct sock *sk, int family, gfp_t priority)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004868{
Paul Moore84914b72010-04-22 14:46:18 -04004869 struct sk_security_struct *sksec;
4870
4871 sksec = kzalloc(sizeof(*sksec), priority);
4872 if (!sksec)
4873 return -ENOMEM;
4874
4875 sksec->peer_sid = SECINITSID_UNLABELED;
4876 sksec->sid = SECINITSID_UNLABELED;
Stephen Smalley5dee25d2015-07-10 17:19:57 -04004877 sksec->sclass = SECCLASS_SOCKET;
Paul Moore84914b72010-04-22 14:46:18 -04004878 selinux_netlbl_sk_security_reset(sksec);
4879 sk->sk_security = sksec;
4880
4881 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004882}
4883
4884static void selinux_sk_free_security(struct sock *sk)
4885{
Paul Moore84914b72010-04-22 14:46:18 -04004886 struct sk_security_struct *sksec = sk->sk_security;
4887
4888 sk->sk_security = NULL;
4889 selinux_netlbl_sk_security_free(sksec);
4890 kfree(sksec);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004891}
4892
Venkat Yekkirala892c1412006-08-04 23:08:56 -07004893static void selinux_sk_clone_security(const struct sock *sk, struct sock *newsk)
4894{
Eric Parisdd3e7832010-04-07 15:08:46 -04004895 struct sk_security_struct *sksec = sk->sk_security;
4896 struct sk_security_struct *newsksec = newsk->sk_security;
Venkat Yekkirala892c1412006-08-04 23:08:56 -07004897
Eric Parisdd3e7832010-04-07 15:08:46 -04004898 newsksec->sid = sksec->sid;
4899 newsksec->peer_sid = sksec->peer_sid;
4900 newsksec->sclass = sksec->sclass;
Paul Moore99f59ed2006-08-29 17:53:48 -07004901
Eric Parisdd3e7832010-04-07 15:08:46 -04004902 selinux_netlbl_sk_security_reset(newsksec);
Venkat Yekkirala892c1412006-08-04 23:08:56 -07004903}
4904
Venkat Yekkiralabeb8d132006-08-04 23:12:42 -07004905static void selinux_sk_getsecid(struct sock *sk, u32 *secid)
Trent Jaegerd28d1e02005-12-13 23:12:40 -08004906{
Trent Jaegerd28d1e02005-12-13 23:12:40 -08004907 if (!sk)
Venkat Yekkiralabeb8d132006-08-04 23:12:42 -07004908 *secid = SECINITSID_ANY_SOCKET;
Venkat Yekkirala892c1412006-08-04 23:08:56 -07004909 else {
4910 struct sk_security_struct *sksec = sk->sk_security;
Trent Jaegerd28d1e02005-12-13 23:12:40 -08004911
Venkat Yekkiralabeb8d132006-08-04 23:12:42 -07004912 *secid = sksec->sid;
Venkat Yekkirala892c1412006-08-04 23:08:56 -07004913 }
Trent Jaegerd28d1e02005-12-13 23:12:40 -08004914}
4915
Eric Paris828dfe12008-04-17 13:17:49 -04004916static void selinux_sock_graft(struct sock *sk, struct socket *parent)
Venkat Yekkirala4237c752006-07-24 23:32:50 -07004917{
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -05004918 struct inode_security_struct *isec =
4919 inode_security_novalidate(SOCK_INODE(parent));
Venkat Yekkirala4237c752006-07-24 23:32:50 -07004920 struct sk_security_struct *sksec = sk->sk_security;
4921
Paul Moore2873ead2014-07-28 10:42:48 -04004922 if (sk->sk_family == PF_INET || sk->sk_family == PF_INET6 ||
4923 sk->sk_family == PF_UNIX)
David Woodhouse2148ccc2006-09-29 15:50:25 -07004924 isec->sid = sksec->sid;
Paul Moore220deb92008-01-29 08:38:23 -05004925 sksec->sclass = isec->sclass;
Venkat Yekkirala4237c752006-07-24 23:32:50 -07004926}
4927
Richard Hainesd4529302018-02-13 20:57:18 +00004928/* Called whenever SCTP receives an INIT chunk. This happens when an incoming
4929 * connect(2), sctp_connectx(3) or sctp_sendmsg(3) (with no association
4930 * already present).
4931 */
4932static int selinux_sctp_assoc_request(struct sctp_endpoint *ep,
4933 struct sk_buff *skb)
4934{
4935 struct sk_security_struct *sksec = ep->base.sk->sk_security;
4936 struct common_audit_data ad;
4937 struct lsm_network_audit net = {0,};
4938 u8 peerlbl_active;
4939 u32 peer_sid = SECINITSID_UNLABELED;
4940 u32 conn_sid;
4941 int err = 0;
4942
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05004943 if (!selinux_policycap_extsockclass())
Richard Hainesd4529302018-02-13 20:57:18 +00004944 return 0;
4945
4946 peerlbl_active = selinux_peerlbl_enabled();
4947
4948 if (peerlbl_active) {
4949 /* This will return peer_sid = SECSID_NULL if there are
4950 * no peer labels, see security_net_peersid_resolve().
4951 */
4952 err = selinux_skb_peerlbl_sid(skb, ep->base.sk->sk_family,
4953 &peer_sid);
4954 if (err)
4955 return err;
4956
4957 if (peer_sid == SECSID_NULL)
4958 peer_sid = SECINITSID_UNLABELED;
4959 }
4960
4961 if (sksec->sctp_assoc_state == SCTP_ASSOC_UNSET) {
4962 sksec->sctp_assoc_state = SCTP_ASSOC_SET;
4963
4964 /* Here as first association on socket. As the peer SID
4965 * was allowed by peer recv (and the netif/node checks),
4966 * then it is approved by policy and used as the primary
4967 * peer SID for getpeercon(3).
4968 */
4969 sksec->peer_sid = peer_sid;
4970 } else if (sksec->peer_sid != peer_sid) {
4971 /* Other association peer SIDs are checked to enforce
4972 * consistency among the peer SIDs.
4973 */
4974 ad.type = LSM_AUDIT_DATA_NET;
4975 ad.u.net = &net;
4976 ad.u.net->sk = ep->base.sk;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05004977 err = avc_has_perm(&selinux_state,
4978 sksec->peer_sid, peer_sid, sksec->sclass,
Richard Hainesd4529302018-02-13 20:57:18 +00004979 SCTP_SOCKET__ASSOCIATION, &ad);
4980 if (err)
4981 return err;
4982 }
4983
4984 /* Compute the MLS component for the connection and store
4985 * the information in ep. This will be used by SCTP TCP type
4986 * sockets and peeled off connections as they cause a new
4987 * socket to be generated. selinux_sctp_sk_clone() will then
4988 * plug this into the new socket.
4989 */
4990 err = selinux_conn_sid(sksec->sid, peer_sid, &conn_sid);
4991 if (err)
4992 return err;
4993
4994 ep->secid = conn_sid;
4995 ep->peer_secid = peer_sid;
4996
4997 /* Set any NetLabel labels including CIPSO/CALIPSO options. */
4998 return selinux_netlbl_sctp_assoc_request(ep, skb);
4999}
5000
5001/* Check if sctp IPv4/IPv6 addresses are valid for binding or connecting
5002 * based on their @optname.
5003 */
5004static int selinux_sctp_bind_connect(struct sock *sk, int optname,
5005 struct sockaddr *address,
5006 int addrlen)
5007{
5008 int len, err = 0, walk_size = 0;
5009 void *addr_buf;
5010 struct sockaddr *addr;
5011 struct socket *sock;
5012
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05005013 if (!selinux_policycap_extsockclass())
Richard Hainesd4529302018-02-13 20:57:18 +00005014 return 0;
5015
5016 /* Process one or more addresses that may be IPv4 or IPv6 */
5017 sock = sk->sk_socket;
5018 addr_buf = address;
5019
5020 while (walk_size < addrlen) {
Ondrej Mosnacekc1383252018-11-13 16:16:08 +01005021 if (walk_size + sizeof(sa_family_t) > addrlen)
5022 return -EINVAL;
5023
Richard Hainesd4529302018-02-13 20:57:18 +00005024 addr = addr_buf;
5025 switch (addr->sa_family) {
Alexey Kodanev4152dc92018-05-11 20:15:13 +03005026 case AF_UNSPEC:
Richard Hainesd4529302018-02-13 20:57:18 +00005027 case AF_INET:
5028 len = sizeof(struct sockaddr_in);
5029 break;
5030 case AF_INET6:
5031 len = sizeof(struct sockaddr_in6);
5032 break;
5033 default:
Alexey Kodanev4152dc92018-05-11 20:15:13 +03005034 return -EINVAL;
Richard Hainesd4529302018-02-13 20:57:18 +00005035 }
5036
5037 err = -EINVAL;
5038 switch (optname) {
5039 /* Bind checks */
5040 case SCTP_PRIMARY_ADDR:
5041 case SCTP_SET_PEER_PRIMARY_ADDR:
5042 case SCTP_SOCKOPT_BINDX_ADD:
5043 err = selinux_socket_bind(sock, addr, len);
5044 break;
5045 /* Connect checks */
5046 case SCTP_SOCKOPT_CONNECTX:
5047 case SCTP_PARAM_SET_PRIMARY:
5048 case SCTP_PARAM_ADD_IP:
5049 case SCTP_SENDMSG_CONNECT:
5050 err = selinux_socket_connect_helper(sock, addr, len);
5051 if (err)
5052 return err;
5053
5054 /* As selinux_sctp_bind_connect() is called by the
5055 * SCTP protocol layer, the socket is already locked,
5056 * therefore selinux_netlbl_socket_connect_locked() is
5057 * is called here. The situations handled are:
5058 * sctp_connectx(3), sctp_sendmsg(3), sendmsg(2),
5059 * whenever a new IP address is added or when a new
5060 * primary address is selected.
5061 * Note that an SCTP connect(2) call happens before
5062 * the SCTP protocol layer and is handled via
5063 * selinux_socket_connect().
5064 */
5065 err = selinux_netlbl_socket_connect_locked(sk, addr);
5066 break;
5067 }
5068
5069 if (err)
5070 return err;
5071
5072 addr_buf += len;
5073 walk_size += len;
5074 }
5075
5076 return 0;
5077}
5078
5079/* Called whenever a new socket is created by accept(2) or sctp_peeloff(3). */
5080static void selinux_sctp_sk_clone(struct sctp_endpoint *ep, struct sock *sk,
5081 struct sock *newsk)
5082{
5083 struct sk_security_struct *sksec = sk->sk_security;
5084 struct sk_security_struct *newsksec = newsk->sk_security;
5085
5086 /* If policy does not support SECCLASS_SCTP_SOCKET then call
5087 * the non-sctp clone version.
5088 */
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05005089 if (!selinux_policycap_extsockclass())
Richard Hainesd4529302018-02-13 20:57:18 +00005090 return selinux_sk_clone_security(sk, newsk);
5091
5092 newsksec->sid = ep->secid;
5093 newsksec->peer_sid = ep->peer_secid;
5094 newsksec->sclass = sksec->sclass;
5095 selinux_netlbl_sctp_sk_clone(sk, newsk);
5096}
5097
Adrian Bunk9a673e52006-08-15 00:03:53 -07005098static int selinux_inet_conn_request(struct sock *sk, struct sk_buff *skb,
5099 struct request_sock *req)
Venkat Yekkirala4237c752006-07-24 23:32:50 -07005100{
5101 struct sk_security_struct *sksec = sk->sk_security;
5102 int err;
Paul Moore0b1f24e2013-12-03 11:39:13 -05005103 u16 family = req->rsk_ops->family;
Paul Moore446b8022013-12-04 16:10:51 -05005104 u32 connsid;
Venkat Yekkirala4237c752006-07-24 23:32:50 -07005105 u32 peersid;
5106
Paul Mooreaa862902008-10-10 10:16:29 -04005107 err = selinux_skb_peerlbl_sid(skb, family, &peersid);
Paul Moore220deb92008-01-29 08:38:23 -05005108 if (err)
5109 return err;
Paul Moore446b8022013-12-04 16:10:51 -05005110 err = selinux_conn_sid(sksec->sid, peersid, &connsid);
5111 if (err)
5112 return err;
5113 req->secid = connsid;
5114 req->peer_secid = peersid;
Venkat Yekkiralaa51c64f2006-07-27 22:01:34 -07005115
Paul Moore389fb8002009-03-27 17:10:34 -04005116 return selinux_netlbl_inet_conn_request(req, family);
Venkat Yekkirala4237c752006-07-24 23:32:50 -07005117}
5118
Adrian Bunk9a673e52006-08-15 00:03:53 -07005119static void selinux_inet_csk_clone(struct sock *newsk,
5120 const struct request_sock *req)
Venkat Yekkirala4237c752006-07-24 23:32:50 -07005121{
5122 struct sk_security_struct *newsksec = newsk->sk_security;
5123
5124 newsksec->sid = req->secid;
Venkat Yekkirala6b877692006-11-08 17:04:09 -06005125 newsksec->peer_sid = req->peer_secid;
Venkat Yekkirala4237c752006-07-24 23:32:50 -07005126 /* NOTE: Ideally, we should also get the isec->sid for the
5127 new socket in sync, but we don't have the isec available yet.
5128 So we will wait until sock_graft to do it, by which
5129 time it will have been created and available. */
Paul Moore99f59ed2006-08-29 17:53:48 -07005130
Paul Moore9f2ad662006-11-17 17:38:53 -05005131 /* We don't need to take any sort of lock here as we are the only
5132 * thread with access to newsksec */
Paul Moore389fb8002009-03-27 17:10:34 -04005133 selinux_netlbl_inet_csk_clone(newsk, req->rsk_ops->family);
Venkat Yekkirala4237c752006-07-24 23:32:50 -07005134}
5135
Paul Moore014ab192008-10-10 10:16:33 -04005136static void selinux_inet_conn_established(struct sock *sk, struct sk_buff *skb)
Venkat Yekkirala6b877692006-11-08 17:04:09 -06005137{
Paul Mooreaa862902008-10-10 10:16:29 -04005138 u16 family = sk->sk_family;
Venkat Yekkirala6b877692006-11-08 17:04:09 -06005139 struct sk_security_struct *sksec = sk->sk_security;
5140
Paul Mooreaa862902008-10-10 10:16:29 -04005141 /* handle mapped IPv4 packets arriving via IPv6 sockets */
5142 if (family == PF_INET6 && skb->protocol == htons(ETH_P_IP))
5143 family = PF_INET;
5144
5145 selinux_skb_peerlbl_sid(skb, family, &sksec->peer_sid);
Venkat Yekkirala6b877692006-11-08 17:04:09 -06005146}
5147
Eric Paris2606fd12010-10-13 16:24:41 -04005148static int selinux_secmark_relabel_packet(u32 sid)
5149{
5150 const struct task_security_struct *__tsec;
5151 u32 tsid;
5152
Casey Schaufler0c6cfa62018-09-21 17:17:16 -07005153 __tsec = selinux_cred(current_cred());
Eric Paris2606fd12010-10-13 16:24:41 -04005154 tsid = __tsec->sid;
5155
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005156 return avc_has_perm(&selinux_state,
5157 tsid, sid, SECCLASS_PACKET, PACKET__RELABELTO,
5158 NULL);
Eric Paris2606fd12010-10-13 16:24:41 -04005159}
5160
5161static void selinux_secmark_refcount_inc(void)
5162{
5163 atomic_inc(&selinux_secmark_refcount);
5164}
5165
5166static void selinux_secmark_refcount_dec(void)
5167{
5168 atomic_dec(&selinux_secmark_refcount);
5169}
5170
Adrian Bunk9a673e52006-08-15 00:03:53 -07005171static void selinux_req_classify_flow(const struct request_sock *req,
5172 struct flowi *fl)
Venkat Yekkirala4237c752006-07-24 23:32:50 -07005173{
David S. Miller1d28f422011-03-12 00:29:39 -05005174 fl->flowi_secid = req->secid;
Venkat Yekkirala4237c752006-07-24 23:32:50 -07005175}
5176
Paul Moore5dbbaf22013-01-14 07:12:19 +00005177static int selinux_tun_dev_alloc_security(void **security)
5178{
5179 struct tun_security_struct *tunsec;
5180
5181 tunsec = kzalloc(sizeof(*tunsec), GFP_KERNEL);
5182 if (!tunsec)
5183 return -ENOMEM;
5184 tunsec->sid = current_sid();
5185
5186 *security = tunsec;
5187 return 0;
5188}
5189
5190static void selinux_tun_dev_free_security(void *security)
5191{
5192 kfree(security);
5193}
5194
Paul Mooreed6d76e2009-08-28 18:12:49 -04005195static int selinux_tun_dev_create(void)
5196{
5197 u32 sid = current_sid();
5198
5199 /* we aren't taking into account the "sockcreate" SID since the socket
5200 * that is being created here is not a socket in the traditional sense,
5201 * instead it is a private sock, accessible only to the kernel, and
5202 * representing a wide range of network traffic spanning multiple
5203 * connections unlike traditional sockets - check the TUN driver to
5204 * get a better understanding of why this socket is special */
5205
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005206 return avc_has_perm(&selinux_state,
5207 sid, sid, SECCLASS_TUN_SOCKET, TUN_SOCKET__CREATE,
Paul Mooreed6d76e2009-08-28 18:12:49 -04005208 NULL);
5209}
5210
Paul Moore5dbbaf22013-01-14 07:12:19 +00005211static int selinux_tun_dev_attach_queue(void *security)
Paul Mooreed6d76e2009-08-28 18:12:49 -04005212{
Paul Moore5dbbaf22013-01-14 07:12:19 +00005213 struct tun_security_struct *tunsec = security;
5214
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005215 return avc_has_perm(&selinux_state,
5216 current_sid(), tunsec->sid, SECCLASS_TUN_SOCKET,
Paul Moore5dbbaf22013-01-14 07:12:19 +00005217 TUN_SOCKET__ATTACH_QUEUE, NULL);
5218}
5219
5220static int selinux_tun_dev_attach(struct sock *sk, void *security)
5221{
5222 struct tun_security_struct *tunsec = security;
Paul Mooreed6d76e2009-08-28 18:12:49 -04005223 struct sk_security_struct *sksec = sk->sk_security;
5224
5225 /* we don't currently perform any NetLabel based labeling here and it
5226 * isn't clear that we would want to do so anyway; while we could apply
5227 * labeling without the support of the TUN user the resulting labeled
5228 * traffic from the other end of the connection would almost certainly
5229 * cause confusion to the TUN user that had no idea network labeling
5230 * protocols were being used */
5231
Paul Moore5dbbaf22013-01-14 07:12:19 +00005232 sksec->sid = tunsec->sid;
Paul Mooreed6d76e2009-08-28 18:12:49 -04005233 sksec->sclass = SECCLASS_TUN_SOCKET;
Paul Moore5dbbaf22013-01-14 07:12:19 +00005234
5235 return 0;
Paul Mooreed6d76e2009-08-28 18:12:49 -04005236}
5237
Paul Moore5dbbaf22013-01-14 07:12:19 +00005238static int selinux_tun_dev_open(void *security)
Paul Mooreed6d76e2009-08-28 18:12:49 -04005239{
Paul Moore5dbbaf22013-01-14 07:12:19 +00005240 struct tun_security_struct *tunsec = security;
Paul Mooreed6d76e2009-08-28 18:12:49 -04005241 u32 sid = current_sid();
5242 int err;
5243
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005244 err = avc_has_perm(&selinux_state,
5245 sid, tunsec->sid, SECCLASS_TUN_SOCKET,
Paul Mooreed6d76e2009-08-28 18:12:49 -04005246 TUN_SOCKET__RELABELFROM, NULL);
5247 if (err)
5248 return err;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005249 err = avc_has_perm(&selinux_state,
5250 sid, sid, SECCLASS_TUN_SOCKET,
Paul Mooreed6d76e2009-08-28 18:12:49 -04005251 TUN_SOCKET__RELABELTO, NULL);
5252 if (err)
5253 return err;
Paul Moore5dbbaf22013-01-14 07:12:19 +00005254 tunsec->sid = sid;
Paul Mooreed6d76e2009-08-28 18:12:49 -04005255
5256 return 0;
5257}
5258
Linus Torvalds1da177e2005-04-16 15:20:36 -07005259static int selinux_nlmsg_perm(struct sock *sk, struct sk_buff *skb)
5260{
5261 int err = 0;
5262 u32 perm;
5263 struct nlmsghdr *nlh;
Paul Moore253bfae2010-04-22 14:46:19 -04005264 struct sk_security_struct *sksec = sk->sk_security;
Eric Paris828dfe12008-04-17 13:17:49 -04005265
Hong zhi guo77954982013-03-27 06:49:35 +00005266 if (skb->len < NLMSG_HDRLEN) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005267 err = -EINVAL;
5268 goto out;
5269 }
Arnaldo Carvalho de Melob529ccf2007-04-25 19:08:35 -07005270 nlh = nlmsg_hdr(skb);
Eric Paris828dfe12008-04-17 13:17:49 -04005271
Paul Moore253bfae2010-04-22 14:46:19 -04005272 err = selinux_nlmsg_lookup(sksec->sclass, nlh->nlmsg_type, &perm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005273 if (err) {
5274 if (err == -EINVAL) {
Vladis Dronov76319942015-12-24 11:09:41 -05005275 pr_warn_ratelimited("SELinux: unrecognized netlink"
5276 " message: protocol=%hu nlmsg_type=%hu sclass=%s"
5277 " pig=%d comm=%s\n",
Marek Milkoviccded3ff2015-06-04 16:22:16 -04005278 sk->sk_protocol, nlh->nlmsg_type,
Vladis Dronov76319942015-12-24 11:09:41 -05005279 secclass_map[sksec->sclass - 1].name,
5280 task_pid_nr(current), current->comm);
Paul Mooree5a5ca92018-03-01 17:38:30 -05005281 if (!enforcing_enabled(&selinux_state) ||
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05005282 security_get_allow_unknown(&selinux_state))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005283 err = 0;
5284 }
5285
5286 /* Ignore */
5287 if (err == -ENOENT)
5288 err = 0;
5289 goto out;
5290 }
5291
Stephen Smalleybe0554c2017-01-09 10:07:31 -05005292 err = sock_has_perm(sk, perm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005293out:
5294 return err;
5295}
5296
5297#ifdef CONFIG_NETFILTER
5298
Paul Moorecbe0d6e2014-09-10 17:09:57 -04005299static unsigned int selinux_ip_forward(struct sk_buff *skb,
5300 const struct net_device *indev,
Paul Mooreeffad8d2008-01-29 08:49:27 -05005301 u16 family)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005302{
Paul Mooredfaebe92008-10-10 10:16:31 -04005303 int err;
Paul Mooreeffad8d2008-01-29 08:49:27 -05005304 char *addrp;
5305 u32 peer_sid;
Thomas Liu2bf49692009-07-14 12:14:09 -04005306 struct common_audit_data ad;
Eric Paris48c62af2012-04-02 13:15:44 -04005307 struct lsm_network_audit net = {0,};
Paul Mooreeffad8d2008-01-29 08:49:27 -05005308 u8 secmark_active;
Paul Moore948bf852008-10-10 10:16:32 -04005309 u8 netlbl_active;
Paul Mooreeffad8d2008-01-29 08:49:27 -05005310 u8 peerlbl_active;
Venkat Yekkirala4237c752006-07-24 23:32:50 -07005311
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05005312 if (!selinux_policycap_netpeer())
Paul Mooreeffad8d2008-01-29 08:49:27 -05005313 return NF_ACCEPT;
Venkat Yekkirala4237c752006-07-24 23:32:50 -07005314
Paul Mooreeffad8d2008-01-29 08:49:27 -05005315 secmark_active = selinux_secmark_enabled();
Paul Moore948bf852008-10-10 10:16:32 -04005316 netlbl_active = netlbl_enabled();
Chris PeBenito2be4d742013-05-03 09:05:39 -04005317 peerlbl_active = selinux_peerlbl_enabled();
Paul Mooreeffad8d2008-01-29 08:49:27 -05005318 if (!secmark_active && !peerlbl_active)
5319 return NF_ACCEPT;
Venkat Yekkirala4237c752006-07-24 23:32:50 -07005320
Paul Moored8395c82008-10-10 10:16:30 -04005321 if (selinux_skb_peerlbl_sid(skb, family, &peer_sid) != 0)
5322 return NF_DROP;
5323
Eric Paris50c205f2012-04-04 15:01:43 -04005324 ad.type = LSM_AUDIT_DATA_NET;
Eric Paris48c62af2012-04-02 13:15:44 -04005325 ad.u.net = &net;
Paul Moorecbe0d6e2014-09-10 17:09:57 -04005326 ad.u.net->netif = indev->ifindex;
Eric Paris48c62af2012-04-02 13:15:44 -04005327 ad.u.net->family = family;
Paul Mooreeffad8d2008-01-29 08:49:27 -05005328 if (selinux_parse_skb(skb, &ad, &addrp, 1, NULL) != 0)
5329 return NF_DROP;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005330
Paul Mooredfaebe92008-10-10 10:16:31 -04005331 if (peerlbl_active) {
Paul Moorecbe0d6e2014-09-10 17:09:57 -04005332 err = selinux_inet_sys_rcv_skb(dev_net(indev), indev->ifindex,
5333 addrp, family, peer_sid, &ad);
Paul Mooredfaebe92008-10-10 10:16:31 -04005334 if (err) {
Huw Daviesa04e71f2016-06-27 15:06:16 -04005335 selinux_netlbl_err(skb, family, err, 1);
Paul Mooreeffad8d2008-01-29 08:49:27 -05005336 return NF_DROP;
Paul Mooredfaebe92008-10-10 10:16:31 -04005337 }
5338 }
Paul Mooreeffad8d2008-01-29 08:49:27 -05005339
5340 if (secmark_active)
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005341 if (avc_has_perm(&selinux_state,
5342 peer_sid, skb->secmark,
Paul Mooreeffad8d2008-01-29 08:49:27 -05005343 SECCLASS_PACKET, PACKET__FORWARD_IN, &ad))
5344 return NF_DROP;
5345
Paul Moore948bf852008-10-10 10:16:32 -04005346 if (netlbl_active)
5347 /* we do this in the FORWARD path and not the POST_ROUTING
5348 * path because we want to make sure we apply the necessary
5349 * labeling before IPsec is applied so we can leverage AH
5350 * protection */
5351 if (selinux_netlbl_skbuff_setsid(skb, family, peer_sid) != 0)
5352 return NF_DROP;
5353
Paul Mooreeffad8d2008-01-29 08:49:27 -05005354 return NF_ACCEPT;
5355}
5356
Eric W. Biederman06198b32015-09-18 14:33:06 -05005357static unsigned int selinux_ipv4_forward(void *priv,
Paul Mooreeffad8d2008-01-29 08:49:27 -05005358 struct sk_buff *skb,
David S. Miller238e54c2015-04-03 20:32:56 -04005359 const struct nf_hook_state *state)
Paul Mooreeffad8d2008-01-29 08:49:27 -05005360{
David S. Miller238e54c2015-04-03 20:32:56 -04005361 return selinux_ip_forward(skb, state->in, PF_INET);
Paul Mooreeffad8d2008-01-29 08:49:27 -05005362}
5363
Javier Martinez Canillas1a93a6e2016-08-08 13:08:25 -04005364#if IS_ENABLED(CONFIG_IPV6)
Eric W. Biederman06198b32015-09-18 14:33:06 -05005365static unsigned int selinux_ipv6_forward(void *priv,
Paul Mooreeffad8d2008-01-29 08:49:27 -05005366 struct sk_buff *skb,
David S. Miller238e54c2015-04-03 20:32:56 -04005367 const struct nf_hook_state *state)
Paul Mooreeffad8d2008-01-29 08:49:27 -05005368{
David S. Miller238e54c2015-04-03 20:32:56 -04005369 return selinux_ip_forward(skb, state->in, PF_INET6);
Paul Mooreeffad8d2008-01-29 08:49:27 -05005370}
5371#endif /* IPV6 */
5372
Paul Moore948bf852008-10-10 10:16:32 -04005373static unsigned int selinux_ip_output(struct sk_buff *skb,
5374 u16 family)
5375{
Paul Moore47180062013-12-04 16:10:45 -05005376 struct sock *sk;
Paul Moore948bf852008-10-10 10:16:32 -04005377 u32 sid;
5378
5379 if (!netlbl_enabled())
5380 return NF_ACCEPT;
5381
5382 /* we do this in the LOCAL_OUT path and not the POST_ROUTING path
5383 * because we want to make sure we apply the necessary labeling
5384 * before IPsec is applied so we can leverage AH protection */
Paul Moore47180062013-12-04 16:10:45 -05005385 sk = skb->sk;
5386 if (sk) {
5387 struct sk_security_struct *sksec;
5388
Eric Dumazete446f9d2015-10-08 05:01:55 -07005389 if (sk_listener(sk))
Paul Moore47180062013-12-04 16:10:45 -05005390 /* if the socket is the listening state then this
5391 * packet is a SYN-ACK packet which means it needs to
5392 * be labeled based on the connection/request_sock and
5393 * not the parent socket. unfortunately, we can't
5394 * lookup the request_sock yet as it isn't queued on
5395 * the parent socket until after the SYN-ACK is sent.
5396 * the "solution" is to simply pass the packet as-is
5397 * as any IP option based labeling should be copied
5398 * from the initial connection request (in the IP
5399 * layer). it is far from ideal, but until we get a
5400 * security label in the packet itself this is the
5401 * best we can do. */
5402 return NF_ACCEPT;
5403
5404 /* standard practice, label using the parent socket */
5405 sksec = sk->sk_security;
Paul Moore948bf852008-10-10 10:16:32 -04005406 sid = sksec->sid;
5407 } else
5408 sid = SECINITSID_KERNEL;
5409 if (selinux_netlbl_skbuff_setsid(skb, family, sid) != 0)
5410 return NF_DROP;
5411
5412 return NF_ACCEPT;
5413}
5414
Eric W. Biederman06198b32015-09-18 14:33:06 -05005415static unsigned int selinux_ipv4_output(void *priv,
Paul Moore948bf852008-10-10 10:16:32 -04005416 struct sk_buff *skb,
David S. Miller238e54c2015-04-03 20:32:56 -04005417 const struct nf_hook_state *state)
Paul Moore948bf852008-10-10 10:16:32 -04005418{
5419 return selinux_ip_output(skb, PF_INET);
5420}
5421
Javier Martinez Canillas1a93a6e2016-08-08 13:08:25 -04005422#if IS_ENABLED(CONFIG_IPV6)
Huw Davies2917f572016-06-27 15:06:15 -04005423static unsigned int selinux_ipv6_output(void *priv,
5424 struct sk_buff *skb,
5425 const struct nf_hook_state *state)
5426{
5427 return selinux_ip_output(skb, PF_INET6);
5428}
5429#endif /* IPV6 */
5430
Paul Mooreeffad8d2008-01-29 08:49:27 -05005431static unsigned int selinux_ip_postroute_compat(struct sk_buff *skb,
5432 int ifindex,
Paul Moored8395c82008-10-10 10:16:30 -04005433 u16 family)
James Morris4e5ab4c2006-06-09 00:33:33 -07005434{
Eric Dumazet54abc682015-11-08 10:54:07 -08005435 struct sock *sk = skb_to_full_sk(skb);
Venkat Yekkirala4237c752006-07-24 23:32:50 -07005436 struct sk_security_struct *sksec;
Thomas Liu2bf49692009-07-14 12:14:09 -04005437 struct common_audit_data ad;
Eric Paris48c62af2012-04-02 13:15:44 -04005438 struct lsm_network_audit net = {0,};
Paul Moored8395c82008-10-10 10:16:30 -04005439 char *addrp;
5440 u8 proto;
James Morris4e5ab4c2006-06-09 00:33:33 -07005441
Paul Mooreeffad8d2008-01-29 08:49:27 -05005442 if (sk == NULL)
5443 return NF_ACCEPT;
Venkat Yekkirala4237c752006-07-24 23:32:50 -07005444 sksec = sk->sk_security;
James Morris4e5ab4c2006-06-09 00:33:33 -07005445
Eric Paris50c205f2012-04-04 15:01:43 -04005446 ad.type = LSM_AUDIT_DATA_NET;
Eric Paris48c62af2012-04-02 13:15:44 -04005447 ad.u.net = &net;
5448 ad.u.net->netif = ifindex;
5449 ad.u.net->family = family;
Paul Moored8395c82008-10-10 10:16:30 -04005450 if (selinux_parse_skb(skb, &ad, &addrp, 0, &proto))
5451 return NF_DROP;
5452
Paul Moore58bfbb52009-03-27 17:10:41 -04005453 if (selinux_secmark_enabled())
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005454 if (avc_has_perm(&selinux_state,
5455 sksec->sid, skb->secmark,
Paul Moored8395c82008-10-10 10:16:30 -04005456 SECCLASS_PACKET, PACKET__SEND, &ad))
Eric Paris2fe66ec2010-11-23 06:28:08 +00005457 return NF_DROP_ERR(-ECONNREFUSED);
James Morris4e5ab4c2006-06-09 00:33:33 -07005458
Steffen Klassertb9679a72011-02-23 12:55:21 +01005459 if (selinux_xfrm_postroute_last(sksec->sid, skb, &ad, proto))
5460 return NF_DROP_ERR(-ECONNREFUSED);
James Morris4e5ab4c2006-06-09 00:33:33 -07005461
Paul Mooreeffad8d2008-01-29 08:49:27 -05005462 return NF_ACCEPT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005463}
5464
Paul Moorecbe0d6e2014-09-10 17:09:57 -04005465static unsigned int selinux_ip_postroute(struct sk_buff *skb,
5466 const struct net_device *outdev,
Paul Mooreeffad8d2008-01-29 08:49:27 -05005467 u16 family)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005468{
Paul Mooreeffad8d2008-01-29 08:49:27 -05005469 u32 secmark_perm;
5470 u32 peer_sid;
Paul Moorecbe0d6e2014-09-10 17:09:57 -04005471 int ifindex = outdev->ifindex;
Paul Mooreeffad8d2008-01-29 08:49:27 -05005472 struct sock *sk;
Thomas Liu2bf49692009-07-14 12:14:09 -04005473 struct common_audit_data ad;
Eric Paris48c62af2012-04-02 13:15:44 -04005474 struct lsm_network_audit net = {0,};
Paul Mooreeffad8d2008-01-29 08:49:27 -05005475 char *addrp;
Paul Mooreeffad8d2008-01-29 08:49:27 -05005476 u8 secmark_active;
5477 u8 peerlbl_active;
5478
Paul Mooreeffad8d2008-01-29 08:49:27 -05005479 /* If any sort of compatibility mode is enabled then handoff processing
5480 * to the selinux_ip_postroute_compat() function to deal with the
5481 * special handling. We do this in an attempt to keep this function
5482 * as fast and as clean as possible. */
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05005483 if (!selinux_policycap_netpeer())
Paul Moored8395c82008-10-10 10:16:30 -04005484 return selinux_ip_postroute_compat(skb, ifindex, family);
Paul Moorec0828e52013-12-10 14:58:01 -05005485
Paul Mooreeffad8d2008-01-29 08:49:27 -05005486 secmark_active = selinux_secmark_enabled();
Chris PeBenito2be4d742013-05-03 09:05:39 -04005487 peerlbl_active = selinux_peerlbl_enabled();
Paul Mooreeffad8d2008-01-29 08:49:27 -05005488 if (!secmark_active && !peerlbl_active)
5489 return NF_ACCEPT;
5490
Eric Dumazet54abc682015-11-08 10:54:07 -08005491 sk = skb_to_full_sk(skb);
Paul Moorec0828e52013-12-10 14:58:01 -05005492
Paul Mooreeffad8d2008-01-29 08:49:27 -05005493#ifdef CONFIG_XFRM
5494 /* If skb->dst->xfrm is non-NULL then the packet is undergoing an IPsec
5495 * packet transformation so allow the packet to pass without any checks
5496 * since we'll have another chance to perform access control checks
5497 * when the packet is on it's final way out.
5498 * NOTE: there appear to be some IPv6 multicast cases where skb->dst
Paul Moorec0828e52013-12-10 14:58:01 -05005499 * is NULL, in this case go ahead and apply access control.
5500 * NOTE: if this is a local socket (skb->sk != NULL) that is in the
5501 * TCP listening state we cannot wait until the XFRM processing
5502 * is done as we will miss out on the SA label if we do;
5503 * unfortunately, this means more work, but it is only once per
5504 * connection. */
5505 if (skb_dst(skb) != NULL && skb_dst(skb)->xfrm != NULL &&
Eric Dumazete446f9d2015-10-08 05:01:55 -07005506 !(sk && sk_listener(sk)))
Paul Mooreeffad8d2008-01-29 08:49:27 -05005507 return NF_ACCEPT;
5508#endif
Paul Mooreeffad8d2008-01-29 08:49:27 -05005509
Paul Moored8395c82008-10-10 10:16:30 -04005510 if (sk == NULL) {
Paul Moore446b8022013-12-04 16:10:51 -05005511 /* Without an associated socket the packet is either coming
5512 * from the kernel or it is being forwarded; check the packet
5513 * to determine which and if the packet is being forwarded
5514 * query the packet directly to determine the security label. */
Steffen Klassert4a7ab3d2011-02-23 12:56:23 +01005515 if (skb->skb_iif) {
5516 secmark_perm = PACKET__FORWARD_OUT;
Paul Moored8395c82008-10-10 10:16:30 -04005517 if (selinux_skb_peerlbl_sid(skb, family, &peer_sid))
Eric Paris04f6d702010-11-23 06:28:02 +00005518 return NF_DROP;
Steffen Klassert4a7ab3d2011-02-23 12:56:23 +01005519 } else {
5520 secmark_perm = PACKET__SEND;
Paul Moored8395c82008-10-10 10:16:30 -04005521 peer_sid = SECINITSID_KERNEL;
Steffen Klassert4a7ab3d2011-02-23 12:56:23 +01005522 }
Eric Dumazete446f9d2015-10-08 05:01:55 -07005523 } else if (sk_listener(sk)) {
Paul Moore446b8022013-12-04 16:10:51 -05005524 /* Locally generated packet but the associated socket is in the
5525 * listening state which means this is a SYN-ACK packet. In
5526 * this particular case the correct security label is assigned
5527 * to the connection/request_sock but unfortunately we can't
5528 * query the request_sock as it isn't queued on the parent
5529 * socket until after the SYN-ACK packet is sent; the only
5530 * viable choice is to regenerate the label like we do in
5531 * selinux_inet_conn_request(). See also selinux_ip_output()
5532 * for similar problems. */
5533 u32 skb_sid;
Eric Dumazete446f9d2015-10-08 05:01:55 -07005534 struct sk_security_struct *sksec;
5535
Eric Dumazete446f9d2015-10-08 05:01:55 -07005536 sksec = sk->sk_security;
Paul Moore446b8022013-12-04 16:10:51 -05005537 if (selinux_skb_peerlbl_sid(skb, family, &skb_sid))
5538 return NF_DROP;
Paul Moorec0828e52013-12-10 14:58:01 -05005539 /* At this point, if the returned skb peerlbl is SECSID_NULL
5540 * and the packet has been through at least one XFRM
5541 * transformation then we must be dealing with the "final"
5542 * form of labeled IPsec packet; since we've already applied
5543 * all of our access controls on this packet we can safely
5544 * pass the packet. */
5545 if (skb_sid == SECSID_NULL) {
5546 switch (family) {
5547 case PF_INET:
5548 if (IPCB(skb)->flags & IPSKB_XFRM_TRANSFORMED)
5549 return NF_ACCEPT;
5550 break;
5551 case PF_INET6:
5552 if (IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED)
5553 return NF_ACCEPT;
Paul Moorea7a91a12014-09-03 10:51:59 -04005554 break;
Paul Moorec0828e52013-12-10 14:58:01 -05005555 default:
5556 return NF_DROP_ERR(-ECONNREFUSED);
5557 }
5558 }
Paul Moore446b8022013-12-04 16:10:51 -05005559 if (selinux_conn_sid(sksec->sid, skb_sid, &peer_sid))
5560 return NF_DROP;
5561 secmark_perm = PACKET__SEND;
Paul Moored8395c82008-10-10 10:16:30 -04005562 } else {
Paul Moore446b8022013-12-04 16:10:51 -05005563 /* Locally generated packet, fetch the security label from the
5564 * associated socket. */
Paul Mooreeffad8d2008-01-29 08:49:27 -05005565 struct sk_security_struct *sksec = sk->sk_security;
5566 peer_sid = sksec->sid;
5567 secmark_perm = PACKET__SEND;
Paul Mooreeffad8d2008-01-29 08:49:27 -05005568 }
5569
Eric Paris50c205f2012-04-04 15:01:43 -04005570 ad.type = LSM_AUDIT_DATA_NET;
Eric Paris48c62af2012-04-02 13:15:44 -04005571 ad.u.net = &net;
5572 ad.u.net->netif = ifindex;
5573 ad.u.net->family = family;
Paul Moored8395c82008-10-10 10:16:30 -04005574 if (selinux_parse_skb(skb, &ad, &addrp, 0, NULL))
Eric Paris04f6d702010-11-23 06:28:02 +00005575 return NF_DROP;
Paul Moored8395c82008-10-10 10:16:30 -04005576
Paul Mooreeffad8d2008-01-29 08:49:27 -05005577 if (secmark_active)
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005578 if (avc_has_perm(&selinux_state,
5579 peer_sid, skb->secmark,
Paul Mooreeffad8d2008-01-29 08:49:27 -05005580 SECCLASS_PACKET, secmark_perm, &ad))
Eric Paris1f1aaf82010-11-16 11:52:57 +00005581 return NF_DROP_ERR(-ECONNREFUSED);
Paul Mooreeffad8d2008-01-29 08:49:27 -05005582
5583 if (peerlbl_active) {
5584 u32 if_sid;
5585 u32 node_sid;
5586
Paul Moorecbe0d6e2014-09-10 17:09:57 -04005587 if (sel_netif_sid(dev_net(outdev), ifindex, &if_sid))
Eric Paris04f6d702010-11-23 06:28:02 +00005588 return NF_DROP;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005589 if (avc_has_perm(&selinux_state,
5590 peer_sid, if_sid,
Paul Mooreeffad8d2008-01-29 08:49:27 -05005591 SECCLASS_NETIF, NETIF__EGRESS, &ad))
Eric Paris1f1aaf82010-11-16 11:52:57 +00005592 return NF_DROP_ERR(-ECONNREFUSED);
Paul Mooreeffad8d2008-01-29 08:49:27 -05005593
5594 if (sel_netnode_sid(addrp, family, &node_sid))
Eric Paris04f6d702010-11-23 06:28:02 +00005595 return NF_DROP;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005596 if (avc_has_perm(&selinux_state,
5597 peer_sid, node_sid,
Paul Mooreeffad8d2008-01-29 08:49:27 -05005598 SECCLASS_NODE, NODE__SENDTO, &ad))
Eric Paris1f1aaf82010-11-16 11:52:57 +00005599 return NF_DROP_ERR(-ECONNREFUSED);
Paul Mooreeffad8d2008-01-29 08:49:27 -05005600 }
5601
5602 return NF_ACCEPT;
5603}
5604
Eric W. Biederman06198b32015-09-18 14:33:06 -05005605static unsigned int selinux_ipv4_postroute(void *priv,
Paul Mooreeffad8d2008-01-29 08:49:27 -05005606 struct sk_buff *skb,
David S. Miller238e54c2015-04-03 20:32:56 -04005607 const struct nf_hook_state *state)
Paul Mooreeffad8d2008-01-29 08:49:27 -05005608{
David S. Miller238e54c2015-04-03 20:32:56 -04005609 return selinux_ip_postroute(skb, state->out, PF_INET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005610}
5611
Javier Martinez Canillas1a93a6e2016-08-08 13:08:25 -04005612#if IS_ENABLED(CONFIG_IPV6)
Eric W. Biederman06198b32015-09-18 14:33:06 -05005613static unsigned int selinux_ipv6_postroute(void *priv,
Paul Mooreeffad8d2008-01-29 08:49:27 -05005614 struct sk_buff *skb,
David S. Miller238e54c2015-04-03 20:32:56 -04005615 const struct nf_hook_state *state)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005616{
David S. Miller238e54c2015-04-03 20:32:56 -04005617 return selinux_ip_postroute(skb, state->out, PF_INET6);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005618}
Linus Torvalds1da177e2005-04-16 15:20:36 -07005619#endif /* IPV6 */
5620
5621#endif /* CONFIG_NETFILTER */
5622
Linus Torvalds1da177e2005-04-16 15:20:36 -07005623static int selinux_netlink_send(struct sock *sk, struct sk_buff *skb)
5624{
Stephen Smalley941fc5b2009-10-01 14:48:23 -04005625 return selinux_nlmsg_perm(sk, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005626}
5627
Casey Schauflerecd5f822018-11-20 11:55:02 -08005628static void ipc_init_security(struct ipc_security_struct *isec, u16 sclass)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005629{
Linus Torvalds1da177e2005-04-16 15:20:36 -07005630 isec->sclass = sclass;
Stephen Smalleybe0554c2017-01-09 10:07:31 -05005631 isec->sid = current_sid();
Linus Torvalds1da177e2005-04-16 15:20:36 -07005632}
5633
5634static int msg_msg_alloc_security(struct msg_msg *msg)
5635{
5636 struct msg_security_struct *msec;
5637
Casey Schauflerecd5f822018-11-20 11:55:02 -08005638 msec = selinux_msg_msg(msg);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005639 msec->sid = SECINITSID_UNLABELED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005640
5641 return 0;
5642}
5643
Linus Torvalds1da177e2005-04-16 15:20:36 -07005644static int ipc_has_perm(struct kern_ipc_perm *ipc_perms,
Stephen Smalley6af963f2005-05-01 08:58:39 -07005645 u32 perms)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005646{
Linus Torvalds1da177e2005-04-16 15:20:36 -07005647 struct ipc_security_struct *isec;
Thomas Liu2bf49692009-07-14 12:14:09 -04005648 struct common_audit_data ad;
David Howells275bb412008-11-14 10:39:19 +11005649 u32 sid = current_sid();
Linus Torvalds1da177e2005-04-16 15:20:36 -07005650
Casey Schaufler7c653822018-09-21 17:19:45 -07005651 isec = selinux_ipc(ipc_perms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005652
Eric Paris50c205f2012-04-04 15:01:43 -04005653 ad.type = LSM_AUDIT_DATA_IPC;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005654 ad.u.ipc_id = ipc_perms->key;
5655
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005656 return avc_has_perm(&selinux_state,
5657 sid, isec->sid, isec->sclass, perms, &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005658}
5659
5660static int selinux_msg_msg_alloc_security(struct msg_msg *msg)
5661{
5662 return msg_msg_alloc_security(msg);
5663}
5664
Linus Torvalds1da177e2005-04-16 15:20:36 -07005665/* message queue security operations */
Eric W. Biedermand8c6e852018-03-22 21:22:26 -05005666static int selinux_msg_queue_alloc_security(struct kern_ipc_perm *msq)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005667{
Linus Torvalds1da177e2005-04-16 15:20:36 -07005668 struct ipc_security_struct *isec;
Thomas Liu2bf49692009-07-14 12:14:09 -04005669 struct common_audit_data ad;
David Howells275bb412008-11-14 10:39:19 +11005670 u32 sid = current_sid();
Linus Torvalds1da177e2005-04-16 15:20:36 -07005671 int rc;
5672
Casey Schauflerecd5f822018-11-20 11:55:02 -08005673 isec = selinux_ipc(msq);
5674 ipc_init_security(isec, SECCLASS_MSGQ);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005675
Eric Paris50c205f2012-04-04 15:01:43 -04005676 ad.type = LSM_AUDIT_DATA_IPC;
Eric W. Biedermand8c6e852018-03-22 21:22:26 -05005677 ad.u.ipc_id = msq->key;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005678
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005679 rc = avc_has_perm(&selinux_state,
5680 sid, isec->sid, SECCLASS_MSGQ,
Linus Torvalds1da177e2005-04-16 15:20:36 -07005681 MSGQ__CREATE, &ad);
Casey Schauflerecd5f822018-11-20 11:55:02 -08005682 return rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005683}
5684
Eric W. Biedermand8c6e852018-03-22 21:22:26 -05005685static int selinux_msg_queue_associate(struct kern_ipc_perm *msq, int msqflg)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005686{
Linus Torvalds1da177e2005-04-16 15:20:36 -07005687 struct ipc_security_struct *isec;
Thomas Liu2bf49692009-07-14 12:14:09 -04005688 struct common_audit_data ad;
David Howells275bb412008-11-14 10:39:19 +11005689 u32 sid = current_sid();
Linus Torvalds1da177e2005-04-16 15:20:36 -07005690
Casey Schaufler7c653822018-09-21 17:19:45 -07005691 isec = selinux_ipc(msq);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005692
Eric Paris50c205f2012-04-04 15:01:43 -04005693 ad.type = LSM_AUDIT_DATA_IPC;
Eric W. Biedermand8c6e852018-03-22 21:22:26 -05005694 ad.u.ipc_id = msq->key;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005695
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005696 return avc_has_perm(&selinux_state,
5697 sid, isec->sid, SECCLASS_MSGQ,
Linus Torvalds1da177e2005-04-16 15:20:36 -07005698 MSGQ__ASSOCIATE, &ad);
5699}
5700
Eric W. Biedermand8c6e852018-03-22 21:22:26 -05005701static int selinux_msg_queue_msgctl(struct kern_ipc_perm *msq, int cmd)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005702{
5703 int err;
5704 int perms;
5705
Eric Paris828dfe12008-04-17 13:17:49 -04005706 switch (cmd) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005707 case IPC_INFO:
5708 case MSG_INFO:
5709 /* No specific object, just general system-wide information. */
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005710 return avc_has_perm(&selinux_state,
5711 current_sid(), SECINITSID_KERNEL,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05005712 SECCLASS_SYSTEM, SYSTEM__IPC_INFO, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005713 case IPC_STAT:
5714 case MSG_STAT:
Davidlohr Bueso23c8cec2018-04-10 16:35:30 -07005715 case MSG_STAT_ANY:
Linus Torvalds1da177e2005-04-16 15:20:36 -07005716 perms = MSGQ__GETATTR | MSGQ__ASSOCIATE;
5717 break;
5718 case IPC_SET:
5719 perms = MSGQ__SETATTR;
5720 break;
5721 case IPC_RMID:
5722 perms = MSGQ__DESTROY;
5723 break;
5724 default:
5725 return 0;
5726 }
5727
Eric W. Biedermand8c6e852018-03-22 21:22:26 -05005728 err = ipc_has_perm(msq, perms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005729 return err;
5730}
5731
Eric W. Biedermand8c6e852018-03-22 21:22:26 -05005732static int selinux_msg_queue_msgsnd(struct kern_ipc_perm *msq, struct msg_msg *msg, int msqflg)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005733{
Linus Torvalds1da177e2005-04-16 15:20:36 -07005734 struct ipc_security_struct *isec;
5735 struct msg_security_struct *msec;
Thomas Liu2bf49692009-07-14 12:14:09 -04005736 struct common_audit_data ad;
David Howells275bb412008-11-14 10:39:19 +11005737 u32 sid = current_sid();
Linus Torvalds1da177e2005-04-16 15:20:36 -07005738 int rc;
5739
Casey Schaufler7c653822018-09-21 17:19:45 -07005740 isec = selinux_ipc(msq);
5741 msec = selinux_msg_msg(msg);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005742
5743 /*
5744 * First time through, need to assign label to the message
5745 */
5746 if (msec->sid == SECINITSID_UNLABELED) {
5747 /*
5748 * Compute new sid based on current process and
5749 * message queue this message will be stored in
5750 */
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05005751 rc = security_transition_sid(&selinux_state, sid, isec->sid,
5752 SECCLASS_MSG, NULL, &msec->sid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005753 if (rc)
5754 return rc;
5755 }
5756
Eric Paris50c205f2012-04-04 15:01:43 -04005757 ad.type = LSM_AUDIT_DATA_IPC;
Eric W. Biedermand8c6e852018-03-22 21:22:26 -05005758 ad.u.ipc_id = msq->key;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005759
5760 /* Can this process write to the queue? */
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005761 rc = avc_has_perm(&selinux_state,
5762 sid, isec->sid, SECCLASS_MSGQ,
Linus Torvalds1da177e2005-04-16 15:20:36 -07005763 MSGQ__WRITE, &ad);
5764 if (!rc)
5765 /* Can this process send the message */
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005766 rc = avc_has_perm(&selinux_state,
5767 sid, msec->sid, SECCLASS_MSG,
David Howells275bb412008-11-14 10:39:19 +11005768 MSG__SEND, &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005769 if (!rc)
5770 /* Can the message be put in the queue? */
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005771 rc = avc_has_perm(&selinux_state,
5772 msec->sid, isec->sid, SECCLASS_MSGQ,
David Howells275bb412008-11-14 10:39:19 +11005773 MSGQ__ENQUEUE, &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005774
5775 return rc;
5776}
5777
Eric W. Biedermand8c6e852018-03-22 21:22:26 -05005778static int selinux_msg_queue_msgrcv(struct kern_ipc_perm *msq, struct msg_msg *msg,
Linus Torvalds1da177e2005-04-16 15:20:36 -07005779 struct task_struct *target,
5780 long type, int mode)
5781{
Linus Torvalds1da177e2005-04-16 15:20:36 -07005782 struct ipc_security_struct *isec;
5783 struct msg_security_struct *msec;
Thomas Liu2bf49692009-07-14 12:14:09 -04005784 struct common_audit_data ad;
David Howells275bb412008-11-14 10:39:19 +11005785 u32 sid = task_sid(target);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005786 int rc;
5787
Casey Schaufler7c653822018-09-21 17:19:45 -07005788 isec = selinux_ipc(msq);
5789 msec = selinux_msg_msg(msg);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005790
Eric Paris50c205f2012-04-04 15:01:43 -04005791 ad.type = LSM_AUDIT_DATA_IPC;
Eric W. Biedermand8c6e852018-03-22 21:22:26 -05005792 ad.u.ipc_id = msq->key;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005793
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005794 rc = avc_has_perm(&selinux_state,
5795 sid, isec->sid,
Linus Torvalds1da177e2005-04-16 15:20:36 -07005796 SECCLASS_MSGQ, MSGQ__READ, &ad);
5797 if (!rc)
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005798 rc = avc_has_perm(&selinux_state,
5799 sid, msec->sid,
Linus Torvalds1da177e2005-04-16 15:20:36 -07005800 SECCLASS_MSG, MSG__RECEIVE, &ad);
5801 return rc;
5802}
5803
5804/* Shared Memory security operations */
Eric W. Biederman7191adf2018-03-22 21:08:27 -05005805static int selinux_shm_alloc_security(struct kern_ipc_perm *shp)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005806{
Linus Torvalds1da177e2005-04-16 15:20:36 -07005807 struct ipc_security_struct *isec;
Thomas Liu2bf49692009-07-14 12:14:09 -04005808 struct common_audit_data ad;
David Howells275bb412008-11-14 10:39:19 +11005809 u32 sid = current_sid();
Linus Torvalds1da177e2005-04-16 15:20:36 -07005810 int rc;
5811
Casey Schauflerecd5f822018-11-20 11:55:02 -08005812 isec = selinux_ipc(shp);
5813 ipc_init_security(isec, SECCLASS_SHM);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005814
Eric Paris50c205f2012-04-04 15:01:43 -04005815 ad.type = LSM_AUDIT_DATA_IPC;
Eric W. Biederman7191adf2018-03-22 21:08:27 -05005816 ad.u.ipc_id = shp->key;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005817
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005818 rc = avc_has_perm(&selinux_state,
5819 sid, isec->sid, SECCLASS_SHM,
Linus Torvalds1da177e2005-04-16 15:20:36 -07005820 SHM__CREATE, &ad);
Casey Schauflerecd5f822018-11-20 11:55:02 -08005821 return rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005822}
5823
Eric W. Biederman7191adf2018-03-22 21:08:27 -05005824static int selinux_shm_associate(struct kern_ipc_perm *shp, int shmflg)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005825{
Linus Torvalds1da177e2005-04-16 15:20:36 -07005826 struct ipc_security_struct *isec;
Thomas Liu2bf49692009-07-14 12:14:09 -04005827 struct common_audit_data ad;
David Howells275bb412008-11-14 10:39:19 +11005828 u32 sid = current_sid();
Linus Torvalds1da177e2005-04-16 15:20:36 -07005829
Casey Schaufler7c653822018-09-21 17:19:45 -07005830 isec = selinux_ipc(shp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005831
Eric Paris50c205f2012-04-04 15:01:43 -04005832 ad.type = LSM_AUDIT_DATA_IPC;
Eric W. Biederman7191adf2018-03-22 21:08:27 -05005833 ad.u.ipc_id = shp->key;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005834
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005835 return avc_has_perm(&selinux_state,
5836 sid, isec->sid, SECCLASS_SHM,
Linus Torvalds1da177e2005-04-16 15:20:36 -07005837 SHM__ASSOCIATE, &ad);
5838}
5839
5840/* Note, at this point, shp is locked down */
Eric W. Biederman7191adf2018-03-22 21:08:27 -05005841static int selinux_shm_shmctl(struct kern_ipc_perm *shp, int cmd)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005842{
5843 int perms;
5844 int err;
5845
Eric Paris828dfe12008-04-17 13:17:49 -04005846 switch (cmd) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005847 case IPC_INFO:
5848 case SHM_INFO:
5849 /* No specific object, just general system-wide information. */
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005850 return avc_has_perm(&selinux_state,
5851 current_sid(), SECINITSID_KERNEL,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05005852 SECCLASS_SYSTEM, SYSTEM__IPC_INFO, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005853 case IPC_STAT:
5854 case SHM_STAT:
Davidlohr Buesoc21a6972018-04-10 16:35:23 -07005855 case SHM_STAT_ANY:
Linus Torvalds1da177e2005-04-16 15:20:36 -07005856 perms = SHM__GETATTR | SHM__ASSOCIATE;
5857 break;
5858 case IPC_SET:
5859 perms = SHM__SETATTR;
5860 break;
5861 case SHM_LOCK:
5862 case SHM_UNLOCK:
5863 perms = SHM__LOCK;
5864 break;
5865 case IPC_RMID:
5866 perms = SHM__DESTROY;
5867 break;
5868 default:
5869 return 0;
5870 }
5871
Eric W. Biederman7191adf2018-03-22 21:08:27 -05005872 err = ipc_has_perm(shp, perms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005873 return err;
5874}
5875
Eric W. Biederman7191adf2018-03-22 21:08:27 -05005876static int selinux_shm_shmat(struct kern_ipc_perm *shp,
Linus Torvalds1da177e2005-04-16 15:20:36 -07005877 char __user *shmaddr, int shmflg)
5878{
5879 u32 perms;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005880
5881 if (shmflg & SHM_RDONLY)
5882 perms = SHM__READ;
5883 else
5884 perms = SHM__READ | SHM__WRITE;
5885
Eric W. Biederman7191adf2018-03-22 21:08:27 -05005886 return ipc_has_perm(shp, perms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005887}
5888
5889/* Semaphore security operations */
Eric W. Biedermanaefad952018-03-22 20:52:43 -05005890static int selinux_sem_alloc_security(struct kern_ipc_perm *sma)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005891{
Linus Torvalds1da177e2005-04-16 15:20:36 -07005892 struct ipc_security_struct *isec;
Thomas Liu2bf49692009-07-14 12:14:09 -04005893 struct common_audit_data ad;
David Howells275bb412008-11-14 10:39:19 +11005894 u32 sid = current_sid();
Linus Torvalds1da177e2005-04-16 15:20:36 -07005895 int rc;
5896
Casey Schauflerecd5f822018-11-20 11:55:02 -08005897 isec = selinux_ipc(sma);
5898 ipc_init_security(isec, SECCLASS_SEM);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005899
Eric Paris50c205f2012-04-04 15:01:43 -04005900 ad.type = LSM_AUDIT_DATA_IPC;
Eric W. Biedermanaefad952018-03-22 20:52:43 -05005901 ad.u.ipc_id = sma->key;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005902
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005903 rc = avc_has_perm(&selinux_state,
5904 sid, isec->sid, SECCLASS_SEM,
Linus Torvalds1da177e2005-04-16 15:20:36 -07005905 SEM__CREATE, &ad);
Casey Schauflerecd5f822018-11-20 11:55:02 -08005906 return rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005907}
5908
Eric W. Biedermanaefad952018-03-22 20:52:43 -05005909static int selinux_sem_associate(struct kern_ipc_perm *sma, int semflg)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005910{
Linus Torvalds1da177e2005-04-16 15:20:36 -07005911 struct ipc_security_struct *isec;
Thomas Liu2bf49692009-07-14 12:14:09 -04005912 struct common_audit_data ad;
David Howells275bb412008-11-14 10:39:19 +11005913 u32 sid = current_sid();
Linus Torvalds1da177e2005-04-16 15:20:36 -07005914
Casey Schaufler7c653822018-09-21 17:19:45 -07005915 isec = selinux_ipc(sma);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005916
Eric Paris50c205f2012-04-04 15:01:43 -04005917 ad.type = LSM_AUDIT_DATA_IPC;
Eric W. Biedermanaefad952018-03-22 20:52:43 -05005918 ad.u.ipc_id = sma->key;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005919
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005920 return avc_has_perm(&selinux_state,
5921 sid, isec->sid, SECCLASS_SEM,
Linus Torvalds1da177e2005-04-16 15:20:36 -07005922 SEM__ASSOCIATE, &ad);
5923}
5924
5925/* Note, at this point, sma is locked down */
Eric W. Biedermanaefad952018-03-22 20:52:43 -05005926static int selinux_sem_semctl(struct kern_ipc_perm *sma, int cmd)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005927{
5928 int err;
5929 u32 perms;
5930
Eric Paris828dfe12008-04-17 13:17:49 -04005931 switch (cmd) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005932 case IPC_INFO:
5933 case SEM_INFO:
5934 /* No specific object, just general system-wide information. */
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005935 return avc_has_perm(&selinux_state,
5936 current_sid(), SECINITSID_KERNEL,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05005937 SECCLASS_SYSTEM, SYSTEM__IPC_INFO, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005938 case GETPID:
5939 case GETNCNT:
5940 case GETZCNT:
5941 perms = SEM__GETATTR;
5942 break;
5943 case GETVAL:
5944 case GETALL:
5945 perms = SEM__READ;
5946 break;
5947 case SETVAL:
5948 case SETALL:
5949 perms = SEM__WRITE;
5950 break;
5951 case IPC_RMID:
5952 perms = SEM__DESTROY;
5953 break;
5954 case IPC_SET:
5955 perms = SEM__SETATTR;
5956 break;
5957 case IPC_STAT:
5958 case SEM_STAT:
Davidlohr Buesoa280d6d2018-04-10 16:35:26 -07005959 case SEM_STAT_ANY:
Linus Torvalds1da177e2005-04-16 15:20:36 -07005960 perms = SEM__GETATTR | SEM__ASSOCIATE;
5961 break;
5962 default:
5963 return 0;
5964 }
5965
Eric W. Biedermanaefad952018-03-22 20:52:43 -05005966 err = ipc_has_perm(sma, perms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005967 return err;
5968}
5969
Eric W. Biedermanaefad952018-03-22 20:52:43 -05005970static int selinux_sem_semop(struct kern_ipc_perm *sma,
Linus Torvalds1da177e2005-04-16 15:20:36 -07005971 struct sembuf *sops, unsigned nsops, int alter)
5972{
5973 u32 perms;
5974
5975 if (alter)
5976 perms = SEM__READ | SEM__WRITE;
5977 else
5978 perms = SEM__READ;
5979
Eric W. Biedermanaefad952018-03-22 20:52:43 -05005980 return ipc_has_perm(sma, perms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005981}
5982
5983static int selinux_ipc_permission(struct kern_ipc_perm *ipcp, short flag)
5984{
Linus Torvalds1da177e2005-04-16 15:20:36 -07005985 u32 av = 0;
5986
Linus Torvalds1da177e2005-04-16 15:20:36 -07005987 av = 0;
5988 if (flag & S_IRUGO)
5989 av |= IPC__UNIX_READ;
5990 if (flag & S_IWUGO)
5991 av |= IPC__UNIX_WRITE;
5992
5993 if (av == 0)
5994 return 0;
5995
Stephen Smalley6af963f2005-05-01 08:58:39 -07005996 return ipc_has_perm(ipcp, av);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005997}
5998
Ahmed S. Darwish713a04ae2008-03-01 21:52:30 +02005999static void selinux_ipc_getsecid(struct kern_ipc_perm *ipcp, u32 *secid)
6000{
Casey Schaufler7c653822018-09-21 17:19:45 -07006001 struct ipc_security_struct *isec = selinux_ipc(ipcp);
Ahmed S. Darwish713a04ae2008-03-01 21:52:30 +02006002 *secid = isec->sid;
6003}
6004
Eric Paris828dfe12008-04-17 13:17:49 -04006005static void selinux_d_instantiate(struct dentry *dentry, struct inode *inode)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006006{
6007 if (inode)
6008 inode_doinit_with_dentry(inode, dentry);
6009}
6010
6011static int selinux_getprocattr(struct task_struct *p,
Al Viro04ff9702007-03-12 16:17:58 +00006012 char *name, char **value)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006013{
David Howells275bb412008-11-14 10:39:19 +11006014 const struct task_security_struct *__tsec;
Dustin Kirkland8c8570f2005-11-03 17:15:16 +00006015 u32 sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006016 int error;
Al Viro04ff9702007-03-12 16:17:58 +00006017 unsigned len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006018
David Howells275bb412008-11-14 10:39:19 +11006019 rcu_read_lock();
Casey Schaufler0c6cfa62018-09-21 17:17:16 -07006020 __tsec = selinux_cred(__task_cred(p));
Linus Torvalds1da177e2005-04-16 15:20:36 -07006021
Stephen Smalleybe0554c2017-01-09 10:07:31 -05006022 if (current != p) {
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006023 error = avc_has_perm(&selinux_state,
6024 current_sid(), __tsec->sid,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05006025 SECCLASS_PROCESS, PROCESS__GETATTR, NULL);
6026 if (error)
6027 goto bad;
6028 }
6029
Linus Torvalds1da177e2005-04-16 15:20:36 -07006030 if (!strcmp(name, "current"))
David Howells275bb412008-11-14 10:39:19 +11006031 sid = __tsec->sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006032 else if (!strcmp(name, "prev"))
David Howells275bb412008-11-14 10:39:19 +11006033 sid = __tsec->osid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006034 else if (!strcmp(name, "exec"))
David Howells275bb412008-11-14 10:39:19 +11006035 sid = __tsec->exec_sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006036 else if (!strcmp(name, "fscreate"))
David Howells275bb412008-11-14 10:39:19 +11006037 sid = __tsec->create_sid;
Michael LeMay4eb582c2006-06-26 00:24:57 -07006038 else if (!strcmp(name, "keycreate"))
David Howells275bb412008-11-14 10:39:19 +11006039 sid = __tsec->keycreate_sid;
Eric Paris42c3e032006-06-26 00:26:03 -07006040 else if (!strcmp(name, "sockcreate"))
David Howells275bb412008-11-14 10:39:19 +11006041 sid = __tsec->sockcreate_sid;
Stephen Smalleybe0554c2017-01-09 10:07:31 -05006042 else {
6043 error = -EINVAL;
6044 goto bad;
6045 }
David Howells275bb412008-11-14 10:39:19 +11006046 rcu_read_unlock();
Linus Torvalds1da177e2005-04-16 15:20:36 -07006047
6048 if (!sid)
6049 return 0;
6050
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05006051 error = security_sid_to_context(&selinux_state, sid, value, &len);
Al Viro04ff9702007-03-12 16:17:58 +00006052 if (error)
6053 return error;
6054 return len;
David Howells275bb412008-11-14 10:39:19 +11006055
Stephen Smalleybe0554c2017-01-09 10:07:31 -05006056bad:
David Howells275bb412008-11-14 10:39:19 +11006057 rcu_read_unlock();
Stephen Smalleybe0554c2017-01-09 10:07:31 -05006058 return error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006059}
6060
Stephen Smalleyb21507e2017-01-09 10:07:31 -05006061static int selinux_setprocattr(const char *name, void *value, size_t size)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006062{
6063 struct task_security_struct *tsec;
David Howellsd84f4f92008-11-14 10:39:23 +11006064 struct cred *new;
Stephen Smalleybe0554c2017-01-09 10:07:31 -05006065 u32 mysid = current_sid(), sid = 0, ptsid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006066 int error;
6067 char *str = value;
6068
Linus Torvalds1da177e2005-04-16 15:20:36 -07006069 /*
6070 * Basic control over ability to set these attributes at all.
Linus Torvalds1da177e2005-04-16 15:20:36 -07006071 */
6072 if (!strcmp(name, "exec"))
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006073 error = avc_has_perm(&selinux_state,
6074 mysid, mysid, SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05006075 PROCESS__SETEXEC, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006076 else if (!strcmp(name, "fscreate"))
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006077 error = avc_has_perm(&selinux_state,
6078 mysid, mysid, SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05006079 PROCESS__SETFSCREATE, NULL);
Michael LeMay4eb582c2006-06-26 00:24:57 -07006080 else if (!strcmp(name, "keycreate"))
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006081 error = avc_has_perm(&selinux_state,
6082 mysid, mysid, SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05006083 PROCESS__SETKEYCREATE, NULL);
Eric Paris42c3e032006-06-26 00:26:03 -07006084 else if (!strcmp(name, "sockcreate"))
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006085 error = avc_has_perm(&selinux_state,
6086 mysid, mysid, SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05006087 PROCESS__SETSOCKCREATE, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006088 else if (!strcmp(name, "current"))
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006089 error = avc_has_perm(&selinux_state,
6090 mysid, mysid, SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05006091 PROCESS__SETCURRENT, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006092 else
6093 error = -EINVAL;
6094 if (error)
6095 return error;
6096
6097 /* Obtain a SID for the context, if one was specified. */
Stephen Smalleya050a572017-01-31 11:54:04 -05006098 if (size && str[0] && str[0] != '\n') {
Linus Torvalds1da177e2005-04-16 15:20:36 -07006099 if (str[size-1] == '\n') {
6100 str[size-1] = 0;
6101 size--;
6102 }
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05006103 error = security_context_to_sid(&selinux_state, value, size,
6104 &sid, GFP_KERNEL);
Stephen Smalley12b29f32008-05-07 13:03:20 -04006105 if (error == -EINVAL && !strcmp(name, "fscreate")) {
Stephen Smalleydb590002017-04-20 11:31:30 -04006106 if (!has_cap_mac_admin(true)) {
Eric Parisd6ea83e2012-04-04 13:45:49 -04006107 struct audit_buffer *ab;
6108 size_t audit_size;
6109
6110 /* We strip a nul only if it is at the end, otherwise the
6111 * context contains a nul and we should audit that */
6112 if (str[size - 1] == '\0')
6113 audit_size = size - 1;
6114 else
6115 audit_size = size;
Richard Guy Briggscdfb6b32018-05-12 21:58:20 -04006116 ab = audit_log_start(audit_context(),
6117 GFP_ATOMIC,
6118 AUDIT_SELINUX_ERR);
Eric Parisd6ea83e2012-04-04 13:45:49 -04006119 audit_log_format(ab, "op=fscreate invalid_context=");
6120 audit_log_n_untrustedstring(ab, value, audit_size);
6121 audit_log_end(ab);
6122
Stephen Smalley12b29f32008-05-07 13:03:20 -04006123 return error;
Eric Parisd6ea83e2012-04-04 13:45:49 -04006124 }
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05006125 error = security_context_to_sid_force(
6126 &selinux_state,
6127 value, size, &sid);
Stephen Smalley12b29f32008-05-07 13:03:20 -04006128 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006129 if (error)
6130 return error;
6131 }
6132
David Howellsd84f4f92008-11-14 10:39:23 +11006133 new = prepare_creds();
6134 if (!new)
6135 return -ENOMEM;
6136
Linus Torvalds1da177e2005-04-16 15:20:36 -07006137 /* Permission checking based on the specified context is
6138 performed during the actual operation (execve,
6139 open/mkdir/...), when we know the full context of the
David Howellsd84f4f92008-11-14 10:39:23 +11006140 operation. See selinux_bprm_set_creds for the execve
Linus Torvalds1da177e2005-04-16 15:20:36 -07006141 checks and may_create for the file creation checks. The
6142 operation will then fail if the context is not permitted. */
Casey Schaufler0c6cfa62018-09-21 17:17:16 -07006143 tsec = selinux_cred(new);
David Howellsd84f4f92008-11-14 10:39:23 +11006144 if (!strcmp(name, "exec")) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07006145 tsec->exec_sid = sid;
David Howellsd84f4f92008-11-14 10:39:23 +11006146 } else if (!strcmp(name, "fscreate")) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07006147 tsec->create_sid = sid;
David Howellsd84f4f92008-11-14 10:39:23 +11006148 } else if (!strcmp(name, "keycreate")) {
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006149 error = avc_has_perm(&selinux_state,
6150 mysid, sid, SECCLASS_KEY, KEY__CREATE,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05006151 NULL);
Michael LeMay4eb582c2006-06-26 00:24:57 -07006152 if (error)
David Howellsd84f4f92008-11-14 10:39:23 +11006153 goto abort_change;
Michael LeMay4eb582c2006-06-26 00:24:57 -07006154 tsec->keycreate_sid = sid;
David Howellsd84f4f92008-11-14 10:39:23 +11006155 } else if (!strcmp(name, "sockcreate")) {
Eric Paris42c3e032006-06-26 00:26:03 -07006156 tsec->sockcreate_sid = sid;
David Howellsd84f4f92008-11-14 10:39:23 +11006157 } else if (!strcmp(name, "current")) {
6158 error = -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006159 if (sid == 0)
David Howellsd84f4f92008-11-14 10:39:23 +11006160 goto abort_change;
KaiGai Koheid9250de2008-08-28 16:35:57 +09006161
David Howellsd84f4f92008-11-14 10:39:23 +11006162 /* Only allow single threaded processes to change context */
6163 error = -EPERM;
Oleg Nesterov5bb459b2009-07-10 03:48:23 +02006164 if (!current_is_single_threaded()) {
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05006165 error = security_bounded_transition(&selinux_state,
6166 tsec->sid, sid);
David Howellsd84f4f92008-11-14 10:39:23 +11006167 if (error)
6168 goto abort_change;
Eric Paris828dfe12008-04-17 13:17:49 -04006169 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006170
6171 /* Check permissions for the transition. */
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006172 error = avc_has_perm(&selinux_state,
6173 tsec->sid, sid, SECCLASS_PROCESS,
Eric Paris828dfe12008-04-17 13:17:49 -04006174 PROCESS__DYNTRANSITION, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006175 if (error)
David Howellsd84f4f92008-11-14 10:39:23 +11006176 goto abort_change;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006177
6178 /* Check for ptracing, and update the task SID if ok.
6179 Otherwise, leave SID unchanged and fail. */
Stephen Smalleybe0554c2017-01-09 10:07:31 -05006180 ptsid = ptrace_parent_sid();
Paul Moore0c6181c2016-03-30 21:41:21 -04006181 if (ptsid != 0) {
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006182 error = avc_has_perm(&selinux_state,
6183 ptsid, sid, SECCLASS_PROCESS,
David Howellsd84f4f92008-11-14 10:39:23 +11006184 PROCESS__PTRACE, NULL);
6185 if (error)
6186 goto abort_change;
6187 }
6188
6189 tsec->sid = sid;
6190 } else {
6191 error = -EINVAL;
6192 goto abort_change;
6193 }
6194
6195 commit_creds(new);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006196 return size;
David Howellsd84f4f92008-11-14 10:39:23 +11006197
6198abort_change:
6199 abort_creds(new);
6200 return error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006201}
6202
David Quigley746df9b2013-05-22 12:50:35 -04006203static int selinux_ismaclabel(const char *name)
6204{
6205 return (strcmp(name, XATTR_SELINUX_SUFFIX) == 0);
6206}
6207
Catherine Zhangdc49c1f2006-08-02 14:12:06 -07006208static int selinux_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
6209{
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05006210 return security_sid_to_context(&selinux_state, secid,
6211 secdata, seclen);
Catherine Zhangdc49c1f2006-08-02 14:12:06 -07006212}
6213
David Howells7bf570d2008-04-29 20:52:51 +01006214static int selinux_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid)
David Howells63cb3442008-01-15 23:47:35 +00006215{
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05006216 return security_context_to_sid(&selinux_state, secdata, seclen,
6217 secid, GFP_KERNEL);
David Howells63cb3442008-01-15 23:47:35 +00006218}
6219
Catherine Zhangdc49c1f2006-08-02 14:12:06 -07006220static void selinux_release_secctx(char *secdata, u32 seclen)
6221{
Paul Moore088999e2007-08-01 11:12:58 -04006222 kfree(secdata);
Catherine Zhangdc49c1f2006-08-02 14:12:06 -07006223}
6224
Andreas Gruenbacher6f3be9f2015-12-24 11:09:40 -05006225static void selinux_inode_invalidate_secctx(struct inode *inode)
6226{
Casey Schaufler80788c22018-09-21 17:19:11 -07006227 struct inode_security_struct *isec = selinux_inode(inode);
Andreas Gruenbacher6f3be9f2015-12-24 11:09:40 -05006228
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01006229 spin_lock(&isec->lock);
Andreas Gruenbacher6f3be9f2015-12-24 11:09:40 -05006230 isec->initialized = LABEL_INVALID;
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01006231 spin_unlock(&isec->lock);
Andreas Gruenbacher6f3be9f2015-12-24 11:09:40 -05006232}
6233
David P. Quigley1ee65e32009-09-03 14:25:57 -04006234/*
6235 * called with inode->i_mutex locked
6236 */
6237static int selinux_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen)
6238{
6239 return selinux_inode_setsecurity(inode, XATTR_SELINUX_SUFFIX, ctx, ctxlen, 0);
6240}
6241
6242/*
6243 * called with inode->i_mutex locked
6244 */
6245static int selinux_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen)
6246{
6247 return __vfs_setxattr_noperm(dentry, XATTR_NAME_SELINUX, ctx, ctxlen, 0);
6248}
6249
6250static int selinux_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen)
6251{
6252 int len = 0;
6253 len = selinux_inode_getsecurity(inode, XATTR_SELINUX_SUFFIX,
6254 ctx, true);
6255 if (len < 0)
6256 return len;
6257 *ctxlen = len;
6258 return 0;
6259}
Michael LeMayd7200242006-06-22 14:47:17 -07006260#ifdef CONFIG_KEYS
6261
David Howellsd84f4f92008-11-14 10:39:23 +11006262static int selinux_key_alloc(struct key *k, const struct cred *cred,
David Howells7e047ef2006-06-26 00:24:50 -07006263 unsigned long flags)
Michael LeMayd7200242006-06-22 14:47:17 -07006264{
David Howellsd84f4f92008-11-14 10:39:23 +11006265 const struct task_security_struct *tsec;
Michael LeMayd7200242006-06-22 14:47:17 -07006266 struct key_security_struct *ksec;
6267
6268 ksec = kzalloc(sizeof(struct key_security_struct), GFP_KERNEL);
6269 if (!ksec)
6270 return -ENOMEM;
6271
Casey Schaufler0c6cfa62018-09-21 17:17:16 -07006272 tsec = selinux_cred(cred);
David Howellsd84f4f92008-11-14 10:39:23 +11006273 if (tsec->keycreate_sid)
6274 ksec->sid = tsec->keycreate_sid;
Michael LeMay4eb582c2006-06-26 00:24:57 -07006275 else
David Howellsd84f4f92008-11-14 10:39:23 +11006276 ksec->sid = tsec->sid;
Michael LeMayd7200242006-06-22 14:47:17 -07006277
David Howells275bb412008-11-14 10:39:19 +11006278 k->security = ksec;
Michael LeMayd7200242006-06-22 14:47:17 -07006279 return 0;
6280}
6281
6282static void selinux_key_free(struct key *k)
6283{
6284 struct key_security_struct *ksec = k->security;
6285
6286 k->security = NULL;
6287 kfree(ksec);
6288}
6289
6290static int selinux_key_permission(key_ref_t key_ref,
David Howellsd84f4f92008-11-14 10:39:23 +11006291 const struct cred *cred,
David Howellsf5895942014-03-14 17:44:49 +00006292 unsigned perm)
Michael LeMayd7200242006-06-22 14:47:17 -07006293{
6294 struct key *key;
Michael LeMayd7200242006-06-22 14:47:17 -07006295 struct key_security_struct *ksec;
David Howells275bb412008-11-14 10:39:19 +11006296 u32 sid;
Michael LeMayd7200242006-06-22 14:47:17 -07006297
6298 /* if no specific permissions are requested, we skip the
6299 permission check. No serious, additional covert channels
6300 appear to be created. */
6301 if (perm == 0)
6302 return 0;
6303
David Howellsd84f4f92008-11-14 10:39:23 +11006304 sid = cred_sid(cred);
David Howells275bb412008-11-14 10:39:19 +11006305
6306 key = key_ref_to_ptr(key_ref);
6307 ksec = key->security;
6308
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006309 return avc_has_perm(&selinux_state,
6310 sid, ksec->sid, SECCLASS_KEY, perm, NULL);
Michael LeMayd7200242006-06-22 14:47:17 -07006311}
6312
David Howells70a5bb72008-04-29 01:01:26 -07006313static int selinux_key_getsecurity(struct key *key, char **_buffer)
6314{
6315 struct key_security_struct *ksec = key->security;
6316 char *context = NULL;
6317 unsigned len;
6318 int rc;
6319
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05006320 rc = security_sid_to_context(&selinux_state, ksec->sid,
6321 &context, &len);
David Howells70a5bb72008-04-29 01:01:26 -07006322 if (!rc)
6323 rc = len;
6324 *_buffer = context;
6325 return rc;
6326}
Daniel Jurgens3a976fa2017-05-19 15:48:56 +03006327#endif
David Howells70a5bb72008-04-29 01:01:26 -07006328
Daniel Jurgens3a976fa2017-05-19 15:48:56 +03006329#ifdef CONFIG_SECURITY_INFINIBAND
Daniel Jurgenscfc4d882017-05-19 15:48:57 +03006330static int selinux_ib_pkey_access(void *ib_sec, u64 subnet_prefix, u16 pkey_val)
6331{
6332 struct common_audit_data ad;
6333 int err;
6334 u32 sid = 0;
6335 struct ib_security_struct *sec = ib_sec;
6336 struct lsm_ibpkey_audit ibpkey;
6337
Daniel Jurgens409dcf32017-05-19 15:48:59 +03006338 err = sel_ib_pkey_sid(subnet_prefix, pkey_val, &sid);
Daniel Jurgenscfc4d882017-05-19 15:48:57 +03006339 if (err)
6340 return err;
6341
6342 ad.type = LSM_AUDIT_DATA_IBPKEY;
6343 ibpkey.subnet_prefix = subnet_prefix;
6344 ibpkey.pkey = pkey_val;
6345 ad.u.ibpkey = &ibpkey;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006346 return avc_has_perm(&selinux_state,
6347 sec->sid, sid,
Daniel Jurgenscfc4d882017-05-19 15:48:57 +03006348 SECCLASS_INFINIBAND_PKEY,
6349 INFINIBAND_PKEY__ACCESS, &ad);
6350}
6351
Daniel Jurgensab861df2017-05-19 15:48:58 +03006352static int selinux_ib_endport_manage_subnet(void *ib_sec, const char *dev_name,
6353 u8 port_num)
6354{
6355 struct common_audit_data ad;
6356 int err;
6357 u32 sid = 0;
6358 struct ib_security_struct *sec = ib_sec;
6359 struct lsm_ibendport_audit ibendport;
6360
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05006361 err = security_ib_endport_sid(&selinux_state, dev_name, port_num,
6362 &sid);
Daniel Jurgensab861df2017-05-19 15:48:58 +03006363
6364 if (err)
6365 return err;
6366
6367 ad.type = LSM_AUDIT_DATA_IBENDPORT;
6368 strncpy(ibendport.dev_name, dev_name, sizeof(ibendport.dev_name));
6369 ibendport.port = port_num;
6370 ad.u.ibendport = &ibendport;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006371 return avc_has_perm(&selinux_state,
6372 sec->sid, sid,
Daniel Jurgensab861df2017-05-19 15:48:58 +03006373 SECCLASS_INFINIBAND_ENDPORT,
6374 INFINIBAND_ENDPORT__MANAGE_SUBNET, &ad);
6375}
6376
Daniel Jurgens3a976fa2017-05-19 15:48:56 +03006377static int selinux_ib_alloc_security(void **ib_sec)
6378{
6379 struct ib_security_struct *sec;
6380
6381 sec = kzalloc(sizeof(*sec), GFP_KERNEL);
6382 if (!sec)
6383 return -ENOMEM;
6384 sec->sid = current_sid();
6385
6386 *ib_sec = sec;
6387 return 0;
6388}
6389
6390static void selinux_ib_free_security(void *ib_sec)
6391{
6392 kfree(ib_sec);
6393}
Michael LeMayd7200242006-06-22 14:47:17 -07006394#endif
6395
Chenbo Fengec27c352017-10-18 13:00:25 -07006396#ifdef CONFIG_BPF_SYSCALL
6397static int selinux_bpf(int cmd, union bpf_attr *attr,
6398 unsigned int size)
6399{
6400 u32 sid = current_sid();
6401 int ret;
6402
6403 switch (cmd) {
6404 case BPF_MAP_CREATE:
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006405 ret = avc_has_perm(&selinux_state,
6406 sid, sid, SECCLASS_BPF, BPF__MAP_CREATE,
Chenbo Fengec27c352017-10-18 13:00:25 -07006407 NULL);
6408 break;
6409 case BPF_PROG_LOAD:
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006410 ret = avc_has_perm(&selinux_state,
6411 sid, sid, SECCLASS_BPF, BPF__PROG_LOAD,
Chenbo Fengec27c352017-10-18 13:00:25 -07006412 NULL);
6413 break;
6414 default:
6415 ret = 0;
6416 break;
6417 }
6418
6419 return ret;
6420}
6421
6422static u32 bpf_map_fmode_to_av(fmode_t fmode)
6423{
6424 u32 av = 0;
6425
6426 if (fmode & FMODE_READ)
6427 av |= BPF__MAP_READ;
6428 if (fmode & FMODE_WRITE)
6429 av |= BPF__MAP_WRITE;
6430 return av;
6431}
6432
Chenbo Fengf66e4482017-10-18 13:00:26 -07006433/* This function will check the file pass through unix socket or binder to see
6434 * if it is a bpf related object. And apply correspinding checks on the bpf
6435 * object based on the type. The bpf maps and programs, not like other files and
6436 * socket, are using a shared anonymous inode inside the kernel as their inode.
6437 * So checking that inode cannot identify if the process have privilege to
6438 * access the bpf object and that's why we have to add this additional check in
6439 * selinux_file_receive and selinux_binder_transfer_files.
6440 */
6441static int bpf_fd_pass(struct file *file, u32 sid)
6442{
6443 struct bpf_security_struct *bpfsec;
6444 struct bpf_prog *prog;
6445 struct bpf_map *map;
6446 int ret;
6447
6448 if (file->f_op == &bpf_map_fops) {
6449 map = file->private_data;
6450 bpfsec = map->security;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006451 ret = avc_has_perm(&selinux_state,
6452 sid, bpfsec->sid, SECCLASS_BPF,
Chenbo Fengf66e4482017-10-18 13:00:26 -07006453 bpf_map_fmode_to_av(file->f_mode), NULL);
6454 if (ret)
6455 return ret;
6456 } else if (file->f_op == &bpf_prog_fops) {
6457 prog = file->private_data;
6458 bpfsec = prog->aux->security;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006459 ret = avc_has_perm(&selinux_state,
6460 sid, bpfsec->sid, SECCLASS_BPF,
Chenbo Fengf66e4482017-10-18 13:00:26 -07006461 BPF__PROG_RUN, NULL);
6462 if (ret)
6463 return ret;
6464 }
6465 return 0;
6466}
6467
Chenbo Fengec27c352017-10-18 13:00:25 -07006468static int selinux_bpf_map(struct bpf_map *map, fmode_t fmode)
6469{
6470 u32 sid = current_sid();
6471 struct bpf_security_struct *bpfsec;
6472
6473 bpfsec = map->security;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006474 return avc_has_perm(&selinux_state,
6475 sid, bpfsec->sid, SECCLASS_BPF,
Chenbo Fengec27c352017-10-18 13:00:25 -07006476 bpf_map_fmode_to_av(fmode), NULL);
6477}
6478
6479static int selinux_bpf_prog(struct bpf_prog *prog)
6480{
6481 u32 sid = current_sid();
6482 struct bpf_security_struct *bpfsec;
6483
6484 bpfsec = prog->aux->security;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006485 return avc_has_perm(&selinux_state,
6486 sid, bpfsec->sid, SECCLASS_BPF,
Chenbo Fengec27c352017-10-18 13:00:25 -07006487 BPF__PROG_RUN, NULL);
6488}
6489
6490static int selinux_bpf_map_alloc(struct bpf_map *map)
6491{
6492 struct bpf_security_struct *bpfsec;
6493
6494 bpfsec = kzalloc(sizeof(*bpfsec), GFP_KERNEL);
6495 if (!bpfsec)
6496 return -ENOMEM;
6497
6498 bpfsec->sid = current_sid();
6499 map->security = bpfsec;
6500
6501 return 0;
6502}
6503
6504static void selinux_bpf_map_free(struct bpf_map *map)
6505{
6506 struct bpf_security_struct *bpfsec = map->security;
6507
6508 map->security = NULL;
6509 kfree(bpfsec);
6510}
6511
6512static int selinux_bpf_prog_alloc(struct bpf_prog_aux *aux)
6513{
6514 struct bpf_security_struct *bpfsec;
6515
6516 bpfsec = kzalloc(sizeof(*bpfsec), GFP_KERNEL);
6517 if (!bpfsec)
6518 return -ENOMEM;
6519
6520 bpfsec->sid = current_sid();
6521 aux->security = bpfsec;
6522
6523 return 0;
6524}
6525
6526static void selinux_bpf_prog_free(struct bpf_prog_aux *aux)
6527{
6528 struct bpf_security_struct *bpfsec = aux->security;
6529
6530 aux->security = NULL;
6531 kfree(bpfsec);
6532}
6533#endif
6534
Casey Schauflerbbd36622018-11-12 09:30:56 -08006535struct lsm_blob_sizes selinux_blob_sizes __lsm_ro_after_init = {
6536 .lbs_cred = sizeof(struct task_security_struct),
Casey Schaufler33bf60c2018-11-12 12:02:49 -08006537 .lbs_file = sizeof(struct file_security_struct),
Casey Schauflerafb1cbe32018-09-21 17:19:29 -07006538 .lbs_inode = sizeof(struct inode_security_struct),
Casey Schauflerecd5f822018-11-20 11:55:02 -08006539 .lbs_ipc = sizeof(struct ipc_security_struct),
6540 .lbs_msg_msg = sizeof(struct msg_security_struct),
Casey Schauflerbbd36622018-11-12 09:30:56 -08006541};
6542
James Morrisca97d932017-02-15 00:18:51 +11006543static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = {
Casey Schauflere20b0432015-05-02 15:11:36 -07006544 LSM_HOOK_INIT(binder_set_context_mgr, selinux_binder_set_context_mgr),
6545 LSM_HOOK_INIT(binder_transaction, selinux_binder_transaction),
6546 LSM_HOOK_INIT(binder_transfer_binder, selinux_binder_transfer_binder),
6547 LSM_HOOK_INIT(binder_transfer_file, selinux_binder_transfer_file),
Ahmed S. Darwish076c54c2008-03-06 18:09:10 +02006548
Casey Schauflere20b0432015-05-02 15:11:36 -07006549 LSM_HOOK_INIT(ptrace_access_check, selinux_ptrace_access_check),
6550 LSM_HOOK_INIT(ptrace_traceme, selinux_ptrace_traceme),
6551 LSM_HOOK_INIT(capget, selinux_capget),
6552 LSM_HOOK_INIT(capset, selinux_capset),
6553 LSM_HOOK_INIT(capable, selinux_capable),
6554 LSM_HOOK_INIT(quotactl, selinux_quotactl),
6555 LSM_HOOK_INIT(quota_on, selinux_quota_on),
6556 LSM_HOOK_INIT(syslog, selinux_syslog),
6557 LSM_HOOK_INIT(vm_enough_memory, selinux_vm_enough_memory),
Stephen Smalley79af7302015-01-21 10:54:10 -05006558
Casey Schauflere20b0432015-05-02 15:11:36 -07006559 LSM_HOOK_INIT(netlink_send, selinux_netlink_send),
Linus Torvalds1da177e2005-04-16 15:20:36 -07006560
Casey Schauflere20b0432015-05-02 15:11:36 -07006561 LSM_HOOK_INIT(bprm_set_creds, selinux_bprm_set_creds),
6562 LSM_HOOK_INIT(bprm_committing_creds, selinux_bprm_committing_creds),
6563 LSM_HOOK_INIT(bprm_committed_creds, selinux_bprm_committed_creds),
Linus Torvalds1da177e2005-04-16 15:20:36 -07006564
Casey Schauflere20b0432015-05-02 15:11:36 -07006565 LSM_HOOK_INIT(sb_alloc_security, selinux_sb_alloc_security),
6566 LSM_HOOK_INIT(sb_free_security, selinux_sb_free_security),
Al Viro5b400232018-12-12 20:13:29 -05006567 LSM_HOOK_INIT(sb_eat_lsm_opts, selinux_sb_eat_lsm_opts),
Al Viro204cc0c2018-12-13 13:41:47 -05006568 LSM_HOOK_INIT(sb_free_mnt_opts, selinux_free_mnt_opts),
Casey Schauflere20b0432015-05-02 15:11:36 -07006569 LSM_HOOK_INIT(sb_remount, selinux_sb_remount),
6570 LSM_HOOK_INIT(sb_kern_mount, selinux_sb_kern_mount),
6571 LSM_HOOK_INIT(sb_show_options, selinux_sb_show_options),
6572 LSM_HOOK_INIT(sb_statfs, selinux_sb_statfs),
6573 LSM_HOOK_INIT(sb_mount, selinux_mount),
6574 LSM_HOOK_INIT(sb_umount, selinux_umount),
6575 LSM_HOOK_INIT(sb_set_mnt_opts, selinux_set_mnt_opts),
6576 LSM_HOOK_INIT(sb_clone_mnt_opts, selinux_sb_clone_mnt_opts),
Al Viro757cbe52018-12-14 23:42:21 -05006577 LSM_HOOK_INIT(sb_add_mnt_opt, selinux_add_mnt_opt),
Linus Torvalds1da177e2005-04-16 15:20:36 -07006578
Casey Schauflere20b0432015-05-02 15:11:36 -07006579 LSM_HOOK_INIT(dentry_init_security, selinux_dentry_init_security),
Vivek Goyala518b0a2016-07-13 10:44:53 -04006580 LSM_HOOK_INIT(dentry_create_files_as, selinux_dentry_create_files_as),
Eric Parise0007522008-03-05 10:31:54 -05006581
Casey Schauflere20b0432015-05-02 15:11:36 -07006582 LSM_HOOK_INIT(inode_alloc_security, selinux_inode_alloc_security),
6583 LSM_HOOK_INIT(inode_free_security, selinux_inode_free_security),
6584 LSM_HOOK_INIT(inode_init_security, selinux_inode_init_security),
6585 LSM_HOOK_INIT(inode_create, selinux_inode_create),
6586 LSM_HOOK_INIT(inode_link, selinux_inode_link),
6587 LSM_HOOK_INIT(inode_unlink, selinux_inode_unlink),
6588 LSM_HOOK_INIT(inode_symlink, selinux_inode_symlink),
6589 LSM_HOOK_INIT(inode_mkdir, selinux_inode_mkdir),
6590 LSM_HOOK_INIT(inode_rmdir, selinux_inode_rmdir),
6591 LSM_HOOK_INIT(inode_mknod, selinux_inode_mknod),
6592 LSM_HOOK_INIT(inode_rename, selinux_inode_rename),
6593 LSM_HOOK_INIT(inode_readlink, selinux_inode_readlink),
6594 LSM_HOOK_INIT(inode_follow_link, selinux_inode_follow_link),
6595 LSM_HOOK_INIT(inode_permission, selinux_inode_permission),
6596 LSM_HOOK_INIT(inode_setattr, selinux_inode_setattr),
6597 LSM_HOOK_INIT(inode_getattr, selinux_inode_getattr),
6598 LSM_HOOK_INIT(inode_setxattr, selinux_inode_setxattr),
6599 LSM_HOOK_INIT(inode_post_setxattr, selinux_inode_post_setxattr),
6600 LSM_HOOK_INIT(inode_getxattr, selinux_inode_getxattr),
6601 LSM_HOOK_INIT(inode_listxattr, selinux_inode_listxattr),
6602 LSM_HOOK_INIT(inode_removexattr, selinux_inode_removexattr),
6603 LSM_HOOK_INIT(inode_getsecurity, selinux_inode_getsecurity),
6604 LSM_HOOK_INIT(inode_setsecurity, selinux_inode_setsecurity),
6605 LSM_HOOK_INIT(inode_listsecurity, selinux_inode_listsecurity),
6606 LSM_HOOK_INIT(inode_getsecid, selinux_inode_getsecid),
Vivek Goyal56909eb2016-07-13 10:44:48 -04006607 LSM_HOOK_INIT(inode_copy_up, selinux_inode_copy_up),
Vivek Goyal19472b62016-07-13 10:44:50 -04006608 LSM_HOOK_INIT(inode_copy_up_xattr, selinux_inode_copy_up_xattr),
Linus Torvalds1da177e2005-04-16 15:20:36 -07006609
Casey Schauflere20b0432015-05-02 15:11:36 -07006610 LSM_HOOK_INIT(file_permission, selinux_file_permission),
6611 LSM_HOOK_INIT(file_alloc_security, selinux_file_alloc_security),
Casey Schauflere20b0432015-05-02 15:11:36 -07006612 LSM_HOOK_INIT(file_ioctl, selinux_file_ioctl),
6613 LSM_HOOK_INIT(mmap_file, selinux_mmap_file),
6614 LSM_HOOK_INIT(mmap_addr, selinux_mmap_addr),
6615 LSM_HOOK_INIT(file_mprotect, selinux_file_mprotect),
6616 LSM_HOOK_INIT(file_lock, selinux_file_lock),
6617 LSM_HOOK_INIT(file_fcntl, selinux_file_fcntl),
6618 LSM_HOOK_INIT(file_set_fowner, selinux_file_set_fowner),
6619 LSM_HOOK_INIT(file_send_sigiotask, selinux_file_send_sigiotask),
6620 LSM_HOOK_INIT(file_receive, selinux_file_receive),
Linus Torvalds1da177e2005-04-16 15:20:36 -07006621
Casey Schauflere20b0432015-05-02 15:11:36 -07006622 LSM_HOOK_INIT(file_open, selinux_file_open),
Linus Torvalds1da177e2005-04-16 15:20:36 -07006623
Tetsuo Handaa79be232017-03-28 23:08:45 +09006624 LSM_HOOK_INIT(task_alloc, selinux_task_alloc),
Casey Schauflere20b0432015-05-02 15:11:36 -07006625 LSM_HOOK_INIT(cred_prepare, selinux_cred_prepare),
6626 LSM_HOOK_INIT(cred_transfer, selinux_cred_transfer),
Matthew Garrett3ec30112018-01-08 13:36:19 -08006627 LSM_HOOK_INIT(cred_getsecid, selinux_cred_getsecid),
Casey Schauflere20b0432015-05-02 15:11:36 -07006628 LSM_HOOK_INIT(kernel_act_as, selinux_kernel_act_as),
6629 LSM_HOOK_INIT(kernel_create_files_as, selinux_kernel_create_files_as),
6630 LSM_HOOK_INIT(kernel_module_request, selinux_kernel_module_request),
Mimi Zoharc77b8cd2018-07-13 14:06:02 -04006631 LSM_HOOK_INIT(kernel_load_data, selinux_kernel_load_data),
Jeff Vander Stoep61d612ea2016-04-05 13:06:27 -07006632 LSM_HOOK_INIT(kernel_read_file, selinux_kernel_read_file),
Casey Schauflere20b0432015-05-02 15:11:36 -07006633 LSM_HOOK_INIT(task_setpgid, selinux_task_setpgid),
6634 LSM_HOOK_INIT(task_getpgid, selinux_task_getpgid),
6635 LSM_HOOK_INIT(task_getsid, selinux_task_getsid),
6636 LSM_HOOK_INIT(task_getsecid, selinux_task_getsecid),
6637 LSM_HOOK_INIT(task_setnice, selinux_task_setnice),
6638 LSM_HOOK_INIT(task_setioprio, selinux_task_setioprio),
6639 LSM_HOOK_INIT(task_getioprio, selinux_task_getioprio),
Stephen Smalley791ec492017-02-17 07:57:00 -05006640 LSM_HOOK_INIT(task_prlimit, selinux_task_prlimit),
Casey Schauflere20b0432015-05-02 15:11:36 -07006641 LSM_HOOK_INIT(task_setrlimit, selinux_task_setrlimit),
6642 LSM_HOOK_INIT(task_setscheduler, selinux_task_setscheduler),
6643 LSM_HOOK_INIT(task_getscheduler, selinux_task_getscheduler),
6644 LSM_HOOK_INIT(task_movememory, selinux_task_movememory),
6645 LSM_HOOK_INIT(task_kill, selinux_task_kill),
Casey Schauflere20b0432015-05-02 15:11:36 -07006646 LSM_HOOK_INIT(task_to_inode, selinux_task_to_inode),
Yuichi Nakamura788e7dd2007-09-14 09:27:07 +09006647
Casey Schauflere20b0432015-05-02 15:11:36 -07006648 LSM_HOOK_INIT(ipc_permission, selinux_ipc_permission),
6649 LSM_HOOK_INIT(ipc_getsecid, selinux_ipc_getsecid),
Linus Torvalds1da177e2005-04-16 15:20:36 -07006650
Casey Schauflere20b0432015-05-02 15:11:36 -07006651 LSM_HOOK_INIT(msg_msg_alloc_security, selinux_msg_msg_alloc_security),
Linus Torvalds1da177e2005-04-16 15:20:36 -07006652
Casey Schauflere20b0432015-05-02 15:11:36 -07006653 LSM_HOOK_INIT(msg_queue_alloc_security,
6654 selinux_msg_queue_alloc_security),
Casey Schauflere20b0432015-05-02 15:11:36 -07006655 LSM_HOOK_INIT(msg_queue_associate, selinux_msg_queue_associate),
6656 LSM_HOOK_INIT(msg_queue_msgctl, selinux_msg_queue_msgctl),
6657 LSM_HOOK_INIT(msg_queue_msgsnd, selinux_msg_queue_msgsnd),
6658 LSM_HOOK_INIT(msg_queue_msgrcv, selinux_msg_queue_msgrcv),
Linus Torvalds1da177e2005-04-16 15:20:36 -07006659
Casey Schauflere20b0432015-05-02 15:11:36 -07006660 LSM_HOOK_INIT(shm_alloc_security, selinux_shm_alloc_security),
Casey Schauflere20b0432015-05-02 15:11:36 -07006661 LSM_HOOK_INIT(shm_associate, selinux_shm_associate),
6662 LSM_HOOK_INIT(shm_shmctl, selinux_shm_shmctl),
6663 LSM_HOOK_INIT(shm_shmat, selinux_shm_shmat),
Linus Torvalds1da177e2005-04-16 15:20:36 -07006664
Casey Schauflere20b0432015-05-02 15:11:36 -07006665 LSM_HOOK_INIT(sem_alloc_security, selinux_sem_alloc_security),
Casey Schauflere20b0432015-05-02 15:11:36 -07006666 LSM_HOOK_INIT(sem_associate, selinux_sem_associate),
6667 LSM_HOOK_INIT(sem_semctl, selinux_sem_semctl),
6668 LSM_HOOK_INIT(sem_semop, selinux_sem_semop),
Linus Torvalds1da177e2005-04-16 15:20:36 -07006669
Casey Schauflere20b0432015-05-02 15:11:36 -07006670 LSM_HOOK_INIT(d_instantiate, selinux_d_instantiate),
Linus Torvalds1da177e2005-04-16 15:20:36 -07006671
Casey Schauflere20b0432015-05-02 15:11:36 -07006672 LSM_HOOK_INIT(getprocattr, selinux_getprocattr),
6673 LSM_HOOK_INIT(setprocattr, selinux_setprocattr),
Linus Torvalds1da177e2005-04-16 15:20:36 -07006674
Casey Schauflere20b0432015-05-02 15:11:36 -07006675 LSM_HOOK_INIT(ismaclabel, selinux_ismaclabel),
6676 LSM_HOOK_INIT(secid_to_secctx, selinux_secid_to_secctx),
6677 LSM_HOOK_INIT(secctx_to_secid, selinux_secctx_to_secid),
6678 LSM_HOOK_INIT(release_secctx, selinux_release_secctx),
Andreas Gruenbacher6f3be9f2015-12-24 11:09:40 -05006679 LSM_HOOK_INIT(inode_invalidate_secctx, selinux_inode_invalidate_secctx),
Casey Schauflere20b0432015-05-02 15:11:36 -07006680 LSM_HOOK_INIT(inode_notifysecctx, selinux_inode_notifysecctx),
6681 LSM_HOOK_INIT(inode_setsecctx, selinux_inode_setsecctx),
6682 LSM_HOOK_INIT(inode_getsecctx, selinux_inode_getsecctx),
Linus Torvalds1da177e2005-04-16 15:20:36 -07006683
Casey Schauflere20b0432015-05-02 15:11:36 -07006684 LSM_HOOK_INIT(unix_stream_connect, selinux_socket_unix_stream_connect),
6685 LSM_HOOK_INIT(unix_may_send, selinux_socket_unix_may_send),
Catherine Zhangdc49c1f2006-08-02 14:12:06 -07006686
Casey Schauflere20b0432015-05-02 15:11:36 -07006687 LSM_HOOK_INIT(socket_create, selinux_socket_create),
6688 LSM_HOOK_INIT(socket_post_create, selinux_socket_post_create),
David Herrmann0b811db2018-05-04 16:28:21 +02006689 LSM_HOOK_INIT(socket_socketpair, selinux_socket_socketpair),
Casey Schauflere20b0432015-05-02 15:11:36 -07006690 LSM_HOOK_INIT(socket_bind, selinux_socket_bind),
6691 LSM_HOOK_INIT(socket_connect, selinux_socket_connect),
6692 LSM_HOOK_INIT(socket_listen, selinux_socket_listen),
6693 LSM_HOOK_INIT(socket_accept, selinux_socket_accept),
6694 LSM_HOOK_INIT(socket_sendmsg, selinux_socket_sendmsg),
6695 LSM_HOOK_INIT(socket_recvmsg, selinux_socket_recvmsg),
6696 LSM_HOOK_INIT(socket_getsockname, selinux_socket_getsockname),
6697 LSM_HOOK_INIT(socket_getpeername, selinux_socket_getpeername),
6698 LSM_HOOK_INIT(socket_getsockopt, selinux_socket_getsockopt),
6699 LSM_HOOK_INIT(socket_setsockopt, selinux_socket_setsockopt),
6700 LSM_HOOK_INIT(socket_shutdown, selinux_socket_shutdown),
6701 LSM_HOOK_INIT(socket_sock_rcv_skb, selinux_socket_sock_rcv_skb),
6702 LSM_HOOK_INIT(socket_getpeersec_stream,
6703 selinux_socket_getpeersec_stream),
6704 LSM_HOOK_INIT(socket_getpeersec_dgram, selinux_socket_getpeersec_dgram),
6705 LSM_HOOK_INIT(sk_alloc_security, selinux_sk_alloc_security),
6706 LSM_HOOK_INIT(sk_free_security, selinux_sk_free_security),
6707 LSM_HOOK_INIT(sk_clone_security, selinux_sk_clone_security),
6708 LSM_HOOK_INIT(sk_getsecid, selinux_sk_getsecid),
6709 LSM_HOOK_INIT(sock_graft, selinux_sock_graft),
Richard Hainesd4529302018-02-13 20:57:18 +00006710 LSM_HOOK_INIT(sctp_assoc_request, selinux_sctp_assoc_request),
6711 LSM_HOOK_INIT(sctp_sk_clone, selinux_sctp_sk_clone),
6712 LSM_HOOK_INIT(sctp_bind_connect, selinux_sctp_bind_connect),
Casey Schauflere20b0432015-05-02 15:11:36 -07006713 LSM_HOOK_INIT(inet_conn_request, selinux_inet_conn_request),
6714 LSM_HOOK_INIT(inet_csk_clone, selinux_inet_csk_clone),
6715 LSM_HOOK_INIT(inet_conn_established, selinux_inet_conn_established),
6716 LSM_HOOK_INIT(secmark_relabel_packet, selinux_secmark_relabel_packet),
6717 LSM_HOOK_INIT(secmark_refcount_inc, selinux_secmark_refcount_inc),
6718 LSM_HOOK_INIT(secmark_refcount_dec, selinux_secmark_refcount_dec),
6719 LSM_HOOK_INIT(req_classify_flow, selinux_req_classify_flow),
6720 LSM_HOOK_INIT(tun_dev_alloc_security, selinux_tun_dev_alloc_security),
6721 LSM_HOOK_INIT(tun_dev_free_security, selinux_tun_dev_free_security),
6722 LSM_HOOK_INIT(tun_dev_create, selinux_tun_dev_create),
6723 LSM_HOOK_INIT(tun_dev_attach_queue, selinux_tun_dev_attach_queue),
6724 LSM_HOOK_INIT(tun_dev_attach, selinux_tun_dev_attach),
6725 LSM_HOOK_INIT(tun_dev_open, selinux_tun_dev_open),
Daniel Jurgens3a976fa2017-05-19 15:48:56 +03006726#ifdef CONFIG_SECURITY_INFINIBAND
Daniel Jurgenscfc4d882017-05-19 15:48:57 +03006727 LSM_HOOK_INIT(ib_pkey_access, selinux_ib_pkey_access),
Daniel Jurgensab861df2017-05-19 15:48:58 +03006728 LSM_HOOK_INIT(ib_endport_manage_subnet,
6729 selinux_ib_endport_manage_subnet),
Daniel Jurgens3a976fa2017-05-19 15:48:56 +03006730 LSM_HOOK_INIT(ib_alloc_security, selinux_ib_alloc_security),
6731 LSM_HOOK_INIT(ib_free_security, selinux_ib_free_security),
6732#endif
Trent Jaegerd28d1e02005-12-13 23:12:40 -08006733#ifdef CONFIG_SECURITY_NETWORK_XFRM
Casey Schauflere20b0432015-05-02 15:11:36 -07006734 LSM_HOOK_INIT(xfrm_policy_alloc_security, selinux_xfrm_policy_alloc),
6735 LSM_HOOK_INIT(xfrm_policy_clone_security, selinux_xfrm_policy_clone),
6736 LSM_HOOK_INIT(xfrm_policy_free_security, selinux_xfrm_policy_free),
6737 LSM_HOOK_INIT(xfrm_policy_delete_security, selinux_xfrm_policy_delete),
6738 LSM_HOOK_INIT(xfrm_state_alloc, selinux_xfrm_state_alloc),
6739 LSM_HOOK_INIT(xfrm_state_alloc_acquire,
6740 selinux_xfrm_state_alloc_acquire),
6741 LSM_HOOK_INIT(xfrm_state_free_security, selinux_xfrm_state_free),
6742 LSM_HOOK_INIT(xfrm_state_delete_security, selinux_xfrm_state_delete),
6743 LSM_HOOK_INIT(xfrm_policy_lookup, selinux_xfrm_policy_lookup),
6744 LSM_HOOK_INIT(xfrm_state_pol_flow_match,
6745 selinux_xfrm_state_pol_flow_match),
6746 LSM_HOOK_INIT(xfrm_decode_session, selinux_xfrm_decode_session),
Linus Torvalds1da177e2005-04-16 15:20:36 -07006747#endif
Michael LeMayd7200242006-06-22 14:47:17 -07006748
6749#ifdef CONFIG_KEYS
Casey Schauflere20b0432015-05-02 15:11:36 -07006750 LSM_HOOK_INIT(key_alloc, selinux_key_alloc),
6751 LSM_HOOK_INIT(key_free, selinux_key_free),
6752 LSM_HOOK_INIT(key_permission, selinux_key_permission),
6753 LSM_HOOK_INIT(key_getsecurity, selinux_key_getsecurity),
Michael LeMayd7200242006-06-22 14:47:17 -07006754#endif
Ahmed S. Darwish9d57a7f2008-03-01 22:03:14 +02006755
6756#ifdef CONFIG_AUDIT
Casey Schauflere20b0432015-05-02 15:11:36 -07006757 LSM_HOOK_INIT(audit_rule_init, selinux_audit_rule_init),
6758 LSM_HOOK_INIT(audit_rule_known, selinux_audit_rule_known),
6759 LSM_HOOK_INIT(audit_rule_match, selinux_audit_rule_match),
6760 LSM_HOOK_INIT(audit_rule_free, selinux_audit_rule_free),
Ahmed S. Darwish9d57a7f2008-03-01 22:03:14 +02006761#endif
Chenbo Fengec27c352017-10-18 13:00:25 -07006762
6763#ifdef CONFIG_BPF_SYSCALL
6764 LSM_HOOK_INIT(bpf, selinux_bpf),
6765 LSM_HOOK_INIT(bpf_map, selinux_bpf_map),
6766 LSM_HOOK_INIT(bpf_prog, selinux_bpf_prog),
6767 LSM_HOOK_INIT(bpf_map_alloc_security, selinux_bpf_map_alloc),
6768 LSM_HOOK_INIT(bpf_prog_alloc_security, selinux_bpf_prog_alloc),
6769 LSM_HOOK_INIT(bpf_map_free_security, selinux_bpf_map_free),
6770 LSM_HOOK_INIT(bpf_prog_free_security, selinux_bpf_prog_free),
6771#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07006772};
6773
6774static __init int selinux_init(void)
6775{
peter enderborgc103a912018-06-12 10:09:03 +02006776 pr_info("SELinux: Initializing.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07006777
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05006778 memset(&selinux_state, 0, sizeof(selinux_state));
Paul Mooree5a5ca92018-03-01 17:38:30 -05006779 enforcing_set(&selinux_state, selinux_enforcing_boot);
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05006780 selinux_state.checkreqprot = selinux_checkreqprot_boot;
6781 selinux_ss_init(&selinux_state.ss);
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006782 selinux_avc_init(&selinux_state.avc);
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05006783
Linus Torvalds1da177e2005-04-16 15:20:36 -07006784 /* Set the security state for the initial task. */
David Howellsd84f4f92008-11-14 10:39:23 +11006785 cred_init_security();
Linus Torvalds1da177e2005-04-16 15:20:36 -07006786
Stephen Smalleyfcaaade2010-04-28 15:57:57 -04006787 default_noexec = !(VM_DATA_DEFAULT_FLAGS & VM_EXEC);
6788
Linus Torvalds1da177e2005-04-16 15:20:36 -07006789 avc_init();
6790
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05006791 avtab_cache_init();
6792
6793 ebitmap_cache_init();
6794
6795 hashtab_cache_init();
6796
Casey Schauflerd69dece52017-01-18 17:09:05 -08006797 security_add_hooks(selinux_hooks, ARRAY_SIZE(selinux_hooks), "selinux");
Linus Torvalds1da177e2005-04-16 15:20:36 -07006798
Paul Moore615e51f2014-06-26 14:33:56 -04006799 if (avc_add_callback(selinux_netcache_avc_callback, AVC_CALLBACK_RESET))
6800 panic("SELinux: Unable to register AVC netcache callback\n");
6801
Daniel Jurgens8f408ab2017-05-19 15:48:53 +03006802 if (avc_add_callback(selinux_lsm_notifier_avc_callback, AVC_CALLBACK_RESET))
6803 panic("SELinux: Unable to register AVC LSM notifier callback\n");
6804
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05006805 if (selinux_enforcing_boot)
peter enderborgc103a912018-06-12 10:09:03 +02006806 pr_debug("SELinux: Starting in enforcing mode\n");
Eric Paris828dfe12008-04-17 13:17:49 -04006807 else
peter enderborgc103a912018-06-12 10:09:03 +02006808 pr_debug("SELinux: Starting in permissive mode\n");
Michael LeMayd7200242006-06-22 14:47:17 -07006809
Linus Torvalds1da177e2005-04-16 15:20:36 -07006810 return 0;
6811}
6812
Al Viroe8c26252010-03-23 06:36:54 -04006813static void delayed_superblock_init(struct super_block *sb, void *unused)
6814{
Al Viro204cc0c2018-12-13 13:41:47 -05006815 selinux_set_mnt_opts(sb, NULL, 0, NULL);
Al Viroe8c26252010-03-23 06:36:54 -04006816}
6817
Linus Torvalds1da177e2005-04-16 15:20:36 -07006818void selinux_complete_init(void)
6819{
peter enderborgc103a912018-06-12 10:09:03 +02006820 pr_debug("SELinux: Completing initialization.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07006821
6822 /* Set up any superblocks initialized prior to the policy load. */
peter enderborgc103a912018-06-12 10:09:03 +02006823 pr_debug("SELinux: Setting up existing superblocks.\n");
Al Viroe8c26252010-03-23 06:36:54 -04006824 iterate_supers(delayed_superblock_init, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006825}
6826
6827/* SELinux requires early initialization in order to label
6828 all processes and objects when they are created. */
Kees Cook3d6e5f62018-10-10 17:18:23 -07006829DEFINE_LSM(selinux) = {
Kees Cook07aed2f2018-10-10 17:18:24 -07006830 .name = "selinux",
Kees Cook14bd99c2018-09-19 19:57:06 -07006831 .flags = LSM_FLAG_LEGACY_MAJOR | LSM_FLAG_EXCLUSIVE,
Kees Cookc5459b82018-09-13 22:28:48 -07006832 .enabled = &selinux_enabled,
Casey Schauflerbbd36622018-11-12 09:30:56 -08006833 .blobs = &selinux_blob_sizes,
Kees Cook3d6e5f62018-10-10 17:18:23 -07006834 .init = selinux_init,
6835};
Linus Torvalds1da177e2005-04-16 15:20:36 -07006836
Stephen Smalleyc2b507f2006-02-04 23:27:50 -08006837#if defined(CONFIG_NETFILTER)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006838
Florian Westphal591bb272017-07-26 11:40:52 +02006839static const struct nf_hook_ops selinux_nf_ops[] = {
Paul Mooreeffad8d2008-01-29 08:49:27 -05006840 {
6841 .hook = selinux_ipv4_postroute,
Alban Crequy2597a832012-05-14 03:56:39 +00006842 .pf = NFPROTO_IPV4,
Paul Mooreeffad8d2008-01-29 08:49:27 -05006843 .hooknum = NF_INET_POST_ROUTING,
6844 .priority = NF_IP_PRI_SELINUX_LAST,
6845 },
6846 {
6847 .hook = selinux_ipv4_forward,
Alban Crequy2597a832012-05-14 03:56:39 +00006848 .pf = NFPROTO_IPV4,
Paul Mooreeffad8d2008-01-29 08:49:27 -05006849 .hooknum = NF_INET_FORWARD,
6850 .priority = NF_IP_PRI_SELINUX_FIRST,
Paul Moore948bf852008-10-10 10:16:32 -04006851 },
6852 {
6853 .hook = selinux_ipv4_output,
Alban Crequy2597a832012-05-14 03:56:39 +00006854 .pf = NFPROTO_IPV4,
Paul Moore948bf852008-10-10 10:16:32 -04006855 .hooknum = NF_INET_LOCAL_OUT,
6856 .priority = NF_IP_PRI_SELINUX_FIRST,
Jiri Pirko25db6be2014-09-03 17:42:13 +02006857 },
Javier Martinez Canillas1a93a6e2016-08-08 13:08:25 -04006858#if IS_ENABLED(CONFIG_IPV6)
Paul Mooreeffad8d2008-01-29 08:49:27 -05006859 {
6860 .hook = selinux_ipv6_postroute,
Alban Crequy2597a832012-05-14 03:56:39 +00006861 .pf = NFPROTO_IPV6,
Paul Mooreeffad8d2008-01-29 08:49:27 -05006862 .hooknum = NF_INET_POST_ROUTING,
6863 .priority = NF_IP6_PRI_SELINUX_LAST,
6864 },
6865 {
6866 .hook = selinux_ipv6_forward,
Alban Crequy2597a832012-05-14 03:56:39 +00006867 .pf = NFPROTO_IPV6,
Paul Mooreeffad8d2008-01-29 08:49:27 -05006868 .hooknum = NF_INET_FORWARD,
6869 .priority = NF_IP6_PRI_SELINUX_FIRST,
Jiri Pirko25db6be2014-09-03 17:42:13 +02006870 },
Huw Davies2917f572016-06-27 15:06:15 -04006871 {
6872 .hook = selinux_ipv6_output,
6873 .pf = NFPROTO_IPV6,
6874 .hooknum = NF_INET_LOCAL_OUT,
6875 .priority = NF_IP6_PRI_SELINUX_FIRST,
6876 },
Linus Torvalds1da177e2005-04-16 15:20:36 -07006877#endif /* IPV6 */
Jiri Pirko25db6be2014-09-03 17:42:13 +02006878};
Linus Torvalds1da177e2005-04-16 15:20:36 -07006879
Florian Westphal8e71bf72017-04-21 11:49:09 +02006880static int __net_init selinux_nf_register(struct net *net)
6881{
6882 return nf_register_net_hooks(net, selinux_nf_ops,
6883 ARRAY_SIZE(selinux_nf_ops));
6884}
6885
6886static void __net_exit selinux_nf_unregister(struct net *net)
6887{
6888 nf_unregister_net_hooks(net, selinux_nf_ops,
6889 ARRAY_SIZE(selinux_nf_ops));
6890}
6891
6892static struct pernet_operations selinux_net_ops = {
6893 .init = selinux_nf_register,
6894 .exit = selinux_nf_unregister,
6895};
6896
Linus Torvalds1da177e2005-04-16 15:20:36 -07006897static int __init selinux_nf_ip_init(void)
6898{
Jiri Pirko25db6be2014-09-03 17:42:13 +02006899 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006900
6901 if (!selinux_enabled)
Jiri Pirko25db6be2014-09-03 17:42:13 +02006902 return 0;
Eric Parisfadcdb42007-02-22 18:11:31 -05006903
peter enderborgc103a912018-06-12 10:09:03 +02006904 pr_debug("SELinux: Registering netfilter hooks\n");
Eric Parisfadcdb42007-02-22 18:11:31 -05006905
Florian Westphal8e71bf72017-04-21 11:49:09 +02006906 err = register_pernet_subsys(&selinux_net_ops);
Alexey Dobriyan6c5a9d22008-07-26 17:48:15 -07006907 if (err)
Florian Westphal8e71bf72017-04-21 11:49:09 +02006908 panic("SELinux: register_pernet_subsys: error %d\n", err);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006909
Jiri Pirko25db6be2014-09-03 17:42:13 +02006910 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006911}
Linus Torvalds1da177e2005-04-16 15:20:36 -07006912__initcall(selinux_nf_ip_init);
6913
6914#ifdef CONFIG_SECURITY_SELINUX_DISABLE
6915static void selinux_nf_ip_exit(void)
6916{
peter enderborgc103a912018-06-12 10:09:03 +02006917 pr_debug("SELinux: Unregistering netfilter hooks\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07006918
Florian Westphal8e71bf72017-04-21 11:49:09 +02006919 unregister_pernet_subsys(&selinux_net_ops);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006920}
6921#endif
6922
Stephen Smalleyc2b507f2006-02-04 23:27:50 -08006923#else /* CONFIG_NETFILTER */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006924
6925#ifdef CONFIG_SECURITY_SELINUX_DISABLE
6926#define selinux_nf_ip_exit()
6927#endif
6928
Stephen Smalleyc2b507f2006-02-04 23:27:50 -08006929#endif /* CONFIG_NETFILTER */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006930
6931#ifdef CONFIG_SECURITY_SELINUX_DISABLE
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05006932int selinux_disable(struct selinux_state *state)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006933{
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05006934 if (state->initialized) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07006935 /* Not permitted after initial policy load. */
6936 return -EINVAL;
6937 }
6938
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05006939 if (state->disabled) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07006940 /* Only do this once. */
6941 return -EINVAL;
6942 }
6943
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05006944 state->disabled = 1;
6945
peter enderborgc103a912018-06-12 10:09:03 +02006946 pr_info("SELinux: Disabled at runtime.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07006947
Stephen Smalley30d55282006-05-03 10:52:36 -04006948 selinux_enabled = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006949
Casey Schauflerb1d9e6b2015-05-02 15:11:42 -07006950 security_delete_hooks(selinux_hooks, ARRAY_SIZE(selinux_hooks));
Linus Torvalds1da177e2005-04-16 15:20:36 -07006951
Eric Parisaf8ff042009-09-20 21:23:01 -04006952 /* Try to destroy the avc node cache */
6953 avc_disable();
6954
Linus Torvalds1da177e2005-04-16 15:20:36 -07006955 /* Unregister netfilter hooks. */
6956 selinux_nf_ip_exit();
6957
6958 /* Unregister selinuxfs. */
6959 exit_sel_fs();
6960
6961 return 0;
6962}
6963#endif