~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/security/lockdown/lockdown.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0
  2 /* Lock down the kernel
  3  *
  4  * Copyright (C) 2016 Red Hat, Inc. All Rights Reserved.
  5  * Written by David Howells (dhowells@redhat.com)
  6  *
  7  * This program is free software; you can redistribute it and/or
  8  * modify it under the terms of the GNU General Public Licence
  9  * as published by the Free Software Foundation; either version
 10  * 2 of the Licence, or (at your option) any later version.
 11  */
 12 
 13 #include <linux/security.h>
 14 #include <linux/export.h>
 15 #include <linux/lsm_hooks.h>
 16 #include <uapi/linux/lsm.h>
 17 
 18 static enum lockdown_reason kernel_locked_down;
 19 
 20 static const enum lockdown_reason lockdown_levels[] = {LOCKDOWN_NONE,
 21                                                  LOCKDOWN_INTEGRITY_MAX,
 22                                                  LOCKDOWN_CONFIDENTIALITY_MAX};
 23 
 24 /*
 25  * Put the kernel into lock-down mode.
 26  */
 27 static int lock_kernel_down(const char *where, enum lockdown_reason level)
 28 {
 29         if (kernel_locked_down >= level)
 30                 return -EPERM;
 31 
 32         kernel_locked_down = level;
 33         pr_notice("Kernel is locked down from %s; see man kernel_lockdown.7\n",
 34                   where);
 35         return 0;
 36 }
 37 
 38 static int __init lockdown_param(char *level)
 39 {
 40         if (!level)
 41                 return -EINVAL;
 42 
 43         if (strcmp(level, "integrity") == 0)
 44                 lock_kernel_down("command line", LOCKDOWN_INTEGRITY_MAX);
 45         else if (strcmp(level, "confidentiality") == 0)
 46                 lock_kernel_down("command line", LOCKDOWN_CONFIDENTIALITY_MAX);
 47         else
 48                 return -EINVAL;
 49 
 50         return 0;
 51 }
 52 
 53 early_param("lockdown", lockdown_param);
 54 
 55 /**
 56  * lockdown_is_locked_down - Find out if the kernel is locked down
 57  * @what: Tag to use in notice generated if lockdown is in effect
 58  */
 59 static int lockdown_is_locked_down(enum lockdown_reason what)
 60 {
 61         if (WARN(what >= LOCKDOWN_CONFIDENTIALITY_MAX,
 62                  "Invalid lockdown reason"))
 63                 return -EPERM;
 64 
 65         if (kernel_locked_down >= what) {
 66                 if (lockdown_reasons[what])
 67                         pr_notice_ratelimited("Lockdown: %s: %s is restricted; see man kernel_lockdown.7\n",
 68                                   current->comm, lockdown_reasons[what]);
 69                 return -EPERM;
 70         }
 71 
 72         return 0;
 73 }
 74 
 75 static struct security_hook_list lockdown_hooks[] __ro_after_init = {
 76         LSM_HOOK_INIT(locked_down, lockdown_is_locked_down),
 77 };
 78 
 79 const struct lsm_id lockdown_lsmid = {
 80         .name = "lockdown",
 81         .id = LSM_ID_LOCKDOWN,
 82 };
 83 
 84 static int __init lockdown_lsm_init(void)
 85 {
 86 #if defined(CONFIG_LOCK_DOWN_KERNEL_FORCE_INTEGRITY)
 87         lock_kernel_down("Kernel configuration", LOCKDOWN_INTEGRITY_MAX);
 88 #elif defined(CONFIG_LOCK_DOWN_KERNEL_FORCE_CONFIDENTIALITY)
 89         lock_kernel_down("Kernel configuration", LOCKDOWN_CONFIDENTIALITY_MAX);
 90 #endif
 91         security_add_hooks(lockdown_hooks, ARRAY_SIZE(lockdown_hooks),
 92                            &lockdown_lsmid);
 93         return 0;
 94 }
 95 
 96 static ssize_t lockdown_read(struct file *filp, char __user *buf, size_t count,
 97                              loff_t *ppos)
 98 {
 99         char temp[80];
100         int i, offset = 0;
101 
102         for (i = 0; i < ARRAY_SIZE(lockdown_levels); i++) {
103                 enum lockdown_reason level = lockdown_levels[i];
104 
105                 if (lockdown_reasons[level]) {
106                         const char *label = lockdown_reasons[level];
107 
108                         if (kernel_locked_down == level)
109                                 offset += sprintf(temp+offset, "[%s] ", label);
110                         else
111                                 offset += sprintf(temp+offset, "%s ", label);
112                 }
113         }
114 
115         /* Convert the last space to a newline if needed. */
116         if (offset > 0)
117                 temp[offset-1] = '\n';
118 
119         return simple_read_from_buffer(buf, count, ppos, temp, strlen(temp));
120 }
121 
122 static ssize_t lockdown_write(struct file *file, const char __user *buf,
123                               size_t n, loff_t *ppos)
124 {
125         char *state;
126         int i, len, err = -EINVAL;
127 
128         state = memdup_user_nul(buf, n);
129         if (IS_ERR(state))
130                 return PTR_ERR(state);
131 
132         len = strlen(state);
133         if (len && state[len-1] == '\n') {
134                 state[len-1] = '\0';
135                 len--;
136         }
137 
138         for (i = 0; i < ARRAY_SIZE(lockdown_levels); i++) {
139                 enum lockdown_reason level = lockdown_levels[i];
140                 const char *label = lockdown_reasons[level];
141 
142                 if (label && !strcmp(state, label))
143                         err = lock_kernel_down("securityfs", level);
144         }
145 
146         kfree(state);
147         return err ? err : n;
148 }
149 
150 static const struct file_operations lockdown_ops = {
151         .read  = lockdown_read,
152         .write = lockdown_write,
153 };
154 
155 static int __init lockdown_secfs_init(void)
156 {
157         struct dentry *dentry;
158 
159         dentry = securityfs_create_file("lockdown", 0644, NULL, NULL,
160                                         &lockdown_ops);
161         return PTR_ERR_OR_ZERO(dentry);
162 }
163 
164 core_initcall(lockdown_secfs_init);
165 
166 #ifdef CONFIG_SECURITY_LOCKDOWN_LSM_EARLY
167 DEFINE_EARLY_LSM(lockdown) = {
168 #else
169 DEFINE_LSM(lockdown) = {
170 #endif
171         .name = "lockdown",
172         .init = lockdown_lsm_init,
173 };
174 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php