blob: 085409b367949b637e265a2436567e18b3e82c60 [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>
David Howells442155c2018-11-01 23:07:24 +000051#include <linux/fs_context.h>
52#include <linux/fs_parser.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070053#include <linux/netfilter_ipv4.h>
54#include <linux/netfilter_ipv6.h>
55#include <linux/tty.h>
56#include <net/icmp.h>
Stephen Hemminger227b60f2007-10-10 17:30:46 -070057#include <net/ip.h> /* for local_port_range[] */
Linus Torvalds1da177e2005-04-16 15:20:36 -070058#include <net/tcp.h> /* struct or_callable used in sock_rcv_skb */
Paul Moore47180062013-12-04 16:10:45 -050059#include <net/inet_connection_sock.h>
Paul Moore220deb92008-01-29 08:38:23 -050060#include <net/net_namespace.h>
Paul Moored621d352008-01-29 08:43:36 -050061#include <net/netlabel.h>
Eric Parisf5269712008-05-14 11:27:45 -040062#include <linux/uaccess.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070063#include <asm/ioctls.h>
Arun Sharma600634972011-07-26 16:09:06 -070064#include <linux/atomic.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070065#include <linux/bitops.h>
66#include <linux/interrupt.h>
67#include <linux/netdevice.h> /* for network interface checks */
Hong zhi guo77954982013-03-27 06:49:35 +000068#include <net/netlink.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070069#include <linux/tcp.h>
70#include <linux/udp.h>
James Morris2ee92d42006-11-13 16:09:01 -080071#include <linux/dccp.h>
Richard Hainesd4529302018-02-13 20:57:18 +000072#include <linux/sctp.h>
73#include <net/sctp/structs.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070074#include <linux/quota.h>
75#include <linux/un.h> /* for Unix socket types */
76#include <net/af_unix.h> /* for Unix socket types */
77#include <linux/parser.h>
78#include <linux/nfs_mount.h>
79#include <net/ipv6.h>
80#include <linux/hugetlb.h>
81#include <linux/personality.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070082#include <linux/audit.h>
Eric Paris6931dfc2005-06-30 02:58:51 -070083#include <linux/string.h>
Eric Paris23970742006-09-25 23:32:01 -070084#include <linux/mutex.h>
Frank Mayharf06febc2008-09-12 09:54:39 -070085#include <linux/posix-timers.h>
Kees Cook00234592010-02-03 15:36:43 -080086#include <linux/syslog.h>
Serge E. Hallyn34867402011-03-23 16:43:17 -070087#include <linux/user_namespace.h>
Paul Gortmaker44fc7ea2011-05-26 20:52:10 -040088#include <linux/export.h>
Al Viro40401532012-02-13 03:58:52 +000089#include <linux/msg.h>
90#include <linux/shm.h>
Chenbo Fengec27c352017-10-18 13:00:25 -070091#include <linux/bpf.h>
David Howellse262e32d2018-11-01 23:07:23 +000092#include <uapi/linux/mount.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070093
94#include "avc.h"
95#include "objsec.h"
96#include "netif.h"
Paul Moore224dfbd2008-01-29 08:38:13 -050097#include "netnode.h"
Paul Moore3e1121722008-04-10 10:48:14 -040098#include "netport.h"
Daniel Jurgens409dcf32017-05-19 15:48:59 +030099#include "ibpkey.h"
Trent Jaegerd28d1e02005-12-13 23:12:40 -0800100#include "xfrm.h"
Paul Moorec60475b2007-02-28 15:14:23 -0500101#include "netlabel.h"
Ahmed S. Darwish9d57a7f2008-03-01 22:03:14 +0200102#include "audit.h"
James Morris7b98a582011-08-30 12:52:32 +1000103#include "avc_ss.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -0700104
Stephen Smalleyaa8e7122018-03-01 18:48:02 -0500105struct selinux_state selinux_state;
106
Paul Moored621d352008-01-29 08:43:36 -0500107/* SECMARK reference count */
James Morris56a4ca92011-08-17 11:08:43 +1000108static atomic_t selinux_secmark_refcount = ATOMIC_INIT(0);
Paul Moored621d352008-01-29 08:43:36 -0500109
Linus Torvalds1da177e2005-04-16 15:20:36 -0700110#ifdef CONFIG_SECURITY_SELINUX_DEVELOP
Stephen Smalleyaa8e7122018-03-01 18:48:02 -0500111static int selinux_enforcing_boot;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700112
113static int __init enforcing_setup(char *str)
114{
Eric Parisf5269712008-05-14 11:27:45 -0400115 unsigned long enforcing;
Jingoo Han29707b22014-02-05 15:13:14 +0900116 if (!kstrtoul(str, 0, &enforcing))
Stephen Smalleyaa8e7122018-03-01 18:48:02 -0500117 selinux_enforcing_boot = enforcing ? 1 : 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700118 return 1;
119}
120__setup("enforcing=", enforcing_setup);
Stephen Smalleyaa8e7122018-03-01 18:48:02 -0500121#else
122#define selinux_enforcing_boot 1
Linus Torvalds1da177e2005-04-16 15:20:36 -0700123#endif
124
Kees Cookbe6ec882018-10-01 17:08:57 -0700125int selinux_enabled __lsm_ro_after_init = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700126#ifdef CONFIG_SECURITY_SELINUX_BOOTPARAM
Linus Torvalds1da177e2005-04-16 15:20:36 -0700127static int __init selinux_enabled_setup(char *str)
128{
Eric Parisf5269712008-05-14 11:27:45 -0400129 unsigned long enabled;
Jingoo Han29707b22014-02-05 15:13:14 +0900130 if (!kstrtoul(str, 0, &enabled))
Eric Parisf5269712008-05-14 11:27:45 -0400131 selinux_enabled = enabled ? 1 : 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700132 return 1;
133}
134__setup("selinux=", selinux_enabled_setup);
135#endif
136
Stephen Smalleyaa8e7122018-03-01 18:48:02 -0500137static unsigned int selinux_checkreqprot_boot =
138 CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE;
139
140static int __init checkreqprot_setup(char *str)
141{
142 unsigned long checkreqprot;
143
144 if (!kstrtoul(str, 0, &checkreqprot))
145 selinux_checkreqprot_boot = checkreqprot ? 1 : 0;
146 return 1;
147}
148__setup("checkreqprot=", checkreqprot_setup);
149
Paul Moored621d352008-01-29 08:43:36 -0500150/**
151 * selinux_secmark_enabled - Check to see if SECMARK is currently enabled
152 *
153 * Description:
154 * This function checks the SECMARK reference counter to see if any SECMARK
155 * targets are currently configured, if the reference counter is greater than
156 * zero SECMARK is considered to be enabled. Returns true (1) if SECMARK is
Chris PeBenito2be4d742013-05-03 09:05:39 -0400157 * enabled, false (0) if SECMARK is disabled. If the always_check_network
158 * policy capability is enabled, SECMARK is always considered enabled.
Paul Moored621d352008-01-29 08:43:36 -0500159 *
160 */
161static int selinux_secmark_enabled(void)
162{
Stephen Smalleyaa8e7122018-03-01 18:48:02 -0500163 return (selinux_policycap_alwaysnetwork() ||
164 atomic_read(&selinux_secmark_refcount));
Chris PeBenito2be4d742013-05-03 09:05:39 -0400165}
166
167/**
168 * selinux_peerlbl_enabled - Check to see if peer labeling is currently enabled
169 *
170 * Description:
171 * This function checks if NetLabel or labeled IPSEC is enabled. Returns true
172 * (1) if any are enabled or false (0) if neither are enabled. If the
173 * always_check_network policy capability is enabled, peer labeling
174 * is always considered enabled.
175 *
176 */
177static int selinux_peerlbl_enabled(void)
178{
Stephen Smalleyaa8e7122018-03-01 18:48:02 -0500179 return (selinux_policycap_alwaysnetwork() ||
180 netlbl_enabled() || selinux_xfrm_enabled());
Paul Moored621d352008-01-29 08:43:36 -0500181}
182
Paul Moore615e51f2014-06-26 14:33:56 -0400183static int selinux_netcache_avc_callback(u32 event)
184{
185 if (event == AVC_CALLBACK_RESET) {
186 sel_netif_flush();
187 sel_netnode_flush();
188 sel_netport_flush();
189 synchronize_net();
190 }
191 return 0;
192}
193
Daniel Jurgens8f408ab2017-05-19 15:48:53 +0300194static int selinux_lsm_notifier_avc_callback(u32 event)
195{
Daniel Jurgens409dcf32017-05-19 15:48:59 +0300196 if (event == AVC_CALLBACK_RESET) {
197 sel_ib_pkey_flush();
Daniel Jurgens8f408ab2017-05-19 15:48:53 +0300198 call_lsm_notifier(LSM_POLICY_CHANGE, NULL);
Daniel Jurgens409dcf32017-05-19 15:48:59 +0300199 }
Daniel Jurgens8f408ab2017-05-19 15:48:53 +0300200
201 return 0;
202}
203
David Howellsd84f4f92008-11-14 10:39:23 +1100204/*
205 * initialise the security for the init task
206 */
207static void cred_init_security(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700208{
David Howells3b11a1d2008-11-14 10:39:26 +1100209 struct cred *cred = (struct cred *) current->real_cred;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700210 struct task_security_struct *tsec;
211
Casey Schauflerbbd36622018-11-12 09:30:56 -0800212 tsec = selinux_cred(cred);
David Howellsd84f4f92008-11-14 10:39:23 +1100213 tsec->osid = tsec->sid = SECINITSID_KERNEL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700214}
215
David Howells275bb412008-11-14 10:39:19 +1100216/*
David Howells88e67f32008-11-14 10:39:21 +1100217 * get the security ID of a set of credentials
218 */
219static inline u32 cred_sid(const struct cred *cred)
220{
221 const struct task_security_struct *tsec;
222
Casey Schaufler0c6cfa62018-09-21 17:17:16 -0700223 tsec = selinux_cred(cred);
David Howells88e67f32008-11-14 10:39:21 +1100224 return tsec->sid;
225}
226
227/*
David Howells3b11a1d2008-11-14 10:39:26 +1100228 * get the objective security ID of a task
David Howells275bb412008-11-14 10:39:19 +1100229 */
230static inline u32 task_sid(const struct task_struct *task)
231{
David Howells275bb412008-11-14 10:39:19 +1100232 u32 sid;
233
234 rcu_read_lock();
David Howells88e67f32008-11-14 10:39:21 +1100235 sid = cred_sid(__task_cred(task));
David Howells275bb412008-11-14 10:39:19 +1100236 rcu_read_unlock();
237 return sid;
238}
239
David Howells88e67f32008-11-14 10:39:21 +1100240/* Allocate and free functions for each kind of security blob. */
241
Linus Torvalds1da177e2005-04-16 15:20:36 -0700242static int inode_alloc_security(struct inode *inode)
243{
Casey Schauflerafb1cbe32018-09-21 17:19:29 -0700244 struct inode_security_struct *isec = selinux_inode(inode);
David Howells275bb412008-11-14 10:39:19 +1100245 u32 sid = current_sid();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700246
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +0100247 spin_lock_init(&isec->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700248 INIT_LIST_HEAD(&isec->list);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700249 isec->inode = inode;
250 isec->sid = SECINITSID_UNLABELED;
251 isec->sclass = SECCLASS_FILE;
David Howells275bb412008-11-14 10:39:19 +1100252 isec->task_sid = sid;
Andreas Gruenbacher42059112016-11-10 22:18:27 +0100253 isec->initialized = LABEL_INVALID;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700254
255 return 0;
256}
257
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -0500258static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dentry);
259
260/*
261 * Try reloading inode security labels that have been marked as invalid. The
262 * @may_sleep parameter indicates when sleeping and thus reloading labels is
Andreas Gruenbacher42059112016-11-10 22:18:27 +0100263 * allowed; when set to false, returns -ECHILD when the label is
Al Viroe9193282018-04-24 21:31:02 -0400264 * invalid. The @dentry parameter should be set to a dentry of the inode.
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -0500265 */
266static int __inode_security_revalidate(struct inode *inode,
Al Viroe9193282018-04-24 21:31:02 -0400267 struct dentry *dentry,
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -0500268 bool may_sleep)
269{
Casey Schaufler80788c22018-09-21 17:19:11 -0700270 struct inode_security_struct *isec = selinux_inode(inode);
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -0500271
272 might_sleep_if(may_sleep);
273
Stephen Smalleyaa8e7122018-03-01 18:48:02 -0500274 if (selinux_state.initialized &&
275 isec->initialized != LABEL_INITIALIZED) {
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -0500276 if (!may_sleep)
277 return -ECHILD;
278
279 /*
280 * Try reloading the inode security label. This will fail if
281 * @opt_dentry is NULL and no dentry for this inode can be
282 * found; in that case, continue using the old label.
283 */
Al Viroe9193282018-04-24 21:31:02 -0400284 inode_doinit_with_dentry(inode, dentry);
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -0500285 }
286 return 0;
287}
288
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -0500289static struct inode_security_struct *inode_security_novalidate(struct inode *inode)
290{
Casey Schaufler80788c22018-09-21 17:19:11 -0700291 return selinux_inode(inode);
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -0500292}
293
294static struct inode_security_struct *inode_security_rcu(struct inode *inode, bool rcu)
295{
296 int error;
297
298 error = __inode_security_revalidate(inode, NULL, !rcu);
299 if (error)
300 return ERR_PTR(error);
Casey Schaufler80788c22018-09-21 17:19:11 -0700301 return selinux_inode(inode);
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -0500302}
303
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -0500304/*
305 * Get the security label of an inode.
306 */
307static struct inode_security_struct *inode_security(struct inode *inode)
308{
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -0500309 __inode_security_revalidate(inode, NULL, true);
Casey Schaufler80788c22018-09-21 17:19:11 -0700310 return selinux_inode(inode);
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -0500311}
312
Paul Moore2c971652016-04-19 16:36:28 -0400313static struct inode_security_struct *backing_inode_security_novalidate(struct dentry *dentry)
314{
315 struct inode *inode = d_backing_inode(dentry);
316
Casey Schaufler80788c22018-09-21 17:19:11 -0700317 return selinux_inode(inode);
Paul Moore2c971652016-04-19 16:36:28 -0400318}
319
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -0500320/*
321 * Get the security label of a dentry's backing inode.
322 */
323static struct inode_security_struct *backing_inode_security(struct dentry *dentry)
324{
325 struct inode *inode = d_backing_inode(dentry);
326
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -0500327 __inode_security_revalidate(inode, dentry, true);
Casey Schaufler80788c22018-09-21 17:19:11 -0700328 return selinux_inode(inode);
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -0500329}
330
Linus Torvalds1da177e2005-04-16 15:20:36 -0700331static void inode_free_security(struct inode *inode)
332{
Casey Schaufler80788c22018-09-21 17:19:11 -0700333 struct inode_security_struct *isec = selinux_inode(inode);
Casey Schauflerafb1cbe32018-09-21 17:19:29 -0700334 struct superblock_security_struct *sbsec;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700335
Casey Schauflerafb1cbe32018-09-21 17:19:29 -0700336 if (!isec)
337 return;
338 sbsec = inode->i_sb->s_security;
Waiman Long9629d042015-07-10 17:19:56 -0400339 /*
340 * As not all inode security structures are in a list, we check for
341 * empty list outside of the lock to make sure that we won't waste
342 * time taking a lock doing nothing.
343 *
344 * The list_del_init() function can be safely called more than once.
345 * It should not be possible for this function to be called with
346 * concurrent list_add(), but for better safety against future changes
347 * in the code, we use list_empty_careful() here.
348 */
349 if (!list_empty_careful(&isec->list)) {
350 spin_lock(&sbsec->isec_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700351 list_del_init(&isec->list);
Waiman Long9629d042015-07-10 17:19:56 -0400352 spin_unlock(&sbsec->isec_lock);
353 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700354}
355
356static int file_alloc_security(struct file *file)
357{
Casey Schaufler33bf60c2018-11-12 12:02:49 -0800358 struct file_security_struct *fsec = selinux_file(file);
David Howells275bb412008-11-14 10:39:19 +1100359 u32 sid = current_sid();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700360
David Howells275bb412008-11-14 10:39:19 +1100361 fsec->sid = sid;
362 fsec->fown_sid = sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700363
364 return 0;
365}
366
Linus Torvalds1da177e2005-04-16 15:20:36 -0700367static int superblock_alloc_security(struct super_block *sb)
368{
369 struct superblock_security_struct *sbsec;
370
James Morris89d155e2005-10-30 14:59:21 -0800371 sbsec = kzalloc(sizeof(struct superblock_security_struct), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700372 if (!sbsec)
373 return -ENOMEM;
374
Eric Parisbc7e9822006-09-25 23:32:02 -0700375 mutex_init(&sbsec->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700376 INIT_LIST_HEAD(&sbsec->isec_head);
377 spin_lock_init(&sbsec->isec_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700378 sbsec->sb = sb;
379 sbsec->sid = SECINITSID_UNLABELED;
380 sbsec->def_sid = SECINITSID_FILE;
Eric Parisc312feb2006-07-10 04:43:53 -0700381 sbsec->mntpoint_sid = SECINITSID_UNLABELED;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700382 sb->s_security = sbsec;
383
384 return 0;
385}
386
387static void superblock_free_security(struct super_block *sb)
388{
389 struct superblock_security_struct *sbsec = sb->s_security;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700390 sb->s_security = NULL;
391 kfree(sbsec);
392}
393
Al Virobd323652018-12-13 15:04:59 -0500394struct selinux_mnt_opts {
395 const char *fscontext, *context, *rootcontext, *defcontext;
396};
397
Al Viro204cc0c2018-12-13 13:41:47 -0500398static void selinux_free_mnt_opts(void *mnt_opts)
399{
Al Virobd323652018-12-13 15:04:59 -0500400 struct selinux_mnt_opts *opts = mnt_opts;
401 kfree(opts->fscontext);
402 kfree(opts->context);
403 kfree(opts->rootcontext);
404 kfree(opts->defcontext);
Al Viro204cc0c2018-12-13 13:41:47 -0500405 kfree(opts);
406}
407
Linus Torvalds1da177e2005-04-16 15:20:36 -0700408static inline int inode_doinit(struct inode *inode)
409{
410 return inode_doinit_with_dentry(inode, NULL);
411}
412
413enum {
Eric Paris31e87932007-09-19 17:19:12 -0400414 Opt_error = -1,
David Howells442155c2018-11-01 23:07:24 +0000415 Opt_context = 0,
416 Opt_defcontext = 1,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700417 Opt_fscontext = 2,
David Howells442155c2018-11-01 23:07:24 +0000418 Opt_rootcontext = 3,
419 Opt_seclabel = 4,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700420};
421
Al Viroda3d76a2018-12-17 10:14:16 -0500422#define A(s, has_arg) {#s, sizeof(#s) - 1, Opt_##s, has_arg}
Al Viro169d68efb2018-12-14 22:44:50 -0500423static struct {
424 const char *name;
425 int len;
426 int opt;
427 bool has_arg;
428} tokens[] = {
Al Viroda3d76a2018-12-17 10:14:16 -0500429 A(context, true),
430 A(fscontext, true),
431 A(defcontext, true),
432 A(rootcontext, true),
433 A(seclabel, false),
Linus Torvalds1da177e2005-04-16 15:20:36 -0700434};
Al Viro169d68efb2018-12-14 22:44:50 -0500435#undef A
436
437static int match_opt_prefix(char *s, int l, char **arg)
438{
439 int i;
440
441 for (i = 0; i < ARRAY_SIZE(tokens); i++) {
442 size_t len = tokens[i].len;
443 if (len > l || memcmp(s, tokens[i].name, len))
444 continue;
445 if (tokens[i].has_arg) {
446 if (len == l || s[len] != '=')
447 continue;
448 *arg = s + len + 1;
449 } else if (len != l)
450 continue;
451 return tokens[i].opt;
452 }
453 return Opt_error;
454}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700455
456#define SEL_MOUNT_FAIL_MSG "SELinux: duplicate or incompatible mount options\n"
457
Eric Parisc312feb2006-07-10 04:43:53 -0700458static int may_context_mount_sb_relabel(u32 sid,
459 struct superblock_security_struct *sbsec,
David Howells275bb412008-11-14 10:39:19 +1100460 const struct cred *cred)
Eric Parisc312feb2006-07-10 04:43:53 -0700461{
Casey Schaufler0c6cfa62018-09-21 17:17:16 -0700462 const struct task_security_struct *tsec = selinux_cred(cred);
Eric Parisc312feb2006-07-10 04:43:53 -0700463 int rc;
464
Stephen Smalley6b6bc622018-03-05 11:47:56 -0500465 rc = avc_has_perm(&selinux_state,
466 tsec->sid, sbsec->sid, SECCLASS_FILESYSTEM,
Eric Parisc312feb2006-07-10 04:43:53 -0700467 FILESYSTEM__RELABELFROM, NULL);
468 if (rc)
469 return rc;
470
Stephen Smalley6b6bc622018-03-05 11:47:56 -0500471 rc = avc_has_perm(&selinux_state,
472 tsec->sid, sid, SECCLASS_FILESYSTEM,
Eric Parisc312feb2006-07-10 04:43:53 -0700473 FILESYSTEM__RELABELTO, NULL);
474 return rc;
475}
476
Eric Paris08089252006-07-10 04:43:55 -0700477static int may_context_mount_inode_relabel(u32 sid,
478 struct superblock_security_struct *sbsec,
David Howells275bb412008-11-14 10:39:19 +1100479 const struct cred *cred)
Eric Paris08089252006-07-10 04:43:55 -0700480{
Casey Schaufler0c6cfa62018-09-21 17:17:16 -0700481 const struct task_security_struct *tsec = selinux_cred(cred);
Eric Paris08089252006-07-10 04:43:55 -0700482 int rc;
Stephen Smalley6b6bc622018-03-05 11:47:56 -0500483 rc = avc_has_perm(&selinux_state,
484 tsec->sid, sbsec->sid, SECCLASS_FILESYSTEM,
Eric Paris08089252006-07-10 04:43:55 -0700485 FILESYSTEM__RELABELFROM, NULL);
486 if (rc)
487 return rc;
488
Stephen Smalley6b6bc622018-03-05 11:47:56 -0500489 rc = avc_has_perm(&selinux_state,
490 sid, sbsec->sid, SECCLASS_FILESYSTEM,
Eric Paris08089252006-07-10 04:43:55 -0700491 FILESYSTEM__ASSOCIATE, NULL);
492 return rc;
493}
494
Ondrej Mosnaceka83d6dd2018-12-21 21:18:52 +0100495static int selinux_is_genfs_special_handling(struct super_block *sb)
Eric Parisb43e7252012-10-10 14:27:35 -0400496{
Ondrej Mosnaceka83d6dd2018-12-21 21:18:52 +0100497 /* Special handling. Genfs but also in-core setxattr handler */
498 return !strcmp(sb->s_type->name, "sysfs") ||
Mark Salyzynd5f3a5f2015-02-04 11:34:30 -0500499 !strcmp(sb->s_type->name, "pstore") ||
500 !strcmp(sb->s_type->name, "debugfs") ||
Yongqin Liua2c7c6f2017-01-09 10:07:30 -0500501 !strcmp(sb->s_type->name, "tracefs") ||
Stephen Smalley2651225b2017-02-28 10:35:56 -0500502 !strcmp(sb->s_type->name, "rootfs") ||
Stephen Smalleyaa8e7122018-03-01 18:48:02 -0500503 (selinux_policycap_cgroupseclabel() &&
Stephen Smalley2651225b2017-02-28 10:35:56 -0500504 (!strcmp(sb->s_type->name, "cgroup") ||
505 !strcmp(sb->s_type->name, "cgroup2")));
Eric Parisb43e7252012-10-10 14:27:35 -0400506}
507
Ondrej Mosnaceka83d6dd2018-12-21 21:18:52 +0100508static int selinux_is_sblabel_mnt(struct super_block *sb)
509{
510 struct superblock_security_struct *sbsec = sb->s_security;
511
512 /*
513 * IMPORTANT: Double-check logic in this function when adding a new
514 * SECURITY_FS_USE_* definition!
515 */
516 BUILD_BUG_ON(SECURITY_FS_USE_MAX != 7);
517
518 switch (sbsec->behavior) {
519 case SECURITY_FS_USE_XATTR:
520 case SECURITY_FS_USE_TRANS:
521 case SECURITY_FS_USE_TASK:
522 case SECURITY_FS_USE_NATIVE:
523 return 1;
524
525 case SECURITY_FS_USE_GENFS:
526 return selinux_is_genfs_special_handling(sb);
527
528 /* Never allow relabeling on context mounts */
529 case SECURITY_FS_USE_MNTPOINT:
530 case SECURITY_FS_USE_NONE:
531 default:
532 return 0;
533 }
534}
535
Eric Parisc9180a52007-11-30 13:00:35 -0500536static int sb_finish_set_opts(struct super_block *sb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700537{
538 struct superblock_security_struct *sbsec = sb->s_security;
539 struct dentry *root = sb->s_root;
David Howellsc6f493d2015-03-17 22:26:22 +0000540 struct inode *root_inode = d_backing_inode(root);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700541 int rc = 0;
542
Linus Torvalds1da177e2005-04-16 15:20:36 -0700543 if (sbsec->behavior == SECURITY_FS_USE_XATTR) {
544 /* Make sure that the xattr handler exists and that no
545 error other than -ENODATA is returned by getxattr on
546 the root directory. -ENODATA is ok, as this may be
547 the first boot of the SELinux kernel before we have
548 assigned xattr values to the filesystem. */
Andreas Gruenbacher5d6c3192016-09-29 17:48:42 +0200549 if (!(root_inode->i_opflags & IOP_XATTR)) {
peter enderborgc103a912018-06-12 10:09:03 +0200550 pr_warn("SELinux: (dev %s, type %s) has no "
Linus Torvalds29b1deb2013-12-15 11:17:45 -0800551 "xattr support\n", sb->s_id, sb->s_type->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700552 rc = -EOPNOTSUPP;
553 goto out;
554 }
Andreas Gruenbacher5d6c3192016-09-29 17:48:42 +0200555
556 rc = __vfs_getxattr(root, root_inode, XATTR_NAME_SELINUX, NULL, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700557 if (rc < 0 && rc != -ENODATA) {
558 if (rc == -EOPNOTSUPP)
peter enderborgc103a912018-06-12 10:09:03 +0200559 pr_warn("SELinux: (dev %s, type "
Linus Torvalds29b1deb2013-12-15 11:17:45 -0800560 "%s) has no security xattr handler\n",
561 sb->s_id, sb->s_type->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700562 else
peter enderborgc103a912018-06-12 10:09:03 +0200563 pr_warn("SELinux: (dev %s, type "
Linus Torvalds29b1deb2013-12-15 11:17:45 -0800564 "%s) getxattr errno %d\n", sb->s_id,
565 sb->s_type->name, -rc);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700566 goto out;
567 }
568 }
569
Eric Pariseadcabc2012-08-24 15:59:14 -0400570 sbsec->flags |= SE_SBINITIALIZED;
Scott Mayhew0b4d3452017-06-05 11:45:04 -0400571
572 /*
573 * Explicitly set or clear SBLABEL_MNT. It's not sufficient to simply
574 * leave the flag untouched because sb_clone_mnt_opts might be handing
575 * us a superblock that needs the flag to be cleared.
576 */
Eric Parisb43e7252012-10-10 14:27:35 -0400577 if (selinux_is_sblabel_mnt(sb))
Eric Paris12f348b2012-10-09 10:56:25 -0400578 sbsec->flags |= SBLABEL_MNT;
Scott Mayhew0b4d3452017-06-05 11:45:04 -0400579 else
580 sbsec->flags &= ~SBLABEL_MNT;
David P. Quigleyddd29ec2009-09-09 14:25:37 -0400581
Linus Torvalds1da177e2005-04-16 15:20:36 -0700582 /* Initialize the root inode. */
Eric Parisc9180a52007-11-30 13:00:35 -0500583 rc = inode_doinit_with_dentry(root_inode, root);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700584
585 /* Initialize any other inodes associated with the superblock, e.g.
586 inodes created prior to initial policy load or inodes created
587 during get_sb by a pseudo filesystem that directly
588 populates itself. */
589 spin_lock(&sbsec->isec_lock);
Al Viro8d641242018-12-10 15:34:12 -0500590 while (!list_empty(&sbsec->isec_head)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700591 struct inode_security_struct *isec =
Al Viro8d641242018-12-10 15:34:12 -0500592 list_first_entry(&sbsec->isec_head,
Eric Parisc9180a52007-11-30 13:00:35 -0500593 struct inode_security_struct, list);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700594 struct inode *inode = isec->inode;
Stephen Smalley923190d2014-10-06 16:32:52 -0400595 list_del_init(&isec->list);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700596 spin_unlock(&sbsec->isec_lock);
597 inode = igrab(inode);
598 if (inode) {
Eric Parisc9180a52007-11-30 13:00:35 -0500599 if (!IS_PRIVATE(inode))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700600 inode_doinit(inode);
601 iput(inode);
602 }
603 spin_lock(&sbsec->isec_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700604 }
605 spin_unlock(&sbsec->isec_lock);
606out:
Eric Parisc9180a52007-11-30 13:00:35 -0500607 return rc;
608}
609
Eric Parisc9180a52007-11-30 13:00:35 -0500610static int bad_option(struct superblock_security_struct *sbsec, char flag,
611 u32 old_sid, u32 new_sid)
612{
David P. Quigley0d90a7e2009-01-16 09:22:02 -0500613 char mnt_flags = sbsec->flags & SE_MNTMASK;
614
Eric Parisc9180a52007-11-30 13:00:35 -0500615 /* check if the old mount command had the same options */
David P. Quigley0d90a7e2009-01-16 09:22:02 -0500616 if (sbsec->flags & SE_SBINITIALIZED)
Eric Parisc9180a52007-11-30 13:00:35 -0500617 if (!(sbsec->flags & flag) ||
618 (old_sid != new_sid))
619 return 1;
620
621 /* check if we were passed the same options twice,
622 * aka someone passed context=a,context=b
623 */
David P. Quigley0d90a7e2009-01-16 09:22:02 -0500624 if (!(sbsec->flags & SE_SBINITIALIZED))
625 if (mnt_flags & flag)
Eric Parisc9180a52007-11-30 13:00:35 -0500626 return 1;
627 return 0;
628}
Eric Parise0007522008-03-05 10:31:54 -0500629
Al Virobd323652018-12-13 15:04:59 -0500630static int parse_sid(struct super_block *sb, const char *s, u32 *sid)
631{
632 int rc = security_context_str_to_sid(&selinux_state, s,
633 sid, GFP_KERNEL);
634 if (rc)
635 pr_warn("SELinux: security_context_str_to_sid"
636 "(%s) failed for (dev %s, type %s) errno=%d\n",
637 s, sb->s_id, sb->s_type->name, rc);
638 return rc;
639}
640
Eric Parisc9180a52007-11-30 13:00:35 -0500641/*
642 * Allow filesystems with binary mount data to explicitly set mount point
643 * labeling information.
644 */
Eric Parise0007522008-03-05 10:31:54 -0500645static int selinux_set_mnt_opts(struct super_block *sb,
Al Viro204cc0c2018-12-13 13:41:47 -0500646 void *mnt_opts,
David Quigley649f6e72013-05-22 12:50:36 -0400647 unsigned long kern_flags,
648 unsigned long *set_kern_flags)
Eric Parisc9180a52007-11-30 13:00:35 -0500649{
David Howells275bb412008-11-14 10:39:19 +1100650 const struct cred *cred = current_cred();
Eric Parisc9180a52007-11-30 13:00:35 -0500651 struct superblock_security_struct *sbsec = sb->s_security;
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -0500652 struct dentry *root = sbsec->sb->s_root;
Al Virobd323652018-12-13 15:04:59 -0500653 struct selinux_mnt_opts *opts = mnt_opts;
Paul Moore2c971652016-04-19 16:36:28 -0400654 struct inode_security_struct *root_isec;
Eric Parisc9180a52007-11-30 13:00:35 -0500655 u32 fscontext_sid = 0, context_sid = 0, rootcontext_sid = 0;
656 u32 defcontext_sid = 0;
Al Virobd323652018-12-13 15:04:59 -0500657 int rc = 0;
Eric Parisc9180a52007-11-30 13:00:35 -0500658
659 mutex_lock(&sbsec->lock);
660
Stephen Smalleyaa8e7122018-03-01 18:48:02 -0500661 if (!selinux_state.initialized) {
Al Virobd323652018-12-13 15:04:59 -0500662 if (!opts) {
Eric Parisc9180a52007-11-30 13:00:35 -0500663 /* Defer initialization until selinux_complete_init,
664 after the initial policy is loaded and the security
665 server is ready to handle calls. */
Eric Parisc9180a52007-11-30 13:00:35 -0500666 goto out;
667 }
668 rc = -EINVAL;
peter enderborgc103a912018-06-12 10:09:03 +0200669 pr_warn("SELinux: Unable to set superblock options "
Eric Paris744ba352008-04-17 11:52:44 -0400670 "before the security server is initialized\n");
Eric Parisc9180a52007-11-30 13:00:35 -0500671 goto out;
672 }
David Quigley649f6e72013-05-22 12:50:36 -0400673 if (kern_flags && !set_kern_flags) {
674 /* Specifying internal flags without providing a place to
675 * place the results is not allowed */
676 rc = -EINVAL;
677 goto out;
678 }
Eric Parisc9180a52007-11-30 13:00:35 -0500679
680 /*
Eric Parise0007522008-03-05 10:31:54 -0500681 * Binary mount data FS will come through this function twice. Once
682 * from an explicit call and once from the generic calls from the vfs.
683 * Since the generic VFS calls will not contain any security mount data
684 * we need to skip the double mount verification.
685 *
686 * This does open a hole in which we will not notice if the first
687 * mount using this sb set explict options and a second mount using
688 * this sb does not set any security options. (The first options
689 * will be used for both mounts)
690 */
David P. Quigley0d90a7e2009-01-16 09:22:02 -0500691 if ((sbsec->flags & SE_SBINITIALIZED) && (sb->s_type->fs_flags & FS_BINARY_MOUNTDATA)
Al Virobd323652018-12-13 15:04:59 -0500692 && !opts)
Eric Parisf5269712008-05-14 11:27:45 -0400693 goto out;
Eric Parise0007522008-03-05 10:31:54 -0500694
Paul Moore2c971652016-04-19 16:36:28 -0400695 root_isec = backing_inode_security_novalidate(root);
696
Eric Parise0007522008-03-05 10:31:54 -0500697 /*
Eric Parisc9180a52007-11-30 13:00:35 -0500698 * parse the mount options, check if they are valid sids.
699 * also check if someone is trying to mount the same sb more
700 * than once with different security options.
701 */
Al Virobd323652018-12-13 15:04:59 -0500702 if (opts) {
703 if (opts->fscontext) {
704 rc = parse_sid(sb, opts->fscontext, &fscontext_sid);
705 if (rc)
706 goto out;
Eric Parisc9180a52007-11-30 13:00:35 -0500707 if (bad_option(sbsec, FSCONTEXT_MNT, sbsec->sid,
708 fscontext_sid))
709 goto out_double_mount;
Eric Parisc9180a52007-11-30 13:00:35 -0500710 sbsec->flags |= FSCONTEXT_MNT;
Al Virobd323652018-12-13 15:04:59 -0500711 }
712 if (opts->context) {
713 rc = parse_sid(sb, opts->context, &context_sid);
714 if (rc)
715 goto out;
Eric Parisc9180a52007-11-30 13:00:35 -0500716 if (bad_option(sbsec, CONTEXT_MNT, sbsec->mntpoint_sid,
717 context_sid))
718 goto out_double_mount;
Eric Parisc9180a52007-11-30 13:00:35 -0500719 sbsec->flags |= CONTEXT_MNT;
Al Virobd323652018-12-13 15:04:59 -0500720 }
721 if (opts->rootcontext) {
722 rc = parse_sid(sb, opts->rootcontext, &rootcontext_sid);
723 if (rc)
724 goto out;
Eric Parisc9180a52007-11-30 13:00:35 -0500725 if (bad_option(sbsec, ROOTCONTEXT_MNT, root_isec->sid,
726 rootcontext_sid))
727 goto out_double_mount;
Eric Parisc9180a52007-11-30 13:00:35 -0500728 sbsec->flags |= ROOTCONTEXT_MNT;
Al Virobd323652018-12-13 15:04:59 -0500729 }
730 if (opts->defcontext) {
731 rc = parse_sid(sb, opts->defcontext, &defcontext_sid);
732 if (rc)
733 goto out;
Eric Parisc9180a52007-11-30 13:00:35 -0500734 if (bad_option(sbsec, DEFCONTEXT_MNT, sbsec->def_sid,
735 defcontext_sid))
736 goto out_double_mount;
Eric Parisc9180a52007-11-30 13:00:35 -0500737 sbsec->flags |= DEFCONTEXT_MNT;
Eric Parisc9180a52007-11-30 13:00:35 -0500738 }
739 }
740
David P. Quigley0d90a7e2009-01-16 09:22:02 -0500741 if (sbsec->flags & SE_SBINITIALIZED) {
Eric Parisc9180a52007-11-30 13:00:35 -0500742 /* previously mounted with options, but not on this attempt? */
Al Virobd323652018-12-13 15:04:59 -0500743 if ((sbsec->flags & SE_MNTMASK) && !opts)
Eric Parisc9180a52007-11-30 13:00:35 -0500744 goto out_double_mount;
745 rc = 0;
746 goto out;
747 }
748
James Morris089be432008-07-15 18:32:49 +1000749 if (strcmp(sb->s_type->name, "proc") == 0)
Stephen Smalley134509d2015-06-04 16:22:17 -0400750 sbsec->flags |= SE_SBPROC | SE_SBGENFS;
751
Stephen Smalley8e014722015-06-04 16:22:17 -0400752 if (!strcmp(sb->s_type->name, "debugfs") ||
Jeff Vander Stoep6a391182017-06-20 09:35:33 -0700753 !strcmp(sb->s_type->name, "tracefs") ||
Ondrej Mosnacekb7540262019-02-22 15:57:14 +0100754 !strcmp(sb->s_type->name, "pstore"))
755 sbsec->flags |= SE_SBGENFS;
756
757 if (!strcmp(sb->s_type->name, "sysfs") ||
Antonio Murdaca901ef842017-02-09 17:02:42 +0100758 !strcmp(sb->s_type->name, "cgroup") ||
759 !strcmp(sb->s_type->name, "cgroup2"))
Ondrej Mosnacekb7540262019-02-22 15:57:14 +0100760 sbsec->flags |= SE_SBGENFS | SE_SBGENFS_XATTR;
Eric Parisc9180a52007-11-30 13:00:35 -0500761
David Quigleyeb9ae682013-05-22 12:50:37 -0400762 if (!sbsec->behavior) {
763 /*
764 * Determine the labeling behavior to use for this
765 * filesystem type.
766 */
Stephen Smalleyaa8e7122018-03-01 18:48:02 -0500767 rc = security_fs_use(&selinux_state, sb);
David Quigleyeb9ae682013-05-22 12:50:37 -0400768 if (rc) {
peter enderborgc103a912018-06-12 10:09:03 +0200769 pr_warn("%s: security_fs_use(%s) returned %d\n",
David Quigleyeb9ae682013-05-22 12:50:37 -0400770 __func__, sb->s_type->name, rc);
771 goto out;
772 }
Eric Parisc9180a52007-11-30 13:00:35 -0500773 }
Seth Forsheeaad82892016-04-26 14:36:20 -0500774
775 /*
Stephen Smalley01593d32017-01-09 10:07:31 -0500776 * If this is a user namespace mount and the filesystem type is not
777 * explicitly whitelisted, then no contexts are allowed on the command
778 * line and security labels must be ignored.
Seth Forsheeaad82892016-04-26 14:36:20 -0500779 */
Stephen Smalley01593d32017-01-09 10:07:31 -0500780 if (sb->s_user_ns != &init_user_ns &&
781 strcmp(sb->s_type->name, "tmpfs") &&
782 strcmp(sb->s_type->name, "ramfs") &&
783 strcmp(sb->s_type->name, "devpts")) {
Seth Forsheeaad82892016-04-26 14:36:20 -0500784 if (context_sid || fscontext_sid || rootcontext_sid ||
785 defcontext_sid) {
786 rc = -EACCES;
787 goto out;
788 }
789 if (sbsec->behavior == SECURITY_FS_USE_XATTR) {
790 sbsec->behavior = SECURITY_FS_USE_MNTPOINT;
Stephen Smalleyaa8e7122018-03-01 18:48:02 -0500791 rc = security_transition_sid(&selinux_state,
792 current_sid(),
793 current_sid(),
Seth Forsheeaad82892016-04-26 14:36:20 -0500794 SECCLASS_FILE, NULL,
795 &sbsec->mntpoint_sid);
796 if (rc)
797 goto out;
798 }
799 goto out_set_opts;
800 }
801
Eric Parisc9180a52007-11-30 13:00:35 -0500802 /* sets the context of the superblock for the fs being mounted. */
803 if (fscontext_sid) {
David Howells275bb412008-11-14 10:39:19 +1100804 rc = may_context_mount_sb_relabel(fscontext_sid, sbsec, cred);
Eric Parisc9180a52007-11-30 13:00:35 -0500805 if (rc)
806 goto out;
807
808 sbsec->sid = fscontext_sid;
809 }
810
811 /*
812 * Switch to using mount point labeling behavior.
813 * sets the label used on all file below the mountpoint, and will set
814 * the superblock context if not already set.
815 */
David Quigleyeb9ae682013-05-22 12:50:37 -0400816 if (kern_flags & SECURITY_LSM_NATIVE_LABELS && !context_sid) {
817 sbsec->behavior = SECURITY_FS_USE_NATIVE;
818 *set_kern_flags |= SECURITY_LSM_NATIVE_LABELS;
819 }
820
Eric Parisc9180a52007-11-30 13:00:35 -0500821 if (context_sid) {
822 if (!fscontext_sid) {
David Howells275bb412008-11-14 10:39:19 +1100823 rc = may_context_mount_sb_relabel(context_sid, sbsec,
824 cred);
Eric Parisc9180a52007-11-30 13:00:35 -0500825 if (rc)
826 goto out;
827 sbsec->sid = context_sid;
828 } else {
David Howells275bb412008-11-14 10:39:19 +1100829 rc = may_context_mount_inode_relabel(context_sid, sbsec,
830 cred);
Eric Parisc9180a52007-11-30 13:00:35 -0500831 if (rc)
832 goto out;
833 }
834 if (!rootcontext_sid)
835 rootcontext_sid = context_sid;
836
837 sbsec->mntpoint_sid = context_sid;
838 sbsec->behavior = SECURITY_FS_USE_MNTPOINT;
839 }
840
841 if (rootcontext_sid) {
David Howells275bb412008-11-14 10:39:19 +1100842 rc = may_context_mount_inode_relabel(rootcontext_sid, sbsec,
843 cred);
Eric Parisc9180a52007-11-30 13:00:35 -0500844 if (rc)
845 goto out;
846
847 root_isec->sid = rootcontext_sid;
Andreas Gruenbacher6f3be9f2015-12-24 11:09:40 -0500848 root_isec->initialized = LABEL_INITIALIZED;
Eric Parisc9180a52007-11-30 13:00:35 -0500849 }
850
851 if (defcontext_sid) {
David Quigleyeb9ae682013-05-22 12:50:37 -0400852 if (sbsec->behavior != SECURITY_FS_USE_XATTR &&
853 sbsec->behavior != SECURITY_FS_USE_NATIVE) {
Eric Parisc9180a52007-11-30 13:00:35 -0500854 rc = -EINVAL;
peter enderborgc103a912018-06-12 10:09:03 +0200855 pr_warn("SELinux: defcontext option is "
Eric Parisc9180a52007-11-30 13:00:35 -0500856 "invalid for this filesystem type\n");
857 goto out;
858 }
859
860 if (defcontext_sid != sbsec->def_sid) {
861 rc = may_context_mount_inode_relabel(defcontext_sid,
David Howells275bb412008-11-14 10:39:19 +1100862 sbsec, cred);
Eric Parisc9180a52007-11-30 13:00:35 -0500863 if (rc)
864 goto out;
865 }
866
867 sbsec->def_sid = defcontext_sid;
868 }
869
Seth Forsheeaad82892016-04-26 14:36:20 -0500870out_set_opts:
Eric Parisc9180a52007-11-30 13:00:35 -0500871 rc = sb_finish_set_opts(sb);
872out:
Eric Parisbc7e9822006-09-25 23:32:02 -0700873 mutex_unlock(&sbsec->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700874 return rc;
Eric Parisc9180a52007-11-30 13:00:35 -0500875out_double_mount:
876 rc = -EINVAL;
peter enderborgc103a912018-06-12 10:09:03 +0200877 pr_warn("SELinux: mount invalid. Same superblock, different "
Al Virobd323652018-12-13 15:04:59 -0500878 "security settings for (dev %s, type %s)\n", sb->s_id,
879 sb->s_type->name);
Eric Parisc9180a52007-11-30 13:00:35 -0500880 goto out;
881}
882
Jeff Layton094f7b62013-04-01 08:14:24 -0400883static int selinux_cmp_sb_context(const struct super_block *oldsb,
884 const struct super_block *newsb)
885{
886 struct superblock_security_struct *old = oldsb->s_security;
887 struct superblock_security_struct *new = newsb->s_security;
888 char oldflags = old->flags & SE_MNTMASK;
889 char newflags = new->flags & SE_MNTMASK;
890
891 if (oldflags != newflags)
892 goto mismatch;
893 if ((oldflags & FSCONTEXT_MNT) && old->sid != new->sid)
894 goto mismatch;
895 if ((oldflags & CONTEXT_MNT) && old->mntpoint_sid != new->mntpoint_sid)
896 goto mismatch;
897 if ((oldflags & DEFCONTEXT_MNT) && old->def_sid != new->def_sid)
898 goto mismatch;
899 if (oldflags & ROOTCONTEXT_MNT) {
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -0500900 struct inode_security_struct *oldroot = backing_inode_security(oldsb->s_root);
901 struct inode_security_struct *newroot = backing_inode_security(newsb->s_root);
Jeff Layton094f7b62013-04-01 08:14:24 -0400902 if (oldroot->sid != newroot->sid)
903 goto mismatch;
904 }
905 return 0;
906mismatch:
peter enderborgc103a912018-06-12 10:09:03 +0200907 pr_warn("SELinux: mount invalid. Same superblock, "
Jeff Layton094f7b62013-04-01 08:14:24 -0400908 "different security settings for (dev %s, "
909 "type %s)\n", newsb->s_id, newsb->s_type->name);
910 return -EBUSY;
911}
912
913static int selinux_sb_clone_mnt_opts(const struct super_block *oldsb,
Scott Mayhew0b4d3452017-06-05 11:45:04 -0400914 struct super_block *newsb,
915 unsigned long kern_flags,
916 unsigned long *set_kern_flags)
Eric Parisc9180a52007-11-30 13:00:35 -0500917{
Scott Mayhew0b4d3452017-06-05 11:45:04 -0400918 int rc = 0;
Eric Parisc9180a52007-11-30 13:00:35 -0500919 const struct superblock_security_struct *oldsbsec = oldsb->s_security;
920 struct superblock_security_struct *newsbsec = newsb->s_security;
921
922 int set_fscontext = (oldsbsec->flags & FSCONTEXT_MNT);
923 int set_context = (oldsbsec->flags & CONTEXT_MNT);
924 int set_rootcontext = (oldsbsec->flags & ROOTCONTEXT_MNT);
925
Eric Paris0f5e6422008-04-21 16:24:11 -0400926 /*
927 * if the parent was able to be mounted it clearly had no special lsm
Al Viroe8c26252010-03-23 06:36:54 -0400928 * mount options. thus we can safely deal with this superblock later
Eric Paris0f5e6422008-04-21 16:24:11 -0400929 */
Stephen Smalleyaa8e7122018-03-01 18:48:02 -0500930 if (!selinux_state.initialized)
Jeff Layton094f7b62013-04-01 08:14:24 -0400931 return 0;
Eric Parisc9180a52007-11-30 13:00:35 -0500932
Scott Mayhew0b4d3452017-06-05 11:45:04 -0400933 /*
934 * Specifying internal flags without providing a place to
935 * place the results is not allowed.
936 */
937 if (kern_flags && !set_kern_flags)
938 return -EINVAL;
939
Eric Parisc9180a52007-11-30 13:00:35 -0500940 /* how can we clone if the old one wasn't set up?? */
David P. Quigley0d90a7e2009-01-16 09:22:02 -0500941 BUG_ON(!(oldsbsec->flags & SE_SBINITIALIZED));
Eric Parisc9180a52007-11-30 13:00:35 -0500942
Jeff Layton094f7b62013-04-01 08:14:24 -0400943 /* if fs is reusing a sb, make sure that the contexts match */
J. Bruce Fields3815a242019-03-05 16:17:58 -0500944 if (newsbsec->flags & SE_SBINITIALIZED) {
945 if ((kern_flags & SECURITY_LSM_NATIVE_LABELS) && !set_context)
946 *set_kern_flags |= SECURITY_LSM_NATIVE_LABELS;
Jeff Layton094f7b62013-04-01 08:14:24 -0400947 return selinux_cmp_sb_context(oldsb, newsb);
J. Bruce Fields3815a242019-03-05 16:17:58 -0500948 }
Eric Paris5a552612008-04-09 14:08:35 -0400949
Eric Parisc9180a52007-11-30 13:00:35 -0500950 mutex_lock(&newsbsec->lock);
951
952 newsbsec->flags = oldsbsec->flags;
953
954 newsbsec->sid = oldsbsec->sid;
955 newsbsec->def_sid = oldsbsec->def_sid;
956 newsbsec->behavior = oldsbsec->behavior;
957
Scott Mayhew0b4d3452017-06-05 11:45:04 -0400958 if (newsbsec->behavior == SECURITY_FS_USE_NATIVE &&
959 !(kern_flags & SECURITY_LSM_NATIVE_LABELS) && !set_context) {
Stephen Smalleyaa8e7122018-03-01 18:48:02 -0500960 rc = security_fs_use(&selinux_state, newsb);
Scott Mayhew0b4d3452017-06-05 11:45:04 -0400961 if (rc)
962 goto out;
963 }
964
965 if (kern_flags & SECURITY_LSM_NATIVE_LABELS && !set_context) {
966 newsbsec->behavior = SECURITY_FS_USE_NATIVE;
967 *set_kern_flags |= SECURITY_LSM_NATIVE_LABELS;
968 }
969
Eric Parisc9180a52007-11-30 13:00:35 -0500970 if (set_context) {
971 u32 sid = oldsbsec->mntpoint_sid;
972
973 if (!set_fscontext)
974 newsbsec->sid = sid;
975 if (!set_rootcontext) {
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -0500976 struct inode_security_struct *newisec = backing_inode_security(newsb->s_root);
Eric Parisc9180a52007-11-30 13:00:35 -0500977 newisec->sid = sid;
978 }
979 newsbsec->mntpoint_sid = sid;
980 }
981 if (set_rootcontext) {
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -0500982 const struct inode_security_struct *oldisec = backing_inode_security(oldsb->s_root);
983 struct inode_security_struct *newisec = backing_inode_security(newsb->s_root);
Eric Parisc9180a52007-11-30 13:00:35 -0500984
985 newisec->sid = oldisec->sid;
986 }
987
988 sb_finish_set_opts(newsb);
Scott Mayhew0b4d3452017-06-05 11:45:04 -0400989out:
Eric Parisc9180a52007-11-30 13:00:35 -0500990 mutex_unlock(&newsbsec->lock);
Scott Mayhew0b4d3452017-06-05 11:45:04 -0400991 return rc;
Eric Parisc9180a52007-11-30 13:00:35 -0500992}
993
Al Viroba641862018-12-14 20:28:15 -0500994static int selinux_add_opt(int token, const char *s, void **mnt_opts)
Eric Parisc9180a52007-11-30 13:00:35 -0500995{
Al Viroba641862018-12-14 20:28:15 -0500996 struct selinux_mnt_opts *opts = *mnt_opts;
Eric Parisc9180a52007-11-30 13:00:35 -0500997
Al Viroda3d76a2018-12-17 10:14:16 -0500998 if (token == Opt_seclabel) /* eaten and completely ignored */
Al Viro169d68efb2018-12-14 22:44:50 -0500999 return 0;
Eric Parisc9180a52007-11-30 13:00:35 -05001000
Al Viroba641862018-12-14 20:28:15 -05001001 if (!opts) {
1002 opts = kzalloc(sizeof(struct selinux_mnt_opts), GFP_KERNEL);
1003 if (!opts)
1004 return -ENOMEM;
1005 *mnt_opts = opts;
1006 }
1007 if (!s)
1008 return -ENOMEM;
1009 switch (token) {
1010 case Opt_context:
1011 if (opts->context || opts->defcontext)
1012 goto Einval;
1013 opts->context = s;
1014 break;
1015 case Opt_fscontext:
1016 if (opts->fscontext)
1017 goto Einval;
1018 opts->fscontext = s;
1019 break;
1020 case Opt_rootcontext:
1021 if (opts->rootcontext)
1022 goto Einval;
1023 opts->rootcontext = s;
1024 break;
1025 case Opt_defcontext:
1026 if (opts->context || opts->defcontext)
1027 goto Einval;
1028 opts->defcontext = s;
1029 break;
1030 }
1031 return 0;
1032Einval:
1033 pr_warn(SEL_MOUNT_FAIL_MSG);
Al Viroba641862018-12-14 20:28:15 -05001034 return -EINVAL;
1035}
Eric Parisc9180a52007-11-30 13:00:35 -05001036
Al Viro757cbe52018-12-14 23:42:21 -05001037static int selinux_add_mnt_opt(const char *option, const char *val, int len,
1038 void **mnt_opts)
Eric Parisc9180a52007-11-30 13:00:35 -05001039{
Al Viro757cbe52018-12-14 23:42:21 -05001040 int token = Opt_error;
1041 int rc, i;
Eric Parisc9180a52007-11-30 13:00:35 -05001042
Al Viro757cbe52018-12-14 23:42:21 -05001043 for (i = 0; i < ARRAY_SIZE(tokens); i++) {
1044 if (strcmp(option, tokens[i].name) == 0) {
1045 token = tokens[i].opt;
Eric Parisc9180a52007-11-30 13:00:35 -05001046 break;
Eric Parisc9180a52007-11-30 13:00:35 -05001047 }
1048 }
1049
Al Viro757cbe52018-12-14 23:42:21 -05001050 if (token == Opt_error)
1051 return -EINVAL;
Eric Parise0007522008-03-05 10:31:54 -05001052
Al Viro757cbe52018-12-14 23:42:21 -05001053 if (token != Opt_seclabel)
1054 val = kmemdup_nul(val, len, GFP_KERNEL);
1055 rc = selinux_add_opt(token, val, mnt_opts);
1056 if (unlikely(rc)) {
1057 kfree(val);
1058 if (*mnt_opts) {
1059 selinux_free_mnt_opts(*mnt_opts);
1060 *mnt_opts = NULL;
1061 }
1062 }
1063 return rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001064}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001065
Al Viroe3489f82018-12-13 00:24:36 -05001066static int show_sid(struct seq_file *m, u32 sid)
Eric Paris2069f452008-07-04 09:47:13 +10001067{
Al Viroe3489f82018-12-13 00:24:36 -05001068 char *context = NULL;
1069 u32 len;
1070 int rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001071
Al Viroe3489f82018-12-13 00:24:36 -05001072 rc = security_sid_to_context(&selinux_state, sid,
1073 &context, &len);
1074 if (!rc) {
1075 bool has_comma = context && strchr(context, ',');
Linus Torvalds1da177e2005-04-16 15:20:36 -07001076
David Howells442155c2018-11-01 23:07:24 +00001077 seq_putc(m, '=');
Eric Paris2069f452008-07-04 09:47:13 +10001078 if (has_comma)
1079 seq_putc(m, '\"');
Al Viroe3489f82018-12-13 00:24:36 -05001080 seq_escape(m, context, "\"\n\\");
Eric Paris2069f452008-07-04 09:47:13 +10001081 if (has_comma)
1082 seq_putc(m, '\"');
1083 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001084 kfree(context);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001085 return rc;
1086}
Eric Paris2069f452008-07-04 09:47:13 +10001087
1088static int selinux_sb_show_options(struct seq_file *m, struct super_block *sb)
1089{
Al Viroe3489f82018-12-13 00:24:36 -05001090 struct superblock_security_struct *sbsec = sb->s_security;
Eric Paris2069f452008-07-04 09:47:13 +10001091 int rc;
1092
Al Viroe3489f82018-12-13 00:24:36 -05001093 if (!(sbsec->flags & SE_SBINITIALIZED))
1094 return 0;
1095
1096 if (!selinux_state.initialized)
1097 return 0;
1098
1099 if (sbsec->flags & FSCONTEXT_MNT) {
1100 seq_putc(m, ',');
1101 seq_puts(m, FSCONTEXT_STR);
1102 rc = show_sid(m, sbsec->sid);
1103 if (rc)
1104 return rc;
Eric Paris383795c2008-07-29 17:07:26 -04001105 }
Al Viroe3489f82018-12-13 00:24:36 -05001106 if (sbsec->flags & CONTEXT_MNT) {
1107 seq_putc(m, ',');
1108 seq_puts(m, CONTEXT_STR);
1109 rc = show_sid(m, sbsec->mntpoint_sid);
1110 if (rc)
1111 return rc;
1112 }
1113 if (sbsec->flags & DEFCONTEXT_MNT) {
1114 seq_putc(m, ',');
1115 seq_puts(m, DEFCONTEXT_STR);
1116 rc = show_sid(m, sbsec->def_sid);
1117 if (rc)
1118 return rc;
1119 }
1120 if (sbsec->flags & ROOTCONTEXT_MNT) {
1121 struct dentry *root = sbsec->sb->s_root;
1122 struct inode_security_struct *isec = backing_inode_security(root);
1123 seq_putc(m, ',');
1124 seq_puts(m, ROOTCONTEXT_STR);
1125 rc = show_sid(m, isec->sid);
1126 if (rc)
1127 return rc;
1128 }
1129 if (sbsec->flags & SBLABEL_MNT) {
1130 seq_putc(m, ',');
David Howells442155c2018-11-01 23:07:24 +00001131 seq_puts(m, SECLABEL_STR);
Al Viroe3489f82018-12-13 00:24:36 -05001132 }
1133 return 0;
Eric Paris2069f452008-07-04 09:47:13 +10001134}
1135
Linus Torvalds1da177e2005-04-16 15:20:36 -07001136static inline u16 inode_mode_to_security_class(umode_t mode)
1137{
1138 switch (mode & S_IFMT) {
1139 case S_IFSOCK:
1140 return SECCLASS_SOCK_FILE;
1141 case S_IFLNK:
1142 return SECCLASS_LNK_FILE;
1143 case S_IFREG:
1144 return SECCLASS_FILE;
1145 case S_IFBLK:
1146 return SECCLASS_BLK_FILE;
1147 case S_IFDIR:
1148 return SECCLASS_DIR;
1149 case S_IFCHR:
1150 return SECCLASS_CHR_FILE;
1151 case S_IFIFO:
1152 return SECCLASS_FIFO_FILE;
1153
1154 }
1155
1156 return SECCLASS_FILE;
1157}
1158
James Morris13402582005-09-30 14:24:34 -04001159static inline int default_protocol_stream(int protocol)
1160{
1161 return (protocol == IPPROTO_IP || protocol == IPPROTO_TCP);
1162}
1163
1164static inline int default_protocol_dgram(int protocol)
1165{
1166 return (protocol == IPPROTO_IP || protocol == IPPROTO_UDP);
1167}
1168
Linus Torvalds1da177e2005-04-16 15:20:36 -07001169static inline u16 socket_type_to_security_class(int family, int type, int protocol)
1170{
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05001171 int extsockclass = selinux_policycap_extsockclass();
Stephen Smalleyda69a532017-01-09 10:07:30 -05001172
Linus Torvalds1da177e2005-04-16 15:20:36 -07001173 switch (family) {
1174 case PF_UNIX:
1175 switch (type) {
1176 case SOCK_STREAM:
1177 case SOCK_SEQPACKET:
1178 return SECCLASS_UNIX_STREAM_SOCKET;
1179 case SOCK_DGRAM:
Luis Ressel2a764b52017-07-25 15:13:41 -04001180 case SOCK_RAW:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001181 return SECCLASS_UNIX_DGRAM_SOCKET;
1182 }
1183 break;
1184 case PF_INET:
1185 case PF_INET6:
1186 switch (type) {
1187 case SOCK_STREAM:
Stephen Smalleyda69a532017-01-09 10:07:30 -05001188 case SOCK_SEQPACKET:
James Morris13402582005-09-30 14:24:34 -04001189 if (default_protocol_stream(protocol))
1190 return SECCLASS_TCP_SOCKET;
Stephen Smalleyda69a532017-01-09 10:07:30 -05001191 else if (extsockclass && protocol == IPPROTO_SCTP)
1192 return SECCLASS_SCTP_SOCKET;
James Morris13402582005-09-30 14:24:34 -04001193 else
1194 return SECCLASS_RAWIP_SOCKET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001195 case SOCK_DGRAM:
James Morris13402582005-09-30 14:24:34 -04001196 if (default_protocol_dgram(protocol))
1197 return SECCLASS_UDP_SOCKET;
Stephen Smalleyef379792017-01-09 10:07:31 -05001198 else if (extsockclass && (protocol == IPPROTO_ICMP ||
1199 protocol == IPPROTO_ICMPV6))
Stephen Smalleyda69a532017-01-09 10:07:30 -05001200 return SECCLASS_ICMP_SOCKET;
James Morris13402582005-09-30 14:24:34 -04001201 else
1202 return SECCLASS_RAWIP_SOCKET;
James Morris2ee92d42006-11-13 16:09:01 -08001203 case SOCK_DCCP:
1204 return SECCLASS_DCCP_SOCKET;
James Morris13402582005-09-30 14:24:34 -04001205 default:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001206 return SECCLASS_RAWIP_SOCKET;
1207 }
1208 break;
1209 case PF_NETLINK:
1210 switch (protocol) {
1211 case NETLINK_ROUTE:
1212 return SECCLASS_NETLINK_ROUTE_SOCKET;
Pavel Emelyanov7f1fb602011-12-06 07:56:43 +00001213 case NETLINK_SOCK_DIAG:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001214 return SECCLASS_NETLINK_TCPDIAG_SOCKET;
1215 case NETLINK_NFLOG:
1216 return SECCLASS_NETLINK_NFLOG_SOCKET;
1217 case NETLINK_XFRM:
1218 return SECCLASS_NETLINK_XFRM_SOCKET;
1219 case NETLINK_SELINUX:
1220 return SECCLASS_NETLINK_SELINUX_SOCKET;
Stephen Smalley6c6d2e92015-06-04 16:22:16 -04001221 case NETLINK_ISCSI:
1222 return SECCLASS_NETLINK_ISCSI_SOCKET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001223 case NETLINK_AUDIT:
1224 return SECCLASS_NETLINK_AUDIT_SOCKET;
Stephen Smalley6c6d2e92015-06-04 16:22:16 -04001225 case NETLINK_FIB_LOOKUP:
1226 return SECCLASS_NETLINK_FIB_LOOKUP_SOCKET;
1227 case NETLINK_CONNECTOR:
1228 return SECCLASS_NETLINK_CONNECTOR_SOCKET;
1229 case NETLINK_NETFILTER:
1230 return SECCLASS_NETLINK_NETFILTER_SOCKET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001231 case NETLINK_DNRTMSG:
1232 return SECCLASS_NETLINK_DNRT_SOCKET;
James Morris0c9b7942005-04-16 15:24:13 -07001233 case NETLINK_KOBJECT_UEVENT:
1234 return SECCLASS_NETLINK_KOBJECT_UEVENT_SOCKET;
Stephen Smalley6c6d2e92015-06-04 16:22:16 -04001235 case NETLINK_GENERIC:
1236 return SECCLASS_NETLINK_GENERIC_SOCKET;
1237 case NETLINK_SCSITRANSPORT:
1238 return SECCLASS_NETLINK_SCSITRANSPORT_SOCKET;
1239 case NETLINK_RDMA:
1240 return SECCLASS_NETLINK_RDMA_SOCKET;
1241 case NETLINK_CRYPTO:
1242 return SECCLASS_NETLINK_CRYPTO_SOCKET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001243 default:
1244 return SECCLASS_NETLINK_SOCKET;
1245 }
1246 case PF_PACKET:
1247 return SECCLASS_PACKET_SOCKET;
1248 case PF_KEY:
1249 return SECCLASS_KEY_SOCKET;
Christopher J. PeBenito3e3ff152006-06-09 00:25:03 -07001250 case PF_APPLETALK:
1251 return SECCLASS_APPLETALK_SOCKET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001252 }
1253
Stephen Smalleyda69a532017-01-09 10:07:30 -05001254 if (extsockclass) {
1255 switch (family) {
1256 case PF_AX25:
1257 return SECCLASS_AX25_SOCKET;
1258 case PF_IPX:
1259 return SECCLASS_IPX_SOCKET;
1260 case PF_NETROM:
1261 return SECCLASS_NETROM_SOCKET;
Stephen Smalleyda69a532017-01-09 10:07:30 -05001262 case PF_ATMPVC:
1263 return SECCLASS_ATMPVC_SOCKET;
1264 case PF_X25:
1265 return SECCLASS_X25_SOCKET;
1266 case PF_ROSE:
1267 return SECCLASS_ROSE_SOCKET;
1268 case PF_DECnet:
1269 return SECCLASS_DECNET_SOCKET;
1270 case PF_ATMSVC:
1271 return SECCLASS_ATMSVC_SOCKET;
1272 case PF_RDS:
1273 return SECCLASS_RDS_SOCKET;
1274 case PF_IRDA:
1275 return SECCLASS_IRDA_SOCKET;
1276 case PF_PPPOX:
1277 return SECCLASS_PPPOX_SOCKET;
1278 case PF_LLC:
1279 return SECCLASS_LLC_SOCKET;
Stephen Smalleyda69a532017-01-09 10:07:30 -05001280 case PF_CAN:
1281 return SECCLASS_CAN_SOCKET;
1282 case PF_TIPC:
1283 return SECCLASS_TIPC_SOCKET;
1284 case PF_BLUETOOTH:
1285 return SECCLASS_BLUETOOTH_SOCKET;
1286 case PF_IUCV:
1287 return SECCLASS_IUCV_SOCKET;
1288 case PF_RXRPC:
1289 return SECCLASS_RXRPC_SOCKET;
1290 case PF_ISDN:
1291 return SECCLASS_ISDN_SOCKET;
1292 case PF_PHONET:
1293 return SECCLASS_PHONET_SOCKET;
1294 case PF_IEEE802154:
1295 return SECCLASS_IEEE802154_SOCKET;
1296 case PF_CAIF:
1297 return SECCLASS_CAIF_SOCKET;
1298 case PF_ALG:
1299 return SECCLASS_ALG_SOCKET;
1300 case PF_NFC:
1301 return SECCLASS_NFC_SOCKET;
1302 case PF_VSOCK:
1303 return SECCLASS_VSOCK_SOCKET;
1304 case PF_KCM:
1305 return SECCLASS_KCM_SOCKET;
1306 case PF_QIPCRTR:
1307 return SECCLASS_QIPCRTR_SOCKET;
Linus Torvalds3051bf32017-02-22 10:15:09 -08001308 case PF_SMC:
1309 return SECCLASS_SMC_SOCKET;
Björn Töpel68e8b842018-05-02 13:01:22 +02001310 case PF_XDP:
1311 return SECCLASS_XDP_SOCKET;
1312#if PF_MAX > 45
Stephen Smalleyda69a532017-01-09 10:07:30 -05001313#error New address family defined, please update this function.
1314#endif
1315 }
1316 }
1317
Linus Torvalds1da177e2005-04-16 15:20:36 -07001318 return SECCLASS_SOCKET;
1319}
1320
Stephen Smalley134509d2015-06-04 16:22:17 -04001321static int selinux_genfs_get_sid(struct dentry *dentry,
1322 u16 tclass,
1323 u16 flags,
1324 u32 *sid)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001325{
Lucian Adrian Grijincu8e6c9692011-02-01 18:42:22 +02001326 int rc;
Al Virofc640052016-04-10 01:33:30 -04001327 struct super_block *sb = dentry->d_sb;
Lucian Adrian Grijincu8e6c9692011-02-01 18:42:22 +02001328 char *buffer, *path;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001329
Eric Paris828dfe12008-04-17 13:17:49 -04001330 buffer = (char *)__get_free_page(GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001331 if (!buffer)
1332 return -ENOMEM;
1333
Lucian Adrian Grijincu8e6c9692011-02-01 18:42:22 +02001334 path = dentry_path_raw(dentry, buffer, PAGE_SIZE);
1335 if (IS_ERR(path))
1336 rc = PTR_ERR(path);
1337 else {
Stephen Smalley134509d2015-06-04 16:22:17 -04001338 if (flags & SE_SBPROC) {
1339 /* each process gets a /proc/PID/ entry. Strip off the
1340 * PID part to get a valid selinux labeling.
1341 * e.g. /proc/1/net/rpc/nfs -> /net/rpc/nfs */
1342 while (path[1] >= '0' && path[1] <= '9') {
1343 path[1] = '/';
1344 path++;
1345 }
Lucian Adrian Grijincu8e6c9692011-02-01 18:42:22 +02001346 }
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05001347 rc = security_genfs_sid(&selinux_state, sb->s_type->name,
1348 path, tclass, sid);
Stephen Smalley7bb185e2018-09-04 16:51:36 -04001349 if (rc == -ENOENT) {
1350 /* No match in policy, mark as unlabeled. */
1351 *sid = SECINITSID_UNLABELED;
1352 rc = 0;
1353 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001354 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001355 free_page((unsigned long)buffer);
1356 return rc;
1357}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001358
Ondrej Mosnacekb7540262019-02-22 15:57:14 +01001359static int inode_doinit_use_xattr(struct inode *inode, struct dentry *dentry,
1360 u32 def_sid, u32 *sid)
1361{
1362#define INITCONTEXTLEN 255
1363 char *context;
1364 unsigned int len;
1365 int rc;
1366
1367 len = INITCONTEXTLEN;
1368 context = kmalloc(len + 1, GFP_NOFS);
1369 if (!context)
1370 return -ENOMEM;
1371
1372 context[len] = '\0';
1373 rc = __vfs_getxattr(dentry, inode, XATTR_NAME_SELINUX, context, len);
1374 if (rc == -ERANGE) {
1375 kfree(context);
1376
1377 /* Need a larger buffer. Query for the right size. */
1378 rc = __vfs_getxattr(dentry, inode, XATTR_NAME_SELINUX, NULL, 0);
1379 if (rc < 0)
1380 return rc;
1381
1382 len = rc;
1383 context = kmalloc(len + 1, GFP_NOFS);
1384 if (!context)
1385 return -ENOMEM;
1386
1387 context[len] = '\0';
1388 rc = __vfs_getxattr(dentry, inode, XATTR_NAME_SELINUX,
1389 context, len);
1390 }
1391 if (rc < 0) {
1392 kfree(context);
1393 if (rc != -ENODATA) {
1394 pr_warn("SELinux: %s: getxattr returned %d for dev=%s ino=%ld\n",
1395 __func__, -rc, inode->i_sb->s_id, inode->i_ino);
1396 return rc;
1397 }
1398 *sid = def_sid;
1399 return 0;
1400 }
1401
1402 rc = security_context_to_sid_default(&selinux_state, context, rc, sid,
1403 def_sid, GFP_NOFS);
1404 if (rc) {
1405 char *dev = inode->i_sb->s_id;
1406 unsigned long ino = inode->i_ino;
1407
1408 if (rc == -EINVAL) {
1409 pr_notice_ratelimited("SELinux: inode=%lu on dev=%s was found to have an invalid context=%s. This indicates you may need to relabel the inode or the filesystem in question.\n",
1410 ino, dev, context);
1411 } else {
1412 pr_warn("SELinux: %s: context_to_sid(%s) returned %d for dev=%s ino=%ld\n",
1413 __func__, context, -rc, dev, ino);
1414 }
1415 }
1416 kfree(context);
1417 return 0;
1418}
1419
Linus Torvalds1da177e2005-04-16 15:20:36 -07001420/* The inode's security attributes must be initialized before first use. */
1421static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dentry)
1422{
1423 struct superblock_security_struct *sbsec = NULL;
Casey Schaufler80788c22018-09-21 17:19:11 -07001424 struct inode_security_struct *isec = selinux_inode(inode);
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001425 u32 task_sid, sid = 0;
1426 u16 sclass;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001427 struct dentry *dentry;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001428 int rc = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001429
Andreas Gruenbacher6f3be9f2015-12-24 11:09:40 -05001430 if (isec->initialized == LABEL_INITIALIZED)
Andreas Gruenbacher13457d02016-11-10 22:18:29 +01001431 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001432
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001433 spin_lock(&isec->lock);
Andreas Gruenbacher6f3be9f2015-12-24 11:09:40 -05001434 if (isec->initialized == LABEL_INITIALIZED)
Eric Paris23970742006-09-25 23:32:01 -07001435 goto out_unlock;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001436
Andreas Gruenbacher13457d02016-11-10 22:18:29 +01001437 if (isec->sclass == SECCLASS_FILE)
1438 isec->sclass = inode_mode_to_security_class(inode->i_mode);
1439
Linus Torvalds1da177e2005-04-16 15:20:36 -07001440 sbsec = inode->i_sb->s_security;
David P. Quigley0d90a7e2009-01-16 09:22:02 -05001441 if (!(sbsec->flags & SE_SBINITIALIZED)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001442 /* Defer initialization until selinux_complete_init,
1443 after the initial policy is loaded and the security
1444 server is ready to handle calls. */
1445 spin_lock(&sbsec->isec_lock);
1446 if (list_empty(&isec->list))
1447 list_add(&isec->list, &sbsec->isec_head);
1448 spin_unlock(&sbsec->isec_lock);
Eric Paris23970742006-09-25 23:32:01 -07001449 goto out_unlock;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001450 }
1451
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001452 sclass = isec->sclass;
1453 task_sid = isec->task_sid;
1454 sid = isec->sid;
1455 isec->initialized = LABEL_PENDING;
1456 spin_unlock(&isec->lock);
1457
Linus Torvalds1da177e2005-04-16 15:20:36 -07001458 switch (sbsec->behavior) {
David Quigleyeb9ae682013-05-22 12:50:37 -04001459 case SECURITY_FS_USE_NATIVE:
1460 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001461 case SECURITY_FS_USE_XATTR:
Andreas Gruenbacher5d6c3192016-09-29 17:48:42 +02001462 if (!(inode->i_opflags & IOP_XATTR)) {
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001463 sid = sbsec->def_sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001464 break;
1465 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001466 /* Need a dentry, since the xattr API requires one.
1467 Life would be simpler if we could just pass the inode. */
1468 if (opt_dentry) {
1469 /* Called from d_instantiate or d_splice_alias. */
1470 dentry = dget(opt_dentry);
1471 } else {
Al Virob1271252018-04-25 10:28:38 -04001472 /*
1473 * Called from selinux_complete_init, try to find a dentry.
1474 * Some filesystems really want a connected one, so try
1475 * that first. We could split SECURITY_FS_USE_XATTR in
1476 * two, depending upon that...
1477 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001478 dentry = d_find_alias(inode);
Al Virob1271252018-04-25 10:28:38 -04001479 if (!dentry)
1480 dentry = d_find_any_alias(inode);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001481 }
1482 if (!dentry) {
Eric Parisdf7f54c2009-03-09 14:35:58 -04001483 /*
1484 * this is can be hit on boot when a file is accessed
1485 * before the policy is loaded. When we load policy we
1486 * may find inodes that have no dentry on the
1487 * sbsec->isec_head list. No reason to complain as these
1488 * will get fixed up the next time we go through
1489 * inode_doinit with a dentry, before these inodes could
1490 * be used again by userspace.
1491 */
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001492 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001493 }
1494
Ondrej Mosnacekb7540262019-02-22 15:57:14 +01001495 rc = inode_doinit_use_xattr(inode, dentry, sbsec->def_sid,
1496 &sid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001497 dput(dentry);
Ondrej Mosnacekb7540262019-02-22 15:57:14 +01001498 if (rc)
1499 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001500 break;
1501 case SECURITY_FS_USE_TASK:
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001502 sid = task_sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001503 break;
1504 case SECURITY_FS_USE_TRANS:
1505 /* Default to the fs SID. */
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001506 sid = sbsec->sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001507
1508 /* Try to obtain a transition SID. */
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05001509 rc = security_transition_sid(&selinux_state, task_sid, sid,
1510 sclass, NULL, &sid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001511 if (rc)
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001512 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001513 break;
Eric Parisc312feb2006-07-10 04:43:53 -07001514 case SECURITY_FS_USE_MNTPOINT:
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001515 sid = sbsec->mntpoint_sid;
Eric Parisc312feb2006-07-10 04:43:53 -07001516 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001517 default:
Eric Parisc312feb2006-07-10 04:43:53 -07001518 /* Default to the fs superblock SID. */
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001519 sid = sbsec->sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001520
Stephen Smalley134509d2015-06-04 16:22:17 -04001521 if ((sbsec->flags & SE_SBGENFS) && !S_ISLNK(inode->i_mode)) {
Paul Mooref64410e2014-03-19 16:46:18 -04001522 /* We must have a dentry to determine the label on
1523 * procfs inodes */
Al Virob1271252018-04-25 10:28:38 -04001524 if (opt_dentry) {
Paul Mooref64410e2014-03-19 16:46:18 -04001525 /* Called from d_instantiate or
1526 * d_splice_alias. */
1527 dentry = dget(opt_dentry);
Al Virob1271252018-04-25 10:28:38 -04001528 } else {
Paul Mooref64410e2014-03-19 16:46:18 -04001529 /* Called from selinux_complete_init, try to
Al Virob1271252018-04-25 10:28:38 -04001530 * find a dentry. Some filesystems really want
1531 * a connected one, so try that first.
1532 */
Paul Mooref64410e2014-03-19 16:46:18 -04001533 dentry = d_find_alias(inode);
Al Virob1271252018-04-25 10:28:38 -04001534 if (!dentry)
1535 dentry = d_find_any_alias(inode);
1536 }
Paul Mooref64410e2014-03-19 16:46:18 -04001537 /*
1538 * This can be hit on boot when a file is accessed
1539 * before the policy is loaded. When we load policy we
1540 * may find inodes that have no dentry on the
1541 * sbsec->isec_head list. No reason to complain as
1542 * these will get fixed up the next time we go through
1543 * inode_doinit() with a dentry, before these inodes
1544 * could be used again by userspace.
1545 */
1546 if (!dentry)
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001547 goto out;
1548 rc = selinux_genfs_get_sid(dentry, sclass,
Stephen Smalley134509d2015-06-04 16:22:17 -04001549 sbsec->flags, &sid);
Ondrej Mosnacekb7540262019-02-22 15:57:14 +01001550 if (rc) {
1551 dput(dentry);
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001552 goto out;
Ondrej Mosnacekb7540262019-02-22 15:57:14 +01001553 }
1554
1555 if ((sbsec->flags & SE_SBGENFS_XATTR) &&
1556 (inode->i_opflags & IOP_XATTR)) {
1557 rc = inode_doinit_use_xattr(inode, dentry,
1558 sid, &sid);
1559 if (rc) {
1560 dput(dentry);
1561 goto out;
1562 }
1563 }
1564 dput(dentry);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001565 }
1566 break;
1567 }
1568
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001569out:
1570 spin_lock(&isec->lock);
1571 if (isec->initialized == LABEL_PENDING) {
1572 if (!sid || rc) {
1573 isec->initialized = LABEL_INVALID;
1574 goto out_unlock;
1575 }
1576
1577 isec->initialized = LABEL_INITIALIZED;
1578 isec->sid = sid;
1579 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001580
Eric Paris23970742006-09-25 23:32:01 -07001581out_unlock:
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001582 spin_unlock(&isec->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001583 return rc;
1584}
1585
1586/* Convert a Linux signal to an access vector. */
1587static inline u32 signal_to_av(int sig)
1588{
1589 u32 perm = 0;
1590
1591 switch (sig) {
1592 case SIGCHLD:
1593 /* Commonly granted from child to parent. */
1594 perm = PROCESS__SIGCHLD;
1595 break;
1596 case SIGKILL:
1597 /* Cannot be caught or ignored */
1598 perm = PROCESS__SIGKILL;
1599 break;
1600 case SIGSTOP:
1601 /* Cannot be caught or ignored */
1602 perm = PROCESS__SIGSTOP;
1603 break;
1604 default:
1605 /* All other signals. */
1606 perm = PROCESS__SIGNAL;
1607 break;
1608 }
1609
1610 return perm;
1611}
1612
Stephen Smalleyb68e4182008-02-07 11:21:04 -05001613#if CAP_LAST_CAP > 63
1614#error Fix SELinux to handle capabilities > 63.
1615#endif
1616
Linus Torvalds1da177e2005-04-16 15:20:36 -07001617/* Check whether a task is allowed to use a capability. */
Eric Paris6a9de492012-01-03 12:25:14 -05001618static int cred_has_capability(const struct cred *cred,
Micah Mortonc1a85a02019-01-07 16:10:53 -08001619 int cap, unsigned int opts, bool initns)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001620{
Thomas Liu2bf49692009-07-14 12:14:09 -04001621 struct common_audit_data ad;
Eric Paris06112162008-11-11 22:02:50 +11001622 struct av_decision avd;
Stephen Smalleyb68e4182008-02-07 11:21:04 -05001623 u16 sclass;
David Howells3699c532009-01-06 22:27:01 +00001624 u32 sid = cred_sid(cred);
Stephen Smalleyb68e4182008-02-07 11:21:04 -05001625 u32 av = CAP_TO_MASK(cap);
Eric Paris06112162008-11-11 22:02:50 +11001626 int rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001627
Eric Paris50c205f2012-04-04 15:01:43 -04001628 ad.type = LSM_AUDIT_DATA_CAP;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001629 ad.u.cap = cap;
1630
Stephen Smalleyb68e4182008-02-07 11:21:04 -05001631 switch (CAP_TO_INDEX(cap)) {
1632 case 0:
Stephen Smalley8e4ff6f2016-04-08 13:52:00 -04001633 sclass = initns ? SECCLASS_CAPABILITY : SECCLASS_CAP_USERNS;
Stephen Smalleyb68e4182008-02-07 11:21:04 -05001634 break;
1635 case 1:
Stephen Smalley8e4ff6f2016-04-08 13:52:00 -04001636 sclass = initns ? SECCLASS_CAPABILITY2 : SECCLASS_CAP2_USERNS;
Stephen Smalleyb68e4182008-02-07 11:21:04 -05001637 break;
1638 default:
peter enderborgc103a912018-06-12 10:09:03 +02001639 pr_err("SELinux: out of range capability %d\n", cap);
Stephen Smalleyb68e4182008-02-07 11:21:04 -05001640 BUG();
Eric Parisa35c6c832011-04-20 10:21:28 -04001641 return -EINVAL;
Stephen Smalleyb68e4182008-02-07 11:21:04 -05001642 }
Eric Paris06112162008-11-11 22:02:50 +11001643
Stephen Smalley6b6bc622018-03-05 11:47:56 -05001644 rc = avc_has_perm_noaudit(&selinux_state,
1645 sid, sid, sclass, av, 0, &avd);
Micah Mortonc1a85a02019-01-07 16:10:53 -08001646 if (!(opts & CAP_OPT_NOAUDIT)) {
Stephen Smalley6b6bc622018-03-05 11:47:56 -05001647 int rc2 = avc_audit(&selinux_state,
1648 sid, sid, sclass, av, &avd, rc, &ad, 0);
Eric Paris9ade0cf2011-04-25 16:26:29 -04001649 if (rc2)
1650 return rc2;
1651 }
Eric Paris06112162008-11-11 22:02:50 +11001652 return rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001653}
1654
Linus Torvalds1da177e2005-04-16 15:20:36 -07001655/* Check whether a task has a particular permission to an inode.
1656 The 'adp' parameter is optional and allows other audit
1657 data to be passed (e.g. the dentry). */
David Howells88e67f32008-11-14 10:39:21 +11001658static int inode_has_perm(const struct cred *cred,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001659 struct inode *inode,
1660 u32 perms,
Linus Torvalds19e49832013-10-04 12:54:11 -07001661 struct common_audit_data *adp)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001662{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001663 struct inode_security_struct *isec;
David Howells275bb412008-11-14 10:39:19 +11001664 u32 sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001665
David Howellse0e81732009-09-02 09:13:40 +01001666 validate_creds(cred);
1667
Eric Paris828dfe12008-04-17 13:17:49 -04001668 if (unlikely(IS_PRIVATE(inode)))
Stephen Smalleybbaca6c2007-02-14 00:34:16 -08001669 return 0;
1670
David Howells88e67f32008-11-14 10:39:21 +11001671 sid = cred_sid(cred);
Casey Schaufler80788c22018-09-21 17:19:11 -07001672 isec = selinux_inode(inode);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001673
Stephen Smalley6b6bc622018-03-05 11:47:56 -05001674 return avc_has_perm(&selinux_state,
1675 sid, isec->sid, isec->sclass, perms, adp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001676}
1677
1678/* Same as inode_has_perm, but pass explicit audit data containing
1679 the dentry to help the auditing code to more easily generate the
1680 pathname if needed. */
David Howells88e67f32008-11-14 10:39:21 +11001681static inline int dentry_has_perm(const struct cred *cred,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001682 struct dentry *dentry,
1683 u32 av)
1684{
David Howellsc6f493d2015-03-17 22:26:22 +00001685 struct inode *inode = d_backing_inode(dentry);
Thomas Liu2bf49692009-07-14 12:14:09 -04001686 struct common_audit_data ad;
David Howells88e67f32008-11-14 10:39:21 +11001687
Eric Paris50c205f2012-04-04 15:01:43 -04001688 ad.type = LSM_AUDIT_DATA_DENTRY;
Eric Paris2875fa02011-04-28 16:04:24 -04001689 ad.u.dentry = dentry;
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -05001690 __inode_security_revalidate(inode, dentry, true);
Linus Torvalds19e49832013-10-04 12:54:11 -07001691 return inode_has_perm(cred, inode, av, &ad);
Eric Paris2875fa02011-04-28 16:04:24 -04001692}
1693
1694/* Same as inode_has_perm, but pass explicit audit data containing
1695 the path to help the auditing code to more easily generate the
1696 pathname if needed. */
1697static inline int path_has_perm(const struct cred *cred,
Al Viro3f7036a2015-03-08 19:28:30 -04001698 const struct path *path,
Eric Paris2875fa02011-04-28 16:04:24 -04001699 u32 av)
1700{
David Howellsc6f493d2015-03-17 22:26:22 +00001701 struct inode *inode = d_backing_inode(path->dentry);
Eric Paris2875fa02011-04-28 16:04:24 -04001702 struct common_audit_data ad;
1703
Eric Paris50c205f2012-04-04 15:01:43 -04001704 ad.type = LSM_AUDIT_DATA_PATH;
Eric Paris2875fa02011-04-28 16:04:24 -04001705 ad.u.path = *path;
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -05001706 __inode_security_revalidate(inode, path->dentry, true);
Linus Torvalds19e49832013-10-04 12:54:11 -07001707 return inode_has_perm(cred, inode, av, &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001708}
1709
David Howells13f8e982013-06-13 23:37:55 +01001710/* Same as path_has_perm, but uses the inode from the file struct. */
1711static inline int file_path_has_perm(const struct cred *cred,
1712 struct file *file,
1713 u32 av)
1714{
1715 struct common_audit_data ad;
1716
Vivek Goyal43af5de2016-09-09 11:37:49 -04001717 ad.type = LSM_AUDIT_DATA_FILE;
1718 ad.u.file = file;
Linus Torvalds19e49832013-10-04 12:54:11 -07001719 return inode_has_perm(cred, file_inode(file), av, &ad);
David Howells13f8e982013-06-13 23:37:55 +01001720}
1721
Chenbo Fengf66e4482017-10-18 13:00:26 -07001722#ifdef CONFIG_BPF_SYSCALL
1723static int bpf_fd_pass(struct file *file, u32 sid);
1724#endif
1725
Linus Torvalds1da177e2005-04-16 15:20:36 -07001726/* Check whether a task can use an open file descriptor to
1727 access an inode in a given way. Check access to the
1728 descriptor itself, and then use dentry_has_perm to
1729 check a particular permission to the file.
1730 Access to the descriptor is implicitly granted if it
1731 has the same SID as the process. If av is zero, then
1732 access to the file is not checked, e.g. for cases
1733 where only the descriptor is affected like seek. */
David Howells88e67f32008-11-14 10:39:21 +11001734static int file_has_perm(const struct cred *cred,
1735 struct file *file,
1736 u32 av)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001737{
Casey Schauflerbb6c6b02018-09-21 17:22:32 -07001738 struct file_security_struct *fsec = selinux_file(file);
Al Viro496ad9a2013-01-23 17:07:38 -05001739 struct inode *inode = file_inode(file);
Thomas Liu2bf49692009-07-14 12:14:09 -04001740 struct common_audit_data ad;
David Howells88e67f32008-11-14 10:39:21 +11001741 u32 sid = cred_sid(cred);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001742 int rc;
1743
Vivek Goyal43af5de2016-09-09 11:37:49 -04001744 ad.type = LSM_AUDIT_DATA_FILE;
1745 ad.u.file = file;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001746
David Howells275bb412008-11-14 10:39:19 +11001747 if (sid != fsec->sid) {
Stephen Smalley6b6bc622018-03-05 11:47:56 -05001748 rc = avc_has_perm(&selinux_state,
1749 sid, fsec->sid,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001750 SECCLASS_FD,
1751 FD__USE,
1752 &ad);
1753 if (rc)
David Howells88e67f32008-11-14 10:39:21 +11001754 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001755 }
1756
Chenbo Fengf66e4482017-10-18 13:00:26 -07001757#ifdef CONFIG_BPF_SYSCALL
1758 rc = bpf_fd_pass(file, cred_sid(cred));
1759 if (rc)
1760 return rc;
1761#endif
1762
Linus Torvalds1da177e2005-04-16 15:20:36 -07001763 /* av is zero if only checking access to the descriptor. */
David Howells88e67f32008-11-14 10:39:21 +11001764 rc = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001765 if (av)
Linus Torvalds19e49832013-10-04 12:54:11 -07001766 rc = inode_has_perm(cred, inode, av, &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001767
David Howells88e67f32008-11-14 10:39:21 +11001768out:
1769 return rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001770}
1771
David Howellsc3c188b2015-07-10 17:19:58 -04001772/*
1773 * Determine the label for an inode that might be unioned.
1774 */
Vivek Goyalc957f6d2016-07-13 10:44:51 -04001775static int
1776selinux_determine_inode_label(const struct task_security_struct *tsec,
1777 struct inode *dir,
1778 const struct qstr *name, u16 tclass,
1779 u32 *_new_isid)
David Howellsc3c188b2015-07-10 17:19:58 -04001780{
1781 const struct superblock_security_struct *sbsec = dir->i_sb->s_security;
David Howellsc3c188b2015-07-10 17:19:58 -04001782
1783 if ((sbsec->flags & SE_SBINITIALIZED) &&
1784 (sbsec->behavior == SECURITY_FS_USE_MNTPOINT)) {
1785 *_new_isid = sbsec->mntpoint_sid;
1786 } else if ((sbsec->flags & SBLABEL_MNT) &&
1787 tsec->create_sid) {
1788 *_new_isid = tsec->create_sid;
1789 } else {
Paul Moore20cdef82016-04-04 14:14:42 -04001790 const struct inode_security_struct *dsec = inode_security(dir);
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05001791 return security_transition_sid(&selinux_state, tsec->sid,
1792 dsec->sid, tclass,
David Howellsc3c188b2015-07-10 17:19:58 -04001793 name, _new_isid);
1794 }
1795
1796 return 0;
1797}
1798
Linus Torvalds1da177e2005-04-16 15:20:36 -07001799/* Check whether a task can create a file. */
1800static int may_create(struct inode *dir,
1801 struct dentry *dentry,
1802 u16 tclass)
1803{
Casey Schaufler0c6cfa62018-09-21 17:17:16 -07001804 const struct task_security_struct *tsec = selinux_cred(current_cred());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001805 struct inode_security_struct *dsec;
1806 struct superblock_security_struct *sbsec;
David Howells275bb412008-11-14 10:39:19 +11001807 u32 sid, newsid;
Thomas Liu2bf49692009-07-14 12:14:09 -04001808 struct common_audit_data ad;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001809 int rc;
1810
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -05001811 dsec = inode_security(dir);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001812 sbsec = dir->i_sb->s_security;
1813
David Howells275bb412008-11-14 10:39:19 +11001814 sid = tsec->sid;
David Howells275bb412008-11-14 10:39:19 +11001815
Eric Paris50c205f2012-04-04 15:01:43 -04001816 ad.type = LSM_AUDIT_DATA_DENTRY;
Eric Parisa2694342011-04-25 13:10:27 -04001817 ad.u.dentry = dentry;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001818
Stephen Smalley6b6bc622018-03-05 11:47:56 -05001819 rc = avc_has_perm(&selinux_state,
1820 sid, dsec->sid, SECCLASS_DIR,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001821 DIR__ADD_NAME | DIR__SEARCH,
1822 &ad);
1823 if (rc)
1824 return rc;
1825
Casey Schaufler0c6cfa62018-09-21 17:17:16 -07001826 rc = selinux_determine_inode_label(selinux_cred(current_cred()), dir,
Vivek Goyalc957f6d2016-07-13 10:44:51 -04001827 &dentry->d_name, tclass, &newsid);
David Howellsc3c188b2015-07-10 17:19:58 -04001828 if (rc)
1829 return rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001830
Stephen Smalley6b6bc622018-03-05 11:47:56 -05001831 rc = avc_has_perm(&selinux_state,
1832 sid, newsid, tclass, FILE__CREATE, &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001833 if (rc)
1834 return rc;
1835
Stephen Smalley6b6bc622018-03-05 11:47:56 -05001836 return avc_has_perm(&selinux_state,
1837 newsid, sbsec->sid,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001838 SECCLASS_FILESYSTEM,
1839 FILESYSTEM__ASSOCIATE, &ad);
1840}
1841
Eric Paris828dfe12008-04-17 13:17:49 -04001842#define MAY_LINK 0
1843#define MAY_UNLINK 1
1844#define MAY_RMDIR 2
Linus Torvalds1da177e2005-04-16 15:20:36 -07001845
1846/* Check whether a task can link, unlink, or rmdir a file/directory. */
1847static int may_link(struct inode *dir,
1848 struct dentry *dentry,
1849 int kind)
1850
1851{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001852 struct inode_security_struct *dsec, *isec;
Thomas Liu2bf49692009-07-14 12:14:09 -04001853 struct common_audit_data ad;
David Howells275bb412008-11-14 10:39:19 +11001854 u32 sid = current_sid();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001855 u32 av;
1856 int rc;
1857
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -05001858 dsec = inode_security(dir);
1859 isec = backing_inode_security(dentry);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001860
Eric Paris50c205f2012-04-04 15:01:43 -04001861 ad.type = LSM_AUDIT_DATA_DENTRY;
Eric Parisa2694342011-04-25 13:10:27 -04001862 ad.u.dentry = dentry;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001863
1864 av = DIR__SEARCH;
1865 av |= (kind ? DIR__REMOVE_NAME : DIR__ADD_NAME);
Stephen Smalley6b6bc622018-03-05 11:47:56 -05001866 rc = avc_has_perm(&selinux_state,
1867 sid, dsec->sid, SECCLASS_DIR, av, &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001868 if (rc)
1869 return rc;
1870
1871 switch (kind) {
1872 case MAY_LINK:
1873 av = FILE__LINK;
1874 break;
1875 case MAY_UNLINK:
1876 av = FILE__UNLINK;
1877 break;
1878 case MAY_RMDIR:
1879 av = DIR__RMDIR;
1880 break;
1881 default:
peter enderborgc103a912018-06-12 10:09:03 +02001882 pr_warn("SELinux: %s: unrecognized kind %d\n",
Eric Paris744ba352008-04-17 11:52:44 -04001883 __func__, kind);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001884 return 0;
1885 }
1886
Stephen Smalley6b6bc622018-03-05 11:47:56 -05001887 rc = avc_has_perm(&selinux_state,
1888 sid, isec->sid, isec->sclass, av, &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001889 return rc;
1890}
1891
1892static inline int may_rename(struct inode *old_dir,
1893 struct dentry *old_dentry,
1894 struct inode *new_dir,
1895 struct dentry *new_dentry)
1896{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001897 struct inode_security_struct *old_dsec, *new_dsec, *old_isec, *new_isec;
Thomas Liu2bf49692009-07-14 12:14:09 -04001898 struct common_audit_data ad;
David Howells275bb412008-11-14 10:39:19 +11001899 u32 sid = current_sid();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001900 u32 av;
1901 int old_is_dir, new_is_dir;
1902 int rc;
1903
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -05001904 old_dsec = inode_security(old_dir);
1905 old_isec = backing_inode_security(old_dentry);
David Howellse36cb0b2015-01-29 12:02:35 +00001906 old_is_dir = d_is_dir(old_dentry);
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -05001907 new_dsec = inode_security(new_dir);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001908
Eric Paris50c205f2012-04-04 15:01:43 -04001909 ad.type = LSM_AUDIT_DATA_DENTRY;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001910
Eric Parisa2694342011-04-25 13:10:27 -04001911 ad.u.dentry = old_dentry;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05001912 rc = avc_has_perm(&selinux_state,
1913 sid, old_dsec->sid, SECCLASS_DIR,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001914 DIR__REMOVE_NAME | DIR__SEARCH, &ad);
1915 if (rc)
1916 return rc;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05001917 rc = avc_has_perm(&selinux_state,
1918 sid, old_isec->sid,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001919 old_isec->sclass, FILE__RENAME, &ad);
1920 if (rc)
1921 return rc;
1922 if (old_is_dir && new_dir != old_dir) {
Stephen Smalley6b6bc622018-03-05 11:47:56 -05001923 rc = avc_has_perm(&selinux_state,
1924 sid, old_isec->sid,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001925 old_isec->sclass, DIR__REPARENT, &ad);
1926 if (rc)
1927 return rc;
1928 }
1929
Eric Parisa2694342011-04-25 13:10:27 -04001930 ad.u.dentry = new_dentry;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001931 av = DIR__ADD_NAME | DIR__SEARCH;
David Howells2c616d42015-01-29 12:02:33 +00001932 if (d_is_positive(new_dentry))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001933 av |= DIR__REMOVE_NAME;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05001934 rc = avc_has_perm(&selinux_state,
1935 sid, new_dsec->sid, SECCLASS_DIR, av, &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001936 if (rc)
1937 return rc;
David Howells2c616d42015-01-29 12:02:33 +00001938 if (d_is_positive(new_dentry)) {
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -05001939 new_isec = backing_inode_security(new_dentry);
David Howellse36cb0b2015-01-29 12:02:35 +00001940 new_is_dir = d_is_dir(new_dentry);
Stephen Smalley6b6bc622018-03-05 11:47:56 -05001941 rc = avc_has_perm(&selinux_state,
1942 sid, new_isec->sid,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001943 new_isec->sclass,
1944 (new_is_dir ? DIR__RMDIR : FILE__UNLINK), &ad);
1945 if (rc)
1946 return rc;
1947 }
1948
1949 return 0;
1950}
1951
1952/* Check whether a task can perform a filesystem operation. */
David Howells88e67f32008-11-14 10:39:21 +11001953static int superblock_has_perm(const struct cred *cred,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001954 struct super_block *sb,
1955 u32 perms,
Thomas Liu2bf49692009-07-14 12:14:09 -04001956 struct common_audit_data *ad)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001957{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001958 struct superblock_security_struct *sbsec;
David Howells88e67f32008-11-14 10:39:21 +11001959 u32 sid = cred_sid(cred);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001960
Linus Torvalds1da177e2005-04-16 15:20:36 -07001961 sbsec = sb->s_security;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05001962 return avc_has_perm(&selinux_state,
1963 sid, sbsec->sid, SECCLASS_FILESYSTEM, perms, ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001964}
1965
1966/* Convert a Linux mode and permission mask to an access vector. */
1967static inline u32 file_mask_to_av(int mode, int mask)
1968{
1969 u32 av = 0;
1970
Al Virodba19c62011-07-25 20:49:29 -04001971 if (!S_ISDIR(mode)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001972 if (mask & MAY_EXEC)
1973 av |= FILE__EXECUTE;
1974 if (mask & MAY_READ)
1975 av |= FILE__READ;
1976
1977 if (mask & MAY_APPEND)
1978 av |= FILE__APPEND;
1979 else if (mask & MAY_WRITE)
1980 av |= FILE__WRITE;
1981
1982 } else {
1983 if (mask & MAY_EXEC)
1984 av |= DIR__SEARCH;
1985 if (mask & MAY_WRITE)
1986 av |= DIR__WRITE;
1987 if (mask & MAY_READ)
1988 av |= DIR__READ;
1989 }
1990
1991 return av;
1992}
1993
1994/* Convert a Linux file to an access vector. */
1995static inline u32 file_to_av(struct file *file)
1996{
1997 u32 av = 0;
1998
1999 if (file->f_mode & FMODE_READ)
2000 av |= FILE__READ;
2001 if (file->f_mode & FMODE_WRITE) {
2002 if (file->f_flags & O_APPEND)
2003 av |= FILE__APPEND;
2004 else
2005 av |= FILE__WRITE;
2006 }
Stephen Smalley0794c662008-03-17 08:55:18 -04002007 if (!av) {
2008 /*
2009 * Special file opened with flags 3 for ioctl-only use.
2010 */
2011 av = FILE__IOCTL;
2012 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002013
2014 return av;
2015}
2016
Eric Paris8b6a5a32008-10-29 17:06:46 -04002017/*
2018 * Convert a file to an access vector and include the correct open
2019 * open permission.
2020 */
2021static inline u32 open_file_to_av(struct file *file)
2022{
2023 u32 av = file_to_av(file);
Stephen Smalleyccb54472017-05-12 12:41:24 -04002024 struct inode *inode = file_inode(file);
Eric Paris8b6a5a32008-10-29 17:06:46 -04002025
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05002026 if (selinux_policycap_openperm() &&
2027 inode->i_sb->s_magic != SOCKFS_MAGIC)
Eric Paris49b7b8d2010-07-23 11:44:09 -04002028 av |= FILE__OPEN;
2029
Eric Paris8b6a5a32008-10-29 17:06:46 -04002030 return av;
2031}
2032
Linus Torvalds1da177e2005-04-16 15:20:36 -07002033/* Hook functions begin here. */
2034
Stephen Smalley79af7302015-01-21 10:54:10 -05002035static int selinux_binder_set_context_mgr(struct task_struct *mgr)
2036{
2037 u32 mysid = current_sid();
2038 u32 mgrsid = task_sid(mgr);
2039
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002040 return avc_has_perm(&selinux_state,
2041 mysid, mgrsid, SECCLASS_BINDER,
Stephen Smalley79af7302015-01-21 10:54:10 -05002042 BINDER__SET_CONTEXT_MGR, NULL);
2043}
2044
2045static int selinux_binder_transaction(struct task_struct *from,
2046 struct task_struct *to)
2047{
2048 u32 mysid = current_sid();
2049 u32 fromsid = task_sid(from);
2050 u32 tosid = task_sid(to);
2051 int rc;
2052
2053 if (mysid != fromsid) {
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002054 rc = avc_has_perm(&selinux_state,
2055 mysid, fromsid, SECCLASS_BINDER,
Stephen Smalley79af7302015-01-21 10:54:10 -05002056 BINDER__IMPERSONATE, NULL);
2057 if (rc)
2058 return rc;
2059 }
2060
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002061 return avc_has_perm(&selinux_state,
2062 fromsid, tosid, SECCLASS_BINDER, BINDER__CALL,
Stephen Smalley79af7302015-01-21 10:54:10 -05002063 NULL);
2064}
2065
2066static int selinux_binder_transfer_binder(struct task_struct *from,
2067 struct task_struct *to)
2068{
2069 u32 fromsid = task_sid(from);
2070 u32 tosid = task_sid(to);
2071
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002072 return avc_has_perm(&selinux_state,
2073 fromsid, tosid, SECCLASS_BINDER, BINDER__TRANSFER,
Stephen Smalley79af7302015-01-21 10:54:10 -05002074 NULL);
2075}
2076
2077static int selinux_binder_transfer_file(struct task_struct *from,
2078 struct task_struct *to,
2079 struct file *file)
2080{
2081 u32 sid = task_sid(to);
Casey Schauflerbb6c6b02018-09-21 17:22:32 -07002082 struct file_security_struct *fsec = selinux_file(file);
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -05002083 struct dentry *dentry = file->f_path.dentry;
Paul Moore20cdef82016-04-04 14:14:42 -04002084 struct inode_security_struct *isec;
Stephen Smalley79af7302015-01-21 10:54:10 -05002085 struct common_audit_data ad;
2086 int rc;
2087
2088 ad.type = LSM_AUDIT_DATA_PATH;
2089 ad.u.path = file->f_path;
2090
2091 if (sid != fsec->sid) {
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002092 rc = avc_has_perm(&selinux_state,
2093 sid, fsec->sid,
Stephen Smalley79af7302015-01-21 10:54:10 -05002094 SECCLASS_FD,
2095 FD__USE,
2096 &ad);
2097 if (rc)
2098 return rc;
2099 }
2100
Chenbo Fengf66e4482017-10-18 13:00:26 -07002101#ifdef CONFIG_BPF_SYSCALL
2102 rc = bpf_fd_pass(file, sid);
2103 if (rc)
2104 return rc;
2105#endif
2106
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -05002107 if (unlikely(IS_PRIVATE(d_backing_inode(dentry))))
Stephen Smalley79af7302015-01-21 10:54:10 -05002108 return 0;
2109
Paul Moore20cdef82016-04-04 14:14:42 -04002110 isec = backing_inode_security(dentry);
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002111 return avc_has_perm(&selinux_state,
2112 sid, isec->sid, isec->sclass, file_to_av(file),
Stephen Smalley79af7302015-01-21 10:54:10 -05002113 &ad);
2114}
2115
Ingo Molnar9e488582009-05-07 19:26:19 +10002116static int selinux_ptrace_access_check(struct task_struct *child,
David Howells5cd9c582008-08-14 11:37:28 +01002117 unsigned int mode)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002118{
Stephen Smalleybe0554c2017-01-09 10:07:31 -05002119 u32 sid = current_sid();
2120 u32 csid = task_sid(child);
Stephen Smalley006ebb42008-05-19 08:32:49 -04002121
Stephen Smalleybe0554c2017-01-09 10:07:31 -05002122 if (mode & PTRACE_MODE_READ)
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002123 return avc_has_perm(&selinux_state,
2124 sid, csid, SECCLASS_FILE, FILE__READ, NULL);
Stephen Smalleybe0554c2017-01-09 10:07:31 -05002125
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002126 return avc_has_perm(&selinux_state,
2127 sid, csid, SECCLASS_PROCESS, PROCESS__PTRACE, NULL);
David Howells5cd9c582008-08-14 11:37:28 +01002128}
2129
2130static int selinux_ptrace_traceme(struct task_struct *parent)
2131{
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002132 return avc_has_perm(&selinux_state,
2133 task_sid(parent), current_sid(), SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05002134 PROCESS__PTRACE, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002135}
2136
2137static int selinux_capget(struct task_struct *target, kernel_cap_t *effective,
Eric Paris828dfe12008-04-17 13:17:49 -04002138 kernel_cap_t *inheritable, kernel_cap_t *permitted)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002139{
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002140 return avc_has_perm(&selinux_state,
2141 current_sid(), task_sid(target), SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05002142 PROCESS__GETCAP, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002143}
2144
David Howellsd84f4f92008-11-14 10:39:23 +11002145static int selinux_capset(struct cred *new, const struct cred *old,
2146 const kernel_cap_t *effective,
2147 const kernel_cap_t *inheritable,
2148 const kernel_cap_t *permitted)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002149{
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002150 return avc_has_perm(&selinux_state,
2151 cred_sid(old), cred_sid(new), SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05002152 PROCESS__SETCAP, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002153}
2154
James Morris5626d3e2009-01-30 10:05:06 +11002155/*
2156 * (This comment used to live with the selinux_task_setuid hook,
2157 * which was removed).
2158 *
2159 * Since setuid only affects the current process, and since the SELinux
2160 * controls are not based on the Linux identity attributes, SELinux does not
2161 * need to control this operation. However, SELinux does control the use of
2162 * the CAP_SETUID and CAP_SETGID capabilities using the capable hook.
2163 */
2164
Eric Paris6a9de492012-01-03 12:25:14 -05002165static int selinux_capable(const struct cred *cred, struct user_namespace *ns,
Micah Mortonc1a85a02019-01-07 16:10:53 -08002166 int cap, unsigned int opts)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002167{
Micah Mortonc1a85a02019-01-07 16:10:53 -08002168 return cred_has_capability(cred, cap, opts, ns == &init_user_ns);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002169}
2170
Linus Torvalds1da177e2005-04-16 15:20:36 -07002171static int selinux_quotactl(int cmds, int type, int id, struct super_block *sb)
2172{
David Howells88e67f32008-11-14 10:39:21 +11002173 const struct cred *cred = current_cred();
Linus Torvalds1da177e2005-04-16 15:20:36 -07002174 int rc = 0;
2175
2176 if (!sb)
2177 return 0;
2178
2179 switch (cmds) {
Eric Paris828dfe12008-04-17 13:17:49 -04002180 case Q_SYNC:
2181 case Q_QUOTAON:
2182 case Q_QUOTAOFF:
2183 case Q_SETINFO:
2184 case Q_SETQUOTA:
David Howells88e67f32008-11-14 10:39:21 +11002185 rc = superblock_has_perm(cred, sb, FILESYSTEM__QUOTAMOD, NULL);
Eric Paris828dfe12008-04-17 13:17:49 -04002186 break;
2187 case Q_GETFMT:
2188 case Q_GETINFO:
2189 case Q_GETQUOTA:
David Howells88e67f32008-11-14 10:39:21 +11002190 rc = superblock_has_perm(cred, sb, FILESYSTEM__QUOTAGET, NULL);
Eric Paris828dfe12008-04-17 13:17:49 -04002191 break;
2192 default:
2193 rc = 0; /* let the kernel handle invalid cmds */
2194 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002195 }
2196 return rc;
2197}
2198
2199static int selinux_quota_on(struct dentry *dentry)
2200{
David Howells88e67f32008-11-14 10:39:21 +11002201 const struct cred *cred = current_cred();
2202
Eric Paris2875fa02011-04-28 16:04:24 -04002203 return dentry_has_perm(cred, dentry, FILE__QUOTAON);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002204}
2205
Eric Paris12b30522010-11-15 18:36:29 -05002206static int selinux_syslog(int type)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002207{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002208 switch (type) {
Kees Cookd78ca3c2010-02-03 15:37:13 -08002209 case SYSLOG_ACTION_READ_ALL: /* Read last kernel messages */
2210 case SYSLOG_ACTION_SIZE_BUFFER: /* Return size of the log buffer */
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002211 return avc_has_perm(&selinux_state,
2212 current_sid(), SECINITSID_KERNEL,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05002213 SECCLASS_SYSTEM, SYSTEM__SYSLOG_READ, NULL);
Kees Cookd78ca3c2010-02-03 15:37:13 -08002214 case SYSLOG_ACTION_CONSOLE_OFF: /* Disable logging to console */
2215 case SYSLOG_ACTION_CONSOLE_ON: /* Enable logging to console */
2216 /* Set level of messages printed to console */
2217 case SYSLOG_ACTION_CONSOLE_LEVEL:
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002218 return avc_has_perm(&selinux_state,
2219 current_sid(), SECINITSID_KERNEL,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05002220 SECCLASS_SYSTEM, SYSTEM__SYSLOG_CONSOLE,
2221 NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002222 }
Stephen Smalleybe0554c2017-01-09 10:07:31 -05002223 /* All other syslog types */
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002224 return avc_has_perm(&selinux_state,
2225 current_sid(), SECINITSID_KERNEL,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05002226 SECCLASS_SYSTEM, SYSTEM__SYSLOG_MOD, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002227}
2228
2229/*
2230 * Check that a process has enough memory to allocate a new virtual
2231 * mapping. 0 means there is enough memory for the allocation to
2232 * succeed and -ENOMEM implies there is not.
2233 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07002234 * Do not audit the selinux permission check, as this is applied to all
2235 * processes that allocate mappings.
2236 */
Alan Cox34b4e4a2007-08-22 14:01:28 -07002237static int selinux_vm_enough_memory(struct mm_struct *mm, long pages)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002238{
2239 int rc, cap_sys_admin = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002240
Casey Schauflerb1d9e6b2015-05-02 15:11:42 -07002241 rc = cred_has_capability(current_cred(), CAP_SYS_ADMIN,
Micah Mortonc1a85a02019-01-07 16:10:53 -08002242 CAP_OPT_NOAUDIT, true);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002243 if (rc == 0)
2244 cap_sys_admin = 1;
2245
Casey Schauflerb1d9e6b2015-05-02 15:11:42 -07002246 return cap_sys_admin;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002247}
2248
2249/* binprm security operations */
2250
Stephen Smalleybe0554c2017-01-09 10:07:31 -05002251static u32 ptrace_parent_sid(void)
Paul Moore0c6181c2016-03-30 21:41:21 -04002252{
2253 u32 sid = 0;
2254 struct task_struct *tracer;
2255
2256 rcu_read_lock();
Stephen Smalleybe0554c2017-01-09 10:07:31 -05002257 tracer = ptrace_parent(current);
Paul Moore0c6181c2016-03-30 21:41:21 -04002258 if (tracer)
2259 sid = task_sid(tracer);
2260 rcu_read_unlock();
2261
2262 return sid;
2263}
2264
Stephen Smalley7b0d0b42014-08-04 13:36:49 -04002265static int check_nnp_nosuid(const struct linux_binprm *bprm,
2266 const struct task_security_struct *old_tsec,
2267 const struct task_security_struct *new_tsec)
2268{
2269 int nnp = (bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS);
Andy Lutomirski380cf5b2016-06-23 16:41:05 -05002270 int nosuid = !mnt_may_suid(bprm->file->f_path.mnt);
Stephen Smalley7b0d0b42014-08-04 13:36:49 -04002271 int rc;
Stephen Smalleyaf63f412017-07-31 10:12:46 -04002272 u32 av;
Stephen Smalley7b0d0b42014-08-04 13:36:49 -04002273
2274 if (!nnp && !nosuid)
2275 return 0; /* neither NNP nor nosuid */
2276
2277 if (new_tsec->sid == old_tsec->sid)
2278 return 0; /* No change in credentials */
2279
2280 /*
Stephen Smalleyaf63f412017-07-31 10:12:46 -04002281 * If the policy enables the nnp_nosuid_transition policy capability,
2282 * then we permit transitions under NNP or nosuid if the
2283 * policy allows the corresponding permission between
2284 * the old and new contexts.
2285 */
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05002286 if (selinux_policycap_nnp_nosuid_transition()) {
Stephen Smalleyaf63f412017-07-31 10:12:46 -04002287 av = 0;
2288 if (nnp)
2289 av |= PROCESS2__NNP_TRANSITION;
2290 if (nosuid)
2291 av |= PROCESS2__NOSUID_TRANSITION;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002292 rc = avc_has_perm(&selinux_state,
2293 old_tsec->sid, new_tsec->sid,
Stephen Smalleyaf63f412017-07-31 10:12:46 -04002294 SECCLASS_PROCESS2, av, NULL);
2295 if (!rc)
2296 return 0;
2297 }
2298
2299 /*
2300 * We also permit NNP or nosuid transitions to bounded SIDs,
2301 * i.e. SIDs that are guaranteed to only be allowed a subset
2302 * of the permissions of the current SID.
Stephen Smalley7b0d0b42014-08-04 13:36:49 -04002303 */
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05002304 rc = security_bounded_transition(&selinux_state, old_tsec->sid,
2305 new_tsec->sid);
Stephen Smalleyaf63f412017-07-31 10:12:46 -04002306 if (!rc)
2307 return 0;
2308
2309 /*
2310 * On failure, preserve the errno values for NNP vs nosuid.
2311 * NNP: Operation not permitted for caller.
2312 * nosuid: Permission denied to file.
2313 */
2314 if (nnp)
2315 return -EPERM;
2316 return -EACCES;
Stephen Smalley7b0d0b42014-08-04 13:36:49 -04002317}
2318
David Howellsa6f76f22008-11-14 10:39:24 +11002319static int selinux_bprm_set_creds(struct linux_binprm *bprm)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002320{
David Howellsa6f76f22008-11-14 10:39:24 +11002321 const struct task_security_struct *old_tsec;
2322 struct task_security_struct *new_tsec;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002323 struct inode_security_struct *isec;
Thomas Liu2bf49692009-07-14 12:14:09 -04002324 struct common_audit_data ad;
Al Viro496ad9a2013-01-23 17:07:38 -05002325 struct inode *inode = file_inode(bprm->file);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002326 int rc;
2327
David Howellsa6f76f22008-11-14 10:39:24 +11002328 /* SELinux context only depends on initial program or script and not
2329 * the script interpreter */
Kees Cookddb4a142017-07-18 15:25:23 -07002330 if (bprm->called_set_creds)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002331 return 0;
2332
Casey Schaufler0c6cfa62018-09-21 17:17:16 -07002333 old_tsec = selinux_cred(current_cred());
2334 new_tsec = selinux_cred(bprm->cred);
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -05002335 isec = inode_security(inode);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002336
2337 /* Default to the current task SID. */
David Howellsa6f76f22008-11-14 10:39:24 +11002338 new_tsec->sid = old_tsec->sid;
2339 new_tsec->osid = old_tsec->sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002340
Michael LeMay28eba5b2006-06-27 02:53:42 -07002341 /* Reset fs, key, and sock SIDs on execve. */
David Howellsa6f76f22008-11-14 10:39:24 +11002342 new_tsec->create_sid = 0;
2343 new_tsec->keycreate_sid = 0;
2344 new_tsec->sockcreate_sid = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002345
David Howellsa6f76f22008-11-14 10:39:24 +11002346 if (old_tsec->exec_sid) {
2347 new_tsec->sid = old_tsec->exec_sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002348 /* Reset exec SID on execve. */
David Howellsa6f76f22008-11-14 10:39:24 +11002349 new_tsec->exec_sid = 0;
Andy Lutomirski259e5e62012-04-12 16:47:50 -05002350
Stephen Smalley7b0d0b42014-08-04 13:36:49 -04002351 /* Fail on NNP or nosuid if not an allowed transition. */
2352 rc = check_nnp_nosuid(bprm, old_tsec, new_tsec);
2353 if (rc)
2354 return rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002355 } else {
2356 /* Check for a default transition on this program. */
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05002357 rc = security_transition_sid(&selinux_state, old_tsec->sid,
2358 isec->sid, SECCLASS_PROCESS, NULL,
Eric Paris652bb9b2011-02-01 11:05:40 -05002359 &new_tsec->sid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002360 if (rc)
2361 return rc;
Stephen Smalley7b0d0b42014-08-04 13:36:49 -04002362
2363 /*
2364 * Fallback to old SID on NNP or nosuid if not an allowed
2365 * transition.
2366 */
2367 rc = check_nnp_nosuid(bprm, old_tsec, new_tsec);
2368 if (rc)
2369 new_tsec->sid = old_tsec->sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002370 }
2371
Vivek Goyal43af5de2016-09-09 11:37:49 -04002372 ad.type = LSM_AUDIT_DATA_FILE;
2373 ad.u.file = bprm->file;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002374
David Howellsa6f76f22008-11-14 10:39:24 +11002375 if (new_tsec->sid == old_tsec->sid) {
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002376 rc = avc_has_perm(&selinux_state,
2377 old_tsec->sid, isec->sid,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002378 SECCLASS_FILE, FILE__EXECUTE_NO_TRANS, &ad);
2379 if (rc)
2380 return rc;
2381 } else {
2382 /* Check permissions for the transition. */
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002383 rc = avc_has_perm(&selinux_state,
2384 old_tsec->sid, new_tsec->sid,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002385 SECCLASS_PROCESS, PROCESS__TRANSITION, &ad);
2386 if (rc)
2387 return rc;
2388
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002389 rc = avc_has_perm(&selinux_state,
2390 new_tsec->sid, isec->sid,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002391 SECCLASS_FILE, FILE__ENTRYPOINT, &ad);
2392 if (rc)
2393 return rc;
2394
David Howellsa6f76f22008-11-14 10:39:24 +11002395 /* Check for shared state */
2396 if (bprm->unsafe & LSM_UNSAFE_SHARE) {
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002397 rc = avc_has_perm(&selinux_state,
2398 old_tsec->sid, new_tsec->sid,
David Howellsa6f76f22008-11-14 10:39:24 +11002399 SECCLASS_PROCESS, PROCESS__SHARE,
2400 NULL);
2401 if (rc)
2402 return -EPERM;
2403 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002404
David Howellsa6f76f22008-11-14 10:39:24 +11002405 /* Make sure that anyone attempting to ptrace over a task that
2406 * changes its SID has the appropriate permit */
Eric W. Biederman9227dd22017-01-23 17:26:31 +13002407 if (bprm->unsafe & LSM_UNSAFE_PTRACE) {
Stephen Smalleybe0554c2017-01-09 10:07:31 -05002408 u32 ptsid = ptrace_parent_sid();
David Howellsa6f76f22008-11-14 10:39:24 +11002409 if (ptsid != 0) {
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002410 rc = avc_has_perm(&selinux_state,
2411 ptsid, new_tsec->sid,
David Howellsa6f76f22008-11-14 10:39:24 +11002412 SECCLASS_PROCESS,
2413 PROCESS__PTRACE, NULL);
2414 if (rc)
2415 return -EPERM;
2416 }
2417 }
2418
2419 /* Clear any possibly unsafe personality bits on exec: */
2420 bprm->per_clear |= PER_CLEAR_ON_SETID;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002421
Linus Torvalds1da177e2005-04-16 15:20:36 -07002422 /* Enable secure mode for SIDs transitions unless
2423 the noatsecure permission is granted between
2424 the two SIDs, i.e. ahp returns 0. */
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002425 rc = avc_has_perm(&selinux_state,
2426 old_tsec->sid, new_tsec->sid,
Kees Cook62874c32017-07-18 15:25:25 -07002427 SECCLASS_PROCESS, PROCESS__NOATSECURE,
2428 NULL);
2429 bprm->secureexec |= !!rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002430 }
2431
Kees Cook62874c32017-07-18 15:25:25 -07002432 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002433}
2434
Al Viroc3c073f2012-08-21 22:32:06 -04002435static int match_file(const void *p, struct file *file, unsigned fd)
2436{
2437 return file_has_perm(p, file, file_to_av(file)) ? fd + 1 : 0;
2438}
2439
Linus Torvalds1da177e2005-04-16 15:20:36 -07002440/* Derived from fs/exec.c:flush_old_files. */
David Howells745ca242008-11-14 10:39:22 +11002441static inline void flush_unauthorized_files(const struct cred *cred,
2442 struct files_struct *files)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002443{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002444 struct file *file, *devnull = NULL;
Stephen Smalleyb20c8122006-09-25 23:32:03 -07002445 struct tty_struct *tty;
Peter Zijlstra24ec8392006-12-08 02:36:04 -08002446 int drop_tty = 0;
Al Viroc3c073f2012-08-21 22:32:06 -04002447 unsigned n;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002448
Peter Zijlstra24ec8392006-12-08 02:36:04 -08002449 tty = get_current_tty();
Linus Torvalds1da177e2005-04-16 15:20:36 -07002450 if (tty) {
Peter Hurley4a510962016-01-09 21:35:23 -08002451 spin_lock(&tty->files_lock);
Eric Paris37dd0bd2008-10-31 17:40:00 -04002452 if (!list_empty(&tty->tty_files)) {
Nick Piggind996b622010-08-18 04:37:36 +10002453 struct tty_file_private *file_priv;
Eric Paris37dd0bd2008-10-31 17:40:00 -04002454
Linus Torvalds1da177e2005-04-16 15:20:36 -07002455 /* Revalidate access to controlling tty.
David Howells13f8e982013-06-13 23:37:55 +01002456 Use file_path_has_perm on the tty path directly
2457 rather than using file_has_perm, as this particular
2458 open file may belong to another process and we are
2459 only interested in the inode-based check here. */
Nick Piggind996b622010-08-18 04:37:36 +10002460 file_priv = list_first_entry(&tty->tty_files,
2461 struct tty_file_private, list);
2462 file = file_priv->file;
David Howells13f8e982013-06-13 23:37:55 +01002463 if (file_path_has_perm(cred, file, FILE__READ | FILE__WRITE))
Peter Zijlstra24ec8392006-12-08 02:36:04 -08002464 drop_tty = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002465 }
Peter Hurley4a510962016-01-09 21:35:23 -08002466 spin_unlock(&tty->files_lock);
Alan Cox452a00d2008-10-13 10:39:13 +01002467 tty_kref_put(tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002468 }
Eric W. Biederman98a27ba2007-05-08 00:26:56 -07002469 /* Reset controlling tty. */
2470 if (drop_tty)
2471 no_tty();
Linus Torvalds1da177e2005-04-16 15:20:36 -07002472
2473 /* Revalidate access to inherited open files. */
Al Viroc3c073f2012-08-21 22:32:06 -04002474 n = iterate_fd(files, 0, match_file, cred);
2475 if (!n) /* none found? */
2476 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002477
Al Viroc3c073f2012-08-21 22:32:06 -04002478 devnull = dentry_open(&selinux_null, O_RDWR, cred);
Al Viro45525b22012-10-16 13:30:07 -04002479 if (IS_ERR(devnull))
2480 devnull = NULL;
2481 /* replace all the matching ones with this */
2482 do {
2483 replace_fd(n - 1, devnull, 0);
2484 } while ((n = iterate_fd(files, n, match_file, cred)) != 0);
2485 if (devnull)
Al Viroc3c073f2012-08-21 22:32:06 -04002486 fput(devnull);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002487}
2488
Linus Torvalds1da177e2005-04-16 15:20:36 -07002489/*
David Howellsa6f76f22008-11-14 10:39:24 +11002490 * Prepare a process for imminent new credential changes due to exec
Linus Torvalds1da177e2005-04-16 15:20:36 -07002491 */
David Howellsa6f76f22008-11-14 10:39:24 +11002492static void selinux_bprm_committing_creds(struct linux_binprm *bprm)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002493{
David Howellsa6f76f22008-11-14 10:39:24 +11002494 struct task_security_struct *new_tsec;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002495 struct rlimit *rlim, *initrlim;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002496 int rc, i;
2497
Casey Schaufler0c6cfa62018-09-21 17:17:16 -07002498 new_tsec = selinux_cred(bprm->cred);
David Howellsa6f76f22008-11-14 10:39:24 +11002499 if (new_tsec->sid == new_tsec->osid)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002500 return;
2501
2502 /* Close files for which the new task SID is not authorized. */
David Howellsa6f76f22008-11-14 10:39:24 +11002503 flush_unauthorized_files(bprm->cred, current->files);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002504
David Howellsa6f76f22008-11-14 10:39:24 +11002505 /* Always clear parent death signal on SID transitions. */
2506 current->pdeath_signal = 0;
2507
2508 /* Check whether the new SID can inherit resource limits from the old
2509 * SID. If not, reset all soft limits to the lower of the current
2510 * task's hard limit and the init task's soft limit.
2511 *
2512 * Note that the setting of hard limits (even to lower them) can be
2513 * controlled by the setrlimit check. The inclusion of the init task's
2514 * soft limit into the computation is to avoid resetting soft limits
2515 * higher than the default soft limit for cases where the default is
2516 * lower than the hard limit, e.g. RLIMIT_CORE or RLIMIT_STACK.
2517 */
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002518 rc = avc_has_perm(&selinux_state,
2519 new_tsec->osid, new_tsec->sid, SECCLASS_PROCESS,
David Howellsa6f76f22008-11-14 10:39:24 +11002520 PROCESS__RLIMITINH, NULL);
2521 if (rc) {
Oleg Nesteroveb2d55a2010-06-23 22:43:32 +02002522 /* protect against do_prlimit() */
2523 task_lock(current);
David Howellsa6f76f22008-11-14 10:39:24 +11002524 for (i = 0; i < RLIM_NLIMITS; i++) {
2525 rlim = current->signal->rlim + i;
2526 initrlim = init_task.signal->rlim + i;
2527 rlim->rlim_cur = min(rlim->rlim_max, initrlim->rlim_cur);
2528 }
Oleg Nesteroveb2d55a2010-06-23 22:43:32 +02002529 task_unlock(current);
Nicolas Pitrebaa73d92016-11-11 00:10:10 -05002530 if (IS_ENABLED(CONFIG_POSIX_TIMERS))
2531 update_rlimit_cpu(current, rlimit(RLIMIT_CPU));
David Howellsa6f76f22008-11-14 10:39:24 +11002532 }
2533}
2534
2535/*
2536 * Clean up the process immediately after the installation of new credentials
2537 * due to exec
2538 */
2539static void selinux_bprm_committed_creds(struct linux_binprm *bprm)
2540{
Casey Schaufler0c6cfa62018-09-21 17:17:16 -07002541 const struct task_security_struct *tsec = selinux_cred(current_cred());
David Howellsa6f76f22008-11-14 10:39:24 +11002542 struct itimerval itimer;
David Howellsa6f76f22008-11-14 10:39:24 +11002543 u32 osid, sid;
2544 int rc, i;
David Howellsa6f76f22008-11-14 10:39:24 +11002545
David Howellsa6f76f22008-11-14 10:39:24 +11002546 osid = tsec->osid;
2547 sid = tsec->sid;
2548
2549 if (sid == osid)
2550 return;
2551
2552 /* Check whether the new SID can inherit signal state from the old SID.
2553 * If not, clear itimers to avoid subsequent signal generation and
2554 * flush and unblock signals.
2555 *
2556 * This must occur _after_ the task SID has been updated so that any
2557 * kill done after the flush will be checked against the new SID.
2558 */
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002559 rc = avc_has_perm(&selinux_state,
2560 osid, sid, SECCLASS_PROCESS, PROCESS__SIGINH, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002561 if (rc) {
Nicolas Pitrebaa73d92016-11-11 00:10:10 -05002562 if (IS_ENABLED(CONFIG_POSIX_TIMERS)) {
2563 memset(&itimer, 0, sizeof itimer);
2564 for (i = 0; i < 3; i++)
2565 do_setitimer(i, &itimer, NULL);
2566 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002567 spin_lock_irq(&current->sighand->siglock);
Oleg Nesterov9e7c8f82015-06-04 16:22:16 -04002568 if (!fatal_signal_pending(current)) {
2569 flush_sigqueue(&current->pending);
2570 flush_sigqueue(&current->signal->shared_pending);
David Howells3bcac022009-04-29 13:45:05 +01002571 flush_signal_handlers(current, 1);
2572 sigemptyset(&current->blocked);
Oleg Nesterov9e7c8f82015-06-04 16:22:16 -04002573 recalc_sigpending();
David Howells3bcac022009-04-29 13:45:05 +01002574 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002575 spin_unlock_irq(&current->sighand->siglock);
2576 }
2577
David Howellsa6f76f22008-11-14 10:39:24 +11002578 /* Wake up the parent if it is waiting so that it can recheck
2579 * wait permission to the new task SID. */
Oleg Nesterovecd6de32009-04-29 16:02:24 +02002580 read_lock(&tasklist_lock);
Oleg Nesterov0b7570e2009-09-23 15:56:46 -07002581 __wake_up_parent(current, current->real_parent);
Oleg Nesterovecd6de32009-04-29 16:02:24 +02002582 read_unlock(&tasklist_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002583}
2584
2585/* superblock security operations */
2586
2587static int selinux_sb_alloc_security(struct super_block *sb)
2588{
2589 return superblock_alloc_security(sb);
2590}
2591
2592static void selinux_sb_free_security(struct super_block *sb)
2593{
2594 superblock_free_security(sb);
2595}
2596
Al Viro99dbbb52018-12-14 21:56:23 -05002597static inline int opt_len(const char *s)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002598{
Al Viro99dbbb52018-12-14 21:56:23 -05002599 bool open_quote = false;
2600 int len;
2601 char c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002602
Al Viro99dbbb52018-12-14 21:56:23 -05002603 for (len = 0; (c = s[len]) != '\0'; len++) {
2604 if (c == '"')
Cory Olmo3528a952006-09-29 01:58:44 -07002605 open_quote = !open_quote;
Al Viro99dbbb52018-12-14 21:56:23 -05002606 if (c == ',' && !open_quote)
2607 break;
2608 }
2609 return len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002610}
2611
Al Viro204cc0c2018-12-13 13:41:47 -05002612static int selinux_sb_eat_lsm_opts(char *options, void **mnt_opts)
Eric Paris026eb162011-03-03 16:09:14 -05002613{
Al Viro99dbbb52018-12-14 21:56:23 -05002614 char *from = options;
2615 char *to = options;
2616 bool first = true;
Al Viro5b400232018-12-12 20:13:29 -05002617
Al Viro99dbbb52018-12-14 21:56:23 -05002618 while (1) {
2619 int len = opt_len(from);
2620 int token, rc;
2621 char *arg = NULL;
2622
2623 token = match_opt_prefix(from, len, &arg);
2624
2625 if (token != Opt_error) {
2626 char *p, *q;
2627
2628 /* strip quotes */
2629 if (arg) {
2630 for (p = q = arg; p < from + len; p++) {
2631 char c = *p;
2632 if (c != '"')
2633 *q++ = c;
2634 }
2635 arg = kmemdup_nul(arg, q - arg, GFP_KERNEL);
2636 }
2637 rc = selinux_add_opt(token, arg, mnt_opts);
2638 if (unlikely(rc)) {
2639 kfree(arg);
2640 if (*mnt_opts) {
2641 selinux_free_mnt_opts(*mnt_opts);
2642 *mnt_opts = NULL;
2643 }
2644 return rc;
2645 }
2646 } else {
2647 if (!first) { // copy with preceding comma
2648 from--;
2649 len++;
2650 }
2651 if (to != from)
2652 memmove(to, from, len);
2653 to += len;
2654 first = false;
2655 }
2656 if (!from[len])
2657 break;
2658 from += len + 1;
2659 }
2660 *to = '\0';
2661 return 0;
Al Viro5b400232018-12-12 20:13:29 -05002662}
2663
Al Viro204cc0c2018-12-13 13:41:47 -05002664static int selinux_sb_remount(struct super_block *sb, void *mnt_opts)
Eric Paris026eb162011-03-03 16:09:14 -05002665{
Al Virobd323652018-12-13 15:04:59 -05002666 struct selinux_mnt_opts *opts = mnt_opts;
Eric Paris026eb162011-03-03 16:09:14 -05002667 struct superblock_security_struct *sbsec = sb->s_security;
Al Virobd323652018-12-13 15:04:59 -05002668 u32 sid;
2669 int rc;
Eric Paris026eb162011-03-03 16:09:14 -05002670
2671 if (!(sbsec->flags & SE_SBINITIALIZED))
2672 return 0;
2673
Al Viro204cc0c2018-12-13 13:41:47 -05002674 if (!opts)
Eric Paris026eb162011-03-03 16:09:14 -05002675 return 0;
2676
Al Virobd323652018-12-13 15:04:59 -05002677 if (opts->fscontext) {
2678 rc = parse_sid(sb, opts->fscontext, &sid);
2679 if (rc)
Al Viroc039bc32018-12-01 23:06:57 -05002680 return rc;
Al Virobd323652018-12-13 15:04:59 -05002681 if (bad_option(sbsec, FSCONTEXT_MNT, sbsec->sid, sid))
2682 goto out_bad_option;
Eric Paris026eb162011-03-03 16:09:14 -05002683 }
Al Virobd323652018-12-13 15:04:59 -05002684 if (opts->context) {
2685 rc = parse_sid(sb, opts->context, &sid);
2686 if (rc)
2687 return rc;
2688 if (bad_option(sbsec, CONTEXT_MNT, sbsec->mntpoint_sid, sid))
2689 goto out_bad_option;
2690 }
2691 if (opts->rootcontext) {
2692 struct inode_security_struct *root_isec;
2693 root_isec = backing_inode_security(sb->s_root);
2694 rc = parse_sid(sb, opts->rootcontext, &sid);
2695 if (rc)
2696 return rc;
2697 if (bad_option(sbsec, ROOTCONTEXT_MNT, root_isec->sid, sid))
2698 goto out_bad_option;
2699 }
2700 if (opts->defcontext) {
2701 rc = parse_sid(sb, opts->defcontext, &sid);
2702 if (rc)
2703 return rc;
2704 if (bad_option(sbsec, DEFCONTEXT_MNT, sbsec->def_sid, sid))
2705 goto out_bad_option;
Eric Paris026eb162011-03-03 16:09:14 -05002706 }
Al Viroc039bc32018-12-01 23:06:57 -05002707 return 0;
Eric Paris026eb162011-03-03 16:09:14 -05002708
Eric Paris026eb162011-03-03 16:09:14 -05002709out_bad_option:
peter enderborgc103a912018-06-12 10:09:03 +02002710 pr_warn("SELinux: unable to change security options "
Linus Torvalds29b1deb2013-12-15 11:17:45 -08002711 "during remount (dev %s, type=%s)\n", sb->s_id,
2712 sb->s_type->name);
Al Viroc039bc32018-12-01 23:06:57 -05002713 return -EINVAL;
Eric Paris026eb162011-03-03 16:09:14 -05002714}
2715
Al Viroa10d7c22018-12-05 11:58:35 -05002716static int selinux_sb_kern_mount(struct super_block *sb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002717{
David Howells88e67f32008-11-14 10:39:21 +11002718 const struct cred *cred = current_cred();
Thomas Liu2bf49692009-07-14 12:14:09 -04002719 struct common_audit_data ad;
James Morris74192242008-12-19 11:41:10 +11002720
Eric Paris50c205f2012-04-04 15:01:43 -04002721 ad.type = LSM_AUDIT_DATA_DENTRY;
Eric Parisa2694342011-04-25 13:10:27 -04002722 ad.u.dentry = sb->s_root;
David Howells88e67f32008-11-14 10:39:21 +11002723 return superblock_has_perm(cred, sb, FILESYSTEM__MOUNT, &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002724}
2725
David Howells726c3342006-06-23 02:02:58 -07002726static int selinux_sb_statfs(struct dentry *dentry)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002727{
David Howells88e67f32008-11-14 10:39:21 +11002728 const struct cred *cred = current_cred();
Thomas Liu2bf49692009-07-14 12:14:09 -04002729 struct common_audit_data ad;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002730
Eric Paris50c205f2012-04-04 15:01:43 -04002731 ad.type = LSM_AUDIT_DATA_DENTRY;
Eric Parisa2694342011-04-25 13:10:27 -04002732 ad.u.dentry = dentry->d_sb->s_root;
David Howells88e67f32008-11-14 10:39:21 +11002733 return superblock_has_perm(cred, dentry->d_sb, FILESYSTEM__GETATTR, &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002734}
2735
Al Viro808d4e32012-10-11 11:42:01 -04002736static int selinux_mount(const char *dev_name,
Al Viro8a04c432016-03-25 14:52:53 -04002737 const struct path *path,
Al Viro808d4e32012-10-11 11:42:01 -04002738 const char *type,
Eric Paris828dfe12008-04-17 13:17:49 -04002739 unsigned long flags,
2740 void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002741{
David Howells88e67f32008-11-14 10:39:21 +11002742 const struct cred *cred = current_cred();
Linus Torvalds1da177e2005-04-16 15:20:36 -07002743
2744 if (flags & MS_REMOUNT)
Al Virod8c95842011-12-07 18:16:57 -05002745 return superblock_has_perm(cred, path->dentry->d_sb,
Eric Paris828dfe12008-04-17 13:17:49 -04002746 FILESYSTEM__REMOUNT, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002747 else
Eric Paris2875fa02011-04-28 16:04:24 -04002748 return path_has_perm(cred, path, FILE__MOUNTON);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002749}
2750
2751static int selinux_umount(struct vfsmount *mnt, int flags)
2752{
David Howells88e67f32008-11-14 10:39:21 +11002753 const struct cred *cred = current_cred();
Linus Torvalds1da177e2005-04-16 15:20:36 -07002754
David Howells88e67f32008-11-14 10:39:21 +11002755 return superblock_has_perm(cred, mnt->mnt_sb,
Eric Paris828dfe12008-04-17 13:17:49 -04002756 FILESYSTEM__UNMOUNT, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002757}
2758
Al Viro0b520752018-12-23 16:02:47 -05002759static int selinux_fs_context_dup(struct fs_context *fc,
2760 struct fs_context *src_fc)
2761{
2762 const struct selinux_mnt_opts *src = src_fc->security;
2763 struct selinux_mnt_opts *opts;
2764
2765 if (!src)
2766 return 0;
2767
2768 fc->security = kzalloc(sizeof(struct selinux_mnt_opts), GFP_KERNEL);
2769 if (!fc->security)
2770 return -ENOMEM;
2771
2772 opts = fc->security;
2773
2774 if (src->fscontext) {
2775 opts->fscontext = kstrdup(src->fscontext, GFP_KERNEL);
2776 if (!opts->fscontext)
2777 return -ENOMEM;
2778 }
2779 if (src->context) {
2780 opts->context = kstrdup(src->context, GFP_KERNEL);
2781 if (!opts->context)
2782 return -ENOMEM;
2783 }
2784 if (src->rootcontext) {
2785 opts->rootcontext = kstrdup(src->rootcontext, GFP_KERNEL);
2786 if (!opts->rootcontext)
2787 return -ENOMEM;
2788 }
2789 if (src->defcontext) {
2790 opts->defcontext = kstrdup(src->defcontext, GFP_KERNEL);
2791 if (!opts->defcontext)
2792 return -ENOMEM;
2793 }
2794 return 0;
2795}
2796
David Howells442155c2018-11-01 23:07:24 +00002797static const struct fs_parameter_spec selinux_param_specs[] = {
2798 fsparam_string(CONTEXT_STR, Opt_context),
2799 fsparam_string(DEFCONTEXT_STR, Opt_defcontext),
2800 fsparam_string(FSCONTEXT_STR, Opt_fscontext),
2801 fsparam_string(ROOTCONTEXT_STR, Opt_rootcontext),
2802 fsparam_flag (SECLABEL_STR, Opt_seclabel),
2803 {}
2804};
2805
2806static const struct fs_parameter_description selinux_fs_parameters = {
2807 .name = "SELinux",
2808 .specs = selinux_param_specs,
2809};
2810
2811static int selinux_fs_context_parse_param(struct fs_context *fc,
2812 struct fs_parameter *param)
2813{
2814 struct fs_parse_result result;
2815 int opt, rc;
2816
2817 opt = fs_parse(fc, &selinux_fs_parameters, param, &result);
2818 if (opt < 0)
2819 return opt;
2820
2821 rc = selinux_add_opt(opt, param->string, &fc->security);
2822 if (!rc) {
2823 param->string = NULL;
2824 rc = 1;
2825 }
2826 return rc;
2827}
2828
Linus Torvalds1da177e2005-04-16 15:20:36 -07002829/* inode security operations */
2830
2831static int selinux_inode_alloc_security(struct inode *inode)
2832{
2833 return inode_alloc_security(inode);
2834}
2835
2836static void selinux_inode_free_security(struct inode *inode)
2837{
2838 inode_free_security(inode);
2839}
2840
David Quigleyd47be3d2013-05-22 12:50:34 -04002841static int selinux_dentry_init_security(struct dentry *dentry, int mode,
Al Viro4f3ccd72016-07-20 16:06:15 -04002842 const struct qstr *name, void **ctx,
David Quigleyd47be3d2013-05-22 12:50:34 -04002843 u32 *ctxlen)
2844{
David Quigleyd47be3d2013-05-22 12:50:34 -04002845 u32 newsid;
2846 int rc;
2847
Casey Schaufler0c6cfa62018-09-21 17:17:16 -07002848 rc = selinux_determine_inode_label(selinux_cred(current_cred()),
Vivek Goyalc957f6d2016-07-13 10:44:51 -04002849 d_inode(dentry->d_parent), name,
David Howellsc3c188b2015-07-10 17:19:58 -04002850 inode_mode_to_security_class(mode),
2851 &newsid);
2852 if (rc)
2853 return rc;
David Quigleyd47be3d2013-05-22 12:50:34 -04002854
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05002855 return security_sid_to_context(&selinux_state, newsid, (char **)ctx,
2856 ctxlen);
David Quigleyd47be3d2013-05-22 12:50:34 -04002857}
2858
Vivek Goyala518b0a2016-07-13 10:44:53 -04002859static int selinux_dentry_create_files_as(struct dentry *dentry, int mode,
2860 struct qstr *name,
2861 const struct cred *old,
2862 struct cred *new)
2863{
2864 u32 newsid;
2865 int rc;
2866 struct task_security_struct *tsec;
2867
Casey Schaufler0c6cfa62018-09-21 17:17:16 -07002868 rc = selinux_determine_inode_label(selinux_cred(old),
Vivek Goyala518b0a2016-07-13 10:44:53 -04002869 d_inode(dentry->d_parent), name,
2870 inode_mode_to_security_class(mode),
2871 &newsid);
2872 if (rc)
2873 return rc;
2874
Casey Schaufler0c6cfa62018-09-21 17:17:16 -07002875 tsec = selinux_cred(new);
Vivek Goyala518b0a2016-07-13 10:44:53 -04002876 tsec->create_sid = newsid;
2877 return 0;
2878}
2879
Stephen Smalley5e41ff92005-09-09 13:01:35 -07002880static int selinux_inode_init_security(struct inode *inode, struct inode *dir,
Tetsuo Handa95489062013-07-25 05:44:02 +09002881 const struct qstr *qstr,
2882 const char **name,
Eric Paris2a7dba32011-02-01 11:05:39 -05002883 void **value, size_t *len)
Stephen Smalley5e41ff92005-09-09 13:01:35 -07002884{
Casey Schaufler0c6cfa62018-09-21 17:17:16 -07002885 const struct task_security_struct *tsec = selinux_cred(current_cred());
Stephen Smalley5e41ff92005-09-09 13:01:35 -07002886 struct superblock_security_struct *sbsec;
Corentin LABBEc0d4f462017-10-04 20:32:17 +02002887 u32 newsid, clen;
Stephen Smalley5e41ff92005-09-09 13:01:35 -07002888 int rc;
Tetsuo Handa95489062013-07-25 05:44:02 +09002889 char *context;
Stephen Smalley5e41ff92005-09-09 13:01:35 -07002890
Stephen Smalley5e41ff92005-09-09 13:01:35 -07002891 sbsec = dir->i_sb->s_security;
Stephen Smalley5e41ff92005-09-09 13:01:35 -07002892
David Howells275bb412008-11-14 10:39:19 +11002893 newsid = tsec->create_sid;
2894
Casey Schaufler0c6cfa62018-09-21 17:17:16 -07002895 rc = selinux_determine_inode_label(selinux_cred(current_cred()),
David Howellsc3c188b2015-07-10 17:19:58 -04002896 dir, qstr,
2897 inode_mode_to_security_class(inode->i_mode),
2898 &newsid);
2899 if (rc)
2900 return rc;
Stephen Smalley5e41ff92005-09-09 13:01:35 -07002901
Eric Paris296fddf2006-09-25 23:32:00 -07002902 /* Possibly defer initialization to selinux_complete_init. */
David P. Quigley0d90a7e2009-01-16 09:22:02 -05002903 if (sbsec->flags & SE_SBINITIALIZED) {
Casey Schaufler80788c22018-09-21 17:19:11 -07002904 struct inode_security_struct *isec = selinux_inode(inode);
Eric Paris296fddf2006-09-25 23:32:00 -07002905 isec->sclass = inode_mode_to_security_class(inode->i_mode);
2906 isec->sid = newsid;
Andreas Gruenbacher6f3be9f2015-12-24 11:09:40 -05002907 isec->initialized = LABEL_INITIALIZED;
Eric Paris296fddf2006-09-25 23:32:00 -07002908 }
Stephen Smalley5e41ff92005-09-09 13:01:35 -07002909
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05002910 if (!selinux_state.initialized || !(sbsec->flags & SBLABEL_MNT))
Stephen Smalley25a74f32005-11-08 21:34:33 -08002911 return -EOPNOTSUPP;
2912
Tetsuo Handa95489062013-07-25 05:44:02 +09002913 if (name)
2914 *name = XATTR_SELINUX_SUFFIX;
Stephen Smalley570bc1c2005-09-09 13:01:43 -07002915
2916 if (value && len) {
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05002917 rc = security_sid_to_context_force(&selinux_state, newsid,
2918 &context, &clen);
Tetsuo Handa95489062013-07-25 05:44:02 +09002919 if (rc)
Stephen Smalley570bc1c2005-09-09 13:01:43 -07002920 return rc;
Stephen Smalley570bc1c2005-09-09 13:01:43 -07002921 *value = context;
2922 *len = clen;
2923 }
Stephen Smalley5e41ff92005-09-09 13:01:35 -07002924
Stephen Smalley5e41ff92005-09-09 13:01:35 -07002925 return 0;
2926}
2927
Al Viro4acdaf22011-07-26 01:42:34 -04002928static int selinux_inode_create(struct inode *dir, struct dentry *dentry, umode_t mode)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002929{
2930 return may_create(dir, dentry, SECCLASS_FILE);
2931}
2932
Linus Torvalds1da177e2005-04-16 15:20:36 -07002933static int selinux_inode_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry)
2934{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002935 return may_link(dir, old_dentry, MAY_LINK);
2936}
2937
Linus Torvalds1da177e2005-04-16 15:20:36 -07002938static int selinux_inode_unlink(struct inode *dir, struct dentry *dentry)
2939{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002940 return may_link(dir, dentry, MAY_UNLINK);
2941}
2942
2943static int selinux_inode_symlink(struct inode *dir, struct dentry *dentry, const char *name)
2944{
2945 return may_create(dir, dentry, SECCLASS_LNK_FILE);
2946}
2947
Al Viro18bb1db2011-07-26 01:41:39 -04002948static int selinux_inode_mkdir(struct inode *dir, struct dentry *dentry, umode_t mask)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002949{
2950 return may_create(dir, dentry, SECCLASS_DIR);
2951}
2952
Linus Torvalds1da177e2005-04-16 15:20:36 -07002953static int selinux_inode_rmdir(struct inode *dir, struct dentry *dentry)
2954{
2955 return may_link(dir, dentry, MAY_RMDIR);
2956}
2957
Al Viro1a67aaf2011-07-26 01:52:52 -04002958static int selinux_inode_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002959{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002960 return may_create(dir, dentry, inode_mode_to_security_class(mode));
2961}
2962
Linus Torvalds1da177e2005-04-16 15:20:36 -07002963static int selinux_inode_rename(struct inode *old_inode, struct dentry *old_dentry,
Eric Paris828dfe12008-04-17 13:17:49 -04002964 struct inode *new_inode, struct dentry *new_dentry)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002965{
2966 return may_rename(old_inode, old_dentry, new_inode, new_dentry);
2967}
2968
Linus Torvalds1da177e2005-04-16 15:20:36 -07002969static int selinux_inode_readlink(struct dentry *dentry)
2970{
David Howells88e67f32008-11-14 10:39:21 +11002971 const struct cred *cred = current_cred();
2972
Eric Paris2875fa02011-04-28 16:04:24 -04002973 return dentry_has_perm(cred, dentry, FILE__READ);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002974}
2975
NeilBrownbda0be72015-03-23 13:37:39 +11002976static int selinux_inode_follow_link(struct dentry *dentry, struct inode *inode,
2977 bool rcu)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002978{
David Howells88e67f32008-11-14 10:39:21 +11002979 const struct cred *cred = current_cred();
NeilBrownbda0be72015-03-23 13:37:39 +11002980 struct common_audit_data ad;
2981 struct inode_security_struct *isec;
2982 u32 sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002983
NeilBrownbda0be72015-03-23 13:37:39 +11002984 validate_creds(cred);
2985
2986 ad.type = LSM_AUDIT_DATA_DENTRY;
2987 ad.u.dentry = dentry;
2988 sid = cred_sid(cred);
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -05002989 isec = inode_security_rcu(inode, rcu);
2990 if (IS_ERR(isec))
2991 return PTR_ERR(isec);
NeilBrownbda0be72015-03-23 13:37:39 +11002992
Stephen Smalleye46e01e2018-12-12 10:10:56 -05002993 return avc_has_perm(&selinux_state,
2994 sid, isec->sid, isec->sclass, FILE__READ, &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002995}
2996
Eric Parisd4cf970d2012-04-04 15:01:42 -04002997static noinline int audit_inode_permission(struct inode *inode,
2998 u32 perms, u32 audited, u32 denied,
Stephen Smalley626b9742014-04-29 11:29:04 -07002999 int result,
Eric Parisd4cf970d2012-04-04 15:01:42 -04003000 unsigned flags)
3001{
3002 struct common_audit_data ad;
Casey Schaufler80788c22018-09-21 17:19:11 -07003003 struct inode_security_struct *isec = selinux_inode(inode);
Eric Parisd4cf970d2012-04-04 15:01:42 -04003004 int rc;
3005
Eric Paris50c205f2012-04-04 15:01:43 -04003006 ad.type = LSM_AUDIT_DATA_INODE;
Eric Parisd4cf970d2012-04-04 15:01:42 -04003007 ad.u.inode = inode;
3008
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003009 rc = slow_avc_audit(&selinux_state,
3010 current_sid(), isec->sid, isec->sclass, perms,
Stephen Smalley626b9742014-04-29 11:29:04 -07003011 audited, denied, result, &ad, flags);
Eric Parisd4cf970d2012-04-04 15:01:42 -04003012 if (rc)
3013 return rc;
3014 return 0;
3015}
3016
Al Viroe74f71e2011-06-20 19:38:15 -04003017static int selinux_inode_permission(struct inode *inode, int mask)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003018{
David Howells88e67f32008-11-14 10:39:21 +11003019 const struct cred *cred = current_cred();
Eric Parisb782e0a2010-07-23 11:44:03 -04003020 u32 perms;
3021 bool from_access;
Al Virocf1dd1d2011-06-20 19:44:08 -04003022 unsigned flags = mask & MAY_NOT_BLOCK;
Eric Paris2e334052012-04-04 15:01:42 -04003023 struct inode_security_struct *isec;
3024 u32 sid;
3025 struct av_decision avd;
3026 int rc, rc2;
3027 u32 audited, denied;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003028
Eric Parisb782e0a2010-07-23 11:44:03 -04003029 from_access = mask & MAY_ACCESS;
Eric Parisd09ca732010-07-23 11:43:57 -04003030 mask &= (MAY_READ|MAY_WRITE|MAY_EXEC|MAY_APPEND);
3031
Eric Parisb782e0a2010-07-23 11:44:03 -04003032 /* No permission to check. Existence test. */
3033 if (!mask)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003034 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003035
Eric Paris2e334052012-04-04 15:01:42 -04003036 validate_creds(cred);
Eric Parisb782e0a2010-07-23 11:44:03 -04003037
Eric Paris2e334052012-04-04 15:01:42 -04003038 if (unlikely(IS_PRIVATE(inode)))
3039 return 0;
Eric Parisb782e0a2010-07-23 11:44:03 -04003040
3041 perms = file_mask_to_av(inode->i_mode, mask);
3042
Eric Paris2e334052012-04-04 15:01:42 -04003043 sid = cred_sid(cred);
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -05003044 isec = inode_security_rcu(inode, flags & MAY_NOT_BLOCK);
3045 if (IS_ERR(isec))
3046 return PTR_ERR(isec);
Eric Paris2e334052012-04-04 15:01:42 -04003047
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003048 rc = avc_has_perm_noaudit(&selinux_state,
Stephen Smalley3a28cff2018-12-12 10:10:55 -05003049 sid, isec->sid, isec->sclass, perms,
3050 (flags & MAY_NOT_BLOCK) ? AVC_NONBLOCKING : 0,
3051 &avd);
Eric Paris2e334052012-04-04 15:01:42 -04003052 audited = avc_audit_required(perms, &avd, rc,
3053 from_access ? FILE__AUDIT_ACCESS : 0,
3054 &denied);
3055 if (likely(!audited))
3056 return rc;
3057
Stephen Smalley626b9742014-04-29 11:29:04 -07003058 rc2 = audit_inode_permission(inode, perms, audited, denied, rc, flags);
Eric Paris2e334052012-04-04 15:01:42 -04003059 if (rc2)
3060 return rc2;
3061 return rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003062}
3063
3064static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr)
3065{
David Howells88e67f32008-11-14 10:39:21 +11003066 const struct cred *cred = current_cred();
Stephen Smalleyccb54472017-05-12 12:41:24 -04003067 struct inode *inode = d_backing_inode(dentry);
Amerigo Wangbc6a6002009-08-20 19:29:02 -07003068 unsigned int ia_valid = iattr->ia_valid;
Eric Paris95dbf732012-04-04 13:45:34 -04003069 __u32 av = FILE__WRITE;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003070
Amerigo Wangbc6a6002009-08-20 19:29:02 -07003071 /* ATTR_FORCE is just used for ATTR_KILL_S[UG]ID. */
3072 if (ia_valid & ATTR_FORCE) {
3073 ia_valid &= ~(ATTR_KILL_SUID | ATTR_KILL_SGID | ATTR_MODE |
3074 ATTR_FORCE);
3075 if (!ia_valid)
3076 return 0;
3077 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003078
Amerigo Wangbc6a6002009-08-20 19:29:02 -07003079 if (ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID |
3080 ATTR_ATIME_SET | ATTR_MTIME_SET | ATTR_TIMES_SET))
Eric Paris2875fa02011-04-28 16:04:24 -04003081 return dentry_has_perm(cred, dentry, FILE__SETATTR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003082
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05003083 if (selinux_policycap_openperm() &&
Stephen Smalleyccb54472017-05-12 12:41:24 -04003084 inode->i_sb->s_magic != SOCKFS_MAGIC &&
3085 (ia_valid & ATTR_SIZE) &&
3086 !(ia_valid & ATTR_FILE))
Eric Paris95dbf732012-04-04 13:45:34 -04003087 av |= FILE__OPEN;
3088
3089 return dentry_has_perm(cred, dentry, av);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003090}
3091
Al Viro3f7036a2015-03-08 19:28:30 -04003092static int selinux_inode_getattr(const struct path *path)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003093{
Al Viro3f7036a2015-03-08 19:28:30 -04003094 return path_has_perm(current_cred(), path, FILE__GETATTR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003095}
3096
Stephen Smalleydb590002017-04-20 11:31:30 -04003097static bool has_cap_mac_admin(bool audit)
3098{
3099 const struct cred *cred = current_cred();
Micah Mortonc1a85a02019-01-07 16:10:53 -08003100 unsigned int opts = audit ? CAP_OPT_NONE : CAP_OPT_NOAUDIT;
Stephen Smalleydb590002017-04-20 11:31:30 -04003101
Micah Mortonc1a85a02019-01-07 16:10:53 -08003102 if (cap_capable(cred, &init_user_ns, CAP_MAC_ADMIN, opts))
Stephen Smalleydb590002017-04-20 11:31:30 -04003103 return false;
Micah Mortonc1a85a02019-01-07 16:10:53 -08003104 if (cred_has_capability(cred, CAP_MAC_ADMIN, opts, true))
Stephen Smalleydb590002017-04-20 11:31:30 -04003105 return false;
3106 return true;
3107}
3108
David Howells8f0cfa52008-04-29 00:59:41 -07003109static int selinux_inode_setxattr(struct dentry *dentry, const char *name,
3110 const void *value, size_t size, int flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003111{
David Howellsc6f493d2015-03-17 22:26:22 +00003112 struct inode *inode = d_backing_inode(dentry);
Paul Moore20cdef82016-04-04 14:14:42 -04003113 struct inode_security_struct *isec;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003114 struct superblock_security_struct *sbsec;
Thomas Liu2bf49692009-07-14 12:14:09 -04003115 struct common_audit_data ad;
David Howells275bb412008-11-14 10:39:19 +11003116 u32 newsid, sid = current_sid();
Linus Torvalds1da177e2005-04-16 15:20:36 -07003117 int rc = 0;
3118
Eric W. Biederman6b240302017-10-02 09:38:20 -05003119 if (strcmp(name, XATTR_NAME_SELINUX)) {
3120 rc = cap_inode_setxattr(dentry, name, value, size, flags);
3121 if (rc)
3122 return rc;
3123
3124 /* Not an attribute we recognize, so just check the
3125 ordinary setattr permission. */
3126 return dentry_has_perm(current_cred(), dentry, FILE__SETATTR);
3127 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003128
3129 sbsec = inode->i_sb->s_security;
Eric Paris12f348b2012-10-09 10:56:25 -04003130 if (!(sbsec->flags & SBLABEL_MNT))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003131 return -EOPNOTSUPP;
3132
Serge E. Hallyn2e149672011-03-23 16:43:26 -07003133 if (!inode_owner_or_capable(inode))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003134 return -EPERM;
3135
Eric Paris50c205f2012-04-04 15:01:43 -04003136 ad.type = LSM_AUDIT_DATA_DENTRY;
Eric Parisa2694342011-04-25 13:10:27 -04003137 ad.u.dentry = dentry;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003138
Paul Moore20cdef82016-04-04 14:14:42 -04003139 isec = backing_inode_security(dentry);
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003140 rc = avc_has_perm(&selinux_state,
3141 sid, isec->sid, isec->sclass,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003142 FILE__RELABELFROM, &ad);
3143 if (rc)
3144 return rc;
3145
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05003146 rc = security_context_to_sid(&selinux_state, value, size, &newsid,
3147 GFP_KERNEL);
Stephen Smalley12b29f32008-05-07 13:03:20 -04003148 if (rc == -EINVAL) {
Stephen Smalleydb590002017-04-20 11:31:30 -04003149 if (!has_cap_mac_admin(true)) {
Eric Parisd6ea83e2012-04-04 13:45:49 -04003150 struct audit_buffer *ab;
3151 size_t audit_size;
Eric Parisd6ea83e2012-04-04 13:45:49 -04003152
3153 /* We strip a nul only if it is at the end, otherwise the
3154 * context contains a nul and we should audit that */
Al Viroe3fea3f2012-06-09 08:15:16 +01003155 if (value) {
Colin Ian Kingadd24372017-10-14 13:46:55 +01003156 const char *str = value;
3157
Al Viroe3fea3f2012-06-09 08:15:16 +01003158 if (str[size - 1] == '\0')
3159 audit_size = size - 1;
3160 else
3161 audit_size = size;
3162 } else {
Al Viroe3fea3f2012-06-09 08:15:16 +01003163 audit_size = 0;
3164 }
Richard Guy Briggscdfb6b32018-05-12 21:58:20 -04003165 ab = audit_log_start(audit_context(),
3166 GFP_ATOMIC, AUDIT_SELINUX_ERR);
Eric Parisd6ea83e2012-04-04 13:45:49 -04003167 audit_log_format(ab, "op=setxattr invalid_context=");
3168 audit_log_n_untrustedstring(ab, value, audit_size);
3169 audit_log_end(ab);
3170
Stephen Smalley12b29f32008-05-07 13:03:20 -04003171 return rc;
Eric Parisd6ea83e2012-04-04 13:45:49 -04003172 }
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05003173 rc = security_context_to_sid_force(&selinux_state, value,
3174 size, &newsid);
Stephen Smalley12b29f32008-05-07 13:03:20 -04003175 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003176 if (rc)
3177 return rc;
3178
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003179 rc = avc_has_perm(&selinux_state,
3180 sid, newsid, isec->sclass,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003181 FILE__RELABELTO, &ad);
3182 if (rc)
3183 return rc;
3184
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05003185 rc = security_validate_transition(&selinux_state, isec->sid, newsid,
3186 sid, isec->sclass);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003187 if (rc)
3188 return rc;
3189
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003190 return avc_has_perm(&selinux_state,
3191 newsid,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003192 sbsec->sid,
3193 SECCLASS_FILESYSTEM,
3194 FILESYSTEM__ASSOCIATE,
3195 &ad);
3196}
3197
David Howells8f0cfa52008-04-29 00:59:41 -07003198static void selinux_inode_post_setxattr(struct dentry *dentry, const char *name,
Eric Parisf5269712008-05-14 11:27:45 -04003199 const void *value, size_t size,
David Howells8f0cfa52008-04-29 00:59:41 -07003200 int flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003201{
David Howellsc6f493d2015-03-17 22:26:22 +00003202 struct inode *inode = d_backing_inode(dentry);
Paul Moore20cdef82016-04-04 14:14:42 -04003203 struct inode_security_struct *isec;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003204 u32 newsid;
3205 int rc;
3206
3207 if (strcmp(name, XATTR_NAME_SELINUX)) {
3208 /* Not an attribute we recognize, so nothing to do. */
3209 return;
3210 }
3211
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05003212 rc = security_context_to_sid_force(&selinux_state, value, size,
3213 &newsid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003214 if (rc) {
peter enderborgc103a912018-06-12 10:09:03 +02003215 pr_err("SELinux: unable to map context to SID"
Stephen Smalley12b29f32008-05-07 13:03:20 -04003216 "for (%s, %lu), rc=%d\n",
3217 inode->i_sb->s_id, inode->i_ino, -rc);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003218 return;
3219 }
3220
Paul Moore20cdef82016-04-04 14:14:42 -04003221 isec = backing_inode_security(dentry);
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01003222 spin_lock(&isec->lock);
David Quigleyaa9c2662013-05-22 12:50:44 -04003223 isec->sclass = inode_mode_to_security_class(inode->i_mode);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003224 isec->sid = newsid;
Andreas Gruenbacher6f3be9f2015-12-24 11:09:40 -05003225 isec->initialized = LABEL_INITIALIZED;
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01003226 spin_unlock(&isec->lock);
David Quigleyaa9c2662013-05-22 12:50:44 -04003227
Linus Torvalds1da177e2005-04-16 15:20:36 -07003228 return;
3229}
3230
David Howells8f0cfa52008-04-29 00:59:41 -07003231static int selinux_inode_getxattr(struct dentry *dentry, const char *name)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003232{
David Howells88e67f32008-11-14 10:39:21 +11003233 const struct cred *cred = current_cred();
3234
Eric Paris2875fa02011-04-28 16:04:24 -04003235 return dentry_has_perm(cred, dentry, FILE__GETATTR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003236}
3237
Eric Paris828dfe12008-04-17 13:17:49 -04003238static int selinux_inode_listxattr(struct dentry *dentry)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003239{
David Howells88e67f32008-11-14 10:39:21 +11003240 const struct cred *cred = current_cred();
3241
Eric Paris2875fa02011-04-28 16:04:24 -04003242 return dentry_has_perm(cred, dentry, FILE__GETATTR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003243}
3244
David Howells8f0cfa52008-04-29 00:59:41 -07003245static int selinux_inode_removexattr(struct dentry *dentry, const char *name)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003246{
Eric W. Biederman6b240302017-10-02 09:38:20 -05003247 if (strcmp(name, XATTR_NAME_SELINUX)) {
3248 int rc = cap_inode_removexattr(dentry, name);
3249 if (rc)
3250 return rc;
3251
3252 /* Not an attribute we recognize, so just check the
3253 ordinary setattr permission. */
3254 return dentry_has_perm(current_cred(), dentry, FILE__SETATTR);
3255 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003256
3257 /* No one is allowed to remove a SELinux security label.
3258 You can change the label, but all data must be labeled. */
3259 return -EACCES;
3260}
3261
James Morrisd381d8a2005-10-30 14:59:22 -08003262/*
Stephen Smalleyabc69bb2008-05-21 14:16:12 -04003263 * Copy the inode security context value to the user.
James Morrisd381d8a2005-10-30 14:59:22 -08003264 *
3265 * Permission check is handled by selinux_inode_getxattr hook.
3266 */
Andreas Gruenbacherea861df2015-12-24 11:09:39 -05003267static int selinux_inode_getsecurity(struct inode *inode, const char *name, void **buffer, bool alloc)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003268{
David P. Quigley42492592008-02-04 22:29:39 -08003269 u32 size;
3270 int error;
3271 char *context = NULL;
Paul Moore20cdef82016-04-04 14:14:42 -04003272 struct inode_security_struct *isec;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003273
Dustin Kirkland8c8570f2005-11-03 17:15:16 +00003274 if (strcmp(name, XATTR_SELINUX_SUFFIX))
3275 return -EOPNOTSUPP;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003276
Stephen Smalleyabc69bb2008-05-21 14:16:12 -04003277 /*
3278 * If the caller has CAP_MAC_ADMIN, then get the raw context
3279 * value even if it is not defined by current policy; otherwise,
3280 * use the in-core value under current policy.
3281 * Use the non-auditing forms of the permission checks since
3282 * getxattr may be called by unprivileged processes commonly
3283 * and lack of permission just means that we fall back to the
3284 * in-core context value, not a denial.
3285 */
Paul Moore20cdef82016-04-04 14:14:42 -04003286 isec = inode_security(inode);
Stephen Smalleydb590002017-04-20 11:31:30 -04003287 if (has_cap_mac_admin(false))
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05003288 error = security_sid_to_context_force(&selinux_state,
3289 isec->sid, &context,
Stephen Smalleyabc69bb2008-05-21 14:16:12 -04003290 &size);
3291 else
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05003292 error = security_sid_to_context(&selinux_state, isec->sid,
3293 &context, &size);
David P. Quigley42492592008-02-04 22:29:39 -08003294 if (error)
3295 return error;
3296 error = size;
3297 if (alloc) {
3298 *buffer = context;
3299 goto out_nofree;
3300 }
3301 kfree(context);
3302out_nofree:
3303 return error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003304}
3305
3306static int selinux_inode_setsecurity(struct inode *inode, const char *name,
Eric Paris828dfe12008-04-17 13:17:49 -04003307 const void *value, size_t size, int flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003308{
Paul Moore2c971652016-04-19 16:36:28 -04003309 struct inode_security_struct *isec = inode_security_novalidate(inode);
Ondrej Mosnacek53e0c2a2018-12-21 21:18:53 +01003310 struct superblock_security_struct *sbsec = inode->i_sb->s_security;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003311 u32 newsid;
3312 int rc;
3313
3314 if (strcmp(name, XATTR_SELINUX_SUFFIX))
3315 return -EOPNOTSUPP;
3316
Ondrej Mosnacek53e0c2a2018-12-21 21:18:53 +01003317 if (!(sbsec->flags & SBLABEL_MNT))
3318 return -EOPNOTSUPP;
3319
Linus Torvalds1da177e2005-04-16 15:20:36 -07003320 if (!value || !size)
3321 return -EACCES;
3322
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05003323 rc = security_context_to_sid(&selinux_state, value, size, &newsid,
3324 GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003325 if (rc)
3326 return rc;
3327
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01003328 spin_lock(&isec->lock);
David Quigleyaa9c2662013-05-22 12:50:44 -04003329 isec->sclass = inode_mode_to_security_class(inode->i_mode);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003330 isec->sid = newsid;
Andreas Gruenbacher6f3be9f2015-12-24 11:09:40 -05003331 isec->initialized = LABEL_INITIALIZED;
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01003332 spin_unlock(&isec->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003333 return 0;
3334}
3335
3336static int selinux_inode_listsecurity(struct inode *inode, char *buffer, size_t buffer_size)
3337{
3338 const int len = sizeof(XATTR_NAME_SELINUX);
3339 if (buffer && len <= buffer_size)
3340 memcpy(buffer, XATTR_NAME_SELINUX, len);
3341 return len;
3342}
3343
Andreas Gruenbacherd6335d72015-12-24 11:09:39 -05003344static void selinux_inode_getsecid(struct inode *inode, u32 *secid)
Ahmed S. Darwish713a04ae2008-03-01 21:52:30 +02003345{
Andreas Gruenbachere817c2f2016-02-18 12:04:08 +01003346 struct inode_security_struct *isec = inode_security_novalidate(inode);
Ahmed S. Darwish713a04ae2008-03-01 21:52:30 +02003347 *secid = isec->sid;
3348}
3349
Vivek Goyal56909eb2016-07-13 10:44:48 -04003350static int selinux_inode_copy_up(struct dentry *src, struct cred **new)
3351{
3352 u32 sid;
3353 struct task_security_struct *tsec;
3354 struct cred *new_creds = *new;
3355
3356 if (new_creds == NULL) {
3357 new_creds = prepare_creds();
3358 if (!new_creds)
3359 return -ENOMEM;
3360 }
3361
Casey Schaufler0c6cfa62018-09-21 17:17:16 -07003362 tsec = selinux_cred(new_creds);
Vivek Goyal56909eb2016-07-13 10:44:48 -04003363 /* Get label from overlay inode and set it in create_sid */
3364 selinux_inode_getsecid(d_inode(src), &sid);
3365 tsec->create_sid = sid;
3366 *new = new_creds;
3367 return 0;
3368}
3369
Vivek Goyal19472b62016-07-13 10:44:50 -04003370static int selinux_inode_copy_up_xattr(const char *name)
3371{
3372 /* The copy_up hook above sets the initial context on an inode, but we
3373 * don't then want to overwrite it by blindly copying all the lower
3374 * xattrs up. Instead, we have to filter out SELinux-related xattrs.
3375 */
3376 if (strcmp(name, XATTR_NAME_SELINUX) == 0)
3377 return 1; /* Discard */
3378 /*
3379 * Any other attribute apart from SELINUX is not claimed, supported
3380 * by selinux.
3381 */
3382 return -EOPNOTSUPP;
3383}
3384
Linus Torvalds1da177e2005-04-16 15:20:36 -07003385/* file security operations */
3386
Yuichi Nakamura788e7dd2007-09-14 09:27:07 +09003387static int selinux_revalidate_file_permission(struct file *file, int mask)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003388{
David Howells88e67f32008-11-14 10:39:21 +11003389 const struct cred *cred = current_cred();
Al Viro496ad9a2013-01-23 17:07:38 -05003390 struct inode *inode = file_inode(file);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003391
Linus Torvalds1da177e2005-04-16 15:20:36 -07003392 /* file_mask_to_av won't add FILE__WRITE if MAY_APPEND is set */
3393 if ((file->f_flags & O_APPEND) && (mask & MAY_WRITE))
3394 mask |= MAY_APPEND;
3395
Paul Moore389fb8002009-03-27 17:10:34 -04003396 return file_has_perm(cred, file,
3397 file_mask_to_av(inode->i_mode, mask));
Linus Torvalds1da177e2005-04-16 15:20:36 -07003398}
3399
Yuichi Nakamura788e7dd2007-09-14 09:27:07 +09003400static int selinux_file_permission(struct file *file, int mask)
3401{
Al Viro496ad9a2013-01-23 17:07:38 -05003402 struct inode *inode = file_inode(file);
Casey Schauflerbb6c6b02018-09-21 17:22:32 -07003403 struct file_security_struct *fsec = selinux_file(file);
Andreas Gruenbacherb1973672016-01-05 23:12:33 +01003404 struct inode_security_struct *isec;
Stephen Smalley20dda182009-06-22 14:54:53 -04003405 u32 sid = current_sid();
3406
Paul Moore389fb8002009-03-27 17:10:34 -04003407 if (!mask)
Yuichi Nakamura788e7dd2007-09-14 09:27:07 +09003408 /* No permission to check. Existence test. */
3409 return 0;
Yuichi Nakamura788e7dd2007-09-14 09:27:07 +09003410
Andreas Gruenbacherb1973672016-01-05 23:12:33 +01003411 isec = inode_security(inode);
Stephen Smalley20dda182009-06-22 14:54:53 -04003412 if (sid == fsec->sid && fsec->isid == isec->sid &&
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003413 fsec->pseqno == avc_policy_seqno(&selinux_state))
Eric Paris83d49852012-04-04 13:45:40 -04003414 /* No change since file_open check. */
Stephen Smalley20dda182009-06-22 14:54:53 -04003415 return 0;
3416
Yuichi Nakamura788e7dd2007-09-14 09:27:07 +09003417 return selinux_revalidate_file_permission(file, mask);
3418}
3419
Linus Torvalds1da177e2005-04-16 15:20:36 -07003420static int selinux_file_alloc_security(struct file *file)
3421{
3422 return file_alloc_security(file);
3423}
3424
Jeff Vander Stoepfa1aa142015-07-10 17:19:56 -04003425/*
3426 * Check whether a task has the ioctl permission and cmd
3427 * operation to an inode.
3428 */
Geliang Tang1d2a1682015-10-21 17:44:27 -04003429static int ioctl_has_perm(const struct cred *cred, struct file *file,
Jeff Vander Stoepfa1aa142015-07-10 17:19:56 -04003430 u32 requested, u16 cmd)
3431{
3432 struct common_audit_data ad;
Casey Schauflerbb6c6b02018-09-21 17:22:32 -07003433 struct file_security_struct *fsec = selinux_file(file);
Jeff Vander Stoepfa1aa142015-07-10 17:19:56 -04003434 struct inode *inode = file_inode(file);
Paul Moore20cdef82016-04-04 14:14:42 -04003435 struct inode_security_struct *isec;
Jeff Vander Stoepfa1aa142015-07-10 17:19:56 -04003436 struct lsm_ioctlop_audit ioctl;
3437 u32 ssid = cred_sid(cred);
3438 int rc;
3439 u8 driver = cmd >> 8;
3440 u8 xperm = cmd & 0xff;
3441
3442 ad.type = LSM_AUDIT_DATA_IOCTL_OP;
3443 ad.u.op = &ioctl;
3444 ad.u.op->cmd = cmd;
3445 ad.u.op->path = file->f_path;
3446
3447 if (ssid != fsec->sid) {
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003448 rc = avc_has_perm(&selinux_state,
3449 ssid, fsec->sid,
Jeff Vander Stoepfa1aa142015-07-10 17:19:56 -04003450 SECCLASS_FD,
3451 FD__USE,
3452 &ad);
3453 if (rc)
3454 goto out;
3455 }
3456
3457 if (unlikely(IS_PRIVATE(inode)))
3458 return 0;
3459
Paul Moore20cdef82016-04-04 14:14:42 -04003460 isec = inode_security(inode);
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003461 rc = avc_has_extended_perms(&selinux_state,
3462 ssid, isec->sid, isec->sclass,
3463 requested, driver, xperm, &ad);
Jeff Vander Stoepfa1aa142015-07-10 17:19:56 -04003464out:
3465 return rc;
3466}
3467
Linus Torvalds1da177e2005-04-16 15:20:36 -07003468static int selinux_file_ioctl(struct file *file, unsigned int cmd,
3469 unsigned long arg)
3470{
David Howells88e67f32008-11-14 10:39:21 +11003471 const struct cred *cred = current_cred();
Eric Paris0b24dcb2011-02-25 15:39:20 -05003472 int error = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003473
Eric Paris0b24dcb2011-02-25 15:39:20 -05003474 switch (cmd) {
3475 case FIONREAD:
3476 /* fall through */
3477 case FIBMAP:
3478 /* fall through */
3479 case FIGETBSZ:
3480 /* fall through */
Al Viro2f99c362012-03-23 16:04:05 -04003481 case FS_IOC_GETFLAGS:
Eric Paris0b24dcb2011-02-25 15:39:20 -05003482 /* fall through */
Al Viro2f99c362012-03-23 16:04:05 -04003483 case FS_IOC_GETVERSION:
Eric Paris0b24dcb2011-02-25 15:39:20 -05003484 error = file_has_perm(cred, file, FILE__GETATTR);
3485 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003486
Al Viro2f99c362012-03-23 16:04:05 -04003487 case FS_IOC_SETFLAGS:
Eric Paris0b24dcb2011-02-25 15:39:20 -05003488 /* fall through */
Al Viro2f99c362012-03-23 16:04:05 -04003489 case FS_IOC_SETVERSION:
Eric Paris0b24dcb2011-02-25 15:39:20 -05003490 error = file_has_perm(cred, file, FILE__SETATTR);
3491 break;
3492
3493 /* sys_ioctl() checks */
3494 case FIONBIO:
3495 /* fall through */
3496 case FIOASYNC:
3497 error = file_has_perm(cred, file, 0);
3498 break;
3499
3500 case KDSKBENT:
3501 case KDSKBSENT:
Eric Paris6a9de492012-01-03 12:25:14 -05003502 error = cred_has_capability(cred, CAP_SYS_TTY_CONFIG,
Micah Mortonc1a85a02019-01-07 16:10:53 -08003503 CAP_OPT_NONE, true);
Eric Paris0b24dcb2011-02-25 15:39:20 -05003504 break;
3505
3506 /* default case assumes that the command will go
3507 * to the file's ioctl() function.
3508 */
3509 default:
Jeff Vander Stoepfa1aa142015-07-10 17:19:56 -04003510 error = ioctl_has_perm(cred, file, FILE__IOCTL, (u16) cmd);
Eric Paris0b24dcb2011-02-25 15:39:20 -05003511 }
3512 return error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003513}
3514
Stephen Smalleyfcaaade2010-04-28 15:57:57 -04003515static int default_noexec;
3516
Linus Torvalds1da177e2005-04-16 15:20:36 -07003517static int file_map_prot_check(struct file *file, unsigned long prot, int shared)
3518{
David Howells88e67f32008-11-14 10:39:21 +11003519 const struct cred *cred = current_cred();
Stephen Smalleybe0554c2017-01-09 10:07:31 -05003520 u32 sid = cred_sid(cred);
David Howellsd84f4f92008-11-14 10:39:23 +11003521 int rc = 0;
David Howells88e67f32008-11-14 10:39:21 +11003522
Stephen Smalleyfcaaade2010-04-28 15:57:57 -04003523 if (default_noexec &&
Stephen Smalley892e8ca2015-07-10 09:40:59 -04003524 (prot & PROT_EXEC) && (!file || IS_PRIVATE(file_inode(file)) ||
3525 (!shared && (prot & PROT_WRITE)))) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003526 /*
3527 * We are making executable an anonymous mapping or a
3528 * private file mapping that will also be writable.
3529 * This has an additional check.
3530 */
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003531 rc = avc_has_perm(&selinux_state,
3532 sid, sid, SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05003533 PROCESS__EXECMEM, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003534 if (rc)
David Howellsd84f4f92008-11-14 10:39:23 +11003535 goto error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003536 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003537
3538 if (file) {
3539 /* read access is always possible with a mapping */
3540 u32 av = FILE__READ;
3541
3542 /* write access only matters if the mapping is shared */
3543 if (shared && (prot & PROT_WRITE))
3544 av |= FILE__WRITE;
3545
3546 if (prot & PROT_EXEC)
3547 av |= FILE__EXECUTE;
3548
David Howells88e67f32008-11-14 10:39:21 +11003549 return file_has_perm(cred, file, av);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003550 }
David Howellsd84f4f92008-11-14 10:39:23 +11003551
3552error:
3553 return rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003554}
3555
Al Viroe5467852012-05-30 13:30:51 -04003556static int selinux_mmap_addr(unsigned long addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003557{
Casey Schauflerb1d9e6b2015-05-02 15:11:42 -07003558 int rc = 0;
Paul Moore98883bf2014-03-19 16:46:11 -04003559
3560 if (addr < CONFIG_LSM_MMAP_MIN_ADDR) {
3561 u32 sid = current_sid();
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003562 rc = avc_has_perm(&selinux_state,
3563 sid, sid, SECCLASS_MEMPROTECT,
Paul Moore98883bf2014-03-19 16:46:11 -04003564 MEMPROTECT__MMAP_ZERO, NULL);
3565 }
3566
3567 return rc;
Al Viroe5467852012-05-30 13:30:51 -04003568}
Linus Torvalds1da177e2005-04-16 15:20:36 -07003569
Al Viroe5467852012-05-30 13:30:51 -04003570static int selinux_mmap_file(struct file *file, unsigned long reqprot,
3571 unsigned long prot, unsigned long flags)
3572{
Stephen Smalley3ba4bf52017-05-05 09:14:48 -04003573 struct common_audit_data ad;
3574 int rc;
3575
3576 if (file) {
3577 ad.type = LSM_AUDIT_DATA_FILE;
3578 ad.u.file = file;
3579 rc = inode_has_perm(current_cred(), file_inode(file),
3580 FILE__MAP, &ad);
3581 if (rc)
3582 return rc;
3583 }
3584
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05003585 if (selinux_state.checkreqprot)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003586 prot = reqprot;
3587
3588 return file_map_prot_check(file, prot,
3589 (flags & MAP_TYPE) == MAP_SHARED);
3590}
3591
3592static int selinux_file_mprotect(struct vm_area_struct *vma,
3593 unsigned long reqprot,
3594 unsigned long prot)
3595{
David Howells88e67f32008-11-14 10:39:21 +11003596 const struct cred *cred = current_cred();
Stephen Smalleybe0554c2017-01-09 10:07:31 -05003597 u32 sid = cred_sid(cred);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003598
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05003599 if (selinux_state.checkreqprot)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003600 prot = reqprot;
3601
Stephen Smalleyfcaaade2010-04-28 15:57:57 -04003602 if (default_noexec &&
3603 (prot & PROT_EXEC) && !(vma->vm_flags & VM_EXEC)) {
James Morrisd541bbe2009-01-29 12:19:51 +11003604 int rc = 0;
Stephen Smalleydb4c9642006-02-01 03:05:54 -08003605 if (vma->vm_start >= vma->vm_mm->start_brk &&
3606 vma->vm_end <= vma->vm_mm->brk) {
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003607 rc = avc_has_perm(&selinux_state,
3608 sid, sid, SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05003609 PROCESS__EXECHEAP, NULL);
Stephen Smalleydb4c9642006-02-01 03:05:54 -08003610 } else if (!vma->vm_file &&
Stephen Smalleyc2316db2016-04-08 13:55:03 -04003611 ((vma->vm_start <= vma->vm_mm->start_stack &&
3612 vma->vm_end >= vma->vm_mm->start_stack) ||
Andy Lutomirskid17af502016-09-30 10:58:58 -07003613 vma_is_stack_for_current(vma))) {
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003614 rc = avc_has_perm(&selinux_state,
3615 sid, sid, SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05003616 PROCESS__EXECSTACK, NULL);
Stephen Smalleydb4c9642006-02-01 03:05:54 -08003617 } else if (vma->vm_file && vma->anon_vma) {
3618 /*
3619 * We are making executable a file mapping that has
3620 * had some COW done. Since pages might have been
3621 * written, check ability to execute the possibly
3622 * modified content. This typically should only
3623 * occur for text relocations.
3624 */
David Howellsd84f4f92008-11-14 10:39:23 +11003625 rc = file_has_perm(cred, vma->vm_file, FILE__EXECMOD);
Stephen Smalleydb4c9642006-02-01 03:05:54 -08003626 }
Lorenzo Hernandez García-Hierro6b992192005-06-25 14:54:34 -07003627 if (rc)
3628 return rc;
3629 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003630
3631 return file_map_prot_check(vma->vm_file, prot, vma->vm_flags&VM_SHARED);
3632}
3633
3634static int selinux_file_lock(struct file *file, unsigned int cmd)
3635{
David Howells88e67f32008-11-14 10:39:21 +11003636 const struct cred *cred = current_cred();
3637
3638 return file_has_perm(cred, file, FILE__LOCK);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003639}
3640
3641static int selinux_file_fcntl(struct file *file, unsigned int cmd,
3642 unsigned long arg)
3643{
David Howells88e67f32008-11-14 10:39:21 +11003644 const struct cred *cred = current_cred();
Linus Torvalds1da177e2005-04-16 15:20:36 -07003645 int err = 0;
3646
3647 switch (cmd) {
Eric Paris828dfe12008-04-17 13:17:49 -04003648 case F_SETFL:
Eric Paris828dfe12008-04-17 13:17:49 -04003649 if ((file->f_flags & O_APPEND) && !(arg & O_APPEND)) {
David Howells88e67f32008-11-14 10:39:21 +11003650 err = file_has_perm(cred, file, FILE__WRITE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003651 break;
Eric Paris828dfe12008-04-17 13:17:49 -04003652 }
3653 /* fall through */
3654 case F_SETOWN:
3655 case F_SETSIG:
3656 case F_GETFL:
3657 case F_GETOWN:
3658 case F_GETSIG:
Cyrill Gorcunov1d151c32012-07-30 14:43:00 -07003659 case F_GETOWNER_UIDS:
Eric Paris828dfe12008-04-17 13:17:49 -04003660 /* Just check FD__USE permission */
David Howells88e67f32008-11-14 10:39:21 +11003661 err = file_has_perm(cred, file, 0);
Eric Paris828dfe12008-04-17 13:17:49 -04003662 break;
3663 case F_GETLK:
3664 case F_SETLK:
3665 case F_SETLKW:
Jeff Layton0d3f7a22014-04-22 08:23:58 -04003666 case F_OFD_GETLK:
3667 case F_OFD_SETLK:
3668 case F_OFD_SETLKW:
Linus Torvalds1da177e2005-04-16 15:20:36 -07003669#if BITS_PER_LONG == 32
Eric Paris828dfe12008-04-17 13:17:49 -04003670 case F_GETLK64:
3671 case F_SETLK64:
3672 case F_SETLKW64:
Linus Torvalds1da177e2005-04-16 15:20:36 -07003673#endif
David Howells88e67f32008-11-14 10:39:21 +11003674 err = file_has_perm(cred, file, FILE__LOCK);
Eric Paris828dfe12008-04-17 13:17:49 -04003675 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003676 }
3677
3678 return err;
3679}
3680
Jeff Laytone0b93ed2014-08-22 11:27:32 -04003681static void selinux_file_set_fowner(struct file *file)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003682{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003683 struct file_security_struct *fsec;
3684
Casey Schauflerbb6c6b02018-09-21 17:22:32 -07003685 fsec = selinux_file(file);
David Howells275bb412008-11-14 10:39:19 +11003686 fsec->fown_sid = current_sid();
Linus Torvalds1da177e2005-04-16 15:20:36 -07003687}
3688
3689static int selinux_file_send_sigiotask(struct task_struct *tsk,
3690 struct fown_struct *fown, int signum)
3691{
Eric Paris828dfe12008-04-17 13:17:49 -04003692 struct file *file;
Stephen Smalley65c90bc2009-05-04 15:43:18 -04003693 u32 sid = task_sid(tsk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003694 u32 perm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003695 struct file_security_struct *fsec;
3696
3697 /* struct fown_struct is never outside the context of a struct file */
Eric Paris828dfe12008-04-17 13:17:49 -04003698 file = container_of(fown, struct file, f_owner);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003699
Casey Schauflerbb6c6b02018-09-21 17:22:32 -07003700 fsec = selinux_file(file);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003701
3702 if (!signum)
3703 perm = signal_to_av(SIGIO); /* as per send_sigio_to_task */
3704 else
3705 perm = signal_to_av(signum);
3706
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003707 return avc_has_perm(&selinux_state,
3708 fsec->fown_sid, sid,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003709 SECCLASS_PROCESS, perm, NULL);
3710}
3711
3712static int selinux_file_receive(struct file *file)
3713{
David Howells88e67f32008-11-14 10:39:21 +11003714 const struct cred *cred = current_cred();
3715
3716 return file_has_perm(cred, file, file_to_av(file));
Linus Torvalds1da177e2005-04-16 15:20:36 -07003717}
3718
Al Viro94817692018-07-10 14:13:18 -04003719static int selinux_file_open(struct file *file)
Yuichi Nakamura788e7dd2007-09-14 09:27:07 +09003720{
3721 struct file_security_struct *fsec;
Yuichi Nakamura788e7dd2007-09-14 09:27:07 +09003722 struct inode_security_struct *isec;
David Howellsd84f4f92008-11-14 10:39:23 +11003723
Casey Schauflerbb6c6b02018-09-21 17:22:32 -07003724 fsec = selinux_file(file);
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -05003725 isec = inode_security(file_inode(file));
Yuichi Nakamura788e7dd2007-09-14 09:27:07 +09003726 /*
3727 * Save inode label and policy sequence number
3728 * at open-time so that selinux_file_permission
3729 * can determine whether revalidation is necessary.
3730 * Task label is already saved in the file security
3731 * struct as its SID.
3732 */
3733 fsec->isid = isec->sid;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003734 fsec->pseqno = avc_policy_seqno(&selinux_state);
Yuichi Nakamura788e7dd2007-09-14 09:27:07 +09003735 /*
3736 * Since the inode label or policy seqno may have changed
3737 * between the selinux_inode_permission check and the saving
3738 * of state above, recheck that access is still permitted.
3739 * Otherwise, access might never be revalidated against the
3740 * new inode label or new policy.
3741 * This check is not redundant - do not remove.
3742 */
Al Viro94817692018-07-10 14:13:18 -04003743 return file_path_has_perm(file->f_cred, file, open_file_to_av(file));
Yuichi Nakamura788e7dd2007-09-14 09:27:07 +09003744}
3745
Linus Torvalds1da177e2005-04-16 15:20:36 -07003746/* task security operations */
3747
Tetsuo Handaa79be232017-03-28 23:08:45 +09003748static int selinux_task_alloc(struct task_struct *task,
3749 unsigned long clone_flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003750{
Stephen Smalleybe0554c2017-01-09 10:07:31 -05003751 u32 sid = current_sid();
3752
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003753 return avc_has_perm(&selinux_state,
3754 sid, sid, SECCLASS_PROCESS, PROCESS__FORK, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003755}
3756
David Howellsf1752ee2008-11-14 10:39:17 +11003757/*
David Howellsd84f4f92008-11-14 10:39:23 +11003758 * prepare a new set of credentials for modification
3759 */
3760static int selinux_cred_prepare(struct cred *new, const struct cred *old,
3761 gfp_t gfp)
3762{
Casey Schauflerbbd36622018-11-12 09:30:56 -08003763 const struct task_security_struct *old_tsec = selinux_cred(old);
3764 struct task_security_struct *tsec = selinux_cred(new);
David Howellsd84f4f92008-11-14 10:39:23 +11003765
Casey Schauflerbbd36622018-11-12 09:30:56 -08003766 *tsec = *old_tsec;
David Howellsd84f4f92008-11-14 10:39:23 +11003767 return 0;
3768}
3769
3770/*
David Howellsee18d642009-09-02 09:14:21 +01003771 * transfer the SELinux data to a blank set of creds
3772 */
3773static void selinux_cred_transfer(struct cred *new, const struct cred *old)
3774{
Casey Schaufler0c6cfa62018-09-21 17:17:16 -07003775 const struct task_security_struct *old_tsec = selinux_cred(old);
3776 struct task_security_struct *tsec = selinux_cred(new);
David Howellsee18d642009-09-02 09:14:21 +01003777
3778 *tsec = *old_tsec;
3779}
3780
Matthew Garrett3ec30112018-01-08 13:36:19 -08003781static void selinux_cred_getsecid(const struct cred *c, u32 *secid)
3782{
3783 *secid = cred_sid(c);
3784}
3785
David Howellsee18d642009-09-02 09:14:21 +01003786/*
David Howells3a3b7ce2008-11-14 10:39:28 +11003787 * set the security data for a kernel service
3788 * - all the creation contexts are set to unlabelled
3789 */
3790static int selinux_kernel_act_as(struct cred *new, u32 secid)
3791{
Casey Schaufler0c6cfa62018-09-21 17:17:16 -07003792 struct task_security_struct *tsec = selinux_cred(new);
David Howells3a3b7ce2008-11-14 10:39:28 +11003793 u32 sid = current_sid();
3794 int ret;
3795
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003796 ret = avc_has_perm(&selinux_state,
3797 sid, secid,
David Howells3a3b7ce2008-11-14 10:39:28 +11003798 SECCLASS_KERNEL_SERVICE,
3799 KERNEL_SERVICE__USE_AS_OVERRIDE,
3800 NULL);
3801 if (ret == 0) {
3802 tsec->sid = secid;
3803 tsec->create_sid = 0;
3804 tsec->keycreate_sid = 0;
3805 tsec->sockcreate_sid = 0;
3806 }
3807 return ret;
3808}
3809
3810/*
3811 * set the file creation context in a security record to the same as the
3812 * objective context of the specified inode
3813 */
3814static int selinux_kernel_create_files_as(struct cred *new, struct inode *inode)
3815{
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -05003816 struct inode_security_struct *isec = inode_security(inode);
Casey Schaufler0c6cfa62018-09-21 17:17:16 -07003817 struct task_security_struct *tsec = selinux_cred(new);
David Howells3a3b7ce2008-11-14 10:39:28 +11003818 u32 sid = current_sid();
3819 int ret;
3820
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003821 ret = avc_has_perm(&selinux_state,
3822 sid, isec->sid,
David Howells3a3b7ce2008-11-14 10:39:28 +11003823 SECCLASS_KERNEL_SERVICE,
3824 KERNEL_SERVICE__CREATE_FILES_AS,
3825 NULL);
3826
3827 if (ret == 0)
3828 tsec->create_sid = isec->sid;
David Howellsef574712010-02-26 01:56:16 +00003829 return ret;
David Howells3a3b7ce2008-11-14 10:39:28 +11003830}
3831
Eric Parisdd8dbf22009-11-03 16:35:32 +11003832static int selinux_kernel_module_request(char *kmod_name)
Eric Paris25354c42009-08-13 09:45:03 -04003833{
Eric Parisdd8dbf22009-11-03 16:35:32 +11003834 struct common_audit_data ad;
3835
Eric Paris50c205f2012-04-04 15:01:43 -04003836 ad.type = LSM_AUDIT_DATA_KMOD;
Eric Parisdd8dbf22009-11-03 16:35:32 +11003837 ad.u.kmod_name = kmod_name;
3838
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003839 return avc_has_perm(&selinux_state,
3840 current_sid(), SECINITSID_KERNEL, SECCLASS_SYSTEM,
Eric Parisdd8dbf22009-11-03 16:35:32 +11003841 SYSTEM__MODULE_REQUEST, &ad);
Eric Paris25354c42009-08-13 09:45:03 -04003842}
3843
Jeff Vander Stoep61d612ea2016-04-05 13:06:27 -07003844static int selinux_kernel_module_from_file(struct file *file)
3845{
3846 struct common_audit_data ad;
3847 struct inode_security_struct *isec;
3848 struct file_security_struct *fsec;
3849 u32 sid = current_sid();
3850 int rc;
3851
3852 /* init_module */
3853 if (file == NULL)
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003854 return avc_has_perm(&selinux_state,
3855 sid, sid, SECCLASS_SYSTEM,
Jeff Vander Stoep61d612ea2016-04-05 13:06:27 -07003856 SYSTEM__MODULE_LOAD, NULL);
3857
3858 /* finit_module */
Paul Moore20cdef82016-04-04 14:14:42 -04003859
Vivek Goyal43af5de2016-09-09 11:37:49 -04003860 ad.type = LSM_AUDIT_DATA_FILE;
3861 ad.u.file = file;
Jeff Vander Stoep61d612ea2016-04-05 13:06:27 -07003862
Casey Schauflerbb6c6b02018-09-21 17:22:32 -07003863 fsec = selinux_file(file);
Jeff Vander Stoep61d612ea2016-04-05 13:06:27 -07003864 if (sid != fsec->sid) {
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003865 rc = avc_has_perm(&selinux_state,
3866 sid, fsec->sid, SECCLASS_FD, FD__USE, &ad);
Jeff Vander Stoep61d612ea2016-04-05 13:06:27 -07003867 if (rc)
3868 return rc;
3869 }
3870
Paul Moore20cdef82016-04-04 14:14:42 -04003871 isec = inode_security(file_inode(file));
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003872 return avc_has_perm(&selinux_state,
3873 sid, isec->sid, SECCLASS_SYSTEM,
Jeff Vander Stoep61d612ea2016-04-05 13:06:27 -07003874 SYSTEM__MODULE_LOAD, &ad);
3875}
3876
3877static int selinux_kernel_read_file(struct file *file,
3878 enum kernel_read_file_id id)
3879{
3880 int rc = 0;
3881
3882 switch (id) {
3883 case READING_MODULE:
3884 rc = selinux_kernel_module_from_file(file);
3885 break;
3886 default:
3887 break;
3888 }
3889
3890 return rc;
3891}
3892
Mimi Zoharc77b8cd2018-07-13 14:06:02 -04003893static int selinux_kernel_load_data(enum kernel_load_data_id id)
3894{
3895 int rc = 0;
3896
3897 switch (id) {
3898 case LOADING_MODULE:
3899 rc = selinux_kernel_module_from_file(NULL);
3900 default:
3901 break;
3902 }
3903
3904 return rc;
3905}
3906
Linus Torvalds1da177e2005-04-16 15:20:36 -07003907static int selinux_task_setpgid(struct task_struct *p, pid_t pgid)
3908{
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003909 return avc_has_perm(&selinux_state,
3910 current_sid(), task_sid(p), SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05003911 PROCESS__SETPGID, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003912}
3913
3914static int selinux_task_getpgid(struct task_struct *p)
3915{
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003916 return avc_has_perm(&selinux_state,
3917 current_sid(), task_sid(p), SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05003918 PROCESS__GETPGID, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003919}
3920
3921static int selinux_task_getsid(struct task_struct *p)
3922{
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003923 return avc_has_perm(&selinux_state,
3924 current_sid(), task_sid(p), SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05003925 PROCESS__GETSESSION, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003926}
3927
David Quigleyf9008e4c2006-06-30 01:55:46 -07003928static void selinux_task_getsecid(struct task_struct *p, u32 *secid)
3929{
David Howells275bb412008-11-14 10:39:19 +11003930 *secid = task_sid(p);
David Quigleyf9008e4c2006-06-30 01:55:46 -07003931}
3932
Linus Torvalds1da177e2005-04-16 15:20:36 -07003933static int selinux_task_setnice(struct task_struct *p, int nice)
3934{
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003935 return avc_has_perm(&selinux_state,
3936 current_sid(), task_sid(p), SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05003937 PROCESS__SETSCHED, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003938}
3939
James Morris03e68062006-06-23 02:03:58 -07003940static int selinux_task_setioprio(struct task_struct *p, int ioprio)
3941{
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003942 return avc_has_perm(&selinux_state,
3943 current_sid(), task_sid(p), SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05003944 PROCESS__SETSCHED, NULL);
James Morris03e68062006-06-23 02:03:58 -07003945}
3946
David Quigleya1836a42006-06-30 01:55:49 -07003947static int selinux_task_getioprio(struct task_struct *p)
3948{
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003949 return avc_has_perm(&selinux_state,
3950 current_sid(), task_sid(p), SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05003951 PROCESS__GETSCHED, NULL);
David Quigleya1836a42006-06-30 01:55:49 -07003952}
3953
Corentin LABBE42985552017-10-04 20:32:18 +02003954static int selinux_task_prlimit(const struct cred *cred, const struct cred *tcred,
3955 unsigned int flags)
Stephen Smalley791ec492017-02-17 07:57:00 -05003956{
3957 u32 av = 0;
3958
Stephen Smalley84e68852017-02-28 09:35:08 -05003959 if (!flags)
3960 return 0;
Stephen Smalley791ec492017-02-17 07:57:00 -05003961 if (flags & LSM_PRLIMIT_WRITE)
3962 av |= PROCESS__SETRLIMIT;
3963 if (flags & LSM_PRLIMIT_READ)
3964 av |= PROCESS__GETRLIMIT;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003965 return avc_has_perm(&selinux_state,
3966 cred_sid(cred), cred_sid(tcred),
Stephen Smalley791ec492017-02-17 07:57:00 -05003967 SECCLASS_PROCESS, av, NULL);
3968}
3969
Jiri Slaby8fd00b42009-08-26 18:41:16 +02003970static int selinux_task_setrlimit(struct task_struct *p, unsigned int resource,
3971 struct rlimit *new_rlim)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003972{
Jiri Slaby8fd00b42009-08-26 18:41:16 +02003973 struct rlimit *old_rlim = p->signal->rlim + resource;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003974
3975 /* Control the ability to change the hard limit (whether
3976 lowering or raising it), so that the hard limit can
3977 later be used as a safe reset point for the soft limit
David Howellsd84f4f92008-11-14 10:39:23 +11003978 upon context transitions. See selinux_bprm_committing_creds. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07003979 if (old_rlim->rlim_max != new_rlim->rlim_max)
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003980 return avc_has_perm(&selinux_state,
3981 current_sid(), task_sid(p),
Stephen Smalleybe0554c2017-01-09 10:07:31 -05003982 SECCLASS_PROCESS, PROCESS__SETRLIMIT, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003983
3984 return 0;
3985}
3986
KOSAKI Motohirob0ae1982010-10-15 04:21:18 +09003987static int selinux_task_setscheduler(struct task_struct *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003988{
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003989 return avc_has_perm(&selinux_state,
3990 current_sid(), task_sid(p), SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05003991 PROCESS__SETSCHED, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003992}
3993
3994static int selinux_task_getscheduler(struct task_struct *p)
3995{
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003996 return avc_has_perm(&selinux_state,
3997 current_sid(), task_sid(p), SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05003998 PROCESS__GETSCHED, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003999}
4000
David Quigley35601542006-06-23 02:04:01 -07004001static int selinux_task_movememory(struct task_struct *p)
4002{
Stephen Smalley6b6bc622018-03-05 11:47:56 -05004003 return avc_has_perm(&selinux_state,
4004 current_sid(), task_sid(p), SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05004005 PROCESS__SETSCHED, NULL);
David Quigley35601542006-06-23 02:04:01 -07004006}
4007
Eric W. Biedermanae7795b2018-09-25 11:27:20 +02004008static int selinux_task_kill(struct task_struct *p, struct kernel_siginfo *info,
Stephen Smalley6b4f3d02017-09-08 12:40:01 -04004009 int sig, const struct cred *cred)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004010{
Stephen Smalley6b4f3d02017-09-08 12:40:01 -04004011 u32 secid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004012 u32 perm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004013
Linus Torvalds1da177e2005-04-16 15:20:36 -07004014 if (!sig)
4015 perm = PROCESS__SIGNULL; /* null signal; existence test */
4016 else
4017 perm = signal_to_av(sig);
Stephen Smalley6b4f3d02017-09-08 12:40:01 -04004018 if (!cred)
Stephen Smalleybe0554c2017-01-09 10:07:31 -05004019 secid = current_sid();
Stephen Smalley6b4f3d02017-09-08 12:40:01 -04004020 else
4021 secid = cred_sid(cred);
Stephen Smalley6b6bc622018-03-05 11:47:56 -05004022 return avc_has_perm(&selinux_state,
4023 secid, task_sid(p), SECCLASS_PROCESS, perm, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004024}
4025
Linus Torvalds1da177e2005-04-16 15:20:36 -07004026static void selinux_task_to_inode(struct task_struct *p,
4027 struct inode *inode)
4028{
Casey Schaufler80788c22018-09-21 17:19:11 -07004029 struct inode_security_struct *isec = selinux_inode(inode);
David Howells275bb412008-11-14 10:39:19 +11004030 u32 sid = task_sid(p);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004031
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01004032 spin_lock(&isec->lock);
Andreas Gruenbacherdb978da2016-11-10 22:18:28 +01004033 isec->sclass = inode_mode_to_security_class(inode->i_mode);
David Howells275bb412008-11-14 10:39:19 +11004034 isec->sid = sid;
Andreas Gruenbacher6f3be9f2015-12-24 11:09:40 -05004035 isec->initialized = LABEL_INITIALIZED;
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01004036 spin_unlock(&isec->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004037}
4038
Linus Torvalds1da177e2005-04-16 15:20:36 -07004039/* Returns error only if unable to parse addresses */
Venkat Yekkirala67f83cb2006-11-08 17:04:26 -06004040static int selinux_parse_skb_ipv4(struct sk_buff *skb,
Thomas Liu2bf49692009-07-14 12:14:09 -04004041 struct common_audit_data *ad, u8 *proto)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004042{
4043 int offset, ihlen, ret = -EINVAL;
4044 struct iphdr _iph, *ih;
4045
Arnaldo Carvalho de Melobbe735e2007-03-10 22:16:10 -03004046 offset = skb_network_offset(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004047 ih = skb_header_pointer(skb, offset, sizeof(_iph), &_iph);
4048 if (ih == NULL)
4049 goto out;
4050
4051 ihlen = ih->ihl * 4;
4052 if (ihlen < sizeof(_iph))
4053 goto out;
4054
Eric Paris48c62af2012-04-02 13:15:44 -04004055 ad->u.net->v4info.saddr = ih->saddr;
4056 ad->u.net->v4info.daddr = ih->daddr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004057 ret = 0;
4058
Venkat Yekkirala67f83cb2006-11-08 17:04:26 -06004059 if (proto)
4060 *proto = ih->protocol;
4061
Linus Torvalds1da177e2005-04-16 15:20:36 -07004062 switch (ih->protocol) {
Eric Paris828dfe12008-04-17 13:17:49 -04004063 case IPPROTO_TCP: {
4064 struct tcphdr _tcph, *th;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004065
Eric Paris828dfe12008-04-17 13:17:49 -04004066 if (ntohs(ih->frag_off) & IP_OFFSET)
4067 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004068
4069 offset += ihlen;
4070 th = skb_header_pointer(skb, offset, sizeof(_tcph), &_tcph);
4071 if (th == NULL)
4072 break;
4073
Eric Paris48c62af2012-04-02 13:15:44 -04004074 ad->u.net->sport = th->source;
4075 ad->u.net->dport = th->dest;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004076 break;
Eric Paris828dfe12008-04-17 13:17:49 -04004077 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004078
Eric Paris828dfe12008-04-17 13:17:49 -04004079 case IPPROTO_UDP: {
4080 struct udphdr _udph, *uh;
4081
4082 if (ntohs(ih->frag_off) & IP_OFFSET)
4083 break;
4084
4085 offset += ihlen;
4086 uh = skb_header_pointer(skb, offset, sizeof(_udph), &_udph);
4087 if (uh == NULL)
4088 break;
4089
Eric Paris48c62af2012-04-02 13:15:44 -04004090 ad->u.net->sport = uh->source;
4091 ad->u.net->dport = uh->dest;
Eric Paris828dfe12008-04-17 13:17:49 -04004092 break;
4093 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004094
James Morris2ee92d42006-11-13 16:09:01 -08004095 case IPPROTO_DCCP: {
4096 struct dccp_hdr _dccph, *dh;
4097
4098 if (ntohs(ih->frag_off) & IP_OFFSET)
4099 break;
4100
4101 offset += ihlen;
4102 dh = skb_header_pointer(skb, offset, sizeof(_dccph), &_dccph);
4103 if (dh == NULL)
4104 break;
4105
Eric Paris48c62af2012-04-02 13:15:44 -04004106 ad->u.net->sport = dh->dccph_sport;
4107 ad->u.net->dport = dh->dccph_dport;
James Morris2ee92d42006-11-13 16:09:01 -08004108 break;
Eric Paris828dfe12008-04-17 13:17:49 -04004109 }
James Morris2ee92d42006-11-13 16:09:01 -08004110
Richard Hainesd4529302018-02-13 20:57:18 +00004111#if IS_ENABLED(CONFIG_IP_SCTP)
4112 case IPPROTO_SCTP: {
4113 struct sctphdr _sctph, *sh;
4114
4115 if (ntohs(ih->frag_off) & IP_OFFSET)
4116 break;
4117
4118 offset += ihlen;
4119 sh = skb_header_pointer(skb, offset, sizeof(_sctph), &_sctph);
4120 if (sh == NULL)
4121 break;
4122
4123 ad->u.net->sport = sh->source;
4124 ad->u.net->dport = sh->dest;
4125 break;
4126 }
4127#endif
Eric Paris828dfe12008-04-17 13:17:49 -04004128 default:
4129 break;
4130 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004131out:
4132 return ret;
4133}
4134
Javier Martinez Canillas1a93a6e2016-08-08 13:08:25 -04004135#if IS_ENABLED(CONFIG_IPV6)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004136
4137/* Returns error only if unable to parse addresses */
Venkat Yekkirala67f83cb2006-11-08 17:04:26 -06004138static int selinux_parse_skb_ipv6(struct sk_buff *skb,
Thomas Liu2bf49692009-07-14 12:14:09 -04004139 struct common_audit_data *ad, u8 *proto)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004140{
4141 u8 nexthdr;
4142 int ret = -EINVAL, offset;
4143 struct ipv6hdr _ipv6h, *ip6;
Jesse Gross75f28112011-11-30 17:05:51 -08004144 __be16 frag_off;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004145
Arnaldo Carvalho de Melobbe735e2007-03-10 22:16:10 -03004146 offset = skb_network_offset(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004147 ip6 = skb_header_pointer(skb, offset, sizeof(_ipv6h), &_ipv6h);
4148 if (ip6 == NULL)
4149 goto out;
4150
Eric Paris48c62af2012-04-02 13:15:44 -04004151 ad->u.net->v6info.saddr = ip6->saddr;
4152 ad->u.net->v6info.daddr = ip6->daddr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004153 ret = 0;
4154
4155 nexthdr = ip6->nexthdr;
4156 offset += sizeof(_ipv6h);
Jesse Gross75f28112011-11-30 17:05:51 -08004157 offset = ipv6_skip_exthdr(skb, offset, &nexthdr, &frag_off);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004158 if (offset < 0)
4159 goto out;
4160
Venkat Yekkirala67f83cb2006-11-08 17:04:26 -06004161 if (proto)
4162 *proto = nexthdr;
4163
Linus Torvalds1da177e2005-04-16 15:20:36 -07004164 switch (nexthdr) {
4165 case IPPROTO_TCP: {
Eric Paris828dfe12008-04-17 13:17:49 -04004166 struct tcphdr _tcph, *th;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004167
4168 th = skb_header_pointer(skb, offset, sizeof(_tcph), &_tcph);
4169 if (th == NULL)
4170 break;
4171
Eric Paris48c62af2012-04-02 13:15:44 -04004172 ad->u.net->sport = th->source;
4173 ad->u.net->dport = th->dest;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004174 break;
4175 }
4176
4177 case IPPROTO_UDP: {
4178 struct udphdr _udph, *uh;
4179
4180 uh = skb_header_pointer(skb, offset, sizeof(_udph), &_udph);
4181 if (uh == NULL)
4182 break;
4183
Eric Paris48c62af2012-04-02 13:15:44 -04004184 ad->u.net->sport = uh->source;
4185 ad->u.net->dport = uh->dest;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004186 break;
4187 }
4188
James Morris2ee92d42006-11-13 16:09:01 -08004189 case IPPROTO_DCCP: {
4190 struct dccp_hdr _dccph, *dh;
4191
4192 dh = skb_header_pointer(skb, offset, sizeof(_dccph), &_dccph);
4193 if (dh == NULL)
4194 break;
4195
Eric Paris48c62af2012-04-02 13:15:44 -04004196 ad->u.net->sport = dh->dccph_sport;
4197 ad->u.net->dport = dh->dccph_dport;
James Morris2ee92d42006-11-13 16:09:01 -08004198 break;
Eric Paris828dfe12008-04-17 13:17:49 -04004199 }
James Morris2ee92d42006-11-13 16:09:01 -08004200
Richard Hainesd4529302018-02-13 20:57:18 +00004201#if IS_ENABLED(CONFIG_IP_SCTP)
4202 case IPPROTO_SCTP: {
4203 struct sctphdr _sctph, *sh;
4204
4205 sh = skb_header_pointer(skb, offset, sizeof(_sctph), &_sctph);
4206 if (sh == NULL)
4207 break;
4208
4209 ad->u.net->sport = sh->source;
4210 ad->u.net->dport = sh->dest;
4211 break;
4212 }
4213#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07004214 /* includes fragments */
4215 default:
4216 break;
4217 }
4218out:
4219 return ret;
4220}
4221
4222#endif /* IPV6 */
4223
Thomas Liu2bf49692009-07-14 12:14:09 -04004224static int selinux_parse_skb(struct sk_buff *skb, struct common_audit_data *ad,
David Howellscf9481e2008-07-27 21:31:07 +10004225 char **_addrp, int src, u8 *proto)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004226{
David Howellscf9481e2008-07-27 21:31:07 +10004227 char *addrp;
4228 int ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004229
Eric Paris48c62af2012-04-02 13:15:44 -04004230 switch (ad->u.net->family) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004231 case PF_INET:
Venkat Yekkirala67f83cb2006-11-08 17:04:26 -06004232 ret = selinux_parse_skb_ipv4(skb, ad, proto);
David Howellscf9481e2008-07-27 21:31:07 +10004233 if (ret)
4234 goto parse_error;
Eric Paris48c62af2012-04-02 13:15:44 -04004235 addrp = (char *)(src ? &ad->u.net->v4info.saddr :
4236 &ad->u.net->v4info.daddr);
David Howellscf9481e2008-07-27 21:31:07 +10004237 goto okay;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004238
Javier Martinez Canillas1a93a6e2016-08-08 13:08:25 -04004239#if IS_ENABLED(CONFIG_IPV6)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004240 case PF_INET6:
Venkat Yekkirala67f83cb2006-11-08 17:04:26 -06004241 ret = selinux_parse_skb_ipv6(skb, ad, proto);
David Howellscf9481e2008-07-27 21:31:07 +10004242 if (ret)
4243 goto parse_error;
Eric Paris48c62af2012-04-02 13:15:44 -04004244 addrp = (char *)(src ? &ad->u.net->v6info.saddr :
4245 &ad->u.net->v6info.daddr);
David Howellscf9481e2008-07-27 21:31:07 +10004246 goto okay;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004247#endif /* IPV6 */
4248 default:
David Howellscf9481e2008-07-27 21:31:07 +10004249 addrp = NULL;
4250 goto okay;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004251 }
4252
David Howellscf9481e2008-07-27 21:31:07 +10004253parse_error:
peter enderborgc103a912018-06-12 10:09:03 +02004254 pr_warn(
David Howellscf9481e2008-07-27 21:31:07 +10004255 "SELinux: failure in selinux_parse_skb(),"
4256 " unable to parse packet\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07004257 return ret;
David Howellscf9481e2008-07-27 21:31:07 +10004258
4259okay:
4260 if (_addrp)
4261 *_addrp = addrp;
4262 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004263}
4264
Paul Moore4f6a9932007-03-01 14:35:22 -05004265/**
Paul Moore220deb92008-01-29 08:38:23 -05004266 * selinux_skb_peerlbl_sid - Determine the peer label of a packet
Paul Moore4f6a9932007-03-01 14:35:22 -05004267 * @skb: the packet
Paul Moore75e22912008-01-29 08:38:04 -05004268 * @family: protocol family
Paul Moore220deb92008-01-29 08:38:23 -05004269 * @sid: the packet's peer label SID
Paul Moore4f6a9932007-03-01 14:35:22 -05004270 *
4271 * Description:
Paul Moore220deb92008-01-29 08:38:23 -05004272 * Check the various different forms of network peer labeling and determine
4273 * the peer label/SID for the packet; most of the magic actually occurs in
4274 * the security server function security_net_peersid_cmp(). The function
4275 * returns zero if the value in @sid is valid (although it may be SECSID_NULL)
4276 * or -EACCES if @sid is invalid due to inconsistencies with the different
4277 * peer labels.
Paul Moore4f6a9932007-03-01 14:35:22 -05004278 *
4279 */
Paul Moore220deb92008-01-29 08:38:23 -05004280static int selinux_skb_peerlbl_sid(struct sk_buff *skb, u16 family, u32 *sid)
Paul Moore4f6a9932007-03-01 14:35:22 -05004281{
Paul Moore71f1cb02008-01-29 08:51:16 -05004282 int err;
Paul Moore4f6a9932007-03-01 14:35:22 -05004283 u32 xfrm_sid;
4284 u32 nlbl_sid;
Paul Moore220deb92008-01-29 08:38:23 -05004285 u32 nlbl_type;
Paul Moore4f6a9932007-03-01 14:35:22 -05004286
Paul Moore817eff72013-12-10 14:57:54 -05004287 err = selinux_xfrm_skb_sid(skb, &xfrm_sid);
Paul Moorebed4d7e2013-07-23 17:38:40 -04004288 if (unlikely(err))
4289 return -EACCES;
4290 err = selinux_netlbl_skbuff_getsid(skb, family, &nlbl_type, &nlbl_sid);
4291 if (unlikely(err))
4292 return -EACCES;
Paul Moore220deb92008-01-29 08:38:23 -05004293
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05004294 err = security_net_peersid_resolve(&selinux_state, nlbl_sid,
4295 nlbl_type, xfrm_sid, sid);
Paul Moore71f1cb02008-01-29 08:51:16 -05004296 if (unlikely(err)) {
peter enderborgc103a912018-06-12 10:09:03 +02004297 pr_warn(
Paul Moore71f1cb02008-01-29 08:51:16 -05004298 "SELinux: failure in selinux_skb_peerlbl_sid(),"
4299 " unable to determine packet's peer label\n");
Paul Moore220deb92008-01-29 08:38:23 -05004300 return -EACCES;
Paul Moore71f1cb02008-01-29 08:51:16 -05004301 }
Paul Moore220deb92008-01-29 08:38:23 -05004302
4303 return 0;
Paul Moore4f6a9932007-03-01 14:35:22 -05004304}
4305
Paul Moore446b8022013-12-04 16:10:51 -05004306/**
4307 * selinux_conn_sid - Determine the child socket label for a connection
4308 * @sk_sid: the parent socket's SID
4309 * @skb_sid: the packet's SID
4310 * @conn_sid: the resulting connection SID
4311 *
4312 * If @skb_sid is valid then the user:role:type information from @sk_sid is
4313 * combined with the MLS information from @skb_sid in order to create
4314 * @conn_sid. If @skb_sid is not valid then then @conn_sid is simply a copy
4315 * of @sk_sid. Returns zero on success, negative values on failure.
4316 *
4317 */
4318static int selinux_conn_sid(u32 sk_sid, u32 skb_sid, u32 *conn_sid)
4319{
4320 int err = 0;
4321
4322 if (skb_sid != SECSID_NULL)
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05004323 err = security_sid_mls_copy(&selinux_state, sk_sid, skb_sid,
4324 conn_sid);
Paul Moore446b8022013-12-04 16:10:51 -05004325 else
4326 *conn_sid = sk_sid;
4327
4328 return err;
4329}
4330
Linus Torvalds1da177e2005-04-16 15:20:36 -07004331/* socket security operations */
Paul Moored4f2d972010-04-22 14:46:18 -04004332
Harry Ciao2ad18bd2011-03-02 13:32:34 +08004333static int socket_sockcreate_sid(const struct task_security_struct *tsec,
4334 u16 secclass, u32 *socksid)
Paul Moored4f2d972010-04-22 14:46:18 -04004335{
Harry Ciao2ad18bd2011-03-02 13:32:34 +08004336 if (tsec->sockcreate_sid > SECSID_NULL) {
4337 *socksid = tsec->sockcreate_sid;
4338 return 0;
4339 }
4340
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05004341 return security_transition_sid(&selinux_state, tsec->sid, tsec->sid,
4342 secclass, NULL, socksid);
Paul Moored4f2d972010-04-22 14:46:18 -04004343}
4344
Stephen Smalleybe0554c2017-01-09 10:07:31 -05004345static int sock_has_perm(struct sock *sk, u32 perms)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004346{
Paul Moore253bfae2010-04-22 14:46:19 -04004347 struct sk_security_struct *sksec = sk->sk_security;
Thomas Liu2bf49692009-07-14 12:14:09 -04004348 struct common_audit_data ad;
Eric Paris48c62af2012-04-02 13:15:44 -04004349 struct lsm_network_audit net = {0,};
Linus Torvalds1da177e2005-04-16 15:20:36 -07004350
Paul Moore253bfae2010-04-22 14:46:19 -04004351 if (sksec->sid == SECINITSID_KERNEL)
4352 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004353
Eric Paris50c205f2012-04-04 15:01:43 -04004354 ad.type = LSM_AUDIT_DATA_NET;
Eric Paris48c62af2012-04-02 13:15:44 -04004355 ad.u.net = &net;
4356 ad.u.net->sk = sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004357
Stephen Smalley6b6bc622018-03-05 11:47:56 -05004358 return avc_has_perm(&selinux_state,
4359 current_sid(), sksec->sid, sksec->sclass, perms,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05004360 &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004361}
4362
4363static int selinux_socket_create(int family, int type,
4364 int protocol, int kern)
4365{
Casey Schaufler0c6cfa62018-09-21 17:17:16 -07004366 const struct task_security_struct *tsec = selinux_cred(current_cred());
Paul Moored4f2d972010-04-22 14:46:18 -04004367 u32 newsid;
David Howells275bb412008-11-14 10:39:19 +11004368 u16 secclass;
Harry Ciao2ad18bd2011-03-02 13:32:34 +08004369 int rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004370
4371 if (kern)
Paul Moored4f2d972010-04-22 14:46:18 -04004372 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004373
David Howells275bb412008-11-14 10:39:19 +11004374 secclass = socket_type_to_security_class(family, type, protocol);
Harry Ciao2ad18bd2011-03-02 13:32:34 +08004375 rc = socket_sockcreate_sid(tsec, secclass, &newsid);
4376 if (rc)
4377 return rc;
4378
Stephen Smalley6b6bc622018-03-05 11:47:56 -05004379 return avc_has_perm(&selinux_state,
4380 tsec->sid, newsid, secclass, SOCKET__CREATE, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004381}
4382
Venkat Yekkirala7420ed22006-08-04 23:17:57 -07004383static int selinux_socket_post_create(struct socket *sock, int family,
4384 int type, int protocol, int kern)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004385{
Casey Schaufler0c6cfa62018-09-21 17:17:16 -07004386 const struct task_security_struct *tsec = selinux_cred(current_cred());
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -05004387 struct inode_security_struct *isec = inode_security_novalidate(SOCK_INODE(sock));
Venkat Yekkirala892c1412006-08-04 23:08:56 -07004388 struct sk_security_struct *sksec;
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01004389 u16 sclass = socket_type_to_security_class(family, type, protocol);
4390 u32 sid = SECINITSID_KERNEL;
David Howells275bb412008-11-14 10:39:19 +11004391 int err = 0;
4392
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01004393 if (!kern) {
4394 err = socket_sockcreate_sid(tsec, sclass, &sid);
Harry Ciao2ad18bd2011-03-02 13:32:34 +08004395 if (err)
4396 return err;
4397 }
David Howells275bb412008-11-14 10:39:19 +11004398
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01004399 isec->sclass = sclass;
4400 isec->sid = sid;
Andreas Gruenbacher6f3be9f2015-12-24 11:09:40 -05004401 isec->initialized = LABEL_INITIALIZED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004402
Venkat Yekkirala892c1412006-08-04 23:08:56 -07004403 if (sock->sk) {
4404 sksec = sock->sk->sk_security;
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01004405 sksec->sclass = sclass;
4406 sksec->sid = sid;
Richard Hainesd4529302018-02-13 20:57:18 +00004407 /* Allows detection of the first association on this socket */
4408 if (sksec->sclass == SECCLASS_SCTP_SOCKET)
4409 sksec->sctp_assoc_state = SCTP_ASSOC_UNSET;
4410
Paul Moore389fb8002009-03-27 17:10:34 -04004411 err = selinux_netlbl_socket_post_create(sock->sk, family);
Venkat Yekkirala892c1412006-08-04 23:08:56 -07004412 }
4413
Venkat Yekkirala7420ed22006-08-04 23:17:57 -07004414 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004415}
4416
David Herrmann0b811db2018-05-04 16:28:21 +02004417static int selinux_socket_socketpair(struct socket *socka,
4418 struct socket *sockb)
4419{
4420 struct sk_security_struct *sksec_a = socka->sk->sk_security;
4421 struct sk_security_struct *sksec_b = sockb->sk->sk_security;
4422
4423 sksec_a->peer_sid = sksec_b->sid;
4424 sksec_b->peer_sid = sksec_a->sid;
4425
4426 return 0;
4427}
4428
Linus Torvalds1da177e2005-04-16 15:20:36 -07004429/* Range of port numbers used to automatically bind.
4430 Need to determine whether we should perform a name_bind
4431 permission check between the socket and the port number. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07004432
4433static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, int addrlen)
4434{
Paul Moore253bfae2010-04-22 14:46:19 -04004435 struct sock *sk = sock->sk;
Alexey Kodanev0f8db8c2018-05-11 20:15:11 +03004436 struct sk_security_struct *sksec = sk->sk_security;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004437 u16 family;
4438 int err;
4439
Stephen Smalleybe0554c2017-01-09 10:07:31 -05004440 err = sock_has_perm(sk, SOCKET__BIND);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004441 if (err)
4442 goto out;
4443
Richard Hainesd4529302018-02-13 20:57:18 +00004444 /* If PF_INET or PF_INET6, check name_bind permission for the port. */
Paul Moore253bfae2010-04-22 14:46:19 -04004445 family = sk->sk_family;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004446 if (family == PF_INET || family == PF_INET6) {
4447 char *addrp;
Thomas Liu2bf49692009-07-14 12:14:09 -04004448 struct common_audit_data ad;
Eric Paris48c62af2012-04-02 13:15:44 -04004449 struct lsm_network_audit net = {0,};
Linus Torvalds1da177e2005-04-16 15:20:36 -07004450 struct sockaddr_in *addr4 = NULL;
4451 struct sockaddr_in6 *addr6 = NULL;
Alexey Kodanev0f8db8c2018-05-11 20:15:11 +03004452 u16 family_sa = address->sa_family;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004453 unsigned short snum;
James Morrise399f982008-06-12 01:39:58 +10004454 u32 sid, node_perm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004455
Richard Hainesd4529302018-02-13 20:57:18 +00004456 /*
4457 * sctp_bindx(3) calls via selinux_sctp_bind_connect()
4458 * that validates multiple binding addresses. Because of this
4459 * need to check address->sa_family as it is possible to have
4460 * sk->sk_family = PF_INET6 with addr->sa_family = AF_INET.
4461 */
Alexey Kodanev0f8db8c2018-05-11 20:15:11 +03004462 switch (family_sa) {
4463 case AF_UNSPEC:
Richard Haines68741a8a2018-03-02 19:54:34 +00004464 case AF_INET:
4465 if (addrlen < sizeof(struct sockaddr_in))
4466 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004467 addr4 = (struct sockaddr_in *)address;
Alexey Kodanev0f8db8c2018-05-11 20:15:11 +03004468 if (family_sa == AF_UNSPEC) {
4469 /* see __inet_bind(), we only want to allow
4470 * AF_UNSPEC if the address is INADDR_ANY
4471 */
4472 if (addr4->sin_addr.s_addr != htonl(INADDR_ANY))
4473 goto err_af;
4474 family_sa = AF_INET;
4475 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004476 snum = ntohs(addr4->sin_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004477 addrp = (char *)&addr4->sin_addr.s_addr;
Richard Haines68741a8a2018-03-02 19:54:34 +00004478 break;
4479 case AF_INET6:
4480 if (addrlen < SIN6_LEN_RFC2133)
4481 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004482 addr6 = (struct sockaddr_in6 *)address;
4483 snum = ntohs(addr6->sin6_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004484 addrp = (char *)&addr6->sin6_addr.s6_addr;
Richard Haines68741a8a2018-03-02 19:54:34 +00004485 break;
4486 default:
Alexey Kodanev0f8db8c2018-05-11 20:15:11 +03004487 goto err_af;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004488 }
4489
Alexey Kodanev88b7d372018-05-11 20:15:12 +03004490 ad.type = LSM_AUDIT_DATA_NET;
4491 ad.u.net = &net;
4492 ad.u.net->sport = htons(snum);
4493 ad.u.net->family = family_sa;
4494
Stephen Hemminger227b60f2007-10-10 17:30:46 -07004495 if (snum) {
4496 int low, high;
4497
Eric W. Biederman0bbf87d2013-09-28 14:10:59 -07004498 inet_get_local_port_range(sock_net(sk), &low, &high);
Stephen Hemminger227b60f2007-10-10 17:30:46 -07004499
Krister Johansen4548b682017-01-20 17:49:11 -08004500 if (snum < max(inet_prot_sock(sock_net(sk)), low) ||
4501 snum > high) {
Paul Moore3e1121722008-04-10 10:48:14 -04004502 err = sel_netport_sid(sk->sk_protocol,
4503 snum, &sid);
Stephen Hemminger227b60f2007-10-10 17:30:46 -07004504 if (err)
4505 goto out;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05004506 err = avc_has_perm(&selinux_state,
4507 sksec->sid, sid,
Paul Moore253bfae2010-04-22 14:46:19 -04004508 sksec->sclass,
Stephen Hemminger227b60f2007-10-10 17:30:46 -07004509 SOCKET__NAME_BIND, &ad);
4510 if (err)
4511 goto out;
4512 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004513 }
Eric Paris828dfe12008-04-17 13:17:49 -04004514
Paul Moore253bfae2010-04-22 14:46:19 -04004515 switch (sksec->sclass) {
James Morris13402582005-09-30 14:24:34 -04004516 case SECCLASS_TCP_SOCKET:
Linus Torvalds1da177e2005-04-16 15:20:36 -07004517 node_perm = TCP_SOCKET__NODE_BIND;
4518 break;
Eric Paris828dfe12008-04-17 13:17:49 -04004519
James Morris13402582005-09-30 14:24:34 -04004520 case SECCLASS_UDP_SOCKET:
Linus Torvalds1da177e2005-04-16 15:20:36 -07004521 node_perm = UDP_SOCKET__NODE_BIND;
4522 break;
James Morris2ee92d42006-11-13 16:09:01 -08004523
4524 case SECCLASS_DCCP_SOCKET:
4525 node_perm = DCCP_SOCKET__NODE_BIND;
4526 break;
4527
Richard Hainesd4529302018-02-13 20:57:18 +00004528 case SECCLASS_SCTP_SOCKET:
4529 node_perm = SCTP_SOCKET__NODE_BIND;
4530 break;
4531
Linus Torvalds1da177e2005-04-16 15:20:36 -07004532 default:
4533 node_perm = RAWIP_SOCKET__NODE_BIND;
4534 break;
4535 }
Eric Paris828dfe12008-04-17 13:17:49 -04004536
Alexey Kodanev88b7d372018-05-11 20:15:12 +03004537 err = sel_netnode_sid(addrp, family_sa, &sid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004538 if (err)
4539 goto out;
Eric Paris828dfe12008-04-17 13:17:49 -04004540
Alexey Kodanev0f8db8c2018-05-11 20:15:11 +03004541 if (family_sa == AF_INET)
Eric Paris48c62af2012-04-02 13:15:44 -04004542 ad.u.net->v4info.saddr = addr4->sin_addr.s_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004543 else
Eric Paris48c62af2012-04-02 13:15:44 -04004544 ad.u.net->v6info.saddr = addr6->sin6_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004545
Stephen Smalley6b6bc622018-03-05 11:47:56 -05004546 err = avc_has_perm(&selinux_state,
4547 sksec->sid, sid,
Paul Moore253bfae2010-04-22 14:46:19 -04004548 sksec->sclass, node_perm, &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004549 if (err)
4550 goto out;
4551 }
4552out:
4553 return err;
Alexey Kodanev0f8db8c2018-05-11 20:15:11 +03004554err_af:
4555 /* Note that SCTP services expect -EINVAL, others -EAFNOSUPPORT. */
4556 if (sksec->sclass == SECCLASS_SCTP_SOCKET)
4557 return -EINVAL;
4558 return -EAFNOSUPPORT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004559}
4560
Richard Hainesd4529302018-02-13 20:57:18 +00004561/* This supports connect(2) and SCTP connect services such as sctp_connectx(3)
Kees Cookd61330c2019-02-17 14:08:36 -08004562 * and sctp_sendmsg(3) as described in Documentation/security/SCTP.rst
Richard Hainesd4529302018-02-13 20:57:18 +00004563 */
4564static int selinux_socket_connect_helper(struct socket *sock,
4565 struct sockaddr *address, int addrlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004566{
Paul Moore014ab192008-10-10 10:16:33 -04004567 struct sock *sk = sock->sk;
Paul Moore253bfae2010-04-22 14:46:19 -04004568 struct sk_security_struct *sksec = sk->sk_security;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004569 int err;
4570
Stephen Smalleybe0554c2017-01-09 10:07:31 -05004571 err = sock_has_perm(sk, SOCKET__CONNECT);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004572 if (err)
4573 return err;
4574
4575 /*
Richard Hainesd4529302018-02-13 20:57:18 +00004576 * If a TCP, DCCP or SCTP socket, check name_connect permission
4577 * for the port.
Linus Torvalds1da177e2005-04-16 15:20:36 -07004578 */
Paul Moore253bfae2010-04-22 14:46:19 -04004579 if (sksec->sclass == SECCLASS_TCP_SOCKET ||
Richard Hainesd4529302018-02-13 20:57:18 +00004580 sksec->sclass == SECCLASS_DCCP_SOCKET ||
4581 sksec->sclass == SECCLASS_SCTP_SOCKET) {
Thomas Liu2bf49692009-07-14 12:14:09 -04004582 struct common_audit_data ad;
Eric Paris48c62af2012-04-02 13:15:44 -04004583 struct lsm_network_audit net = {0,};
Linus Torvalds1da177e2005-04-16 15:20:36 -07004584 struct sockaddr_in *addr4 = NULL;
4585 struct sockaddr_in6 *addr6 = NULL;
4586 unsigned short snum;
James Morris2ee92d42006-11-13 16:09:01 -08004587 u32 sid, perm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004588
Richard Hainesd4529302018-02-13 20:57:18 +00004589 /* sctp_connectx(3) calls via selinux_sctp_bind_connect()
4590 * that validates multiple connect addresses. Because of this
4591 * need to check address->sa_family as it is possible to have
4592 * sk->sk_family = PF_INET6 with addr->sa_family = AF_INET.
4593 */
Richard Haines68741a8a2018-03-02 19:54:34 +00004594 switch (address->sa_family) {
4595 case AF_INET:
Linus Torvalds1da177e2005-04-16 15:20:36 -07004596 addr4 = (struct sockaddr_in *)address;
Stephen Smalley911656f2005-07-28 21:16:21 -07004597 if (addrlen < sizeof(struct sockaddr_in))
Linus Torvalds1da177e2005-04-16 15:20:36 -07004598 return -EINVAL;
4599 snum = ntohs(addr4->sin_port);
Richard Haines68741a8a2018-03-02 19:54:34 +00004600 break;
4601 case AF_INET6:
Linus Torvalds1da177e2005-04-16 15:20:36 -07004602 addr6 = (struct sockaddr_in6 *)address;
Stephen Smalley911656f2005-07-28 21:16:21 -07004603 if (addrlen < SIN6_LEN_RFC2133)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004604 return -EINVAL;
4605 snum = ntohs(addr6->sin6_port);
Richard Haines68741a8a2018-03-02 19:54:34 +00004606 break;
4607 default:
4608 /* Note that SCTP services expect -EINVAL, whereas
4609 * others expect -EAFNOSUPPORT.
4610 */
4611 if (sksec->sclass == SECCLASS_SCTP_SOCKET)
4612 return -EINVAL;
4613 else
4614 return -EAFNOSUPPORT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004615 }
4616
Paul Moore3e1121722008-04-10 10:48:14 -04004617 err = sel_netport_sid(sk->sk_protocol, snum, &sid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004618 if (err)
Richard Hainesd4529302018-02-13 20:57:18 +00004619 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004620
Richard Hainesd4529302018-02-13 20:57:18 +00004621 switch (sksec->sclass) {
4622 case SECCLASS_TCP_SOCKET:
4623 perm = TCP_SOCKET__NAME_CONNECT;
4624 break;
4625 case SECCLASS_DCCP_SOCKET:
4626 perm = DCCP_SOCKET__NAME_CONNECT;
4627 break;
4628 case SECCLASS_SCTP_SOCKET:
4629 perm = SCTP_SOCKET__NAME_CONNECT;
4630 break;
4631 }
James Morris2ee92d42006-11-13 16:09:01 -08004632
Eric Paris50c205f2012-04-04 15:01:43 -04004633 ad.type = LSM_AUDIT_DATA_NET;
Eric Paris48c62af2012-04-02 13:15:44 -04004634 ad.u.net = &net;
4635 ad.u.net->dport = htons(snum);
Alexey Kodanev88b7d372018-05-11 20:15:12 +03004636 ad.u.net->family = address->sa_family;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05004637 err = avc_has_perm(&selinux_state,
4638 sksec->sid, sid, sksec->sclass, perm, &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004639 if (err)
Richard Hainesd4529302018-02-13 20:57:18 +00004640 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004641 }
4642
Richard Hainesd4529302018-02-13 20:57:18 +00004643 return 0;
4644}
Paul Moore014ab192008-10-10 10:16:33 -04004645
Richard Hainesd4529302018-02-13 20:57:18 +00004646/* Supports connect(2), see comments in selinux_socket_connect_helper() */
4647static int selinux_socket_connect(struct socket *sock,
4648 struct sockaddr *address, int addrlen)
4649{
4650 int err;
4651 struct sock *sk = sock->sk;
4652
4653 err = selinux_socket_connect_helper(sock, address, addrlen);
4654 if (err)
4655 return err;
4656
4657 return selinux_netlbl_socket_connect(sk, address);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004658}
4659
4660static int selinux_socket_listen(struct socket *sock, int backlog)
4661{
Stephen Smalleybe0554c2017-01-09 10:07:31 -05004662 return sock_has_perm(sock->sk, SOCKET__LISTEN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004663}
4664
4665static int selinux_socket_accept(struct socket *sock, struct socket *newsock)
4666{
4667 int err;
4668 struct inode_security_struct *isec;
4669 struct inode_security_struct *newisec;
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01004670 u16 sclass;
4671 u32 sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004672
Stephen Smalleybe0554c2017-01-09 10:07:31 -05004673 err = sock_has_perm(sock->sk, SOCKET__ACCEPT);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004674 if (err)
4675 return err;
4676
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -05004677 isec = inode_security_novalidate(SOCK_INODE(sock));
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01004678 spin_lock(&isec->lock);
4679 sclass = isec->sclass;
4680 sid = isec->sid;
4681 spin_unlock(&isec->lock);
4682
4683 newisec = inode_security_novalidate(SOCK_INODE(newsock));
4684 newisec->sclass = sclass;
4685 newisec->sid = sid;
Andreas Gruenbacher6f3be9f2015-12-24 11:09:40 -05004686 newisec->initialized = LABEL_INITIALIZED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004687
4688 return 0;
4689}
4690
4691static int selinux_socket_sendmsg(struct socket *sock, struct msghdr *msg,
Eric Paris828dfe12008-04-17 13:17:49 -04004692 int size)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004693{
Stephen Smalleybe0554c2017-01-09 10:07:31 -05004694 return sock_has_perm(sock->sk, SOCKET__WRITE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004695}
4696
4697static int selinux_socket_recvmsg(struct socket *sock, struct msghdr *msg,
4698 int size, int flags)
4699{
Stephen Smalleybe0554c2017-01-09 10:07:31 -05004700 return sock_has_perm(sock->sk, SOCKET__READ);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004701}
4702
4703static int selinux_socket_getsockname(struct socket *sock)
4704{
Stephen Smalleybe0554c2017-01-09 10:07:31 -05004705 return sock_has_perm(sock->sk, SOCKET__GETATTR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004706}
4707
4708static int selinux_socket_getpeername(struct socket *sock)
4709{
Stephen Smalleybe0554c2017-01-09 10:07:31 -05004710 return sock_has_perm(sock->sk, SOCKET__GETATTR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004711}
4712
Eric Paris828dfe12008-04-17 13:17:49 -04004713static int selinux_socket_setsockopt(struct socket *sock, int level, int optname)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004714{
Paul Mooref8687af2006-10-30 15:22:15 -08004715 int err;
4716
Stephen Smalleybe0554c2017-01-09 10:07:31 -05004717 err = sock_has_perm(sock->sk, SOCKET__SETOPT);
Paul Mooref8687af2006-10-30 15:22:15 -08004718 if (err)
4719 return err;
4720
4721 return selinux_netlbl_socket_setsockopt(sock, level, optname);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004722}
4723
4724static int selinux_socket_getsockopt(struct socket *sock, int level,
4725 int optname)
4726{
Stephen Smalleybe0554c2017-01-09 10:07:31 -05004727 return sock_has_perm(sock->sk, SOCKET__GETOPT);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004728}
4729
4730static int selinux_socket_shutdown(struct socket *sock, int how)
4731{
Stephen Smalleybe0554c2017-01-09 10:07:31 -05004732 return sock_has_perm(sock->sk, SOCKET__SHUTDOWN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004733}
4734
David S. Miller3610cda2011-01-05 15:38:53 -08004735static int selinux_socket_unix_stream_connect(struct sock *sock,
4736 struct sock *other,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004737 struct sock *newsk)
4738{
David S. Miller3610cda2011-01-05 15:38:53 -08004739 struct sk_security_struct *sksec_sock = sock->sk_security;
4740 struct sk_security_struct *sksec_other = other->sk_security;
Paul Moore4d1e2452010-04-22 14:46:18 -04004741 struct sk_security_struct *sksec_new = newsk->sk_security;
Thomas Liu2bf49692009-07-14 12:14:09 -04004742 struct common_audit_data ad;
Eric Paris48c62af2012-04-02 13:15:44 -04004743 struct lsm_network_audit net = {0,};
Linus Torvalds1da177e2005-04-16 15:20:36 -07004744 int err;
4745
Eric Paris50c205f2012-04-04 15:01:43 -04004746 ad.type = LSM_AUDIT_DATA_NET;
Eric Paris48c62af2012-04-02 13:15:44 -04004747 ad.u.net = &net;
4748 ad.u.net->sk = other;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004749
Stephen Smalley6b6bc622018-03-05 11:47:56 -05004750 err = avc_has_perm(&selinux_state,
4751 sksec_sock->sid, sksec_other->sid,
Paul Moore4d1e2452010-04-22 14:46:18 -04004752 sksec_other->sclass,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004753 UNIX_STREAM_SOCKET__CONNECTTO, &ad);
4754 if (err)
4755 return err;
4756
Linus Torvalds1da177e2005-04-16 15:20:36 -07004757 /* server child socket */
Paul Moore4d1e2452010-04-22 14:46:18 -04004758 sksec_new->peer_sid = sksec_sock->sid;
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05004759 err = security_sid_mls_copy(&selinux_state, sksec_other->sid,
4760 sksec_sock->sid, &sksec_new->sid);
Paul Moore4d1e2452010-04-22 14:46:18 -04004761 if (err)
4762 return err;
Venkat Yekkirala4237c752006-07-24 23:32:50 -07004763
Paul Moore4d1e2452010-04-22 14:46:18 -04004764 /* connecting socket */
4765 sksec_sock->peer_sid = sksec_new->sid;
4766
4767 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004768}
4769
4770static int selinux_socket_unix_may_send(struct socket *sock,
4771 struct socket *other)
4772{
Paul Moore253bfae2010-04-22 14:46:19 -04004773 struct sk_security_struct *ssec = sock->sk->sk_security;
4774 struct sk_security_struct *osec = other->sk->sk_security;
Thomas Liu2bf49692009-07-14 12:14:09 -04004775 struct common_audit_data ad;
Eric Paris48c62af2012-04-02 13:15:44 -04004776 struct lsm_network_audit net = {0,};
Linus Torvalds1da177e2005-04-16 15:20:36 -07004777
Eric Paris50c205f2012-04-04 15:01:43 -04004778 ad.type = LSM_AUDIT_DATA_NET;
Eric Paris48c62af2012-04-02 13:15:44 -04004779 ad.u.net = &net;
4780 ad.u.net->sk = other->sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004781
Stephen Smalley6b6bc622018-03-05 11:47:56 -05004782 return avc_has_perm(&selinux_state,
4783 ssec->sid, osec->sid, osec->sclass, SOCKET__SENDTO,
Paul Moore253bfae2010-04-22 14:46:19 -04004784 &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004785}
4786
Paul Moorecbe0d6e2014-09-10 17:09:57 -04004787static int selinux_inet_sys_rcv_skb(struct net *ns, int ifindex,
4788 char *addrp, u16 family, u32 peer_sid,
Thomas Liu2bf49692009-07-14 12:14:09 -04004789 struct common_audit_data *ad)
Paul Mooreeffad8d2008-01-29 08:49:27 -05004790{
4791 int err;
4792 u32 if_sid;
4793 u32 node_sid;
4794
Paul Moorecbe0d6e2014-09-10 17:09:57 -04004795 err = sel_netif_sid(ns, ifindex, &if_sid);
Paul Mooreeffad8d2008-01-29 08:49:27 -05004796 if (err)
4797 return err;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05004798 err = avc_has_perm(&selinux_state,
4799 peer_sid, if_sid,
Paul Mooreeffad8d2008-01-29 08:49:27 -05004800 SECCLASS_NETIF, NETIF__INGRESS, ad);
4801 if (err)
4802 return err;
4803
4804 err = sel_netnode_sid(addrp, family, &node_sid);
4805 if (err)
4806 return err;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05004807 return avc_has_perm(&selinux_state,
4808 peer_sid, node_sid,
Paul Mooreeffad8d2008-01-29 08:49:27 -05004809 SECCLASS_NODE, NODE__RECVFROM, ad);
4810}
4811
Paul Moore220deb92008-01-29 08:38:23 -05004812static int selinux_sock_rcv_skb_compat(struct sock *sk, struct sk_buff *skb,
Paul Moored8395c82008-10-10 10:16:30 -04004813 u16 family)
Paul Moore220deb92008-01-29 08:38:23 -05004814{
Paul Moore277d3422008-12-31 12:54:11 -05004815 int err = 0;
Paul Moore220deb92008-01-29 08:38:23 -05004816 struct sk_security_struct *sksec = sk->sk_security;
Paul Moore220deb92008-01-29 08:38:23 -05004817 u32 sk_sid = sksec->sid;
Thomas Liu2bf49692009-07-14 12:14:09 -04004818 struct common_audit_data ad;
Eric Paris48c62af2012-04-02 13:15:44 -04004819 struct lsm_network_audit net = {0,};
Paul Moored8395c82008-10-10 10:16:30 -04004820 char *addrp;
4821
Eric Paris50c205f2012-04-04 15:01:43 -04004822 ad.type = LSM_AUDIT_DATA_NET;
Eric Paris48c62af2012-04-02 13:15:44 -04004823 ad.u.net = &net;
4824 ad.u.net->netif = skb->skb_iif;
4825 ad.u.net->family = family;
Paul Moored8395c82008-10-10 10:16:30 -04004826 err = selinux_parse_skb(skb, &ad, &addrp, 1, NULL);
4827 if (err)
4828 return err;
Paul Moore220deb92008-01-29 08:38:23 -05004829
Paul Moore58bfbb52009-03-27 17:10:41 -04004830 if (selinux_secmark_enabled()) {
Stephen Smalley6b6bc622018-03-05 11:47:56 -05004831 err = avc_has_perm(&selinux_state,
4832 sk_sid, skb->secmark, SECCLASS_PACKET,
Paul Moored8395c82008-10-10 10:16:30 -04004833 PACKET__RECV, &ad);
Paul Moore58bfbb52009-03-27 17:10:41 -04004834 if (err)
4835 return err;
4836 }
Paul Moore220deb92008-01-29 08:38:23 -05004837
Steffen Klassertb9679a72011-02-23 12:55:21 +01004838 err = selinux_netlbl_sock_rcv_skb(sksec, skb, family, &ad);
4839 if (err)
4840 return err;
4841 err = selinux_xfrm_sock_rcv_skb(sksec->sid, skb, &ad);
Trent Jaegerd28d1e02005-12-13 23:12:40 -08004842
James Morris4e5ab4c2006-06-09 00:33:33 -07004843 return err;
4844}
Trent Jaegerd28d1e02005-12-13 23:12:40 -08004845
James Morris4e5ab4c2006-06-09 00:33:33 -07004846static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
4847{
Paul Moore220deb92008-01-29 08:38:23 -05004848 int err;
Venkat Yekkirala4237c752006-07-24 23:32:50 -07004849 struct sk_security_struct *sksec = sk->sk_security;
Paul Moore220deb92008-01-29 08:38:23 -05004850 u16 family = sk->sk_family;
4851 u32 sk_sid = sksec->sid;
Thomas Liu2bf49692009-07-14 12:14:09 -04004852 struct common_audit_data ad;
Eric Paris48c62af2012-04-02 13:15:44 -04004853 struct lsm_network_audit net = {0,};
Paul Moore220deb92008-01-29 08:38:23 -05004854 char *addrp;
Paul Moored8395c82008-10-10 10:16:30 -04004855 u8 secmark_active;
4856 u8 peerlbl_active;
James Morris4e5ab4c2006-06-09 00:33:33 -07004857
James Morris4e5ab4c2006-06-09 00:33:33 -07004858 if (family != PF_INET && family != PF_INET6)
Paul Moore220deb92008-01-29 08:38:23 -05004859 return 0;
James Morris4e5ab4c2006-06-09 00:33:33 -07004860
4861 /* Handle mapped IPv4 packets arriving via IPv6 sockets */
Al Viro87fcd702006-12-04 22:00:55 +00004862 if (family == PF_INET6 && skb->protocol == htons(ETH_P_IP))
James Morris4e5ab4c2006-06-09 00:33:33 -07004863 family = PF_INET;
4864
Paul Moored8395c82008-10-10 10:16:30 -04004865 /* If any sort of compatibility mode is enabled then handoff processing
4866 * to the selinux_sock_rcv_skb_compat() function to deal with the
4867 * special handling. We do this in an attempt to keep this function
4868 * as fast and as clean as possible. */
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05004869 if (!selinux_policycap_netpeer())
Paul Moored8395c82008-10-10 10:16:30 -04004870 return selinux_sock_rcv_skb_compat(sk, skb, family);
4871
4872 secmark_active = selinux_secmark_enabled();
Chris PeBenito2be4d742013-05-03 09:05:39 -04004873 peerlbl_active = selinux_peerlbl_enabled();
Paul Moored8395c82008-10-10 10:16:30 -04004874 if (!secmark_active && !peerlbl_active)
4875 return 0;
4876
Eric Paris50c205f2012-04-04 15:01:43 -04004877 ad.type = LSM_AUDIT_DATA_NET;
Eric Paris48c62af2012-04-02 13:15:44 -04004878 ad.u.net = &net;
4879 ad.u.net->netif = skb->skb_iif;
4880 ad.u.net->family = family;
Paul Moore224dfbd2008-01-29 08:38:13 -05004881 err = selinux_parse_skb(skb, &ad, &addrp, 1, NULL);
James Morris4e5ab4c2006-06-09 00:33:33 -07004882 if (err)
Paul Moore220deb92008-01-29 08:38:23 -05004883 return err;
James Morris4e5ab4c2006-06-09 00:33:33 -07004884
Paul Moored8395c82008-10-10 10:16:30 -04004885 if (peerlbl_active) {
Paul Moored621d352008-01-29 08:43:36 -05004886 u32 peer_sid;
4887
4888 err = selinux_skb_peerlbl_sid(skb, family, &peer_sid);
4889 if (err)
4890 return err;
Paul Moorecbe0d6e2014-09-10 17:09:57 -04004891 err = selinux_inet_sys_rcv_skb(sock_net(sk), skb->skb_iif,
4892 addrp, family, peer_sid, &ad);
Paul Mooredfaebe92008-10-10 10:16:31 -04004893 if (err) {
Huw Daviesa04e71f2016-06-27 15:06:16 -04004894 selinux_netlbl_err(skb, family, err, 0);
Paul Mooreeffad8d2008-01-29 08:49:27 -05004895 return err;
Paul Mooredfaebe92008-10-10 10:16:31 -04004896 }
Stephen Smalley6b6bc622018-03-05 11:47:56 -05004897 err = avc_has_perm(&selinux_state,
4898 sk_sid, peer_sid, SECCLASS_PEER,
Paul Moored621d352008-01-29 08:43:36 -05004899 PEER__RECV, &ad);
Chad Hanson46d01d62013-12-23 17:45:01 -05004900 if (err) {
Huw Daviesa04e71f2016-06-27 15:06:16 -04004901 selinux_netlbl_err(skb, family, err, 0);
Chad Hanson46d01d62013-12-23 17:45:01 -05004902 return err;
4903 }
Paul Moored621d352008-01-29 08:43:36 -05004904 }
4905
Paul Moored8395c82008-10-10 10:16:30 -04004906 if (secmark_active) {
Stephen Smalley6b6bc622018-03-05 11:47:56 -05004907 err = avc_has_perm(&selinux_state,
4908 sk_sid, skb->secmark, SECCLASS_PACKET,
Paul Mooreeffad8d2008-01-29 08:49:27 -05004909 PACKET__RECV, &ad);
4910 if (err)
4911 return err;
4912 }
4913
Paul Moored621d352008-01-29 08:43:36 -05004914 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004915}
4916
Catherine Zhang2c7946a2006-03-20 22:41:23 -08004917static int selinux_socket_getpeersec_stream(struct socket *sock, char __user *optval,
4918 int __user *optlen, unsigned len)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004919{
4920 int err = 0;
4921 char *scontext;
4922 u32 scontext_len;
Paul Moore253bfae2010-04-22 14:46:19 -04004923 struct sk_security_struct *sksec = sock->sk->sk_security;
Paul Moore3de4bab2006-11-17 17:38:54 -05004924 u32 peer_sid = SECSID_NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004925
Paul Moore253bfae2010-04-22 14:46:19 -04004926 if (sksec->sclass == SECCLASS_UNIX_STREAM_SOCKET ||
Richard Hainesd4529302018-02-13 20:57:18 +00004927 sksec->sclass == SECCLASS_TCP_SOCKET ||
4928 sksec->sclass == SECCLASS_SCTP_SOCKET)
Eric Parisdd3e7832010-04-07 15:08:46 -04004929 peer_sid = sksec->peer_sid;
Paul Moore253bfae2010-04-22 14:46:19 -04004930 if (peer_sid == SECSID_NULL)
4931 return -ENOPROTOOPT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004932
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05004933 err = security_sid_to_context(&selinux_state, peer_sid, &scontext,
4934 &scontext_len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004935 if (err)
Paul Moore253bfae2010-04-22 14:46:19 -04004936 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004937
4938 if (scontext_len > len) {
4939 err = -ERANGE;
4940 goto out_len;
4941 }
4942
4943 if (copy_to_user(optval, scontext, scontext_len))
4944 err = -EFAULT;
4945
4946out_len:
4947 if (put_user(scontext_len, optlen))
4948 err = -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004949 kfree(scontext);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004950 return err;
4951}
4952
Catherine Zhangdc49c1f2006-08-02 14:12:06 -07004953static int selinux_socket_getpeersec_dgram(struct socket *sock, struct sk_buff *skb, u32 *secid)
Catherine Zhang2c7946a2006-03-20 22:41:23 -08004954{
Catherine Zhangdc49c1f2006-08-02 14:12:06 -07004955 u32 peer_secid = SECSID_NULL;
Paul Moore75e22912008-01-29 08:38:04 -05004956 u16 family;
Paul Moore899134f2016-03-28 15:19:10 -04004957 struct inode_security_struct *isec;
Catherine Zhang877ce7c2006-06-29 12:27:47 -07004958
Paul Mooreaa862902008-10-10 10:16:29 -04004959 if (skb && skb->protocol == htons(ETH_P_IP))
4960 family = PF_INET;
4961 else if (skb && skb->protocol == htons(ETH_P_IPV6))
4962 family = PF_INET6;
4963 else if (sock)
Paul Moore75e22912008-01-29 08:38:04 -05004964 family = sock->sk->sk_family;
Paul Moore75e22912008-01-29 08:38:04 -05004965 else
4966 goto out;
4967
Paul Moore899134f2016-03-28 15:19:10 -04004968 if (sock && family == PF_UNIX) {
4969 isec = inode_security_novalidate(SOCK_INODE(sock));
4970 peer_secid = isec->sid;
4971 } else if (skb)
Paul Moore220deb92008-01-29 08:38:23 -05004972 selinux_skb_peerlbl_sid(skb, family, &peer_secid);
Catherine Zhang2c7946a2006-03-20 22:41:23 -08004973
Paul Moore75e22912008-01-29 08:38:04 -05004974out:
Catherine Zhangdc49c1f2006-08-02 14:12:06 -07004975 *secid = peer_secid;
Paul Moore75e22912008-01-29 08:38:04 -05004976 if (peer_secid == SECSID_NULL)
4977 return -EINVAL;
4978 return 0;
Catherine Zhang2c7946a2006-03-20 22:41:23 -08004979}
4980
Al Viro7d877f32005-10-21 03:20:43 -04004981static int selinux_sk_alloc_security(struct sock *sk, int family, gfp_t priority)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004982{
Paul Moore84914b72010-04-22 14:46:18 -04004983 struct sk_security_struct *sksec;
4984
4985 sksec = kzalloc(sizeof(*sksec), priority);
4986 if (!sksec)
4987 return -ENOMEM;
4988
4989 sksec->peer_sid = SECINITSID_UNLABELED;
4990 sksec->sid = SECINITSID_UNLABELED;
Stephen Smalley5dee25d2015-07-10 17:19:57 -04004991 sksec->sclass = SECCLASS_SOCKET;
Paul Moore84914b72010-04-22 14:46:18 -04004992 selinux_netlbl_sk_security_reset(sksec);
4993 sk->sk_security = sksec;
4994
4995 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004996}
4997
4998static void selinux_sk_free_security(struct sock *sk)
4999{
Paul Moore84914b72010-04-22 14:46:18 -04005000 struct sk_security_struct *sksec = sk->sk_security;
5001
5002 sk->sk_security = NULL;
5003 selinux_netlbl_sk_security_free(sksec);
5004 kfree(sksec);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005005}
5006
Venkat Yekkirala892c1412006-08-04 23:08:56 -07005007static void selinux_sk_clone_security(const struct sock *sk, struct sock *newsk)
5008{
Eric Parisdd3e7832010-04-07 15:08:46 -04005009 struct sk_security_struct *sksec = sk->sk_security;
5010 struct sk_security_struct *newsksec = newsk->sk_security;
Venkat Yekkirala892c1412006-08-04 23:08:56 -07005011
Eric Parisdd3e7832010-04-07 15:08:46 -04005012 newsksec->sid = sksec->sid;
5013 newsksec->peer_sid = sksec->peer_sid;
5014 newsksec->sclass = sksec->sclass;
Paul Moore99f59ed2006-08-29 17:53:48 -07005015
Eric Parisdd3e7832010-04-07 15:08:46 -04005016 selinux_netlbl_sk_security_reset(newsksec);
Venkat Yekkirala892c1412006-08-04 23:08:56 -07005017}
5018
Venkat Yekkiralabeb8d132006-08-04 23:12:42 -07005019static void selinux_sk_getsecid(struct sock *sk, u32 *secid)
Trent Jaegerd28d1e02005-12-13 23:12:40 -08005020{
Trent Jaegerd28d1e02005-12-13 23:12:40 -08005021 if (!sk)
Venkat Yekkiralabeb8d132006-08-04 23:12:42 -07005022 *secid = SECINITSID_ANY_SOCKET;
Venkat Yekkirala892c1412006-08-04 23:08:56 -07005023 else {
5024 struct sk_security_struct *sksec = sk->sk_security;
Trent Jaegerd28d1e02005-12-13 23:12:40 -08005025
Venkat Yekkiralabeb8d132006-08-04 23:12:42 -07005026 *secid = sksec->sid;
Venkat Yekkirala892c1412006-08-04 23:08:56 -07005027 }
Trent Jaegerd28d1e02005-12-13 23:12:40 -08005028}
5029
Eric Paris828dfe12008-04-17 13:17:49 -04005030static void selinux_sock_graft(struct sock *sk, struct socket *parent)
Venkat Yekkirala4237c752006-07-24 23:32:50 -07005031{
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -05005032 struct inode_security_struct *isec =
5033 inode_security_novalidate(SOCK_INODE(parent));
Venkat Yekkirala4237c752006-07-24 23:32:50 -07005034 struct sk_security_struct *sksec = sk->sk_security;
5035
Paul Moore2873ead2014-07-28 10:42:48 -04005036 if (sk->sk_family == PF_INET || sk->sk_family == PF_INET6 ||
5037 sk->sk_family == PF_UNIX)
David Woodhouse2148ccc2006-09-29 15:50:25 -07005038 isec->sid = sksec->sid;
Paul Moore220deb92008-01-29 08:38:23 -05005039 sksec->sclass = isec->sclass;
Venkat Yekkirala4237c752006-07-24 23:32:50 -07005040}
5041
Richard Hainesd4529302018-02-13 20:57:18 +00005042/* Called whenever SCTP receives an INIT chunk. This happens when an incoming
5043 * connect(2), sctp_connectx(3) or sctp_sendmsg(3) (with no association
5044 * already present).
5045 */
5046static int selinux_sctp_assoc_request(struct sctp_endpoint *ep,
5047 struct sk_buff *skb)
5048{
5049 struct sk_security_struct *sksec = ep->base.sk->sk_security;
5050 struct common_audit_data ad;
5051 struct lsm_network_audit net = {0,};
5052 u8 peerlbl_active;
5053 u32 peer_sid = SECINITSID_UNLABELED;
5054 u32 conn_sid;
5055 int err = 0;
5056
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05005057 if (!selinux_policycap_extsockclass())
Richard Hainesd4529302018-02-13 20:57:18 +00005058 return 0;
5059
5060 peerlbl_active = selinux_peerlbl_enabled();
5061
5062 if (peerlbl_active) {
5063 /* This will return peer_sid = SECSID_NULL if there are
5064 * no peer labels, see security_net_peersid_resolve().
5065 */
5066 err = selinux_skb_peerlbl_sid(skb, ep->base.sk->sk_family,
5067 &peer_sid);
5068 if (err)
5069 return err;
5070
5071 if (peer_sid == SECSID_NULL)
5072 peer_sid = SECINITSID_UNLABELED;
5073 }
5074
5075 if (sksec->sctp_assoc_state == SCTP_ASSOC_UNSET) {
5076 sksec->sctp_assoc_state = SCTP_ASSOC_SET;
5077
5078 /* Here as first association on socket. As the peer SID
5079 * was allowed by peer recv (and the netif/node checks),
5080 * then it is approved by policy and used as the primary
5081 * peer SID for getpeercon(3).
5082 */
5083 sksec->peer_sid = peer_sid;
5084 } else if (sksec->peer_sid != peer_sid) {
5085 /* Other association peer SIDs are checked to enforce
5086 * consistency among the peer SIDs.
5087 */
5088 ad.type = LSM_AUDIT_DATA_NET;
5089 ad.u.net = &net;
5090 ad.u.net->sk = ep->base.sk;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005091 err = avc_has_perm(&selinux_state,
5092 sksec->peer_sid, peer_sid, sksec->sclass,
Richard Hainesd4529302018-02-13 20:57:18 +00005093 SCTP_SOCKET__ASSOCIATION, &ad);
5094 if (err)
5095 return err;
5096 }
5097
5098 /* Compute the MLS component for the connection and store
5099 * the information in ep. This will be used by SCTP TCP type
5100 * sockets and peeled off connections as they cause a new
5101 * socket to be generated. selinux_sctp_sk_clone() will then
5102 * plug this into the new socket.
5103 */
5104 err = selinux_conn_sid(sksec->sid, peer_sid, &conn_sid);
5105 if (err)
5106 return err;
5107
5108 ep->secid = conn_sid;
5109 ep->peer_secid = peer_sid;
5110
5111 /* Set any NetLabel labels including CIPSO/CALIPSO options. */
5112 return selinux_netlbl_sctp_assoc_request(ep, skb);
5113}
5114
5115/* Check if sctp IPv4/IPv6 addresses are valid for binding or connecting
5116 * based on their @optname.
5117 */
5118static int selinux_sctp_bind_connect(struct sock *sk, int optname,
5119 struct sockaddr *address,
5120 int addrlen)
5121{
5122 int len, err = 0, walk_size = 0;
5123 void *addr_buf;
5124 struct sockaddr *addr;
5125 struct socket *sock;
5126
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05005127 if (!selinux_policycap_extsockclass())
Richard Hainesd4529302018-02-13 20:57:18 +00005128 return 0;
5129
5130 /* Process one or more addresses that may be IPv4 or IPv6 */
5131 sock = sk->sk_socket;
5132 addr_buf = address;
5133
5134 while (walk_size < addrlen) {
Ondrej Mosnacekc1383252018-11-13 16:16:08 +01005135 if (walk_size + sizeof(sa_family_t) > addrlen)
5136 return -EINVAL;
5137
Richard Hainesd4529302018-02-13 20:57:18 +00005138 addr = addr_buf;
5139 switch (addr->sa_family) {
Alexey Kodanev4152dc92018-05-11 20:15:13 +03005140 case AF_UNSPEC:
Richard Hainesd4529302018-02-13 20:57:18 +00005141 case AF_INET:
5142 len = sizeof(struct sockaddr_in);
5143 break;
5144 case AF_INET6:
5145 len = sizeof(struct sockaddr_in6);
5146 break;
5147 default:
Alexey Kodanev4152dc92018-05-11 20:15:13 +03005148 return -EINVAL;
Richard Hainesd4529302018-02-13 20:57:18 +00005149 }
5150
Xin Long292c9972019-03-09 00:07:34 +08005151 if (walk_size + len > addrlen)
5152 return -EINVAL;
5153
Richard Hainesd4529302018-02-13 20:57:18 +00005154 err = -EINVAL;
5155 switch (optname) {
5156 /* Bind checks */
5157 case SCTP_PRIMARY_ADDR:
5158 case SCTP_SET_PEER_PRIMARY_ADDR:
5159 case SCTP_SOCKOPT_BINDX_ADD:
5160 err = selinux_socket_bind(sock, addr, len);
5161 break;
5162 /* Connect checks */
5163 case SCTP_SOCKOPT_CONNECTX:
5164 case SCTP_PARAM_SET_PRIMARY:
5165 case SCTP_PARAM_ADD_IP:
5166 case SCTP_SENDMSG_CONNECT:
5167 err = selinux_socket_connect_helper(sock, addr, len);
5168 if (err)
5169 return err;
5170
5171 /* As selinux_sctp_bind_connect() is called by the
5172 * SCTP protocol layer, the socket is already locked,
5173 * therefore selinux_netlbl_socket_connect_locked() is
5174 * is called here. The situations handled are:
5175 * sctp_connectx(3), sctp_sendmsg(3), sendmsg(2),
5176 * whenever a new IP address is added or when a new
5177 * primary address is selected.
5178 * Note that an SCTP connect(2) call happens before
5179 * the SCTP protocol layer and is handled via
5180 * selinux_socket_connect().
5181 */
5182 err = selinux_netlbl_socket_connect_locked(sk, addr);
5183 break;
5184 }
5185
5186 if (err)
5187 return err;
5188
5189 addr_buf += len;
5190 walk_size += len;
5191 }
5192
5193 return 0;
5194}
5195
5196/* Called whenever a new socket is created by accept(2) or sctp_peeloff(3). */
5197static void selinux_sctp_sk_clone(struct sctp_endpoint *ep, struct sock *sk,
5198 struct sock *newsk)
5199{
5200 struct sk_security_struct *sksec = sk->sk_security;
5201 struct sk_security_struct *newsksec = newsk->sk_security;
5202
5203 /* If policy does not support SECCLASS_SCTP_SOCKET then call
5204 * the non-sctp clone version.
5205 */
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05005206 if (!selinux_policycap_extsockclass())
Richard Hainesd4529302018-02-13 20:57:18 +00005207 return selinux_sk_clone_security(sk, newsk);
5208
5209 newsksec->sid = ep->secid;
5210 newsksec->peer_sid = ep->peer_secid;
5211 newsksec->sclass = sksec->sclass;
5212 selinux_netlbl_sctp_sk_clone(sk, newsk);
5213}
5214
Adrian Bunk9a673e52006-08-15 00:03:53 -07005215static int selinux_inet_conn_request(struct sock *sk, struct sk_buff *skb,
5216 struct request_sock *req)
Venkat Yekkirala4237c752006-07-24 23:32:50 -07005217{
5218 struct sk_security_struct *sksec = sk->sk_security;
5219 int err;
Paul Moore0b1f24e2013-12-03 11:39:13 -05005220 u16 family = req->rsk_ops->family;
Paul Moore446b8022013-12-04 16:10:51 -05005221 u32 connsid;
Venkat Yekkirala4237c752006-07-24 23:32:50 -07005222 u32 peersid;
5223
Paul Mooreaa862902008-10-10 10:16:29 -04005224 err = selinux_skb_peerlbl_sid(skb, family, &peersid);
Paul Moore220deb92008-01-29 08:38:23 -05005225 if (err)
5226 return err;
Paul Moore446b8022013-12-04 16:10:51 -05005227 err = selinux_conn_sid(sksec->sid, peersid, &connsid);
5228 if (err)
5229 return err;
5230 req->secid = connsid;
5231 req->peer_secid = peersid;
Venkat Yekkiralaa51c64f2006-07-27 22:01:34 -07005232
Paul Moore389fb8002009-03-27 17:10:34 -04005233 return selinux_netlbl_inet_conn_request(req, family);
Venkat Yekkirala4237c752006-07-24 23:32:50 -07005234}
5235
Adrian Bunk9a673e52006-08-15 00:03:53 -07005236static void selinux_inet_csk_clone(struct sock *newsk,
5237 const struct request_sock *req)
Venkat Yekkirala4237c752006-07-24 23:32:50 -07005238{
5239 struct sk_security_struct *newsksec = newsk->sk_security;
5240
5241 newsksec->sid = req->secid;
Venkat Yekkirala6b877692006-11-08 17:04:09 -06005242 newsksec->peer_sid = req->peer_secid;
Venkat Yekkirala4237c752006-07-24 23:32:50 -07005243 /* NOTE: Ideally, we should also get the isec->sid for the
5244 new socket in sync, but we don't have the isec available yet.
5245 So we will wait until sock_graft to do it, by which
5246 time it will have been created and available. */
Paul Moore99f59ed2006-08-29 17:53:48 -07005247
Paul Moore9f2ad662006-11-17 17:38:53 -05005248 /* We don't need to take any sort of lock here as we are the only
5249 * thread with access to newsksec */
Paul Moore389fb8002009-03-27 17:10:34 -04005250 selinux_netlbl_inet_csk_clone(newsk, req->rsk_ops->family);
Venkat Yekkirala4237c752006-07-24 23:32:50 -07005251}
5252
Paul Moore014ab192008-10-10 10:16:33 -04005253static void selinux_inet_conn_established(struct sock *sk, struct sk_buff *skb)
Venkat Yekkirala6b877692006-11-08 17:04:09 -06005254{
Paul Mooreaa862902008-10-10 10:16:29 -04005255 u16 family = sk->sk_family;
Venkat Yekkirala6b877692006-11-08 17:04:09 -06005256 struct sk_security_struct *sksec = sk->sk_security;
5257
Paul Mooreaa862902008-10-10 10:16:29 -04005258 /* handle mapped IPv4 packets arriving via IPv6 sockets */
5259 if (family == PF_INET6 && skb->protocol == htons(ETH_P_IP))
5260 family = PF_INET;
5261
5262 selinux_skb_peerlbl_sid(skb, family, &sksec->peer_sid);
Venkat Yekkirala6b877692006-11-08 17:04:09 -06005263}
5264
Eric Paris2606fd12010-10-13 16:24:41 -04005265static int selinux_secmark_relabel_packet(u32 sid)
5266{
5267 const struct task_security_struct *__tsec;
5268 u32 tsid;
5269
Casey Schaufler0c6cfa62018-09-21 17:17:16 -07005270 __tsec = selinux_cred(current_cred());
Eric Paris2606fd12010-10-13 16:24:41 -04005271 tsid = __tsec->sid;
5272
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005273 return avc_has_perm(&selinux_state,
5274 tsid, sid, SECCLASS_PACKET, PACKET__RELABELTO,
5275 NULL);
Eric Paris2606fd12010-10-13 16:24:41 -04005276}
5277
5278static void selinux_secmark_refcount_inc(void)
5279{
5280 atomic_inc(&selinux_secmark_refcount);
5281}
5282
5283static void selinux_secmark_refcount_dec(void)
5284{
5285 atomic_dec(&selinux_secmark_refcount);
5286}
5287
Adrian Bunk9a673e52006-08-15 00:03:53 -07005288static void selinux_req_classify_flow(const struct request_sock *req,
5289 struct flowi *fl)
Venkat Yekkirala4237c752006-07-24 23:32:50 -07005290{
David S. Miller1d28f422011-03-12 00:29:39 -05005291 fl->flowi_secid = req->secid;
Venkat Yekkirala4237c752006-07-24 23:32:50 -07005292}
5293
Paul Moore5dbbaf22013-01-14 07:12:19 +00005294static int selinux_tun_dev_alloc_security(void **security)
5295{
5296 struct tun_security_struct *tunsec;
5297
5298 tunsec = kzalloc(sizeof(*tunsec), GFP_KERNEL);
5299 if (!tunsec)
5300 return -ENOMEM;
5301 tunsec->sid = current_sid();
5302
5303 *security = tunsec;
5304 return 0;
5305}
5306
5307static void selinux_tun_dev_free_security(void *security)
5308{
5309 kfree(security);
5310}
5311
Paul Mooreed6d76e2009-08-28 18:12:49 -04005312static int selinux_tun_dev_create(void)
5313{
5314 u32 sid = current_sid();
5315
5316 /* we aren't taking into account the "sockcreate" SID since the socket
5317 * that is being created here is not a socket in the traditional sense,
5318 * instead it is a private sock, accessible only to the kernel, and
5319 * representing a wide range of network traffic spanning multiple
5320 * connections unlike traditional sockets - check the TUN driver to
5321 * get a better understanding of why this socket is special */
5322
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005323 return avc_has_perm(&selinux_state,
5324 sid, sid, SECCLASS_TUN_SOCKET, TUN_SOCKET__CREATE,
Paul Mooreed6d76e2009-08-28 18:12:49 -04005325 NULL);
5326}
5327
Paul Moore5dbbaf22013-01-14 07:12:19 +00005328static int selinux_tun_dev_attach_queue(void *security)
Paul Mooreed6d76e2009-08-28 18:12:49 -04005329{
Paul Moore5dbbaf22013-01-14 07:12:19 +00005330 struct tun_security_struct *tunsec = security;
5331
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005332 return avc_has_perm(&selinux_state,
5333 current_sid(), tunsec->sid, SECCLASS_TUN_SOCKET,
Paul Moore5dbbaf22013-01-14 07:12:19 +00005334 TUN_SOCKET__ATTACH_QUEUE, NULL);
5335}
5336
5337static int selinux_tun_dev_attach(struct sock *sk, void *security)
5338{
5339 struct tun_security_struct *tunsec = security;
Paul Mooreed6d76e2009-08-28 18:12:49 -04005340 struct sk_security_struct *sksec = sk->sk_security;
5341
5342 /* we don't currently perform any NetLabel based labeling here and it
5343 * isn't clear that we would want to do so anyway; while we could apply
5344 * labeling without the support of the TUN user the resulting labeled
5345 * traffic from the other end of the connection would almost certainly
5346 * cause confusion to the TUN user that had no idea network labeling
5347 * protocols were being used */
5348
Paul Moore5dbbaf22013-01-14 07:12:19 +00005349 sksec->sid = tunsec->sid;
Paul Mooreed6d76e2009-08-28 18:12:49 -04005350 sksec->sclass = SECCLASS_TUN_SOCKET;
Paul Moore5dbbaf22013-01-14 07:12:19 +00005351
5352 return 0;
Paul Mooreed6d76e2009-08-28 18:12:49 -04005353}
5354
Paul Moore5dbbaf22013-01-14 07:12:19 +00005355static int selinux_tun_dev_open(void *security)
Paul Mooreed6d76e2009-08-28 18:12:49 -04005356{
Paul Moore5dbbaf22013-01-14 07:12:19 +00005357 struct tun_security_struct *tunsec = security;
Paul Mooreed6d76e2009-08-28 18:12:49 -04005358 u32 sid = current_sid();
5359 int err;
5360
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005361 err = avc_has_perm(&selinux_state,
5362 sid, tunsec->sid, SECCLASS_TUN_SOCKET,
Paul Mooreed6d76e2009-08-28 18:12:49 -04005363 TUN_SOCKET__RELABELFROM, NULL);
5364 if (err)
5365 return err;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005366 err = avc_has_perm(&selinux_state,
5367 sid, sid, SECCLASS_TUN_SOCKET,
Paul Mooreed6d76e2009-08-28 18:12:49 -04005368 TUN_SOCKET__RELABELTO, NULL);
5369 if (err)
5370 return err;
Paul Moore5dbbaf22013-01-14 07:12:19 +00005371 tunsec->sid = sid;
Paul Mooreed6d76e2009-08-28 18:12:49 -04005372
5373 return 0;
5374}
5375
Linus Torvalds1da177e2005-04-16 15:20:36 -07005376static int selinux_nlmsg_perm(struct sock *sk, struct sk_buff *skb)
5377{
5378 int err = 0;
5379 u32 perm;
5380 struct nlmsghdr *nlh;
Paul Moore253bfae2010-04-22 14:46:19 -04005381 struct sk_security_struct *sksec = sk->sk_security;
Eric Paris828dfe12008-04-17 13:17:49 -04005382
Hong zhi guo77954982013-03-27 06:49:35 +00005383 if (skb->len < NLMSG_HDRLEN) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005384 err = -EINVAL;
5385 goto out;
5386 }
Arnaldo Carvalho de Melob529ccf2007-04-25 19:08:35 -07005387 nlh = nlmsg_hdr(skb);
Eric Paris828dfe12008-04-17 13:17:49 -04005388
Paul Moore253bfae2010-04-22 14:46:19 -04005389 err = selinux_nlmsg_lookup(sksec->sclass, nlh->nlmsg_type, &perm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005390 if (err) {
5391 if (err == -EINVAL) {
Vladis Dronov76319942015-12-24 11:09:41 -05005392 pr_warn_ratelimited("SELinux: unrecognized netlink"
5393 " message: protocol=%hu nlmsg_type=%hu sclass=%s"
5394 " pig=%d comm=%s\n",
Marek Milkoviccded3ff2015-06-04 16:22:16 -04005395 sk->sk_protocol, nlh->nlmsg_type,
Vladis Dronov76319942015-12-24 11:09:41 -05005396 secclass_map[sksec->sclass - 1].name,
5397 task_pid_nr(current), current->comm);
Paul Mooree5a5ca92018-03-01 17:38:30 -05005398 if (!enforcing_enabled(&selinux_state) ||
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05005399 security_get_allow_unknown(&selinux_state))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005400 err = 0;
5401 }
5402
5403 /* Ignore */
5404 if (err == -ENOENT)
5405 err = 0;
5406 goto out;
5407 }
5408
Stephen Smalleybe0554c2017-01-09 10:07:31 -05005409 err = sock_has_perm(sk, perm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005410out:
5411 return err;
5412}
5413
5414#ifdef CONFIG_NETFILTER
5415
Paul Moorecbe0d6e2014-09-10 17:09:57 -04005416static unsigned int selinux_ip_forward(struct sk_buff *skb,
5417 const struct net_device *indev,
Paul Mooreeffad8d2008-01-29 08:49:27 -05005418 u16 family)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005419{
Paul Mooredfaebe92008-10-10 10:16:31 -04005420 int err;
Paul Mooreeffad8d2008-01-29 08:49:27 -05005421 char *addrp;
5422 u32 peer_sid;
Thomas Liu2bf49692009-07-14 12:14:09 -04005423 struct common_audit_data ad;
Eric Paris48c62af2012-04-02 13:15:44 -04005424 struct lsm_network_audit net = {0,};
Paul Mooreeffad8d2008-01-29 08:49:27 -05005425 u8 secmark_active;
Paul Moore948bf852008-10-10 10:16:32 -04005426 u8 netlbl_active;
Paul Mooreeffad8d2008-01-29 08:49:27 -05005427 u8 peerlbl_active;
Venkat Yekkirala4237c752006-07-24 23:32:50 -07005428
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05005429 if (!selinux_policycap_netpeer())
Paul Mooreeffad8d2008-01-29 08:49:27 -05005430 return NF_ACCEPT;
Venkat Yekkirala4237c752006-07-24 23:32:50 -07005431
Paul Mooreeffad8d2008-01-29 08:49:27 -05005432 secmark_active = selinux_secmark_enabled();
Paul Moore948bf852008-10-10 10:16:32 -04005433 netlbl_active = netlbl_enabled();
Chris PeBenito2be4d742013-05-03 09:05:39 -04005434 peerlbl_active = selinux_peerlbl_enabled();
Paul Mooreeffad8d2008-01-29 08:49:27 -05005435 if (!secmark_active && !peerlbl_active)
5436 return NF_ACCEPT;
Venkat Yekkirala4237c752006-07-24 23:32:50 -07005437
Paul Moored8395c82008-10-10 10:16:30 -04005438 if (selinux_skb_peerlbl_sid(skb, family, &peer_sid) != 0)
5439 return NF_DROP;
5440
Eric Paris50c205f2012-04-04 15:01:43 -04005441 ad.type = LSM_AUDIT_DATA_NET;
Eric Paris48c62af2012-04-02 13:15:44 -04005442 ad.u.net = &net;
Paul Moorecbe0d6e2014-09-10 17:09:57 -04005443 ad.u.net->netif = indev->ifindex;
Eric Paris48c62af2012-04-02 13:15:44 -04005444 ad.u.net->family = family;
Paul Mooreeffad8d2008-01-29 08:49:27 -05005445 if (selinux_parse_skb(skb, &ad, &addrp, 1, NULL) != 0)
5446 return NF_DROP;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005447
Paul Mooredfaebe92008-10-10 10:16:31 -04005448 if (peerlbl_active) {
Paul Moorecbe0d6e2014-09-10 17:09:57 -04005449 err = selinux_inet_sys_rcv_skb(dev_net(indev), indev->ifindex,
5450 addrp, family, peer_sid, &ad);
Paul Mooredfaebe92008-10-10 10:16:31 -04005451 if (err) {
Huw Daviesa04e71f2016-06-27 15:06:16 -04005452 selinux_netlbl_err(skb, family, err, 1);
Paul Mooreeffad8d2008-01-29 08:49:27 -05005453 return NF_DROP;
Paul Mooredfaebe92008-10-10 10:16:31 -04005454 }
5455 }
Paul Mooreeffad8d2008-01-29 08:49:27 -05005456
5457 if (secmark_active)
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005458 if (avc_has_perm(&selinux_state,
5459 peer_sid, skb->secmark,
Paul Mooreeffad8d2008-01-29 08:49:27 -05005460 SECCLASS_PACKET, PACKET__FORWARD_IN, &ad))
5461 return NF_DROP;
5462
Paul Moore948bf852008-10-10 10:16:32 -04005463 if (netlbl_active)
5464 /* we do this in the FORWARD path and not the POST_ROUTING
5465 * path because we want to make sure we apply the necessary
5466 * labeling before IPsec is applied so we can leverage AH
5467 * protection */
5468 if (selinux_netlbl_skbuff_setsid(skb, family, peer_sid) != 0)
5469 return NF_DROP;
5470
Paul Mooreeffad8d2008-01-29 08:49:27 -05005471 return NF_ACCEPT;
5472}
5473
Eric W. Biederman06198b32015-09-18 14:33:06 -05005474static unsigned int selinux_ipv4_forward(void *priv,
Paul Mooreeffad8d2008-01-29 08:49:27 -05005475 struct sk_buff *skb,
David S. Miller238e54c2015-04-03 20:32:56 -04005476 const struct nf_hook_state *state)
Paul Mooreeffad8d2008-01-29 08:49:27 -05005477{
David S. Miller238e54c2015-04-03 20:32:56 -04005478 return selinux_ip_forward(skb, state->in, PF_INET);
Paul Mooreeffad8d2008-01-29 08:49:27 -05005479}
5480
Javier Martinez Canillas1a93a6e2016-08-08 13:08:25 -04005481#if IS_ENABLED(CONFIG_IPV6)
Eric W. Biederman06198b32015-09-18 14:33:06 -05005482static unsigned int selinux_ipv6_forward(void *priv,
Paul Mooreeffad8d2008-01-29 08:49:27 -05005483 struct sk_buff *skb,
David S. Miller238e54c2015-04-03 20:32:56 -04005484 const struct nf_hook_state *state)
Paul Mooreeffad8d2008-01-29 08:49:27 -05005485{
David S. Miller238e54c2015-04-03 20:32:56 -04005486 return selinux_ip_forward(skb, state->in, PF_INET6);
Paul Mooreeffad8d2008-01-29 08:49:27 -05005487}
5488#endif /* IPV6 */
5489
Paul Moore948bf852008-10-10 10:16:32 -04005490static unsigned int selinux_ip_output(struct sk_buff *skb,
5491 u16 family)
5492{
Paul Moore47180062013-12-04 16:10:45 -05005493 struct sock *sk;
Paul Moore948bf852008-10-10 10:16:32 -04005494 u32 sid;
5495
5496 if (!netlbl_enabled())
5497 return NF_ACCEPT;
5498
5499 /* we do this in the LOCAL_OUT path and not the POST_ROUTING path
5500 * because we want to make sure we apply the necessary labeling
5501 * before IPsec is applied so we can leverage AH protection */
Paul Moore47180062013-12-04 16:10:45 -05005502 sk = skb->sk;
5503 if (sk) {
5504 struct sk_security_struct *sksec;
5505
Eric Dumazete446f9d2015-10-08 05:01:55 -07005506 if (sk_listener(sk))
Paul Moore47180062013-12-04 16:10:45 -05005507 /* if the socket is the listening state then this
5508 * packet is a SYN-ACK packet which means it needs to
5509 * be labeled based on the connection/request_sock and
5510 * not the parent socket. unfortunately, we can't
5511 * lookup the request_sock yet as it isn't queued on
5512 * the parent socket until after the SYN-ACK is sent.
5513 * the "solution" is to simply pass the packet as-is
5514 * as any IP option based labeling should be copied
5515 * from the initial connection request (in the IP
5516 * layer). it is far from ideal, but until we get a
5517 * security label in the packet itself this is the
5518 * best we can do. */
5519 return NF_ACCEPT;
5520
5521 /* standard practice, label using the parent socket */
5522 sksec = sk->sk_security;
Paul Moore948bf852008-10-10 10:16:32 -04005523 sid = sksec->sid;
5524 } else
5525 sid = SECINITSID_KERNEL;
5526 if (selinux_netlbl_skbuff_setsid(skb, family, sid) != 0)
5527 return NF_DROP;
5528
5529 return NF_ACCEPT;
5530}
5531
Eric W. Biederman06198b32015-09-18 14:33:06 -05005532static unsigned int selinux_ipv4_output(void *priv,
Paul Moore948bf852008-10-10 10:16:32 -04005533 struct sk_buff *skb,
David S. Miller238e54c2015-04-03 20:32:56 -04005534 const struct nf_hook_state *state)
Paul Moore948bf852008-10-10 10:16:32 -04005535{
5536 return selinux_ip_output(skb, PF_INET);
5537}
5538
Javier Martinez Canillas1a93a6e2016-08-08 13:08:25 -04005539#if IS_ENABLED(CONFIG_IPV6)
Huw Davies2917f572016-06-27 15:06:15 -04005540static unsigned int selinux_ipv6_output(void *priv,
5541 struct sk_buff *skb,
5542 const struct nf_hook_state *state)
5543{
5544 return selinux_ip_output(skb, PF_INET6);
5545}
5546#endif /* IPV6 */
5547
Paul Mooreeffad8d2008-01-29 08:49:27 -05005548static unsigned int selinux_ip_postroute_compat(struct sk_buff *skb,
5549 int ifindex,
Paul Moored8395c82008-10-10 10:16:30 -04005550 u16 family)
James Morris4e5ab4c2006-06-09 00:33:33 -07005551{
Eric Dumazet54abc682015-11-08 10:54:07 -08005552 struct sock *sk = skb_to_full_sk(skb);
Venkat Yekkirala4237c752006-07-24 23:32:50 -07005553 struct sk_security_struct *sksec;
Thomas Liu2bf49692009-07-14 12:14:09 -04005554 struct common_audit_data ad;
Eric Paris48c62af2012-04-02 13:15:44 -04005555 struct lsm_network_audit net = {0,};
Paul Moored8395c82008-10-10 10:16:30 -04005556 char *addrp;
5557 u8 proto;
James Morris4e5ab4c2006-06-09 00:33:33 -07005558
Paul Mooreeffad8d2008-01-29 08:49:27 -05005559 if (sk == NULL)
5560 return NF_ACCEPT;
Venkat Yekkirala4237c752006-07-24 23:32:50 -07005561 sksec = sk->sk_security;
James Morris4e5ab4c2006-06-09 00:33:33 -07005562
Eric Paris50c205f2012-04-04 15:01:43 -04005563 ad.type = LSM_AUDIT_DATA_NET;
Eric Paris48c62af2012-04-02 13:15:44 -04005564 ad.u.net = &net;
5565 ad.u.net->netif = ifindex;
5566 ad.u.net->family = family;
Paul Moored8395c82008-10-10 10:16:30 -04005567 if (selinux_parse_skb(skb, &ad, &addrp, 0, &proto))
5568 return NF_DROP;
5569
Paul Moore58bfbb52009-03-27 17:10:41 -04005570 if (selinux_secmark_enabled())
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005571 if (avc_has_perm(&selinux_state,
5572 sksec->sid, skb->secmark,
Paul Moored8395c82008-10-10 10:16:30 -04005573 SECCLASS_PACKET, PACKET__SEND, &ad))
Eric Paris2fe66ec2010-11-23 06:28:08 +00005574 return NF_DROP_ERR(-ECONNREFUSED);
James Morris4e5ab4c2006-06-09 00:33:33 -07005575
Steffen Klassertb9679a72011-02-23 12:55:21 +01005576 if (selinux_xfrm_postroute_last(sksec->sid, skb, &ad, proto))
5577 return NF_DROP_ERR(-ECONNREFUSED);
James Morris4e5ab4c2006-06-09 00:33:33 -07005578
Paul Mooreeffad8d2008-01-29 08:49:27 -05005579 return NF_ACCEPT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005580}
5581
Paul Moorecbe0d6e2014-09-10 17:09:57 -04005582static unsigned int selinux_ip_postroute(struct sk_buff *skb,
5583 const struct net_device *outdev,
Paul Mooreeffad8d2008-01-29 08:49:27 -05005584 u16 family)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005585{
Paul Mooreeffad8d2008-01-29 08:49:27 -05005586 u32 secmark_perm;
5587 u32 peer_sid;
Paul Moorecbe0d6e2014-09-10 17:09:57 -04005588 int ifindex = outdev->ifindex;
Paul Mooreeffad8d2008-01-29 08:49:27 -05005589 struct sock *sk;
Thomas Liu2bf49692009-07-14 12:14:09 -04005590 struct common_audit_data ad;
Eric Paris48c62af2012-04-02 13:15:44 -04005591 struct lsm_network_audit net = {0,};
Paul Mooreeffad8d2008-01-29 08:49:27 -05005592 char *addrp;
Paul Mooreeffad8d2008-01-29 08:49:27 -05005593 u8 secmark_active;
5594 u8 peerlbl_active;
5595
Paul Mooreeffad8d2008-01-29 08:49:27 -05005596 /* If any sort of compatibility mode is enabled then handoff processing
5597 * to the selinux_ip_postroute_compat() function to deal with the
5598 * special handling. We do this in an attempt to keep this function
5599 * as fast and as clean as possible. */
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05005600 if (!selinux_policycap_netpeer())
Paul Moored8395c82008-10-10 10:16:30 -04005601 return selinux_ip_postroute_compat(skb, ifindex, family);
Paul Moorec0828e52013-12-10 14:58:01 -05005602
Paul Mooreeffad8d2008-01-29 08:49:27 -05005603 secmark_active = selinux_secmark_enabled();
Chris PeBenito2be4d742013-05-03 09:05:39 -04005604 peerlbl_active = selinux_peerlbl_enabled();
Paul Mooreeffad8d2008-01-29 08:49:27 -05005605 if (!secmark_active && !peerlbl_active)
5606 return NF_ACCEPT;
5607
Eric Dumazet54abc682015-11-08 10:54:07 -08005608 sk = skb_to_full_sk(skb);
Paul Moorec0828e52013-12-10 14:58:01 -05005609
Paul Mooreeffad8d2008-01-29 08:49:27 -05005610#ifdef CONFIG_XFRM
5611 /* If skb->dst->xfrm is non-NULL then the packet is undergoing an IPsec
5612 * packet transformation so allow the packet to pass without any checks
5613 * since we'll have another chance to perform access control checks
5614 * when the packet is on it's final way out.
5615 * NOTE: there appear to be some IPv6 multicast cases where skb->dst
Paul Moorec0828e52013-12-10 14:58:01 -05005616 * is NULL, in this case go ahead and apply access control.
5617 * NOTE: if this is a local socket (skb->sk != NULL) that is in the
5618 * TCP listening state we cannot wait until the XFRM processing
5619 * is done as we will miss out on the SA label if we do;
5620 * unfortunately, this means more work, but it is only once per
5621 * connection. */
5622 if (skb_dst(skb) != NULL && skb_dst(skb)->xfrm != NULL &&
Eric Dumazete446f9d2015-10-08 05:01:55 -07005623 !(sk && sk_listener(sk)))
Paul Mooreeffad8d2008-01-29 08:49:27 -05005624 return NF_ACCEPT;
5625#endif
Paul Mooreeffad8d2008-01-29 08:49:27 -05005626
Paul Moored8395c82008-10-10 10:16:30 -04005627 if (sk == NULL) {
Paul Moore446b8022013-12-04 16:10:51 -05005628 /* Without an associated socket the packet is either coming
5629 * from the kernel or it is being forwarded; check the packet
5630 * to determine which and if the packet is being forwarded
5631 * query the packet directly to determine the security label. */
Steffen Klassert4a7ab3d2011-02-23 12:56:23 +01005632 if (skb->skb_iif) {
5633 secmark_perm = PACKET__FORWARD_OUT;
Paul Moored8395c82008-10-10 10:16:30 -04005634 if (selinux_skb_peerlbl_sid(skb, family, &peer_sid))
Eric Paris04f6d702010-11-23 06:28:02 +00005635 return NF_DROP;
Steffen Klassert4a7ab3d2011-02-23 12:56:23 +01005636 } else {
5637 secmark_perm = PACKET__SEND;
Paul Moored8395c82008-10-10 10:16:30 -04005638 peer_sid = SECINITSID_KERNEL;
Steffen Klassert4a7ab3d2011-02-23 12:56:23 +01005639 }
Eric Dumazete446f9d2015-10-08 05:01:55 -07005640 } else if (sk_listener(sk)) {
Paul Moore446b8022013-12-04 16:10:51 -05005641 /* Locally generated packet but the associated socket is in the
5642 * listening state which means this is a SYN-ACK packet. In
5643 * this particular case the correct security label is assigned
5644 * to the connection/request_sock but unfortunately we can't
5645 * query the request_sock as it isn't queued on the parent
5646 * socket until after the SYN-ACK packet is sent; the only
5647 * viable choice is to regenerate the label like we do in
5648 * selinux_inet_conn_request(). See also selinux_ip_output()
5649 * for similar problems. */
5650 u32 skb_sid;
Eric Dumazete446f9d2015-10-08 05:01:55 -07005651 struct sk_security_struct *sksec;
5652
Eric Dumazete446f9d2015-10-08 05:01:55 -07005653 sksec = sk->sk_security;
Paul Moore446b8022013-12-04 16:10:51 -05005654 if (selinux_skb_peerlbl_sid(skb, family, &skb_sid))
5655 return NF_DROP;
Paul Moorec0828e52013-12-10 14:58:01 -05005656 /* At this point, if the returned skb peerlbl is SECSID_NULL
5657 * and the packet has been through at least one XFRM
5658 * transformation then we must be dealing with the "final"
5659 * form of labeled IPsec packet; since we've already applied
5660 * all of our access controls on this packet we can safely
5661 * pass the packet. */
5662 if (skb_sid == SECSID_NULL) {
5663 switch (family) {
5664 case PF_INET:
5665 if (IPCB(skb)->flags & IPSKB_XFRM_TRANSFORMED)
5666 return NF_ACCEPT;
5667 break;
5668 case PF_INET6:
5669 if (IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED)
5670 return NF_ACCEPT;
Paul Moorea7a91a12014-09-03 10:51:59 -04005671 break;
Paul Moorec0828e52013-12-10 14:58:01 -05005672 default:
5673 return NF_DROP_ERR(-ECONNREFUSED);
5674 }
5675 }
Paul Moore446b8022013-12-04 16:10:51 -05005676 if (selinux_conn_sid(sksec->sid, skb_sid, &peer_sid))
5677 return NF_DROP;
5678 secmark_perm = PACKET__SEND;
Paul Moored8395c82008-10-10 10:16:30 -04005679 } else {
Paul Moore446b8022013-12-04 16:10:51 -05005680 /* Locally generated packet, fetch the security label from the
5681 * associated socket. */
Paul Mooreeffad8d2008-01-29 08:49:27 -05005682 struct sk_security_struct *sksec = sk->sk_security;
5683 peer_sid = sksec->sid;
5684 secmark_perm = PACKET__SEND;
Paul Mooreeffad8d2008-01-29 08:49:27 -05005685 }
5686
Eric Paris50c205f2012-04-04 15:01:43 -04005687 ad.type = LSM_AUDIT_DATA_NET;
Eric Paris48c62af2012-04-02 13:15:44 -04005688 ad.u.net = &net;
5689 ad.u.net->netif = ifindex;
5690 ad.u.net->family = family;
Paul Moored8395c82008-10-10 10:16:30 -04005691 if (selinux_parse_skb(skb, &ad, &addrp, 0, NULL))
Eric Paris04f6d702010-11-23 06:28:02 +00005692 return NF_DROP;
Paul Moored8395c82008-10-10 10:16:30 -04005693
Paul Mooreeffad8d2008-01-29 08:49:27 -05005694 if (secmark_active)
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005695 if (avc_has_perm(&selinux_state,
5696 peer_sid, skb->secmark,
Paul Mooreeffad8d2008-01-29 08:49:27 -05005697 SECCLASS_PACKET, secmark_perm, &ad))
Eric Paris1f1aaf82010-11-16 11:52:57 +00005698 return NF_DROP_ERR(-ECONNREFUSED);
Paul Mooreeffad8d2008-01-29 08:49:27 -05005699
5700 if (peerlbl_active) {
5701 u32 if_sid;
5702 u32 node_sid;
5703
Paul Moorecbe0d6e2014-09-10 17:09:57 -04005704 if (sel_netif_sid(dev_net(outdev), ifindex, &if_sid))
Eric Paris04f6d702010-11-23 06:28:02 +00005705 return NF_DROP;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005706 if (avc_has_perm(&selinux_state,
5707 peer_sid, if_sid,
Paul Mooreeffad8d2008-01-29 08:49:27 -05005708 SECCLASS_NETIF, NETIF__EGRESS, &ad))
Eric Paris1f1aaf82010-11-16 11:52:57 +00005709 return NF_DROP_ERR(-ECONNREFUSED);
Paul Mooreeffad8d2008-01-29 08:49:27 -05005710
5711 if (sel_netnode_sid(addrp, family, &node_sid))
Eric Paris04f6d702010-11-23 06:28:02 +00005712 return NF_DROP;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005713 if (avc_has_perm(&selinux_state,
5714 peer_sid, node_sid,
Paul Mooreeffad8d2008-01-29 08:49:27 -05005715 SECCLASS_NODE, NODE__SENDTO, &ad))
Eric Paris1f1aaf82010-11-16 11:52:57 +00005716 return NF_DROP_ERR(-ECONNREFUSED);
Paul Mooreeffad8d2008-01-29 08:49:27 -05005717 }
5718
5719 return NF_ACCEPT;
5720}
5721
Eric W. Biederman06198b32015-09-18 14:33:06 -05005722static unsigned int selinux_ipv4_postroute(void *priv,
Paul Mooreeffad8d2008-01-29 08:49:27 -05005723 struct sk_buff *skb,
David S. Miller238e54c2015-04-03 20:32:56 -04005724 const struct nf_hook_state *state)
Paul Mooreeffad8d2008-01-29 08:49:27 -05005725{
David S. Miller238e54c2015-04-03 20:32:56 -04005726 return selinux_ip_postroute(skb, state->out, PF_INET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005727}
5728
Javier Martinez Canillas1a93a6e2016-08-08 13:08:25 -04005729#if IS_ENABLED(CONFIG_IPV6)
Eric W. Biederman06198b32015-09-18 14:33:06 -05005730static unsigned int selinux_ipv6_postroute(void *priv,
Paul Mooreeffad8d2008-01-29 08:49:27 -05005731 struct sk_buff *skb,
David S. Miller238e54c2015-04-03 20:32:56 -04005732 const struct nf_hook_state *state)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005733{
David S. Miller238e54c2015-04-03 20:32:56 -04005734 return selinux_ip_postroute(skb, state->out, PF_INET6);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005735}
Linus Torvalds1da177e2005-04-16 15:20:36 -07005736#endif /* IPV6 */
5737
5738#endif /* CONFIG_NETFILTER */
5739
Linus Torvalds1da177e2005-04-16 15:20:36 -07005740static int selinux_netlink_send(struct sock *sk, struct sk_buff *skb)
5741{
Stephen Smalley941fc5b2009-10-01 14:48:23 -04005742 return selinux_nlmsg_perm(sk, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005743}
5744
Casey Schauflerecd5f822018-11-20 11:55:02 -08005745static void ipc_init_security(struct ipc_security_struct *isec, u16 sclass)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005746{
Linus Torvalds1da177e2005-04-16 15:20:36 -07005747 isec->sclass = sclass;
Stephen Smalleybe0554c2017-01-09 10:07:31 -05005748 isec->sid = current_sid();
Linus Torvalds1da177e2005-04-16 15:20:36 -07005749}
5750
5751static int msg_msg_alloc_security(struct msg_msg *msg)
5752{
5753 struct msg_security_struct *msec;
5754
Casey Schauflerecd5f822018-11-20 11:55:02 -08005755 msec = selinux_msg_msg(msg);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005756 msec->sid = SECINITSID_UNLABELED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005757
5758 return 0;
5759}
5760
Linus Torvalds1da177e2005-04-16 15:20:36 -07005761static int ipc_has_perm(struct kern_ipc_perm *ipc_perms,
Stephen Smalley6af963f2005-05-01 08:58:39 -07005762 u32 perms)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005763{
Linus Torvalds1da177e2005-04-16 15:20:36 -07005764 struct ipc_security_struct *isec;
Thomas Liu2bf49692009-07-14 12:14:09 -04005765 struct common_audit_data ad;
David Howells275bb412008-11-14 10:39:19 +11005766 u32 sid = current_sid();
Linus Torvalds1da177e2005-04-16 15:20:36 -07005767
Casey Schaufler7c653822018-09-21 17:19:45 -07005768 isec = selinux_ipc(ipc_perms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005769
Eric Paris50c205f2012-04-04 15:01:43 -04005770 ad.type = LSM_AUDIT_DATA_IPC;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005771 ad.u.ipc_id = ipc_perms->key;
5772
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005773 return avc_has_perm(&selinux_state,
5774 sid, isec->sid, isec->sclass, perms, &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005775}
5776
5777static int selinux_msg_msg_alloc_security(struct msg_msg *msg)
5778{
5779 return msg_msg_alloc_security(msg);
5780}
5781
Linus Torvalds1da177e2005-04-16 15:20:36 -07005782/* message queue security operations */
Eric W. Biedermand8c6e852018-03-22 21:22:26 -05005783static int selinux_msg_queue_alloc_security(struct kern_ipc_perm *msq)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005784{
Linus Torvalds1da177e2005-04-16 15:20:36 -07005785 struct ipc_security_struct *isec;
Thomas Liu2bf49692009-07-14 12:14:09 -04005786 struct common_audit_data ad;
David Howells275bb412008-11-14 10:39:19 +11005787 u32 sid = current_sid();
Linus Torvalds1da177e2005-04-16 15:20:36 -07005788 int rc;
5789
Casey Schauflerecd5f822018-11-20 11:55:02 -08005790 isec = selinux_ipc(msq);
5791 ipc_init_security(isec, SECCLASS_MSGQ);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005792
Eric Paris50c205f2012-04-04 15:01:43 -04005793 ad.type = LSM_AUDIT_DATA_IPC;
Eric W. Biedermand8c6e852018-03-22 21:22:26 -05005794 ad.u.ipc_id = msq->key;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005795
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005796 rc = avc_has_perm(&selinux_state,
5797 sid, isec->sid, SECCLASS_MSGQ,
Linus Torvalds1da177e2005-04-16 15:20:36 -07005798 MSGQ__CREATE, &ad);
Casey Schauflerecd5f822018-11-20 11:55:02 -08005799 return rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005800}
5801
Eric W. Biedermand8c6e852018-03-22 21:22:26 -05005802static int selinux_msg_queue_associate(struct kern_ipc_perm *msq, int msqflg)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005803{
Linus Torvalds1da177e2005-04-16 15:20:36 -07005804 struct ipc_security_struct *isec;
Thomas Liu2bf49692009-07-14 12:14:09 -04005805 struct common_audit_data ad;
David Howells275bb412008-11-14 10:39:19 +11005806 u32 sid = current_sid();
Linus Torvalds1da177e2005-04-16 15:20:36 -07005807
Casey Schaufler7c653822018-09-21 17:19:45 -07005808 isec = selinux_ipc(msq);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005809
Eric Paris50c205f2012-04-04 15:01:43 -04005810 ad.type = LSM_AUDIT_DATA_IPC;
Eric W. Biedermand8c6e852018-03-22 21:22:26 -05005811 ad.u.ipc_id = msq->key;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005812
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005813 return avc_has_perm(&selinux_state,
5814 sid, isec->sid, SECCLASS_MSGQ,
Linus Torvalds1da177e2005-04-16 15:20:36 -07005815 MSGQ__ASSOCIATE, &ad);
5816}
5817
Eric W. Biedermand8c6e852018-03-22 21:22:26 -05005818static int selinux_msg_queue_msgctl(struct kern_ipc_perm *msq, int cmd)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005819{
5820 int err;
5821 int perms;
5822
Eric Paris828dfe12008-04-17 13:17:49 -04005823 switch (cmd) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005824 case IPC_INFO:
5825 case MSG_INFO:
5826 /* No specific object, just general system-wide information. */
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005827 return avc_has_perm(&selinux_state,
5828 current_sid(), SECINITSID_KERNEL,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05005829 SECCLASS_SYSTEM, SYSTEM__IPC_INFO, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005830 case IPC_STAT:
5831 case MSG_STAT:
Davidlohr Bueso23c8cec2018-04-10 16:35:30 -07005832 case MSG_STAT_ANY:
Linus Torvalds1da177e2005-04-16 15:20:36 -07005833 perms = MSGQ__GETATTR | MSGQ__ASSOCIATE;
5834 break;
5835 case IPC_SET:
5836 perms = MSGQ__SETATTR;
5837 break;
5838 case IPC_RMID:
5839 perms = MSGQ__DESTROY;
5840 break;
5841 default:
5842 return 0;
5843 }
5844
Eric W. Biedermand8c6e852018-03-22 21:22:26 -05005845 err = ipc_has_perm(msq, perms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005846 return err;
5847}
5848
Eric W. Biedermand8c6e852018-03-22 21:22:26 -05005849static int selinux_msg_queue_msgsnd(struct kern_ipc_perm *msq, struct msg_msg *msg, int msqflg)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005850{
Linus Torvalds1da177e2005-04-16 15:20:36 -07005851 struct ipc_security_struct *isec;
5852 struct msg_security_struct *msec;
Thomas Liu2bf49692009-07-14 12:14:09 -04005853 struct common_audit_data ad;
David Howells275bb412008-11-14 10:39:19 +11005854 u32 sid = current_sid();
Linus Torvalds1da177e2005-04-16 15:20:36 -07005855 int rc;
5856
Casey Schaufler7c653822018-09-21 17:19:45 -07005857 isec = selinux_ipc(msq);
5858 msec = selinux_msg_msg(msg);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005859
5860 /*
5861 * First time through, need to assign label to the message
5862 */
5863 if (msec->sid == SECINITSID_UNLABELED) {
5864 /*
5865 * Compute new sid based on current process and
5866 * message queue this message will be stored in
5867 */
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05005868 rc = security_transition_sid(&selinux_state, sid, isec->sid,
5869 SECCLASS_MSG, NULL, &msec->sid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005870 if (rc)
5871 return rc;
5872 }
5873
Eric Paris50c205f2012-04-04 15:01:43 -04005874 ad.type = LSM_AUDIT_DATA_IPC;
Eric W. Biedermand8c6e852018-03-22 21:22:26 -05005875 ad.u.ipc_id = msq->key;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005876
5877 /* Can this process write to the queue? */
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005878 rc = avc_has_perm(&selinux_state,
5879 sid, isec->sid, SECCLASS_MSGQ,
Linus Torvalds1da177e2005-04-16 15:20:36 -07005880 MSGQ__WRITE, &ad);
5881 if (!rc)
5882 /* Can this process send the message */
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005883 rc = avc_has_perm(&selinux_state,
5884 sid, msec->sid, SECCLASS_MSG,
David Howells275bb412008-11-14 10:39:19 +11005885 MSG__SEND, &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005886 if (!rc)
5887 /* Can the message be put in the queue? */
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005888 rc = avc_has_perm(&selinux_state,
5889 msec->sid, isec->sid, SECCLASS_MSGQ,
David Howells275bb412008-11-14 10:39:19 +11005890 MSGQ__ENQUEUE, &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005891
5892 return rc;
5893}
5894
Eric W. Biedermand8c6e852018-03-22 21:22:26 -05005895static int selinux_msg_queue_msgrcv(struct kern_ipc_perm *msq, struct msg_msg *msg,
Linus Torvalds1da177e2005-04-16 15:20:36 -07005896 struct task_struct *target,
5897 long type, int mode)
5898{
Linus Torvalds1da177e2005-04-16 15:20:36 -07005899 struct ipc_security_struct *isec;
5900 struct msg_security_struct *msec;
Thomas Liu2bf49692009-07-14 12:14:09 -04005901 struct common_audit_data ad;
David Howells275bb412008-11-14 10:39:19 +11005902 u32 sid = task_sid(target);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005903 int rc;
5904
Casey Schaufler7c653822018-09-21 17:19:45 -07005905 isec = selinux_ipc(msq);
5906 msec = selinux_msg_msg(msg);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005907
Eric Paris50c205f2012-04-04 15:01:43 -04005908 ad.type = LSM_AUDIT_DATA_IPC;
Eric W. Biedermand8c6e852018-03-22 21:22:26 -05005909 ad.u.ipc_id = msq->key;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005910
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005911 rc = avc_has_perm(&selinux_state,
5912 sid, isec->sid,
Linus Torvalds1da177e2005-04-16 15:20:36 -07005913 SECCLASS_MSGQ, MSGQ__READ, &ad);
5914 if (!rc)
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005915 rc = avc_has_perm(&selinux_state,
5916 sid, msec->sid,
Linus Torvalds1da177e2005-04-16 15:20:36 -07005917 SECCLASS_MSG, MSG__RECEIVE, &ad);
5918 return rc;
5919}
5920
5921/* Shared Memory security operations */
Eric W. Biederman7191adf2018-03-22 21:08:27 -05005922static int selinux_shm_alloc_security(struct kern_ipc_perm *shp)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005923{
Linus Torvalds1da177e2005-04-16 15:20:36 -07005924 struct ipc_security_struct *isec;
Thomas Liu2bf49692009-07-14 12:14:09 -04005925 struct common_audit_data ad;
David Howells275bb412008-11-14 10:39:19 +11005926 u32 sid = current_sid();
Linus Torvalds1da177e2005-04-16 15:20:36 -07005927 int rc;
5928
Casey Schauflerecd5f822018-11-20 11:55:02 -08005929 isec = selinux_ipc(shp);
5930 ipc_init_security(isec, SECCLASS_SHM);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005931
Eric Paris50c205f2012-04-04 15:01:43 -04005932 ad.type = LSM_AUDIT_DATA_IPC;
Eric W. Biederman7191adf2018-03-22 21:08:27 -05005933 ad.u.ipc_id = shp->key;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005934
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005935 rc = avc_has_perm(&selinux_state,
5936 sid, isec->sid, SECCLASS_SHM,
Linus Torvalds1da177e2005-04-16 15:20:36 -07005937 SHM__CREATE, &ad);
Casey Schauflerecd5f822018-11-20 11:55:02 -08005938 return rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005939}
5940
Eric W. Biederman7191adf2018-03-22 21:08:27 -05005941static int selinux_shm_associate(struct kern_ipc_perm *shp, int shmflg)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005942{
Linus Torvalds1da177e2005-04-16 15:20:36 -07005943 struct ipc_security_struct *isec;
Thomas Liu2bf49692009-07-14 12:14:09 -04005944 struct common_audit_data ad;
David Howells275bb412008-11-14 10:39:19 +11005945 u32 sid = current_sid();
Linus Torvalds1da177e2005-04-16 15:20:36 -07005946
Casey Schaufler7c653822018-09-21 17:19:45 -07005947 isec = selinux_ipc(shp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005948
Eric Paris50c205f2012-04-04 15:01:43 -04005949 ad.type = LSM_AUDIT_DATA_IPC;
Eric W. Biederman7191adf2018-03-22 21:08:27 -05005950 ad.u.ipc_id = shp->key;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005951
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005952 return avc_has_perm(&selinux_state,
5953 sid, isec->sid, SECCLASS_SHM,
Linus Torvalds1da177e2005-04-16 15:20:36 -07005954 SHM__ASSOCIATE, &ad);
5955}
5956
5957/* Note, at this point, shp is locked down */
Eric W. Biederman7191adf2018-03-22 21:08:27 -05005958static int selinux_shm_shmctl(struct kern_ipc_perm *shp, int cmd)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005959{
5960 int perms;
5961 int err;
5962
Eric Paris828dfe12008-04-17 13:17:49 -04005963 switch (cmd) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005964 case IPC_INFO:
5965 case SHM_INFO:
5966 /* No specific object, just general system-wide information. */
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005967 return avc_has_perm(&selinux_state,
5968 current_sid(), SECINITSID_KERNEL,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05005969 SECCLASS_SYSTEM, SYSTEM__IPC_INFO, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005970 case IPC_STAT:
5971 case SHM_STAT:
Davidlohr Buesoc21a6972018-04-10 16:35:23 -07005972 case SHM_STAT_ANY:
Linus Torvalds1da177e2005-04-16 15:20:36 -07005973 perms = SHM__GETATTR | SHM__ASSOCIATE;
5974 break;
5975 case IPC_SET:
5976 perms = SHM__SETATTR;
5977 break;
5978 case SHM_LOCK:
5979 case SHM_UNLOCK:
5980 perms = SHM__LOCK;
5981 break;
5982 case IPC_RMID:
5983 perms = SHM__DESTROY;
5984 break;
5985 default:
5986 return 0;
5987 }
5988
Eric W. Biederman7191adf2018-03-22 21:08:27 -05005989 err = ipc_has_perm(shp, perms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005990 return err;
5991}
5992
Eric W. Biederman7191adf2018-03-22 21:08:27 -05005993static int selinux_shm_shmat(struct kern_ipc_perm *shp,
Linus Torvalds1da177e2005-04-16 15:20:36 -07005994 char __user *shmaddr, int shmflg)
5995{
5996 u32 perms;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005997
5998 if (shmflg & SHM_RDONLY)
5999 perms = SHM__READ;
6000 else
6001 perms = SHM__READ | SHM__WRITE;
6002
Eric W. Biederman7191adf2018-03-22 21:08:27 -05006003 return ipc_has_perm(shp, perms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006004}
6005
6006/* Semaphore security operations */
Eric W. Biedermanaefad952018-03-22 20:52:43 -05006007static int selinux_sem_alloc_security(struct kern_ipc_perm *sma)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006008{
Linus Torvalds1da177e2005-04-16 15:20:36 -07006009 struct ipc_security_struct *isec;
Thomas Liu2bf49692009-07-14 12:14:09 -04006010 struct common_audit_data ad;
David Howells275bb412008-11-14 10:39:19 +11006011 u32 sid = current_sid();
Linus Torvalds1da177e2005-04-16 15:20:36 -07006012 int rc;
6013
Casey Schauflerecd5f822018-11-20 11:55:02 -08006014 isec = selinux_ipc(sma);
6015 ipc_init_security(isec, SECCLASS_SEM);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006016
Eric Paris50c205f2012-04-04 15:01:43 -04006017 ad.type = LSM_AUDIT_DATA_IPC;
Eric W. Biedermanaefad952018-03-22 20:52:43 -05006018 ad.u.ipc_id = sma->key;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006019
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006020 rc = avc_has_perm(&selinux_state,
6021 sid, isec->sid, SECCLASS_SEM,
Linus Torvalds1da177e2005-04-16 15:20:36 -07006022 SEM__CREATE, &ad);
Casey Schauflerecd5f822018-11-20 11:55:02 -08006023 return rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006024}
6025
Eric W. Biedermanaefad952018-03-22 20:52:43 -05006026static int selinux_sem_associate(struct kern_ipc_perm *sma, int semflg)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006027{
Linus Torvalds1da177e2005-04-16 15:20:36 -07006028 struct ipc_security_struct *isec;
Thomas Liu2bf49692009-07-14 12:14:09 -04006029 struct common_audit_data ad;
David Howells275bb412008-11-14 10:39:19 +11006030 u32 sid = current_sid();
Linus Torvalds1da177e2005-04-16 15:20:36 -07006031
Casey Schaufler7c653822018-09-21 17:19:45 -07006032 isec = selinux_ipc(sma);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006033
Eric Paris50c205f2012-04-04 15:01:43 -04006034 ad.type = LSM_AUDIT_DATA_IPC;
Eric W. Biedermanaefad952018-03-22 20:52:43 -05006035 ad.u.ipc_id = sma->key;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006036
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006037 return avc_has_perm(&selinux_state,
6038 sid, isec->sid, SECCLASS_SEM,
Linus Torvalds1da177e2005-04-16 15:20:36 -07006039 SEM__ASSOCIATE, &ad);
6040}
6041
6042/* Note, at this point, sma is locked down */
Eric W. Biedermanaefad952018-03-22 20:52:43 -05006043static int selinux_sem_semctl(struct kern_ipc_perm *sma, int cmd)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006044{
6045 int err;
6046 u32 perms;
6047
Eric Paris828dfe12008-04-17 13:17:49 -04006048 switch (cmd) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07006049 case IPC_INFO:
6050 case SEM_INFO:
6051 /* No specific object, just general system-wide information. */
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006052 return avc_has_perm(&selinux_state,
6053 current_sid(), SECINITSID_KERNEL,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05006054 SECCLASS_SYSTEM, SYSTEM__IPC_INFO, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006055 case GETPID:
6056 case GETNCNT:
6057 case GETZCNT:
6058 perms = SEM__GETATTR;
6059 break;
6060 case GETVAL:
6061 case GETALL:
6062 perms = SEM__READ;
6063 break;
6064 case SETVAL:
6065 case SETALL:
6066 perms = SEM__WRITE;
6067 break;
6068 case IPC_RMID:
6069 perms = SEM__DESTROY;
6070 break;
6071 case IPC_SET:
6072 perms = SEM__SETATTR;
6073 break;
6074 case IPC_STAT:
6075 case SEM_STAT:
Davidlohr Buesoa280d6d2018-04-10 16:35:26 -07006076 case SEM_STAT_ANY:
Linus Torvalds1da177e2005-04-16 15:20:36 -07006077 perms = SEM__GETATTR | SEM__ASSOCIATE;
6078 break;
6079 default:
6080 return 0;
6081 }
6082
Eric W. Biedermanaefad952018-03-22 20:52:43 -05006083 err = ipc_has_perm(sma, perms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006084 return err;
6085}
6086
Eric W. Biedermanaefad952018-03-22 20:52:43 -05006087static int selinux_sem_semop(struct kern_ipc_perm *sma,
Linus Torvalds1da177e2005-04-16 15:20:36 -07006088 struct sembuf *sops, unsigned nsops, int alter)
6089{
6090 u32 perms;
6091
6092 if (alter)
6093 perms = SEM__READ | SEM__WRITE;
6094 else
6095 perms = SEM__READ;
6096
Eric W. Biedermanaefad952018-03-22 20:52:43 -05006097 return ipc_has_perm(sma, perms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006098}
6099
6100static int selinux_ipc_permission(struct kern_ipc_perm *ipcp, short flag)
6101{
Linus Torvalds1da177e2005-04-16 15:20:36 -07006102 u32 av = 0;
6103
Linus Torvalds1da177e2005-04-16 15:20:36 -07006104 av = 0;
6105 if (flag & S_IRUGO)
6106 av |= IPC__UNIX_READ;
6107 if (flag & S_IWUGO)
6108 av |= IPC__UNIX_WRITE;
6109
6110 if (av == 0)
6111 return 0;
6112
Stephen Smalley6af963f2005-05-01 08:58:39 -07006113 return ipc_has_perm(ipcp, av);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006114}
6115
Ahmed S. Darwish713a04ae2008-03-01 21:52:30 +02006116static void selinux_ipc_getsecid(struct kern_ipc_perm *ipcp, u32 *secid)
6117{
Casey Schaufler7c653822018-09-21 17:19:45 -07006118 struct ipc_security_struct *isec = selinux_ipc(ipcp);
Ahmed S. Darwish713a04ae2008-03-01 21:52:30 +02006119 *secid = isec->sid;
6120}
6121
Eric Paris828dfe12008-04-17 13:17:49 -04006122static void selinux_d_instantiate(struct dentry *dentry, struct inode *inode)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006123{
6124 if (inode)
6125 inode_doinit_with_dentry(inode, dentry);
6126}
6127
6128static int selinux_getprocattr(struct task_struct *p,
Al Viro04ff9702007-03-12 16:17:58 +00006129 char *name, char **value)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006130{
David Howells275bb412008-11-14 10:39:19 +11006131 const struct task_security_struct *__tsec;
Dustin Kirkland8c8570f2005-11-03 17:15:16 +00006132 u32 sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006133 int error;
Al Viro04ff9702007-03-12 16:17:58 +00006134 unsigned len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006135
David Howells275bb412008-11-14 10:39:19 +11006136 rcu_read_lock();
Casey Schaufler0c6cfa62018-09-21 17:17:16 -07006137 __tsec = selinux_cred(__task_cred(p));
Linus Torvalds1da177e2005-04-16 15:20:36 -07006138
Stephen Smalleybe0554c2017-01-09 10:07:31 -05006139 if (current != p) {
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006140 error = avc_has_perm(&selinux_state,
6141 current_sid(), __tsec->sid,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05006142 SECCLASS_PROCESS, PROCESS__GETATTR, NULL);
6143 if (error)
6144 goto bad;
6145 }
6146
Linus Torvalds1da177e2005-04-16 15:20:36 -07006147 if (!strcmp(name, "current"))
David Howells275bb412008-11-14 10:39:19 +11006148 sid = __tsec->sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006149 else if (!strcmp(name, "prev"))
David Howells275bb412008-11-14 10:39:19 +11006150 sid = __tsec->osid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006151 else if (!strcmp(name, "exec"))
David Howells275bb412008-11-14 10:39:19 +11006152 sid = __tsec->exec_sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006153 else if (!strcmp(name, "fscreate"))
David Howells275bb412008-11-14 10:39:19 +11006154 sid = __tsec->create_sid;
Michael LeMay4eb582c2006-06-26 00:24:57 -07006155 else if (!strcmp(name, "keycreate"))
David Howells275bb412008-11-14 10:39:19 +11006156 sid = __tsec->keycreate_sid;
Eric Paris42c3e032006-06-26 00:26:03 -07006157 else if (!strcmp(name, "sockcreate"))
David Howells275bb412008-11-14 10:39:19 +11006158 sid = __tsec->sockcreate_sid;
Stephen Smalleybe0554c2017-01-09 10:07:31 -05006159 else {
6160 error = -EINVAL;
6161 goto bad;
6162 }
David Howells275bb412008-11-14 10:39:19 +11006163 rcu_read_unlock();
Linus Torvalds1da177e2005-04-16 15:20:36 -07006164
6165 if (!sid)
6166 return 0;
6167
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05006168 error = security_sid_to_context(&selinux_state, sid, value, &len);
Al Viro04ff9702007-03-12 16:17:58 +00006169 if (error)
6170 return error;
6171 return len;
David Howells275bb412008-11-14 10:39:19 +11006172
Stephen Smalleybe0554c2017-01-09 10:07:31 -05006173bad:
David Howells275bb412008-11-14 10:39:19 +11006174 rcu_read_unlock();
Stephen Smalleybe0554c2017-01-09 10:07:31 -05006175 return error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006176}
6177
Stephen Smalleyb21507e2017-01-09 10:07:31 -05006178static int selinux_setprocattr(const char *name, void *value, size_t size)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006179{
6180 struct task_security_struct *tsec;
David Howellsd84f4f92008-11-14 10:39:23 +11006181 struct cred *new;
Stephen Smalleybe0554c2017-01-09 10:07:31 -05006182 u32 mysid = current_sid(), sid = 0, ptsid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006183 int error;
6184 char *str = value;
6185
Linus Torvalds1da177e2005-04-16 15:20:36 -07006186 /*
6187 * Basic control over ability to set these attributes at all.
Linus Torvalds1da177e2005-04-16 15:20:36 -07006188 */
6189 if (!strcmp(name, "exec"))
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006190 error = avc_has_perm(&selinux_state,
6191 mysid, mysid, SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05006192 PROCESS__SETEXEC, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006193 else if (!strcmp(name, "fscreate"))
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006194 error = avc_has_perm(&selinux_state,
6195 mysid, mysid, SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05006196 PROCESS__SETFSCREATE, NULL);
Michael LeMay4eb582c2006-06-26 00:24:57 -07006197 else if (!strcmp(name, "keycreate"))
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006198 error = avc_has_perm(&selinux_state,
6199 mysid, mysid, SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05006200 PROCESS__SETKEYCREATE, NULL);
Eric Paris42c3e032006-06-26 00:26:03 -07006201 else if (!strcmp(name, "sockcreate"))
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006202 error = avc_has_perm(&selinux_state,
6203 mysid, mysid, SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05006204 PROCESS__SETSOCKCREATE, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006205 else if (!strcmp(name, "current"))
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006206 error = avc_has_perm(&selinux_state,
6207 mysid, mysid, SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05006208 PROCESS__SETCURRENT, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006209 else
6210 error = -EINVAL;
6211 if (error)
6212 return error;
6213
6214 /* Obtain a SID for the context, if one was specified. */
Stephen Smalleya050a572017-01-31 11:54:04 -05006215 if (size && str[0] && str[0] != '\n') {
Linus Torvalds1da177e2005-04-16 15:20:36 -07006216 if (str[size-1] == '\n') {
6217 str[size-1] = 0;
6218 size--;
6219 }
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05006220 error = security_context_to_sid(&selinux_state, value, size,
6221 &sid, GFP_KERNEL);
Stephen Smalley12b29f32008-05-07 13:03:20 -04006222 if (error == -EINVAL && !strcmp(name, "fscreate")) {
Stephen Smalleydb590002017-04-20 11:31:30 -04006223 if (!has_cap_mac_admin(true)) {
Eric Parisd6ea83e2012-04-04 13:45:49 -04006224 struct audit_buffer *ab;
6225 size_t audit_size;
6226
6227 /* We strip a nul only if it is at the end, otherwise the
6228 * context contains a nul and we should audit that */
6229 if (str[size - 1] == '\0')
6230 audit_size = size - 1;
6231 else
6232 audit_size = size;
Richard Guy Briggscdfb6b32018-05-12 21:58:20 -04006233 ab = audit_log_start(audit_context(),
6234 GFP_ATOMIC,
6235 AUDIT_SELINUX_ERR);
Eric Parisd6ea83e2012-04-04 13:45:49 -04006236 audit_log_format(ab, "op=fscreate invalid_context=");
6237 audit_log_n_untrustedstring(ab, value, audit_size);
6238 audit_log_end(ab);
6239
Stephen Smalley12b29f32008-05-07 13:03:20 -04006240 return error;
Eric Parisd6ea83e2012-04-04 13:45:49 -04006241 }
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05006242 error = security_context_to_sid_force(
6243 &selinux_state,
6244 value, size, &sid);
Stephen Smalley12b29f32008-05-07 13:03:20 -04006245 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006246 if (error)
6247 return error;
6248 }
6249
David Howellsd84f4f92008-11-14 10:39:23 +11006250 new = prepare_creds();
6251 if (!new)
6252 return -ENOMEM;
6253
Linus Torvalds1da177e2005-04-16 15:20:36 -07006254 /* Permission checking based on the specified context is
6255 performed during the actual operation (execve,
6256 open/mkdir/...), when we know the full context of the
David Howellsd84f4f92008-11-14 10:39:23 +11006257 operation. See selinux_bprm_set_creds for the execve
Linus Torvalds1da177e2005-04-16 15:20:36 -07006258 checks and may_create for the file creation checks. The
6259 operation will then fail if the context is not permitted. */
Casey Schaufler0c6cfa62018-09-21 17:17:16 -07006260 tsec = selinux_cred(new);
David Howellsd84f4f92008-11-14 10:39:23 +11006261 if (!strcmp(name, "exec")) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07006262 tsec->exec_sid = sid;
David Howellsd84f4f92008-11-14 10:39:23 +11006263 } else if (!strcmp(name, "fscreate")) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07006264 tsec->create_sid = sid;
David Howellsd84f4f92008-11-14 10:39:23 +11006265 } else if (!strcmp(name, "keycreate")) {
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006266 error = avc_has_perm(&selinux_state,
6267 mysid, sid, SECCLASS_KEY, KEY__CREATE,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05006268 NULL);
Michael LeMay4eb582c2006-06-26 00:24:57 -07006269 if (error)
David Howellsd84f4f92008-11-14 10:39:23 +11006270 goto abort_change;
Michael LeMay4eb582c2006-06-26 00:24:57 -07006271 tsec->keycreate_sid = sid;
David Howellsd84f4f92008-11-14 10:39:23 +11006272 } else if (!strcmp(name, "sockcreate")) {
Eric Paris42c3e032006-06-26 00:26:03 -07006273 tsec->sockcreate_sid = sid;
David Howellsd84f4f92008-11-14 10:39:23 +11006274 } else if (!strcmp(name, "current")) {
6275 error = -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006276 if (sid == 0)
David Howellsd84f4f92008-11-14 10:39:23 +11006277 goto abort_change;
KaiGai Koheid9250de2008-08-28 16:35:57 +09006278
David Howellsd84f4f92008-11-14 10:39:23 +11006279 /* Only allow single threaded processes to change context */
6280 error = -EPERM;
Oleg Nesterov5bb459b2009-07-10 03:48:23 +02006281 if (!current_is_single_threaded()) {
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05006282 error = security_bounded_transition(&selinux_state,
6283 tsec->sid, sid);
David Howellsd84f4f92008-11-14 10:39:23 +11006284 if (error)
6285 goto abort_change;
Eric Paris828dfe12008-04-17 13:17:49 -04006286 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006287
6288 /* Check permissions for the transition. */
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006289 error = avc_has_perm(&selinux_state,
6290 tsec->sid, sid, SECCLASS_PROCESS,
Eric Paris828dfe12008-04-17 13:17:49 -04006291 PROCESS__DYNTRANSITION, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006292 if (error)
David Howellsd84f4f92008-11-14 10:39:23 +11006293 goto abort_change;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006294
6295 /* Check for ptracing, and update the task SID if ok.
6296 Otherwise, leave SID unchanged and fail. */
Stephen Smalleybe0554c2017-01-09 10:07:31 -05006297 ptsid = ptrace_parent_sid();
Paul Moore0c6181c2016-03-30 21:41:21 -04006298 if (ptsid != 0) {
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006299 error = avc_has_perm(&selinux_state,
6300 ptsid, sid, SECCLASS_PROCESS,
David Howellsd84f4f92008-11-14 10:39:23 +11006301 PROCESS__PTRACE, NULL);
6302 if (error)
6303 goto abort_change;
6304 }
6305
6306 tsec->sid = sid;
6307 } else {
6308 error = -EINVAL;
6309 goto abort_change;
6310 }
6311
6312 commit_creds(new);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006313 return size;
David Howellsd84f4f92008-11-14 10:39:23 +11006314
6315abort_change:
6316 abort_creds(new);
6317 return error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006318}
6319
David Quigley746df9b2013-05-22 12:50:35 -04006320static int selinux_ismaclabel(const char *name)
6321{
6322 return (strcmp(name, XATTR_SELINUX_SUFFIX) == 0);
6323}
6324
Catherine Zhangdc49c1f2006-08-02 14:12:06 -07006325static int selinux_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
6326{
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05006327 return security_sid_to_context(&selinux_state, secid,
6328 secdata, seclen);
Catherine Zhangdc49c1f2006-08-02 14:12:06 -07006329}
6330
David Howells7bf570d2008-04-29 20:52:51 +01006331static int selinux_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid)
David Howells63cb3442008-01-15 23:47:35 +00006332{
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05006333 return security_context_to_sid(&selinux_state, secdata, seclen,
6334 secid, GFP_KERNEL);
David Howells63cb3442008-01-15 23:47:35 +00006335}
6336
Catherine Zhangdc49c1f2006-08-02 14:12:06 -07006337static void selinux_release_secctx(char *secdata, u32 seclen)
6338{
Paul Moore088999e2007-08-01 11:12:58 -04006339 kfree(secdata);
Catherine Zhangdc49c1f2006-08-02 14:12:06 -07006340}
6341
Andreas Gruenbacher6f3be9f2015-12-24 11:09:40 -05006342static void selinux_inode_invalidate_secctx(struct inode *inode)
6343{
Casey Schaufler80788c22018-09-21 17:19:11 -07006344 struct inode_security_struct *isec = selinux_inode(inode);
Andreas Gruenbacher6f3be9f2015-12-24 11:09:40 -05006345
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01006346 spin_lock(&isec->lock);
Andreas Gruenbacher6f3be9f2015-12-24 11:09:40 -05006347 isec->initialized = LABEL_INVALID;
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01006348 spin_unlock(&isec->lock);
Andreas Gruenbacher6f3be9f2015-12-24 11:09:40 -05006349}
6350
David P. Quigley1ee65e32009-09-03 14:25:57 -04006351/*
6352 * called with inode->i_mutex locked
6353 */
6354static int selinux_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen)
6355{
Ondrej Mosnacek53e0c2a2018-12-21 21:18:53 +01006356 int rc = selinux_inode_setsecurity(inode, XATTR_SELINUX_SUFFIX,
6357 ctx, ctxlen, 0);
6358 /* Do not return error when suppressing label (SBLABEL_MNT not set). */
6359 return rc == -EOPNOTSUPP ? 0 : rc;
David P. Quigley1ee65e32009-09-03 14:25:57 -04006360}
6361
6362/*
6363 * called with inode->i_mutex locked
6364 */
6365static int selinux_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen)
6366{
6367 return __vfs_setxattr_noperm(dentry, XATTR_NAME_SELINUX, ctx, ctxlen, 0);
6368}
6369
6370static int selinux_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen)
6371{
6372 int len = 0;
6373 len = selinux_inode_getsecurity(inode, XATTR_SELINUX_SUFFIX,
6374 ctx, true);
6375 if (len < 0)
6376 return len;
6377 *ctxlen = len;
6378 return 0;
6379}
Michael LeMayd7200242006-06-22 14:47:17 -07006380#ifdef CONFIG_KEYS
6381
David Howellsd84f4f92008-11-14 10:39:23 +11006382static int selinux_key_alloc(struct key *k, const struct cred *cred,
David Howells7e047ef2006-06-26 00:24:50 -07006383 unsigned long flags)
Michael LeMayd7200242006-06-22 14:47:17 -07006384{
David Howellsd84f4f92008-11-14 10:39:23 +11006385 const struct task_security_struct *tsec;
Michael LeMayd7200242006-06-22 14:47:17 -07006386 struct key_security_struct *ksec;
6387
6388 ksec = kzalloc(sizeof(struct key_security_struct), GFP_KERNEL);
6389 if (!ksec)
6390 return -ENOMEM;
6391
Casey Schaufler0c6cfa62018-09-21 17:17:16 -07006392 tsec = selinux_cred(cred);
David Howellsd84f4f92008-11-14 10:39:23 +11006393 if (tsec->keycreate_sid)
6394 ksec->sid = tsec->keycreate_sid;
Michael LeMay4eb582c2006-06-26 00:24:57 -07006395 else
David Howellsd84f4f92008-11-14 10:39:23 +11006396 ksec->sid = tsec->sid;
Michael LeMayd7200242006-06-22 14:47:17 -07006397
David Howells275bb412008-11-14 10:39:19 +11006398 k->security = ksec;
Michael LeMayd7200242006-06-22 14:47:17 -07006399 return 0;
6400}
6401
6402static void selinux_key_free(struct key *k)
6403{
6404 struct key_security_struct *ksec = k->security;
6405
6406 k->security = NULL;
6407 kfree(ksec);
6408}
6409
6410static int selinux_key_permission(key_ref_t key_ref,
David Howellsd84f4f92008-11-14 10:39:23 +11006411 const struct cred *cred,
David Howellsf5895942014-03-14 17:44:49 +00006412 unsigned perm)
Michael LeMayd7200242006-06-22 14:47:17 -07006413{
6414 struct key *key;
Michael LeMayd7200242006-06-22 14:47:17 -07006415 struct key_security_struct *ksec;
David Howells275bb412008-11-14 10:39:19 +11006416 u32 sid;
Michael LeMayd7200242006-06-22 14:47:17 -07006417
6418 /* if no specific permissions are requested, we skip the
6419 permission check. No serious, additional covert channels
6420 appear to be created. */
6421 if (perm == 0)
6422 return 0;
6423
David Howellsd84f4f92008-11-14 10:39:23 +11006424 sid = cred_sid(cred);
David Howells275bb412008-11-14 10:39:19 +11006425
6426 key = key_ref_to_ptr(key_ref);
6427 ksec = key->security;
6428
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006429 return avc_has_perm(&selinux_state,
6430 sid, ksec->sid, SECCLASS_KEY, perm, NULL);
Michael LeMayd7200242006-06-22 14:47:17 -07006431}
6432
David Howells70a5bb72008-04-29 01:01:26 -07006433static int selinux_key_getsecurity(struct key *key, char **_buffer)
6434{
6435 struct key_security_struct *ksec = key->security;
6436 char *context = NULL;
6437 unsigned len;
6438 int rc;
6439
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05006440 rc = security_sid_to_context(&selinux_state, ksec->sid,
6441 &context, &len);
David Howells70a5bb72008-04-29 01:01:26 -07006442 if (!rc)
6443 rc = len;
6444 *_buffer = context;
6445 return rc;
6446}
Daniel Jurgens3a976fa2017-05-19 15:48:56 +03006447#endif
David Howells70a5bb72008-04-29 01:01:26 -07006448
Daniel Jurgens3a976fa2017-05-19 15:48:56 +03006449#ifdef CONFIG_SECURITY_INFINIBAND
Daniel Jurgenscfc4d882017-05-19 15:48:57 +03006450static int selinux_ib_pkey_access(void *ib_sec, u64 subnet_prefix, u16 pkey_val)
6451{
6452 struct common_audit_data ad;
6453 int err;
6454 u32 sid = 0;
6455 struct ib_security_struct *sec = ib_sec;
6456 struct lsm_ibpkey_audit ibpkey;
6457
Daniel Jurgens409dcf32017-05-19 15:48:59 +03006458 err = sel_ib_pkey_sid(subnet_prefix, pkey_val, &sid);
Daniel Jurgenscfc4d882017-05-19 15:48:57 +03006459 if (err)
6460 return err;
6461
6462 ad.type = LSM_AUDIT_DATA_IBPKEY;
6463 ibpkey.subnet_prefix = subnet_prefix;
6464 ibpkey.pkey = pkey_val;
6465 ad.u.ibpkey = &ibpkey;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006466 return avc_has_perm(&selinux_state,
6467 sec->sid, sid,
Daniel Jurgenscfc4d882017-05-19 15:48:57 +03006468 SECCLASS_INFINIBAND_PKEY,
6469 INFINIBAND_PKEY__ACCESS, &ad);
6470}
6471
Daniel Jurgensab861df2017-05-19 15:48:58 +03006472static int selinux_ib_endport_manage_subnet(void *ib_sec, const char *dev_name,
6473 u8 port_num)
6474{
6475 struct common_audit_data ad;
6476 int err;
6477 u32 sid = 0;
6478 struct ib_security_struct *sec = ib_sec;
6479 struct lsm_ibendport_audit ibendport;
6480
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05006481 err = security_ib_endport_sid(&selinux_state, dev_name, port_num,
6482 &sid);
Daniel Jurgensab861df2017-05-19 15:48:58 +03006483
6484 if (err)
6485 return err;
6486
6487 ad.type = LSM_AUDIT_DATA_IBENDPORT;
6488 strncpy(ibendport.dev_name, dev_name, sizeof(ibendport.dev_name));
6489 ibendport.port = port_num;
6490 ad.u.ibendport = &ibendport;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006491 return avc_has_perm(&selinux_state,
6492 sec->sid, sid,
Daniel Jurgensab861df2017-05-19 15:48:58 +03006493 SECCLASS_INFINIBAND_ENDPORT,
6494 INFINIBAND_ENDPORT__MANAGE_SUBNET, &ad);
6495}
6496
Daniel Jurgens3a976fa2017-05-19 15:48:56 +03006497static int selinux_ib_alloc_security(void **ib_sec)
6498{
6499 struct ib_security_struct *sec;
6500
6501 sec = kzalloc(sizeof(*sec), GFP_KERNEL);
6502 if (!sec)
6503 return -ENOMEM;
6504 sec->sid = current_sid();
6505
6506 *ib_sec = sec;
6507 return 0;
6508}
6509
6510static void selinux_ib_free_security(void *ib_sec)
6511{
6512 kfree(ib_sec);
6513}
Michael LeMayd7200242006-06-22 14:47:17 -07006514#endif
6515
Chenbo Fengec27c352017-10-18 13:00:25 -07006516#ifdef CONFIG_BPF_SYSCALL
6517static int selinux_bpf(int cmd, union bpf_attr *attr,
6518 unsigned int size)
6519{
6520 u32 sid = current_sid();
6521 int ret;
6522
6523 switch (cmd) {
6524 case BPF_MAP_CREATE:
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006525 ret = avc_has_perm(&selinux_state,
6526 sid, sid, SECCLASS_BPF, BPF__MAP_CREATE,
Chenbo Fengec27c352017-10-18 13:00:25 -07006527 NULL);
6528 break;
6529 case BPF_PROG_LOAD:
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006530 ret = avc_has_perm(&selinux_state,
6531 sid, sid, SECCLASS_BPF, BPF__PROG_LOAD,
Chenbo Fengec27c352017-10-18 13:00:25 -07006532 NULL);
6533 break;
6534 default:
6535 ret = 0;
6536 break;
6537 }
6538
6539 return ret;
6540}
6541
6542static u32 bpf_map_fmode_to_av(fmode_t fmode)
6543{
6544 u32 av = 0;
6545
6546 if (fmode & FMODE_READ)
6547 av |= BPF__MAP_READ;
6548 if (fmode & FMODE_WRITE)
6549 av |= BPF__MAP_WRITE;
6550 return av;
6551}
6552
Chenbo Fengf66e4482017-10-18 13:00:26 -07006553/* This function will check the file pass through unix socket or binder to see
6554 * if it is a bpf related object. And apply correspinding checks on the bpf
6555 * object based on the type. The bpf maps and programs, not like other files and
6556 * socket, are using a shared anonymous inode inside the kernel as their inode.
6557 * So checking that inode cannot identify if the process have privilege to
6558 * access the bpf object and that's why we have to add this additional check in
6559 * selinux_file_receive and selinux_binder_transfer_files.
6560 */
6561static int bpf_fd_pass(struct file *file, u32 sid)
6562{
6563 struct bpf_security_struct *bpfsec;
6564 struct bpf_prog *prog;
6565 struct bpf_map *map;
6566 int ret;
6567
6568 if (file->f_op == &bpf_map_fops) {
6569 map = file->private_data;
6570 bpfsec = map->security;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006571 ret = avc_has_perm(&selinux_state,
6572 sid, bpfsec->sid, SECCLASS_BPF,
Chenbo Fengf66e4482017-10-18 13:00:26 -07006573 bpf_map_fmode_to_av(file->f_mode), NULL);
6574 if (ret)
6575 return ret;
6576 } else if (file->f_op == &bpf_prog_fops) {
6577 prog = file->private_data;
6578 bpfsec = prog->aux->security;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006579 ret = avc_has_perm(&selinux_state,
6580 sid, bpfsec->sid, SECCLASS_BPF,
Chenbo Fengf66e4482017-10-18 13:00:26 -07006581 BPF__PROG_RUN, NULL);
6582 if (ret)
6583 return ret;
6584 }
6585 return 0;
6586}
6587
Chenbo Fengec27c352017-10-18 13:00:25 -07006588static int selinux_bpf_map(struct bpf_map *map, fmode_t fmode)
6589{
6590 u32 sid = current_sid();
6591 struct bpf_security_struct *bpfsec;
6592
6593 bpfsec = map->security;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006594 return avc_has_perm(&selinux_state,
6595 sid, bpfsec->sid, SECCLASS_BPF,
Chenbo Fengec27c352017-10-18 13:00:25 -07006596 bpf_map_fmode_to_av(fmode), NULL);
6597}
6598
6599static int selinux_bpf_prog(struct bpf_prog *prog)
6600{
6601 u32 sid = current_sid();
6602 struct bpf_security_struct *bpfsec;
6603
6604 bpfsec = prog->aux->security;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006605 return avc_has_perm(&selinux_state,
6606 sid, bpfsec->sid, SECCLASS_BPF,
Chenbo Fengec27c352017-10-18 13:00:25 -07006607 BPF__PROG_RUN, NULL);
6608}
6609
6610static int selinux_bpf_map_alloc(struct bpf_map *map)
6611{
6612 struct bpf_security_struct *bpfsec;
6613
6614 bpfsec = kzalloc(sizeof(*bpfsec), GFP_KERNEL);
6615 if (!bpfsec)
6616 return -ENOMEM;
6617
6618 bpfsec->sid = current_sid();
6619 map->security = bpfsec;
6620
6621 return 0;
6622}
6623
6624static void selinux_bpf_map_free(struct bpf_map *map)
6625{
6626 struct bpf_security_struct *bpfsec = map->security;
6627
6628 map->security = NULL;
6629 kfree(bpfsec);
6630}
6631
6632static int selinux_bpf_prog_alloc(struct bpf_prog_aux *aux)
6633{
6634 struct bpf_security_struct *bpfsec;
6635
6636 bpfsec = kzalloc(sizeof(*bpfsec), GFP_KERNEL);
6637 if (!bpfsec)
6638 return -ENOMEM;
6639
6640 bpfsec->sid = current_sid();
6641 aux->security = bpfsec;
6642
6643 return 0;
6644}
6645
6646static void selinux_bpf_prog_free(struct bpf_prog_aux *aux)
6647{
6648 struct bpf_security_struct *bpfsec = aux->security;
6649
6650 aux->security = NULL;
6651 kfree(bpfsec);
6652}
6653#endif
6654
Casey Schauflerbbd36622018-11-12 09:30:56 -08006655struct lsm_blob_sizes selinux_blob_sizes __lsm_ro_after_init = {
6656 .lbs_cred = sizeof(struct task_security_struct),
Casey Schaufler33bf60c2018-11-12 12:02:49 -08006657 .lbs_file = sizeof(struct file_security_struct),
Casey Schauflerafb1cbe32018-09-21 17:19:29 -07006658 .lbs_inode = sizeof(struct inode_security_struct),
Casey Schauflerecd5f822018-11-20 11:55:02 -08006659 .lbs_ipc = sizeof(struct ipc_security_struct),
6660 .lbs_msg_msg = sizeof(struct msg_security_struct),
Casey Schauflerbbd36622018-11-12 09:30:56 -08006661};
6662
James Morrisca97d932017-02-15 00:18:51 +11006663static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = {
Casey Schauflere20b0432015-05-02 15:11:36 -07006664 LSM_HOOK_INIT(binder_set_context_mgr, selinux_binder_set_context_mgr),
6665 LSM_HOOK_INIT(binder_transaction, selinux_binder_transaction),
6666 LSM_HOOK_INIT(binder_transfer_binder, selinux_binder_transfer_binder),
6667 LSM_HOOK_INIT(binder_transfer_file, selinux_binder_transfer_file),
Ahmed S. Darwish076c54c2008-03-06 18:09:10 +02006668
Casey Schauflere20b0432015-05-02 15:11:36 -07006669 LSM_HOOK_INIT(ptrace_access_check, selinux_ptrace_access_check),
6670 LSM_HOOK_INIT(ptrace_traceme, selinux_ptrace_traceme),
6671 LSM_HOOK_INIT(capget, selinux_capget),
6672 LSM_HOOK_INIT(capset, selinux_capset),
6673 LSM_HOOK_INIT(capable, selinux_capable),
6674 LSM_HOOK_INIT(quotactl, selinux_quotactl),
6675 LSM_HOOK_INIT(quota_on, selinux_quota_on),
6676 LSM_HOOK_INIT(syslog, selinux_syslog),
6677 LSM_HOOK_INIT(vm_enough_memory, selinux_vm_enough_memory),
Stephen Smalley79af7302015-01-21 10:54:10 -05006678
Casey Schauflere20b0432015-05-02 15:11:36 -07006679 LSM_HOOK_INIT(netlink_send, selinux_netlink_send),
Linus Torvalds1da177e2005-04-16 15:20:36 -07006680
Casey Schauflere20b0432015-05-02 15:11:36 -07006681 LSM_HOOK_INIT(bprm_set_creds, selinux_bprm_set_creds),
6682 LSM_HOOK_INIT(bprm_committing_creds, selinux_bprm_committing_creds),
6683 LSM_HOOK_INIT(bprm_committed_creds, selinux_bprm_committed_creds),
Linus Torvalds1da177e2005-04-16 15:20:36 -07006684
Al Viro0b520752018-12-23 16:02:47 -05006685 LSM_HOOK_INIT(fs_context_dup, selinux_fs_context_dup),
David Howells442155c2018-11-01 23:07:24 +00006686 LSM_HOOK_INIT(fs_context_parse_param, selinux_fs_context_parse_param),
6687
Casey Schauflere20b0432015-05-02 15:11:36 -07006688 LSM_HOOK_INIT(sb_alloc_security, selinux_sb_alloc_security),
6689 LSM_HOOK_INIT(sb_free_security, selinux_sb_free_security),
Al Viro5b400232018-12-12 20:13:29 -05006690 LSM_HOOK_INIT(sb_eat_lsm_opts, selinux_sb_eat_lsm_opts),
Al Viro204cc0c2018-12-13 13:41:47 -05006691 LSM_HOOK_INIT(sb_free_mnt_opts, selinux_free_mnt_opts),
Casey Schauflere20b0432015-05-02 15:11:36 -07006692 LSM_HOOK_INIT(sb_remount, selinux_sb_remount),
6693 LSM_HOOK_INIT(sb_kern_mount, selinux_sb_kern_mount),
6694 LSM_HOOK_INIT(sb_show_options, selinux_sb_show_options),
6695 LSM_HOOK_INIT(sb_statfs, selinux_sb_statfs),
6696 LSM_HOOK_INIT(sb_mount, selinux_mount),
6697 LSM_HOOK_INIT(sb_umount, selinux_umount),
6698 LSM_HOOK_INIT(sb_set_mnt_opts, selinux_set_mnt_opts),
6699 LSM_HOOK_INIT(sb_clone_mnt_opts, selinux_sb_clone_mnt_opts),
Al Viro757cbe52018-12-14 23:42:21 -05006700 LSM_HOOK_INIT(sb_add_mnt_opt, selinux_add_mnt_opt),
Linus Torvalds1da177e2005-04-16 15:20:36 -07006701
Casey Schauflere20b0432015-05-02 15:11:36 -07006702 LSM_HOOK_INIT(dentry_init_security, selinux_dentry_init_security),
Vivek Goyala518b0a2016-07-13 10:44:53 -04006703 LSM_HOOK_INIT(dentry_create_files_as, selinux_dentry_create_files_as),
Eric Parise0007522008-03-05 10:31:54 -05006704
Casey Schauflere20b0432015-05-02 15:11:36 -07006705 LSM_HOOK_INIT(inode_alloc_security, selinux_inode_alloc_security),
6706 LSM_HOOK_INIT(inode_free_security, selinux_inode_free_security),
6707 LSM_HOOK_INIT(inode_init_security, selinux_inode_init_security),
6708 LSM_HOOK_INIT(inode_create, selinux_inode_create),
6709 LSM_HOOK_INIT(inode_link, selinux_inode_link),
6710 LSM_HOOK_INIT(inode_unlink, selinux_inode_unlink),
6711 LSM_HOOK_INIT(inode_symlink, selinux_inode_symlink),
6712 LSM_HOOK_INIT(inode_mkdir, selinux_inode_mkdir),
6713 LSM_HOOK_INIT(inode_rmdir, selinux_inode_rmdir),
6714 LSM_HOOK_INIT(inode_mknod, selinux_inode_mknod),
6715 LSM_HOOK_INIT(inode_rename, selinux_inode_rename),
6716 LSM_HOOK_INIT(inode_readlink, selinux_inode_readlink),
6717 LSM_HOOK_INIT(inode_follow_link, selinux_inode_follow_link),
6718 LSM_HOOK_INIT(inode_permission, selinux_inode_permission),
6719 LSM_HOOK_INIT(inode_setattr, selinux_inode_setattr),
6720 LSM_HOOK_INIT(inode_getattr, selinux_inode_getattr),
6721 LSM_HOOK_INIT(inode_setxattr, selinux_inode_setxattr),
6722 LSM_HOOK_INIT(inode_post_setxattr, selinux_inode_post_setxattr),
6723 LSM_HOOK_INIT(inode_getxattr, selinux_inode_getxattr),
6724 LSM_HOOK_INIT(inode_listxattr, selinux_inode_listxattr),
6725 LSM_HOOK_INIT(inode_removexattr, selinux_inode_removexattr),
6726 LSM_HOOK_INIT(inode_getsecurity, selinux_inode_getsecurity),
6727 LSM_HOOK_INIT(inode_setsecurity, selinux_inode_setsecurity),
6728 LSM_HOOK_INIT(inode_listsecurity, selinux_inode_listsecurity),
6729 LSM_HOOK_INIT(inode_getsecid, selinux_inode_getsecid),
Vivek Goyal56909eb2016-07-13 10:44:48 -04006730 LSM_HOOK_INIT(inode_copy_up, selinux_inode_copy_up),
Vivek Goyal19472b62016-07-13 10:44:50 -04006731 LSM_HOOK_INIT(inode_copy_up_xattr, selinux_inode_copy_up_xattr),
Linus Torvalds1da177e2005-04-16 15:20:36 -07006732
Casey Schauflere20b0432015-05-02 15:11:36 -07006733 LSM_HOOK_INIT(file_permission, selinux_file_permission),
6734 LSM_HOOK_INIT(file_alloc_security, selinux_file_alloc_security),
Casey Schauflere20b0432015-05-02 15:11:36 -07006735 LSM_HOOK_INIT(file_ioctl, selinux_file_ioctl),
6736 LSM_HOOK_INIT(mmap_file, selinux_mmap_file),
6737 LSM_HOOK_INIT(mmap_addr, selinux_mmap_addr),
6738 LSM_HOOK_INIT(file_mprotect, selinux_file_mprotect),
6739 LSM_HOOK_INIT(file_lock, selinux_file_lock),
6740 LSM_HOOK_INIT(file_fcntl, selinux_file_fcntl),
6741 LSM_HOOK_INIT(file_set_fowner, selinux_file_set_fowner),
6742 LSM_HOOK_INIT(file_send_sigiotask, selinux_file_send_sigiotask),
6743 LSM_HOOK_INIT(file_receive, selinux_file_receive),
Linus Torvalds1da177e2005-04-16 15:20:36 -07006744
Casey Schauflere20b0432015-05-02 15:11:36 -07006745 LSM_HOOK_INIT(file_open, selinux_file_open),
Linus Torvalds1da177e2005-04-16 15:20:36 -07006746
Tetsuo Handaa79be232017-03-28 23:08:45 +09006747 LSM_HOOK_INIT(task_alloc, selinux_task_alloc),
Casey Schauflere20b0432015-05-02 15:11:36 -07006748 LSM_HOOK_INIT(cred_prepare, selinux_cred_prepare),
6749 LSM_HOOK_INIT(cred_transfer, selinux_cred_transfer),
Matthew Garrett3ec30112018-01-08 13:36:19 -08006750 LSM_HOOK_INIT(cred_getsecid, selinux_cred_getsecid),
Casey Schauflere20b0432015-05-02 15:11:36 -07006751 LSM_HOOK_INIT(kernel_act_as, selinux_kernel_act_as),
6752 LSM_HOOK_INIT(kernel_create_files_as, selinux_kernel_create_files_as),
6753 LSM_HOOK_INIT(kernel_module_request, selinux_kernel_module_request),
Mimi Zoharc77b8cd2018-07-13 14:06:02 -04006754 LSM_HOOK_INIT(kernel_load_data, selinux_kernel_load_data),
Jeff Vander Stoep61d612ea2016-04-05 13:06:27 -07006755 LSM_HOOK_INIT(kernel_read_file, selinux_kernel_read_file),
Casey Schauflere20b0432015-05-02 15:11:36 -07006756 LSM_HOOK_INIT(task_setpgid, selinux_task_setpgid),
6757 LSM_HOOK_INIT(task_getpgid, selinux_task_getpgid),
6758 LSM_HOOK_INIT(task_getsid, selinux_task_getsid),
6759 LSM_HOOK_INIT(task_getsecid, selinux_task_getsecid),
6760 LSM_HOOK_INIT(task_setnice, selinux_task_setnice),
6761 LSM_HOOK_INIT(task_setioprio, selinux_task_setioprio),
6762 LSM_HOOK_INIT(task_getioprio, selinux_task_getioprio),
Stephen Smalley791ec492017-02-17 07:57:00 -05006763 LSM_HOOK_INIT(task_prlimit, selinux_task_prlimit),
Casey Schauflere20b0432015-05-02 15:11:36 -07006764 LSM_HOOK_INIT(task_setrlimit, selinux_task_setrlimit),
6765 LSM_HOOK_INIT(task_setscheduler, selinux_task_setscheduler),
6766 LSM_HOOK_INIT(task_getscheduler, selinux_task_getscheduler),
6767 LSM_HOOK_INIT(task_movememory, selinux_task_movememory),
6768 LSM_HOOK_INIT(task_kill, selinux_task_kill),
Casey Schauflere20b0432015-05-02 15:11:36 -07006769 LSM_HOOK_INIT(task_to_inode, selinux_task_to_inode),
Yuichi Nakamura788e7dd2007-09-14 09:27:07 +09006770
Casey Schauflere20b0432015-05-02 15:11:36 -07006771 LSM_HOOK_INIT(ipc_permission, selinux_ipc_permission),
6772 LSM_HOOK_INIT(ipc_getsecid, selinux_ipc_getsecid),
Linus Torvalds1da177e2005-04-16 15:20:36 -07006773
Casey Schauflere20b0432015-05-02 15:11:36 -07006774 LSM_HOOK_INIT(msg_msg_alloc_security, selinux_msg_msg_alloc_security),
Linus Torvalds1da177e2005-04-16 15:20:36 -07006775
Casey Schauflere20b0432015-05-02 15:11:36 -07006776 LSM_HOOK_INIT(msg_queue_alloc_security,
6777 selinux_msg_queue_alloc_security),
Casey Schauflere20b0432015-05-02 15:11:36 -07006778 LSM_HOOK_INIT(msg_queue_associate, selinux_msg_queue_associate),
6779 LSM_HOOK_INIT(msg_queue_msgctl, selinux_msg_queue_msgctl),
6780 LSM_HOOK_INIT(msg_queue_msgsnd, selinux_msg_queue_msgsnd),
6781 LSM_HOOK_INIT(msg_queue_msgrcv, selinux_msg_queue_msgrcv),
Linus Torvalds1da177e2005-04-16 15:20:36 -07006782
Casey Schauflere20b0432015-05-02 15:11:36 -07006783 LSM_HOOK_INIT(shm_alloc_security, selinux_shm_alloc_security),
Casey Schauflere20b0432015-05-02 15:11:36 -07006784 LSM_HOOK_INIT(shm_associate, selinux_shm_associate),
6785 LSM_HOOK_INIT(shm_shmctl, selinux_shm_shmctl),
6786 LSM_HOOK_INIT(shm_shmat, selinux_shm_shmat),
Linus Torvalds1da177e2005-04-16 15:20:36 -07006787
Casey Schauflere20b0432015-05-02 15:11:36 -07006788 LSM_HOOK_INIT(sem_alloc_security, selinux_sem_alloc_security),
Casey Schauflere20b0432015-05-02 15:11:36 -07006789 LSM_HOOK_INIT(sem_associate, selinux_sem_associate),
6790 LSM_HOOK_INIT(sem_semctl, selinux_sem_semctl),
6791 LSM_HOOK_INIT(sem_semop, selinux_sem_semop),
Linus Torvalds1da177e2005-04-16 15:20:36 -07006792
Casey Schauflere20b0432015-05-02 15:11:36 -07006793 LSM_HOOK_INIT(d_instantiate, selinux_d_instantiate),
Linus Torvalds1da177e2005-04-16 15:20:36 -07006794
Casey Schauflere20b0432015-05-02 15:11:36 -07006795 LSM_HOOK_INIT(getprocattr, selinux_getprocattr),
6796 LSM_HOOK_INIT(setprocattr, selinux_setprocattr),
Linus Torvalds1da177e2005-04-16 15:20:36 -07006797
Casey Schauflere20b0432015-05-02 15:11:36 -07006798 LSM_HOOK_INIT(ismaclabel, selinux_ismaclabel),
6799 LSM_HOOK_INIT(secid_to_secctx, selinux_secid_to_secctx),
6800 LSM_HOOK_INIT(secctx_to_secid, selinux_secctx_to_secid),
6801 LSM_HOOK_INIT(release_secctx, selinux_release_secctx),
Andreas Gruenbacher6f3be9f2015-12-24 11:09:40 -05006802 LSM_HOOK_INIT(inode_invalidate_secctx, selinux_inode_invalidate_secctx),
Casey Schauflere20b0432015-05-02 15:11:36 -07006803 LSM_HOOK_INIT(inode_notifysecctx, selinux_inode_notifysecctx),
6804 LSM_HOOK_INIT(inode_setsecctx, selinux_inode_setsecctx),
6805 LSM_HOOK_INIT(inode_getsecctx, selinux_inode_getsecctx),
Linus Torvalds1da177e2005-04-16 15:20:36 -07006806
Casey Schauflere20b0432015-05-02 15:11:36 -07006807 LSM_HOOK_INIT(unix_stream_connect, selinux_socket_unix_stream_connect),
6808 LSM_HOOK_INIT(unix_may_send, selinux_socket_unix_may_send),
Catherine Zhangdc49c1f2006-08-02 14:12:06 -07006809
Casey Schauflere20b0432015-05-02 15:11:36 -07006810 LSM_HOOK_INIT(socket_create, selinux_socket_create),
6811 LSM_HOOK_INIT(socket_post_create, selinux_socket_post_create),
David Herrmann0b811db2018-05-04 16:28:21 +02006812 LSM_HOOK_INIT(socket_socketpair, selinux_socket_socketpair),
Casey Schauflere20b0432015-05-02 15:11:36 -07006813 LSM_HOOK_INIT(socket_bind, selinux_socket_bind),
6814 LSM_HOOK_INIT(socket_connect, selinux_socket_connect),
6815 LSM_HOOK_INIT(socket_listen, selinux_socket_listen),
6816 LSM_HOOK_INIT(socket_accept, selinux_socket_accept),
6817 LSM_HOOK_INIT(socket_sendmsg, selinux_socket_sendmsg),
6818 LSM_HOOK_INIT(socket_recvmsg, selinux_socket_recvmsg),
6819 LSM_HOOK_INIT(socket_getsockname, selinux_socket_getsockname),
6820 LSM_HOOK_INIT(socket_getpeername, selinux_socket_getpeername),
6821 LSM_HOOK_INIT(socket_getsockopt, selinux_socket_getsockopt),
6822 LSM_HOOK_INIT(socket_setsockopt, selinux_socket_setsockopt),
6823 LSM_HOOK_INIT(socket_shutdown, selinux_socket_shutdown),
6824 LSM_HOOK_INIT(socket_sock_rcv_skb, selinux_socket_sock_rcv_skb),
6825 LSM_HOOK_INIT(socket_getpeersec_stream,
6826 selinux_socket_getpeersec_stream),
6827 LSM_HOOK_INIT(socket_getpeersec_dgram, selinux_socket_getpeersec_dgram),
6828 LSM_HOOK_INIT(sk_alloc_security, selinux_sk_alloc_security),
6829 LSM_HOOK_INIT(sk_free_security, selinux_sk_free_security),
6830 LSM_HOOK_INIT(sk_clone_security, selinux_sk_clone_security),
6831 LSM_HOOK_INIT(sk_getsecid, selinux_sk_getsecid),
6832 LSM_HOOK_INIT(sock_graft, selinux_sock_graft),
Richard Hainesd4529302018-02-13 20:57:18 +00006833 LSM_HOOK_INIT(sctp_assoc_request, selinux_sctp_assoc_request),
6834 LSM_HOOK_INIT(sctp_sk_clone, selinux_sctp_sk_clone),
6835 LSM_HOOK_INIT(sctp_bind_connect, selinux_sctp_bind_connect),
Casey Schauflere20b0432015-05-02 15:11:36 -07006836 LSM_HOOK_INIT(inet_conn_request, selinux_inet_conn_request),
6837 LSM_HOOK_INIT(inet_csk_clone, selinux_inet_csk_clone),
6838 LSM_HOOK_INIT(inet_conn_established, selinux_inet_conn_established),
6839 LSM_HOOK_INIT(secmark_relabel_packet, selinux_secmark_relabel_packet),
6840 LSM_HOOK_INIT(secmark_refcount_inc, selinux_secmark_refcount_inc),
6841 LSM_HOOK_INIT(secmark_refcount_dec, selinux_secmark_refcount_dec),
6842 LSM_HOOK_INIT(req_classify_flow, selinux_req_classify_flow),
6843 LSM_HOOK_INIT(tun_dev_alloc_security, selinux_tun_dev_alloc_security),
6844 LSM_HOOK_INIT(tun_dev_free_security, selinux_tun_dev_free_security),
6845 LSM_HOOK_INIT(tun_dev_create, selinux_tun_dev_create),
6846 LSM_HOOK_INIT(tun_dev_attach_queue, selinux_tun_dev_attach_queue),
6847 LSM_HOOK_INIT(tun_dev_attach, selinux_tun_dev_attach),
6848 LSM_HOOK_INIT(tun_dev_open, selinux_tun_dev_open),
Daniel Jurgens3a976fa2017-05-19 15:48:56 +03006849#ifdef CONFIG_SECURITY_INFINIBAND
Daniel Jurgenscfc4d882017-05-19 15:48:57 +03006850 LSM_HOOK_INIT(ib_pkey_access, selinux_ib_pkey_access),
Daniel Jurgensab861df2017-05-19 15:48:58 +03006851 LSM_HOOK_INIT(ib_endport_manage_subnet,
6852 selinux_ib_endport_manage_subnet),
Daniel Jurgens3a976fa2017-05-19 15:48:56 +03006853 LSM_HOOK_INIT(ib_alloc_security, selinux_ib_alloc_security),
6854 LSM_HOOK_INIT(ib_free_security, selinux_ib_free_security),
6855#endif
Trent Jaegerd28d1e02005-12-13 23:12:40 -08006856#ifdef CONFIG_SECURITY_NETWORK_XFRM
Casey Schauflere20b0432015-05-02 15:11:36 -07006857 LSM_HOOK_INIT(xfrm_policy_alloc_security, selinux_xfrm_policy_alloc),
6858 LSM_HOOK_INIT(xfrm_policy_clone_security, selinux_xfrm_policy_clone),
6859 LSM_HOOK_INIT(xfrm_policy_free_security, selinux_xfrm_policy_free),
6860 LSM_HOOK_INIT(xfrm_policy_delete_security, selinux_xfrm_policy_delete),
6861 LSM_HOOK_INIT(xfrm_state_alloc, selinux_xfrm_state_alloc),
6862 LSM_HOOK_INIT(xfrm_state_alloc_acquire,
6863 selinux_xfrm_state_alloc_acquire),
6864 LSM_HOOK_INIT(xfrm_state_free_security, selinux_xfrm_state_free),
6865 LSM_HOOK_INIT(xfrm_state_delete_security, selinux_xfrm_state_delete),
6866 LSM_HOOK_INIT(xfrm_policy_lookup, selinux_xfrm_policy_lookup),
6867 LSM_HOOK_INIT(xfrm_state_pol_flow_match,
6868 selinux_xfrm_state_pol_flow_match),
6869 LSM_HOOK_INIT(xfrm_decode_session, selinux_xfrm_decode_session),
Linus Torvalds1da177e2005-04-16 15:20:36 -07006870#endif
Michael LeMayd7200242006-06-22 14:47:17 -07006871
6872#ifdef CONFIG_KEYS
Casey Schauflere20b0432015-05-02 15:11:36 -07006873 LSM_HOOK_INIT(key_alloc, selinux_key_alloc),
6874 LSM_HOOK_INIT(key_free, selinux_key_free),
6875 LSM_HOOK_INIT(key_permission, selinux_key_permission),
6876 LSM_HOOK_INIT(key_getsecurity, selinux_key_getsecurity),
Michael LeMayd7200242006-06-22 14:47:17 -07006877#endif
Ahmed S. Darwish9d57a7f2008-03-01 22:03:14 +02006878
6879#ifdef CONFIG_AUDIT
Casey Schauflere20b0432015-05-02 15:11:36 -07006880 LSM_HOOK_INIT(audit_rule_init, selinux_audit_rule_init),
6881 LSM_HOOK_INIT(audit_rule_known, selinux_audit_rule_known),
6882 LSM_HOOK_INIT(audit_rule_match, selinux_audit_rule_match),
6883 LSM_HOOK_INIT(audit_rule_free, selinux_audit_rule_free),
Ahmed S. Darwish9d57a7f2008-03-01 22:03:14 +02006884#endif
Chenbo Fengec27c352017-10-18 13:00:25 -07006885
6886#ifdef CONFIG_BPF_SYSCALL
6887 LSM_HOOK_INIT(bpf, selinux_bpf),
6888 LSM_HOOK_INIT(bpf_map, selinux_bpf_map),
6889 LSM_HOOK_INIT(bpf_prog, selinux_bpf_prog),
6890 LSM_HOOK_INIT(bpf_map_alloc_security, selinux_bpf_map_alloc),
6891 LSM_HOOK_INIT(bpf_prog_alloc_security, selinux_bpf_prog_alloc),
6892 LSM_HOOK_INIT(bpf_map_free_security, selinux_bpf_map_free),
6893 LSM_HOOK_INIT(bpf_prog_free_security, selinux_bpf_prog_free),
6894#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07006895};
6896
6897static __init int selinux_init(void)
6898{
peter enderborgc103a912018-06-12 10:09:03 +02006899 pr_info("SELinux: Initializing.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07006900
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05006901 memset(&selinux_state, 0, sizeof(selinux_state));
Paul Mooree5a5ca92018-03-01 17:38:30 -05006902 enforcing_set(&selinux_state, selinux_enforcing_boot);
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05006903 selinux_state.checkreqprot = selinux_checkreqprot_boot;
6904 selinux_ss_init(&selinux_state.ss);
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006905 selinux_avc_init(&selinux_state.avc);
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05006906
Linus Torvalds1da177e2005-04-16 15:20:36 -07006907 /* Set the security state for the initial task. */
David Howellsd84f4f92008-11-14 10:39:23 +11006908 cred_init_security();
Linus Torvalds1da177e2005-04-16 15:20:36 -07006909
Stephen Smalleyfcaaade2010-04-28 15:57:57 -04006910 default_noexec = !(VM_DATA_DEFAULT_FLAGS & VM_EXEC);
6911
Linus Torvalds1da177e2005-04-16 15:20:36 -07006912 avc_init();
6913
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05006914 avtab_cache_init();
6915
6916 ebitmap_cache_init();
6917
6918 hashtab_cache_init();
6919
Casey Schauflerd69dece52017-01-18 17:09:05 -08006920 security_add_hooks(selinux_hooks, ARRAY_SIZE(selinux_hooks), "selinux");
Linus Torvalds1da177e2005-04-16 15:20:36 -07006921
Paul Moore615e51f2014-06-26 14:33:56 -04006922 if (avc_add_callback(selinux_netcache_avc_callback, AVC_CALLBACK_RESET))
6923 panic("SELinux: Unable to register AVC netcache callback\n");
6924
Daniel Jurgens8f408ab2017-05-19 15:48:53 +03006925 if (avc_add_callback(selinux_lsm_notifier_avc_callback, AVC_CALLBACK_RESET))
6926 panic("SELinux: Unable to register AVC LSM notifier callback\n");
6927
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05006928 if (selinux_enforcing_boot)
peter enderborgc103a912018-06-12 10:09:03 +02006929 pr_debug("SELinux: Starting in enforcing mode\n");
Eric Paris828dfe12008-04-17 13:17:49 -04006930 else
peter enderborgc103a912018-06-12 10:09:03 +02006931 pr_debug("SELinux: Starting in permissive mode\n");
Michael LeMayd7200242006-06-22 14:47:17 -07006932
David Howells442155c2018-11-01 23:07:24 +00006933 fs_validate_description(&selinux_fs_parameters);
6934
Linus Torvalds1da177e2005-04-16 15:20:36 -07006935 return 0;
6936}
6937
Al Viroe8c26252010-03-23 06:36:54 -04006938static void delayed_superblock_init(struct super_block *sb, void *unused)
6939{
Al Viro204cc0c2018-12-13 13:41:47 -05006940 selinux_set_mnt_opts(sb, NULL, 0, NULL);
Al Viroe8c26252010-03-23 06:36:54 -04006941}
6942
Linus Torvalds1da177e2005-04-16 15:20:36 -07006943void selinux_complete_init(void)
6944{
peter enderborgc103a912018-06-12 10:09:03 +02006945 pr_debug("SELinux: Completing initialization.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07006946
6947 /* Set up any superblocks initialized prior to the policy load. */
peter enderborgc103a912018-06-12 10:09:03 +02006948 pr_debug("SELinux: Setting up existing superblocks.\n");
Al Viroe8c26252010-03-23 06:36:54 -04006949 iterate_supers(delayed_superblock_init, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006950}
6951
6952/* SELinux requires early initialization in order to label
6953 all processes and objects when they are created. */
Kees Cook3d6e5f62018-10-10 17:18:23 -07006954DEFINE_LSM(selinux) = {
Kees Cook07aed2f2018-10-10 17:18:24 -07006955 .name = "selinux",
Kees Cook14bd99c2018-09-19 19:57:06 -07006956 .flags = LSM_FLAG_LEGACY_MAJOR | LSM_FLAG_EXCLUSIVE,
Kees Cookc5459b82018-09-13 22:28:48 -07006957 .enabled = &selinux_enabled,
Casey Schauflerbbd36622018-11-12 09:30:56 -08006958 .blobs = &selinux_blob_sizes,
Kees Cook3d6e5f62018-10-10 17:18:23 -07006959 .init = selinux_init,
6960};
Linus Torvalds1da177e2005-04-16 15:20:36 -07006961
Stephen Smalleyc2b507f2006-02-04 23:27:50 -08006962#if defined(CONFIG_NETFILTER)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006963
Florian Westphal591bb272017-07-26 11:40:52 +02006964static const struct nf_hook_ops selinux_nf_ops[] = {
Paul Mooreeffad8d2008-01-29 08:49:27 -05006965 {
6966 .hook = selinux_ipv4_postroute,
Alban Crequy2597a832012-05-14 03:56:39 +00006967 .pf = NFPROTO_IPV4,
Paul Mooreeffad8d2008-01-29 08:49:27 -05006968 .hooknum = NF_INET_POST_ROUTING,
6969 .priority = NF_IP_PRI_SELINUX_LAST,
6970 },
6971 {
6972 .hook = selinux_ipv4_forward,
Alban Crequy2597a832012-05-14 03:56:39 +00006973 .pf = NFPROTO_IPV4,
Paul Mooreeffad8d2008-01-29 08:49:27 -05006974 .hooknum = NF_INET_FORWARD,
6975 .priority = NF_IP_PRI_SELINUX_FIRST,
Paul Moore948bf852008-10-10 10:16:32 -04006976 },
6977 {
6978 .hook = selinux_ipv4_output,
Alban Crequy2597a832012-05-14 03:56:39 +00006979 .pf = NFPROTO_IPV4,
Paul Moore948bf852008-10-10 10:16:32 -04006980 .hooknum = NF_INET_LOCAL_OUT,
6981 .priority = NF_IP_PRI_SELINUX_FIRST,
Jiri Pirko25db6be2014-09-03 17:42:13 +02006982 },
Javier Martinez Canillas1a93a6e2016-08-08 13:08:25 -04006983#if IS_ENABLED(CONFIG_IPV6)
Paul Mooreeffad8d2008-01-29 08:49:27 -05006984 {
6985 .hook = selinux_ipv6_postroute,
Alban Crequy2597a832012-05-14 03:56:39 +00006986 .pf = NFPROTO_IPV6,
Paul Mooreeffad8d2008-01-29 08:49:27 -05006987 .hooknum = NF_INET_POST_ROUTING,
6988 .priority = NF_IP6_PRI_SELINUX_LAST,
6989 },
6990 {
6991 .hook = selinux_ipv6_forward,
Alban Crequy2597a832012-05-14 03:56:39 +00006992 .pf = NFPROTO_IPV6,
Paul Mooreeffad8d2008-01-29 08:49:27 -05006993 .hooknum = NF_INET_FORWARD,
6994 .priority = NF_IP6_PRI_SELINUX_FIRST,
Jiri Pirko25db6be2014-09-03 17:42:13 +02006995 },
Huw Davies2917f572016-06-27 15:06:15 -04006996 {
6997 .hook = selinux_ipv6_output,
6998 .pf = NFPROTO_IPV6,
6999 .hooknum = NF_INET_LOCAL_OUT,
7000 .priority = NF_IP6_PRI_SELINUX_FIRST,
7001 },
Linus Torvalds1da177e2005-04-16 15:20:36 -07007002#endif /* IPV6 */
Jiri Pirko25db6be2014-09-03 17:42:13 +02007003};
Linus Torvalds1da177e2005-04-16 15:20:36 -07007004
Florian Westphal8e71bf72017-04-21 11:49:09 +02007005static int __net_init selinux_nf_register(struct net *net)
7006{
7007 return nf_register_net_hooks(net, selinux_nf_ops,
7008 ARRAY_SIZE(selinux_nf_ops));
7009}
7010
7011static void __net_exit selinux_nf_unregister(struct net *net)
7012{
7013 nf_unregister_net_hooks(net, selinux_nf_ops,
7014 ARRAY_SIZE(selinux_nf_ops));
7015}
7016
7017static struct pernet_operations selinux_net_ops = {
7018 .init = selinux_nf_register,
7019 .exit = selinux_nf_unregister,
7020};
7021
Linus Torvalds1da177e2005-04-16 15:20:36 -07007022static int __init selinux_nf_ip_init(void)
7023{
Jiri Pirko25db6be2014-09-03 17:42:13 +02007024 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007025
7026 if (!selinux_enabled)
Jiri Pirko25db6be2014-09-03 17:42:13 +02007027 return 0;
Eric Parisfadcdb42007-02-22 18:11:31 -05007028
peter enderborgc103a912018-06-12 10:09:03 +02007029 pr_debug("SELinux: Registering netfilter hooks\n");
Eric Parisfadcdb42007-02-22 18:11:31 -05007030
Florian Westphal8e71bf72017-04-21 11:49:09 +02007031 err = register_pernet_subsys(&selinux_net_ops);
Alexey Dobriyan6c5a9d22008-07-26 17:48:15 -07007032 if (err)
Florian Westphal8e71bf72017-04-21 11:49:09 +02007033 panic("SELinux: register_pernet_subsys: error %d\n", err);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007034
Jiri Pirko25db6be2014-09-03 17:42:13 +02007035 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007036}
Linus Torvalds1da177e2005-04-16 15:20:36 -07007037__initcall(selinux_nf_ip_init);
7038
7039#ifdef CONFIG_SECURITY_SELINUX_DISABLE
7040static void selinux_nf_ip_exit(void)
7041{
peter enderborgc103a912018-06-12 10:09:03 +02007042 pr_debug("SELinux: Unregistering netfilter hooks\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07007043
Florian Westphal8e71bf72017-04-21 11:49:09 +02007044 unregister_pernet_subsys(&selinux_net_ops);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007045}
7046#endif
7047
Stephen Smalleyc2b507f2006-02-04 23:27:50 -08007048#else /* CONFIG_NETFILTER */
Linus Torvalds1da177e2005-04-16 15:20:36 -07007049
7050#ifdef CONFIG_SECURITY_SELINUX_DISABLE
7051#define selinux_nf_ip_exit()
7052#endif
7053
Stephen Smalleyc2b507f2006-02-04 23:27:50 -08007054#endif /* CONFIG_NETFILTER */
Linus Torvalds1da177e2005-04-16 15:20:36 -07007055
7056#ifdef CONFIG_SECURITY_SELINUX_DISABLE
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05007057int selinux_disable(struct selinux_state *state)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007058{
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05007059 if (state->initialized) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07007060 /* Not permitted after initial policy load. */
7061 return -EINVAL;
7062 }
7063
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05007064 if (state->disabled) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07007065 /* Only do this once. */
7066 return -EINVAL;
7067 }
7068
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05007069 state->disabled = 1;
7070
peter enderborgc103a912018-06-12 10:09:03 +02007071 pr_info("SELinux: Disabled at runtime.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07007072
Stephen Smalley30d55282006-05-03 10:52:36 -04007073 selinux_enabled = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007074
Casey Schauflerb1d9e6b2015-05-02 15:11:42 -07007075 security_delete_hooks(selinux_hooks, ARRAY_SIZE(selinux_hooks));
Linus Torvalds1da177e2005-04-16 15:20:36 -07007076
Eric Parisaf8ff042009-09-20 21:23:01 -04007077 /* Try to destroy the avc node cache */
7078 avc_disable();
7079
Linus Torvalds1da177e2005-04-16 15:20:36 -07007080 /* Unregister netfilter hooks. */
7081 selinux_nf_ip_exit();
7082
7083 /* Unregister selinuxfs. */
7084 exit_sel_fs();
7085
7086 return 0;
7087}
7088#endif