Commit 3bc1fa8ae18f281b40903cce94baba10c3cf9d88

Authored by Chris Wright
Committed by Linus Torvalds
1 parent cd1c6a48ac

[PATCH] LSM: remove BSD secure level security module

This code has suffered from broken core design and lack of developer
attention.  Broken security modules are too dangerous to leave around.  It
is time to remove this one.

Signed-off-by: Chris Wright <chrisw@sous-sol.org>
Acked-by: Michael Halcrow <mhalcrow@us.ibm.com>
Acked-by: Serge Hallyn <serue@us.ibm.com>
Cc: Davi Arnaut <davi.arnaut@gmail.com>
Acked-by: Greg Kroah-Hartman <gregkh@suse.de>
Acked-by: James Morris <jmorris@namei.org>
Acked-by: Alan Cox <alan@redhat.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

Showing 4 changed files with 0 additions and 781 deletions Side-by-side Diff

Documentation/seclvl.txt
1   -BSD Secure Levels Linux Security Module
2   -Michael A. Halcrow <mike@halcrow.us>
3   -
4   -
5   -Introduction
6   -
7   -Under the BSD Secure Levels security model, sets of policies are
8   -associated with levels. Levels range from -1 to 2, with -1 being the
9   -weakest and 2 being the strongest. These security policies are
10   -enforced at the kernel level, so not even the superuser is able to
11   -disable or circumvent them. This hardens the machine against attackers
12   -who gain root access to the system.
13   -
14   -
15   -Levels and Policies
16   -
17   -Level -1 (Permanently Insecure):
18   - - Cannot increase the secure level
19   -
20   -Level 0 (Insecure):
21   - - Cannot ptrace the init process
22   -
23   -Level 1 (Default):
24   - - /dev/mem and /dev/kmem are read-only
25   - - IMMUTABLE and APPEND extended attributes, if set, may not be unset
26   - - Cannot load or unload kernel modules
27   - - Cannot write directly to a mounted block device
28   - - Cannot perform raw I/O operations
29   - - Cannot perform network administrative tasks
30   - - Cannot setuid any file
31   -
32   -Level 2 (Secure):
33   - - Cannot decrement the system time
34   - - Cannot write to any block device, whether mounted or not
35   - - Cannot unmount any mounted filesystems
36   -
37   -
38   -Compilation
39   -
40   -To compile the BSD Secure Levels LSM, seclvl.ko, enable the
41   -SECURITY_SECLVL configuration option. This is found under Security
42   -options -> BSD Secure Levels in the kernel configuration menu.
43   -
44   -
45   -Basic Usage
46   -
47   -Once the machine is in a running state, with all the necessary modules
48   -loaded and all the filesystems mounted, you can load the seclvl.ko
49   -module:
50   -
51   -# insmod seclvl.ko
52   -
53   -The module defaults to secure level 1, except when compiled directly
54   -into the kernel, in which case it defaults to secure level 0. To raise
55   -the secure level to 2, the administrator writes ``2'' to the
56   -seclvl/seclvl file under the sysfs mount point (assumed to be /sys in
57   -these examples):
58   -
59   -# echo -n "2" > /sys/seclvl/seclvl
60   -
61   -Alternatively, you can initialize the module at secure level 2 with
62   -the initlvl module parameter:
63   -
64   -# insmod seclvl.ko initlvl=2
65   -
66   -At this point, it is impossible to remove the module or reduce the
67   -secure level. If the administrator wishes to have the option of doing
68   -so, he must provide a module parameter, sha1_passwd, that specifies
69   -the SHA1 hash of the password that can be used to reduce the secure
70   -level to 0.
71   -
72   -To generate this SHA1 hash, the administrator can use OpenSSL:
73   -
74   -# echo -n "boogabooga" | openssl sha1
75   -abeda4e0f33defa51741217592bf595efb8d289c
76   -
77   -In order to use password-instigated secure level reduction, the SHA1
78   -crypto module must be loaded or compiled into the kernel:
79   -
80   -# insmod sha1.ko
81   -
82   -The administrator can then insmod the seclvl module, including the
83   -SHA1 hash of the password:
84   -
85   -# insmod seclvl.ko
86   - sha1_passwd=abeda4e0f33defa51741217592bf595efb8d289c
87   -
88   -To reduce the secure level, write the password to seclvl/passwd under
89   -your sysfs mount point:
90   -
91   -# echo -n "boogabooga" > /sys/seclvl/passwd
92   -
93   -The September 2004 edition of Sys Admin Magazine has an article about
94   -the BSD Secure Levels LSM. I encourage you to refer to that article
95   -for a more in-depth treatment of this security module:
96   -
97   -http://www.samag.com/documents/s=9304/sam0409a/0409a.htm
... ... @@ -93,18 +93,6 @@
93 93  
94 94 If you are unsure how to answer this question, answer N.
95 95  
96   -config SECURITY_SECLVL
97   - tristate "BSD Secure Levels"
98   - depends on SECURITY
99   - select CRYPTO
100   - select CRYPTO_SHA1
101   - help
102   - Implements BSD Secure Levels as an LSM. See
103   - <file:Documentation/seclvl.txt> for instructions on how to use this
104   - module.
105   -
106   - If you are unsure how to answer this question, answer N.
107   -
108 96 source security/selinux/Kconfig
109 97  
110 98 endmenu
... ... @@ -16,5 +16,4 @@
16 16 obj-$(CONFIG_SECURITY_SELINUX) += selinux/built-in.o
17 17 obj-$(CONFIG_SECURITY_CAPABILITIES) += commoncap.o capability.o
18 18 obj-$(CONFIG_SECURITY_ROOTPLUG) += commoncap.o root_plug.o
19   -obj-$(CONFIG_SECURITY_SECLVL) += seclvl.o
security/seclvl.c
1   -/**
2   - * BSD Secure Levels LSM
3   - *
4   - * Maintainers:
5   - * Michael A. Halcrow <mike@halcrow.us>
6   - * Serge Hallyn <hallyn@cs.wm.edu>
7   - *
8   - * Copyright (c) 2001 WireX Communications, Inc <chris@wirex.com>
9   - * Copyright (c) 2001 Greg Kroah-Hartman <greg@kroah.com>
10   - * Copyright (c) 2002 International Business Machines <robb@austin.ibm.com>
11   - * Copyright (c) 2006 Davi E. M. Arnaut <davi.arnaut@gmail.com>
12   - *
13   - * This program is free software; you can redistribute it and/or modify
14   - * it under the terms of the GNU General Public License as published by
15   - * the Free Software Foundation; either version 2 of the License, or
16   - * (at your option) any later version.
17   - */
18   -
19   -#include <linux/err.h>
20   -#include <linux/module.h>
21   -#include <linux/moduleparam.h>
22   -#include <linux/kernel.h>
23   -#include <linux/init.h>
24   -#include <linux/security.h>
25   -#include <linux/netlink.h>
26   -#include <linux/fs.h>
27   -#include <linux/namei.h>
28   -#include <linux/mount.h>
29   -#include <linux/capability.h>
30   -#include <linux/time.h>
31   -#include <linux/proc_fs.h>
32   -#include <linux/kobject.h>
33   -#include <linux/crypto.h>
34   -#include <asm/scatterlist.h>
35   -#include <linux/scatterlist.h>
36   -#include <linux/gfp.h>
37   -#include <linux/sysfs.h>
38   -
39   -#define SHA1_DIGEST_SIZE 20
40   -
41   -/**
42   - * Module parameter that defines the initial secure level.
43   - *
44   - * When built as a module, it defaults to seclvl 1, which is the
45   - * behavior of BSD secure levels. Note that this default behavior
46   - * wrecks havoc on a machine when the seclvl module is compiled into
47   - * the kernel. In that case, we default to seclvl 0.
48   - */
49   -#ifdef CONFIG_SECURITY_SECLVL_MODULE
50   -static int initlvl = 1;
51   -#else
52   -static int initlvl;
53   -#endif
54   -module_param(initlvl, int, 0);
55   -MODULE_PARM_DESC(initlvl, "Initial secure level (defaults to 1)");
56   -
57   -/* Module parameter that defines the verbosity level */
58   -static int verbosity;
59   -module_param(verbosity, int, 0);
60   -MODULE_PARM_DESC(verbosity, "Initial verbosity level (0 or 1; defaults to "
61   - "0, which is Quiet)");
62   -
63   -/**
64   - * Optional password which can be passed in to bring seclvl to 0
65   - * (i.e., for halt/reboot). Defaults to NULL (the passwd attribute
66   - * file will not be registered in sysfs).
67   - *
68   - * This gets converted to its SHA1 hash when stored. It's probably
69   - * not a good idea to use this parameter when loading seclvl from a
70   - * script; use sha1_passwd instead.
71   - */
72   -
73   -#define MAX_PASSWD_SIZE 32
74   -static char passwd[MAX_PASSWD_SIZE];
75   -module_param_string(passwd, passwd, sizeof(passwd), 0);
76   -MODULE_PARM_DESC(passwd,
77   - "Plaintext of password that sets seclvl=0 when written to "
78   - "(sysfs mount point)/seclvl/passwd\n");
79   -
80   -/**
81   - * SHA1 hashed version of the optional password which can be passed in
82   - * to bring seclvl to 0 (i.e., for halt/reboot). Must be in
83   - * hexadecimal format (40 characters). Defaults to NULL (the passwd
84   - * attribute file will not be registered in sysfs).
85   - *
86   - * Use the sha1sum utility to generate the SHA1 hash of a password:
87   - *
88   - * echo -n "secret" | sha1sum
89   - */
90   -#define MAX_SHA1_PASSWD 41
91   -static char sha1_passwd[MAX_SHA1_PASSWD];
92   -module_param_string(sha1_passwd, sha1_passwd, sizeof(sha1_passwd), 0);
93   -MODULE_PARM_DESC(sha1_passwd,
94   - "SHA1 hash (40 hexadecimal characters) of password that "
95   - "sets seclvl=0 when plaintext password is written to "
96   - "(sysfs mount point)/seclvl/passwd\n");
97   -
98   -static int hideHash = 1;
99   -module_param(hideHash, int, 0);
100   -MODULE_PARM_DESC(hideHash, "When set to 0, reading seclvl/passwd from sysfs "
101   - "will return the SHA1-hashed value of the password that "
102   - "lowers the secure level to 0.\n");
103   -
104   -#define MY_NAME "seclvl"
105   -
106   -/**
107   - * This time-limits log writes to one per second.
108   - */
109   -#define seclvl_printk(verb, type, fmt, arg...) \
110   - do { \
111   - if (verbosity >= verb) { \
112   - static unsigned long _prior; \
113   - unsigned long _now = jiffies; \
114   - if ((_now - _prior) > HZ) { \
115   - printk(type "%s: %s: " fmt, \
116   - MY_NAME, __FUNCTION__ , \
117   - ## arg); \
118   - _prior = _now; \
119   - } \
120   - } \
121   - } while (0)
122   -
123   -/**
124   - * The actual security level. Ranges between -1 and 2 inclusive.
125   - */
126   -static int seclvl;
127   -
128   -/**
129   - * flag to keep track of how we were registered
130   - */
131   -static int secondary;
132   -
133   -/**
134   - * Verifies that the requested secure level is valid, given the current
135   - * secure level.
136   - */
137   -static int seclvl_sanity(int reqlvl)
138   -{
139   - if ((reqlvl < -1) || (reqlvl > 2)) {
140   - seclvl_printk(1, KERN_WARNING, "Attempt to set seclvl out of "
141   - "range: [%d]\n", reqlvl);
142   - return -EINVAL;
143   - }
144   - if ((seclvl == 0) && (reqlvl == -1))
145   - return 0;
146   - if (reqlvl < seclvl) {
147   - seclvl_printk(1, KERN_WARNING, "Attempt to lower seclvl to "
148   - "[%d]\n", reqlvl);
149   - return -EPERM;
150   - }
151   - return 0;
152   -}
153   -
154   -/**
155   - * security level advancement rules:
156   - * Valid levels are -1 through 2, inclusive.
157   - * From -1, stuck. [ in case compiled into kernel ]
158   - * From 0 or above, can only increment.
159   - */
160   -static void do_seclvl_advance(void *data, u64 val)
161   -{
162   - int ret;
163   - int newlvl = (int)val;
164   -
165   - ret = seclvl_sanity(newlvl);
166   - if (ret)
167   - return;
168   -
169   - if (newlvl > 2) {
170   - seclvl_printk(1, KERN_WARNING, "Cannot advance to seclvl "
171   - "[%d]\n", newlvl);
172   - return;
173   - }
174   - if (seclvl == -1) {
175   - seclvl_printk(1, KERN_WARNING, "Not allowed to advance to "
176   - "seclvl [%d]\n", seclvl);
177   - return;
178   - }
179   - seclvl = newlvl; /* would it be more "correct" to set *data? */
180   - return;
181   -}
182   -
183   -static u64 seclvl_int_get(void *data)
184   -{
185   - return *(int *)data;
186   -}
187   -
188   -DEFINE_SIMPLE_ATTRIBUTE(seclvl_file_ops, seclvl_int_get, do_seclvl_advance, "%lld\n");
189   -
190   -static unsigned char hashedPassword[SHA1_DIGEST_SIZE];
191   -
192   -/**
193   - * Converts a block of plaintext of into its SHA1 hashed value.
194   - *
195   - * It would be nice if crypto had a wrapper to do this for us linear
196   - * people...
197   - */
198   -static int
199   -plaintext_to_sha1(unsigned char *hash, const char *plaintext, unsigned int len)
200   -{
201   - struct hash_desc desc;
202   - struct scatterlist sg;
203   - int err;
204   -
205   - if (len > PAGE_SIZE) {
206   - seclvl_printk(0, KERN_ERR, "Plaintext password too large (%d "
207   - "characters). Largest possible is %lu "
208   - "bytes.\n", len, PAGE_SIZE);
209   - return -EINVAL;
210   - }
211   - desc.tfm = crypto_alloc_hash("sha1", 0, CRYPTO_ALG_ASYNC);
212   - if (IS_ERR(desc.tfm)) {
213   - seclvl_printk(0, KERN_ERR,
214   - "Failed to load transform for SHA1\n");
215   - return -EINVAL;
216   - }
217   - sg_init_one(&sg, (u8 *)plaintext, len);
218   - desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP;
219   - err = crypto_hash_digest(&desc, &sg, len, hash);
220   - crypto_free_hash(desc.tfm);
221   - return err;
222   -}
223   -
224   -/**
225   - * Called whenever the user writes to the sysfs passwd handle to this kernel
226   - * object. It hashes the password and compares the hashed results.
227   - */
228   -static ssize_t
229   -passwd_write_file(struct file * file, const char __user * buf,
230   - size_t count, loff_t *ppos)
231   -{
232   - char *p;
233   - int len;
234   - unsigned char tmp[SHA1_DIGEST_SIZE];
235   -
236   - if (!*passwd && !*sha1_passwd) {
237   - seclvl_printk(0, KERN_ERR, "Attempt to password-unlock the "
238   - "seclvl module, but neither a plain text "
239   - "password nor a SHA1 hashed password was "
240   - "passed in as a module parameter! This is a "
241   - "bug, since it should not be possible to be in "
242   - "this part of the module; please tell a "
243   - "maintainer about this event.\n");
244   - return -EINVAL;
245   - }
246   -
247   - if (count >= PAGE_SIZE)
248   - return -EINVAL;
249   - if (*ppos != 0)
250   - return -EINVAL;
251   - p = kmalloc(count, GFP_KERNEL);
252   - if (!p)
253   - return -ENOMEM;
254   - len = -EFAULT;
255   - if (copy_from_user(p, buf, count))
256   - goto out;
257   -
258   - len = count;
259   - /* ``echo "secret" > seclvl/passwd'' includes a newline */
260   - if (p[len - 1] == '\n')
261   - len--;
262   - /* Hash the password, then compare the hashed values */
263   - if ((len = plaintext_to_sha1(tmp, p, len))) {
264   - seclvl_printk(0, KERN_ERR, "Error hashing password: rc = "
265   - "[%d]\n", len);
266   - goto out;
267   - }
268   -
269   - len = -EPERM;
270   - if (memcmp(hashedPassword, tmp, SHA1_DIGEST_SIZE))
271   - goto out;
272   -
273   - seclvl_printk(0, KERN_INFO,
274   - "Password accepted; seclvl reduced to 0.\n");
275   - seclvl = 0;
276   - len = count;
277   -
278   -out:
279   - kfree (p);
280   - return len;
281   -}
282   -
283   -static struct file_operations passwd_file_ops = {
284   - .write = passwd_write_file,
285   -};
286   -
287   -/**
288   - * Explicitely disallow ptrace'ing the init process.
289   - */
290   -static int seclvl_ptrace(struct task_struct *parent, struct task_struct *child)
291   -{
292   - if (seclvl >= 0 && child->pid == 1) {
293   - seclvl_printk(1, KERN_WARNING, "Attempt to ptrace "
294   - "the init process dissallowed in "
295   - "secure level %d\n", seclvl);
296   - return -EPERM;
297   - }
298   - return 0;
299   -}
300   -
301   -/**
302   - * Capability checks for seclvl. The majority of the policy
303   - * enforcement for seclvl takes place here.
304   - */
305   -static int seclvl_capable(struct task_struct *tsk, int cap)
306   -{
307   - int rc = 0;
308   -
309   - /* init can do anything it wants */
310   - if (tsk->pid == 1)
311   - return 0;
312   -
313   - if (seclvl > 0) {
314   - rc = -EPERM;
315   -
316   - if (cap == CAP_LINUX_IMMUTABLE)
317   - seclvl_printk(1, KERN_WARNING, "Attempt to modify "
318   - "the IMMUTABLE and/or APPEND extended "
319   - "attribute on a file with the IMMUTABLE "
320   - "and/or APPEND extended attribute set "
321   - "denied in seclvl [%d]\n", seclvl);
322   - else if (cap == CAP_SYS_RAWIO)
323   - seclvl_printk(1, KERN_WARNING, "Attempt to perform "
324   - "raw I/O while in secure level [%d] "
325   - "denied\n", seclvl);
326   - else if (cap == CAP_NET_ADMIN)
327   - seclvl_printk(1, KERN_WARNING, "Attempt to perform "
328   - "network administrative task while "
329   - "in secure level [%d] denied\n", seclvl);
330   - else if (cap == CAP_SETUID)
331   - seclvl_printk(1, KERN_WARNING, "Attempt to setuid "
332   - "while in secure level [%d] denied\n",
333   - seclvl);
334   - else if (cap == CAP_SETGID)
335   - seclvl_printk(1, KERN_WARNING, "Attempt to setgid "
336   - "while in secure level [%d] denied\n",
337   - seclvl);
338   - else if (cap == CAP_SYS_MODULE)
339   - seclvl_printk(1, KERN_WARNING, "Attempt to perform "
340   - "a module operation while in secure "
341   - "level [%d] denied\n", seclvl);
342   - else
343   - rc = 0;
344   - }
345   -
346   - if (!rc) {
347   - if (!(cap_is_fs_cap(cap) ? tsk->fsuid == 0 : tsk->euid == 0))
348   - rc = -EPERM;
349   - }
350   -
351   - if (rc)
352   - seclvl_printk(1, KERN_WARNING, "Capability denied\n");
353   -
354   - return rc;
355   -}
356   -
357   -/**
358   - * Disallow reversing the clock in seclvl > 1
359   - */
360   -static int seclvl_settime(struct timespec *tv, struct timezone *tz)
361   -{
362   - if (tv && seclvl > 1) {
363   - struct timespec now;
364   - now = current_kernel_time();
365   - if (tv->tv_sec < now.tv_sec ||
366   - (tv->tv_sec == now.tv_sec && tv->tv_nsec < now.tv_nsec)) {
367   - seclvl_printk(1, KERN_WARNING, "Attempt to decrement "
368   - "time in secure level %d denied: "
369   - "current->pid = [%d], "
370   - "current->group_leader->pid = [%d]\n",
371   - seclvl, current->pid,
372   - current->group_leader->pid);
373   - return -EPERM;
374   - } /* if attempt to decrement time */
375   - } /* if seclvl > 1 */
376   - return 0;
377   -}
378   -
379   -/* claim the blockdev to exclude mounters, release on file close */
380   -static int seclvl_bd_claim(struct inode *inode)
381   -{
382   - int holder;
383   - struct block_device *bdev = NULL;
384   - dev_t dev = inode->i_rdev;
385   - bdev = open_by_devnum(dev, FMODE_WRITE);
386   - if (bdev) {
387   - if (bd_claim(bdev, &holder)) {
388   - blkdev_put(bdev);
389   - return -EPERM;
390   - }
391   - /* claimed, mark it to release on close */
392   - inode->i_security = current;
393   - }
394   - return 0;
395   -}
396   -
397   -/* release the blockdev if you claimed it */
398   -static void seclvl_bd_release(struct inode *inode)
399   -{
400   - if (inode && S_ISBLK(inode->i_mode) && inode->i_security == current) {
401   - struct block_device *bdev = inode->i_bdev;
402   - if (bdev) {
403   - bd_release(bdev);
404   - blkdev_put(bdev);
405   - inode->i_security = NULL;
406   - }
407   - }
408   -}
409   -
410   -/**
411   - * Security for writes to block devices is regulated by this seclvl
412   - * function. Deny all writes to block devices in seclvl 2. In
413   - * seclvl 1, we only deny writes to *mounted* block devices.
414   - */
415   -static int
416   -seclvl_inode_permission(struct inode *inode, int mask, struct nameidata *nd)
417   -{
418   - if (current->pid != 1 && S_ISBLK(inode->i_mode) && (mask & MAY_WRITE)) {
419   - switch (seclvl) {
420   - case 2:
421   - seclvl_printk(1, KERN_WARNING, "Write to block device "
422   - "denied in secure level [%d]\n", seclvl);
423   - return -EPERM;
424   - case 1:
425   - if (seclvl_bd_claim(inode)) {
426   - seclvl_printk(1, KERN_WARNING,
427   - "Write to mounted block device "
428   - "denied in secure level [%d]\n",
429   - seclvl);
430   - return -EPERM;
431   - }
432   - }
433   - }
434   - return 0;
435   -}
436   -
437   -/**
438   - * The SUID and SGID bits cannot be set in seclvl >= 1
439   - */
440   -static int seclvl_inode_setattr(struct dentry *dentry, struct iattr *iattr)
441   -{
442   - if (seclvl > 0) {
443   - if (iattr->ia_valid & ATTR_MODE)
444   - if (iattr->ia_mode & S_ISUID ||
445   - iattr->ia_mode & S_ISGID) {
446   - seclvl_printk(1, KERN_WARNING, "Attempt to "
447   - "modify SUID or SGID bit "
448   - "denied in seclvl [%d]\n",
449   - seclvl);
450   - return -EPERM;
451   - }
452   - }
453   - return 0;
454   -}
455   -
456   -/* release busied block devices */
457   -static void seclvl_file_free_security(struct file *filp)
458   -{
459   - struct dentry *dentry = filp->f_dentry;
460   -
461   - if (dentry)
462   - seclvl_bd_release(dentry->d_inode);
463   -}
464   -
465   -/**
466   - * Cannot unmount in secure level 2
467   - */
468   -static int seclvl_umount(struct vfsmount *mnt, int flags)
469   -{
470   - if (current->pid != 1 && seclvl == 2) {
471   - seclvl_printk(1, KERN_WARNING, "Attempt to unmount in secure "
472   - "level %d\n", seclvl);
473   - return -EPERM;
474   - }
475   - return 0;
476   -}
477   -
478   -static struct security_operations seclvl_ops = {
479   - .ptrace = seclvl_ptrace,
480   - .capable = seclvl_capable,
481   - .inode_permission = seclvl_inode_permission,
482   - .inode_setattr = seclvl_inode_setattr,
483   - .file_free_security = seclvl_file_free_security,
484   - .settime = seclvl_settime,
485   - .sb_umount = seclvl_umount,
486   -};
487   -
488   -/**
489   - * Process the password-related module parameters
490   - */
491   -static int processPassword(void)
492   -{
493   - int rc = 0;
494   - if (*passwd) {
495   - char *p;
496   -
497   - if (*sha1_passwd) {
498   - seclvl_printk(0, KERN_ERR, "Error: Both "
499   - "passwd and sha1_passwd "
500   - "were set, but they are mutually "
501   - "exclusive.\n");
502   - return -EINVAL;
503   - }
504   -
505   - p = kstrdup(passwd, GFP_KERNEL);
506   - if (p == NULL)
507   - return -ENOMEM;
508   -
509   - if ((rc = plaintext_to_sha1(hashedPassword, p, strlen(p))))
510   - seclvl_printk(0, KERN_ERR, "Error: SHA1 support not "
511   - "in kernel\n");
512   -
513   - kfree (p);
514   - /* All static data goes to the BSS, which zero's the
515   - * plaintext password out for us. */
516   - } else if (*sha1_passwd) { // Base 16
517   - int i;
518   - i = strlen(sha1_passwd);
519   - if (i != (SHA1_DIGEST_SIZE * 2)) {
520   - seclvl_printk(0, KERN_ERR, "Received [%d] bytes; "
521   - "expected [%d] for the hexadecimal "
522   - "representation of the SHA1 hash of "
523   - "the password.\n",
524   - i, (SHA1_DIGEST_SIZE * 2));
525   - return -EINVAL;
526   - }
527   - while ((i -= 2) + 2) {
528   - unsigned char tmp;
529   - tmp = sha1_passwd[i + 2];
530   - sha1_passwd[i + 2] = '\0';
531   - hashedPassword[i / 2] = (unsigned char)
532   - simple_strtol(&sha1_passwd[i], NULL, 16);
533   - sha1_passwd[i + 2] = tmp;
534   - }
535   - }
536   - return rc;
537   -}
538   -
539   -/**
540   - * securityfs registrations
541   - */
542   -struct dentry *dir_ino, *seclvl_ino, *passwd_ino;
543   -
544   -static int seclvlfs_register(void)
545   -{
546   - int rc = 0;
547   -
548   - dir_ino = securityfs_create_dir("seclvl", NULL);
549   -
550   - if (IS_ERR(dir_ino))
551   - return PTR_ERR(dir_ino);
552   -
553   - seclvl_ino = securityfs_create_file("seclvl", S_IRUGO | S_IWUSR,
554   - dir_ino, &seclvl, &seclvl_file_ops);
555   - if (IS_ERR(seclvl_ino)) {
556   - rc = PTR_ERR(seclvl_ino);
557   - goto out_deldir;
558   - }
559   - if (*passwd || *sha1_passwd) {
560   - passwd_ino = securityfs_create_file("passwd", S_IRUGO | S_IWUSR,
561   - dir_ino, NULL, &passwd_file_ops);
562   - if (IS_ERR(passwd_ino)) {
563   - rc = PTR_ERR(passwd_ino);
564   - goto out_delf;
565   - }
566   - }
567   - return rc;
568   -
569   -out_delf:
570   - securityfs_remove(seclvl_ino);
571   -
572   -out_deldir:
573   - securityfs_remove(dir_ino);
574   -
575   - return rc;
576   -}
577   -
578   -static void seclvlfs_unregister(void)
579   -{
580   - securityfs_remove(seclvl_ino);
581   -
582   - if (*passwd || *sha1_passwd)
583   - securityfs_remove(passwd_ino);
584   -
585   - securityfs_remove(dir_ino);
586   -}
587   -
588   -/**
589   - * Initialize the seclvl module.
590   - */
591   -static int __init seclvl_init(void)
592   -{
593   - int rc = 0;
594   - static char once;
595   -
596   - if (verbosity < 0 || verbosity > 1) {
597   - printk(KERN_ERR "Error: bad verbosity [%d]; only 0 or 1 "
598   - "are valid values\n", verbosity);
599   - rc = -EINVAL;
600   - goto exit;
601   - }
602   - if (initlvl < -1 || initlvl > 2) {
603   - seclvl_printk(0, KERN_ERR, "Error: bad initial securelevel "
604   - "[%d].\n", initlvl);
605   - rc = -EINVAL;
606   - goto exit;
607   - }
608   - seclvl = initlvl;
609   - if ((rc = processPassword())) {
610   - seclvl_printk(0, KERN_ERR, "Error processing the password "
611   - "module parameter(s): rc = [%d]\n", rc);
612   - goto exit;
613   - }
614   -
615   - if ((rc = seclvlfs_register())) {
616   - seclvl_printk(0, KERN_ERR, "Error registering with sysfs\n");
617   - goto exit;
618   - }
619   - /* register ourselves with the security framework */
620   - if (register_security(&seclvl_ops)) {
621   - seclvl_printk(0, KERN_ERR,
622   - "seclvl: Failure registering with the "
623   - "kernel.\n");
624   - /* try registering with primary module */
625   - rc = mod_reg_security(MY_NAME, &seclvl_ops);
626   - if (rc) {
627   - seclvl_printk(0, KERN_ERR, "seclvl: Failure "
628   - "registering with primary security "
629   - "module.\n");
630   - seclvlfs_unregister();
631   - goto exit;
632   - } /* if primary module registered */
633   - secondary = 1;
634   - } /* if we registered ourselves with the security framework */
635   -
636   - seclvl_printk(0, KERN_INFO, "seclvl: Successfully initialized.\n");
637   -
638   - if (once) {
639   - once = 1;
640   - seclvl_printk(0, KERN_INFO, "seclvl is going away. It has been "
641   - "buggy for ages. Also, be warned that "
642   - "Securelevels are useless.");
643   - }
644   - exit:
645   - if (rc)
646   - printk(KERN_ERR "seclvl: Error during initialization: rc = "
647   - "[%d]\n", rc);
648   - return rc;
649   -}
650   -
651   -/**
652   - * Remove the seclvl module.
653   - */
654   -static void __exit seclvl_exit(void)
655   -{
656   - seclvlfs_unregister();
657   -
658   - if (secondary)
659   - mod_unreg_security(MY_NAME, &seclvl_ops);
660   - else if (unregister_security(&seclvl_ops))
661   - seclvl_printk(0, KERN_INFO,
662   - "seclvl: Failure unregistering with the "
663   - "kernel\n");
664   -}
665   -
666   -module_init(seclvl_init);
667   -module_exit(seclvl_exit);
668   -
669   -MODULE_AUTHOR("Michael A. Halcrow <mike@halcrow.us>");
670   -MODULE_DESCRIPTION("LSM implementation of the BSD Secure Levels");
671   -MODULE_LICENSE("GPL");