User: Password:
|
|
Subscribe / Log in / New account

New sys_chmod() hook for the LSM framework

From:  Lorenzo =?ISO-8859-1?Q?Hern=E1ndez_?= =?ISO-8859-1?Q?Garc=EDa-Hierro?= <lorenzo@gnu.org>
To:  "linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>
Subject:  [PATCH] New sys_chmod() hook for the LSM framework
Date:  Tue, 08 Feb 2005 17:14:35 +0100
Cc:  "linux-security-module@wirex.com" <linux-security-module@wirex.com>
Archive-link:  Article, Thread

Hi,

As commented yesterday, I was going to release a few more hooks for some
*critical* syscalls, this one adds a hook to sys_chmod(), and makes us
able to apply checks and logics before releasing the operation to
sys_chmod().

The main goal is to provide a simple way to handle chmod() calls and
apply security restrictions & checks to them, and also add add auditing
capabilities (ie.: log chmod() calls in chroot()'ed environments, etc).

Patch attached and available at:
http://pearls.tuxedo-es.org/patches/sys_chmod_lsm-hook-2....

I would like to see this merged, Chris should decide :)

An user of this will be, as commented in my past emails, vSecurity 0.2
release, and any other LSM module that wants to have control over
chmod()'ing.

I will make available another hook for sys_fchmod() ASAP.

Cheers and thanks in advance,
-- 
Lorenzo Hernández García-Hierro <lorenzo@gnu.org> 
[1024D/6F2B2DEC] & [2048g/9AE91A22][http://tuxedo-es.org]

diff -Nur linux-2.6.11-rc3/fs/open.c linux-2.6.11-rc3.chm/fs/open.c
--- linux-2.6.11-rc3/fs/open.c	2005-02-06 21:40:40.000000000 +0100
+++ linux-2.6.11-rc3.chm/fs/open.c	2005-02-08 16:10:09.901293560 +0100
@@ -650,6 +650,11 @@
 	down(&inode->i_sem);
 	if (mode == (mode_t) -1)
 		mode = inode->i_mode;
+		
+	error = security_chmod(&nd, inode, mode);
+	if (error)
+		goto dput_and_out;	
+	
 	newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
 	newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
 	error = notify_change(nd.dentry, &newattrs);
diff -Nur linux-2.6.11-rc3/include/linux/security.h
linux-2.6.11-rc3.chm/include/linux/security.h
--- linux-2.6.11-rc3/include/linux/security.h	2005-02-06 21:40:27.000000000
+0100
+++ linux-2.6.11-rc3.chm/include/linux/security.h	2005-02-08 16:10:37.670072064
+0100
@@ -1008,6 +1008,12 @@
  *	@ts contains new time
  *	@tz contains new timezone
  *	Return 0 if permission is granted.
+ * @chmod:
+ *	Check permission before changing file modes by sys_chmod().
+ *	@nd contains the nameidata struct.
+ *	@inode contains the inode struct.
+ *	@mode contains the mode value.
+ *	Return 0 if permission is granted.
  * @vm_enough_memory:
  *	Check permissions for allocating a new virtual mapping.
  *      @pages contains the number of pages.
@@ -1044,6 +1050,7 @@
 	int (*quota_on) (struct dentry * dentry);
 	int (*syslog) (int type);
 	int (*settime) (struct timespec *ts, struct timezone *tz);
+	int (*chmod) (struct nameidata *nd, struct inode *inode, mode_t mode);
 	int (*vm_enough_memory) (long pages);
 
 	int (*bprm_alloc_security) (struct linux_binprm * bprm);
@@ -1304,6 +1311,10 @@
 	return security_ops->settime(ts, tz);
 }
 
+static inline int security_chmod(struct nameidata *nd, struct inode *inode, mode_t
mode)
+{
+	return security_ops->chmod(nd, inode, mode);
+}
 
 static inline int security_vm_enough_memory(long pages)
 {
@@ -1986,6 +1997,11 @@
 	return cap_settime(ts, tz);
 }
 
+static inline int security_chmod(struct nameidata *nd, struct inode *inode, mode_t
mode)
+{
+	return 0;
+}
+
 static inline int security_vm_enough_memory(long pages)
 {
 	return cap_vm_enough_memory(pages);
diff -Nur linux-2.6.11-rc3/security/dummy.c
linux-2.6.11-rc3.chm/security/dummy.c
--- linux-2.6.11-rc3/security/dummy.c	2005-02-06 21:40:57.000000000 +0100
+++ linux-2.6.11-rc3.chm/security/dummy.c	2005-02-08 15:58:26.000000000 +0100
@@ -108,6 +108,11 @@
 	return 0;
 }
 
+static int dummy_chmod(struct nameidata *nd, struct inode *inode, mode_t
mode)
+{
+	return 0;
+}
+
 static int dummy_vm_enough_memory(long pages)
 {
 	int cap_sys_admin = 0;
@@ -858,6 +863,7 @@
 	set_to_dummy_if_null(ops, sysctl);
 	set_to_dummy_if_null(ops, syslog);
 	set_to_dummy_if_null(ops, settime);
+	set_to_dummy_if_null(ops, chmod);
 	set_to_dummy_if_null(ops, vm_enough_memory);
 	set_to_dummy_if_null(ops, bprm_alloc_security);
 	set_to_dummy_if_null(ops, bprm_free_security);
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (GNU/Linux)

iD8DBQBCCOVrDcEopW8rLewRArzwAKDiHiuVAgGBP1XZ/xgZxmq9w076QgCg4bQO
TKRvzkwpJdcYqG4xIJVNECw=
=5e2Q
-----END PGP SIGNATURE-----



Copyright © 2005, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds