lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [day] [month] [year] [list]
Message-Id: <201011031111.41084.roberto.sassu@polito.it>
Date:	Wed, 3 Nov 2010 11:11:40 +0100
From:	Roberto Sassu <roberto.sassu@...ito.it>
To:	tyhicks@...ux.vnet.ibm.com
Cc:	kirkland@...onical.com, jmorris@...ei.org,
	linux-security-module@...r.kernel.org,
	linux-kernel@...r.kernel.org, linux-fsdevel@...r.kernel.org
Subject: [PATCH 5/5] ecryptfs: open lower files with kthread credentials

Ecryptfs allows concurrent accesses to an encrypted file by opening the
relative lower inode only once and making the returned file descriptor
available until the ecryptfs inode is destroyed.
The file descriptor is obtained by calling the function dentry_open() for
the lower inode with flag O_RDWR  and the credentials of the process that
issued the open request.
During this procedure two issues may be encountered when using ecryptfs in
conjunction with SELinux: first, a process needs read/write permission
for opening a file even with flag O_RDONLY; second a process needs the
'use' permission in the 'fd' class if the lower file was opened by another
process with different credentials.
This patch replaces the 'cred' structure of the current process, passed to
the function dentry_open(), with the one associated with the 'kthread'
kernel service.

Signed-off-by: Roberto Sassu <roberto.sassu@...ito.it>
---
 fs/ecryptfs/ecryptfs_kernel.h |    3 +--
 fs/ecryptfs/kthread.c         |   17 +++++++++++++----
 fs/ecryptfs/main.c            |    3 +--
 3 files changed, 15 insertions(+), 8 deletions(-)

diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h
index 452be3c..14d167f 100644
--- a/fs/ecryptfs/ecryptfs_kernel.h
+++ b/fs/ecryptfs/ecryptfs_kernel.h
@@ -759,8 +759,7 @@ int ecryptfs_init_kthread(void);
 void ecryptfs_destroy_kthread(void);
 int ecryptfs_privileged_open(struct file **lower_file,
 			     struct dentry *lower_dentry,
-			     struct vfsmount *lower_mnt,
-			     const struct cred *cred);
+			     struct vfsmount *lower_mnt);
 int ecryptfs_init_persistent_file(struct dentry *ecryptfs_dentry);
 int
 ecryptfs_write_tag_70_packet(char *dest, size_t *remaining_bytes,
diff --git a/fs/ecryptfs/kthread.c b/fs/ecryptfs/kthread.c
index d8c3a37..5094601 100644
--- a/fs/ecryptfs/kthread.c
+++ b/fs/ecryptfs/kthread.c
@@ -38,6 +38,7 @@ static struct ecryptfs_kthread_ctl {
 } ecryptfs_kthread_ctl;
 
 static struct task_struct *ecryptfs_kthread;
+static struct cred *ecryptfs_kthread_cred;
 
 /**
  * ecryptfs_threadfn
@@ -74,7 +75,7 @@ static int ecryptfs_threadfn(void *ignored)
 				mntget(req->lower_mnt);
 				(*req->lower_file) = dentry_open(
 					req->lower_dentry, req->lower_mnt,
-					(O_RDWR | O_LARGEFILE), current_cred());
+					(O_RDWR | O_LARGEFILE), ecryptfs_kthread_cred);
 				req->flags |= ECRYPTFS_REQ_PROCESSED;
 			}
 			wake_up(&req->wait);
@@ -99,7 +100,15 @@ int ecryptfs_init_kthread(void)
 		rc = PTR_ERR(ecryptfs_kthread);
 		printk(KERN_ERR "%s: Failed to create kernel thread; rc = [%d]"
 		       "\n", __func__, rc);
+		goto out;
+	}
+	ecryptfs_kthread_cred = prepare_kernel_cred(ecryptfs_kthread);
+	if (IS_ERR(ecryptfs_kthread_cred)) {
+		rc = PTR_ERR(ecryptfs_kthread_cred);
+		printk(KERN_ERR "%s: Failed to obtain the credential struct; "
+				"rc = [%d]\n", __func__, rc);
 	}
+out:
 	return rc;
 }
 
@@ -119,6 +128,7 @@ void ecryptfs_destroy_kthread(void)
 	mutex_unlock(&ecryptfs_kthread_ctl.mux);
 	kthread_stop(ecryptfs_kthread);
 	wake_up(&ecryptfs_kthread_ctl.wait);
+	put_cred(ecryptfs_kthread_cred);
 }
 
 /**
@@ -133,8 +143,7 @@ void ecryptfs_destroy_kthread(void)
  */
 int ecryptfs_privileged_open(struct file **lower_file,
 			     struct dentry *lower_dentry,
-			     struct vfsmount *lower_mnt,
-			     const struct cred *cred)
+			     struct vfsmount *lower_mnt)
 {
 	struct ecryptfs_open_req *req;
 	int flags = O_LARGEFILE;
@@ -146,7 +155,7 @@ int ecryptfs_privileged_open(struct file **lower_file,
 	dget(lower_dentry);
 	mntget(lower_mnt);
 	flags |= IS_RDONLY(lower_dentry->d_inode) ? O_RDONLY : O_RDWR;
-	(*lower_file) = dentry_open(lower_dentry, lower_mnt, flags, cred);
+	(*lower_file) = dentry_open(lower_dentry, lower_mnt, flags, ecryptfs_kthread_cred);
 	if (!IS_ERR(*lower_file))
 		goto out;
 	if (flags & O_RDONLY) {
diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c
index 81821d7..c07bb9a 100644
--- a/fs/ecryptfs/main.c
+++ b/fs/ecryptfs/main.c
@@ -117,7 +117,6 @@ void __ecryptfs_printk(const char *fmt, ...)
  */
 int ecryptfs_init_persistent_file(struct dentry *ecryptfs_dentry)
 {
-	const struct cred *cred = current_cred();
 	struct ecryptfs_inode_info *inode_info =
 		ecryptfs_inode_to_private(ecryptfs_dentry->d_inode);
 	int rc = 0;
@@ -130,7 +129,7 @@ int ecryptfs_init_persistent_file(struct dentry *ecryptfs_dentry)
 
 		lower_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry);
 		rc = ecryptfs_privileged_open(&inode_info->lower_file,
-					      lower_dentry, lower_mnt, cred);
+					      lower_dentry, lower_mnt);
 		if (rc) {
 			printk(KERN_ERR "Error opening lower persistent file "
 			       "for lower_dentry [0x%p] and lower_mnt [0x%p]; "
-- 
1.7.2.3


Download attachment "smime.p7s" of type "application/pkcs7-signature" (4707 bytes)

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ