From: Jeff Mahoney <jeffm@suse.com>
To: Linux Kernel Mailing List <linux-kernel@vger.kernel.org>
Cc: Andrew Morton <akpm@linux-foundation.org>,
Linus Torvalds <torvalds@linux-foundation.org>,
ReiserFS Development List <reiserfs-devel@vger.kernel.org>
Subject: [patch 26/35 xattr-rework] reiserfs: add atomic addition of selinux attributes during inode creation
Date: Mon, 30 Mar 2009 14:02:41 -0400 [thread overview]
Message-ID: <20090330181012.635299114@suse.com> (raw)
In-Reply-To: 20090330180215.951354436@suse.com
[-- Attachment #1: patches.suse/reiserfs-selinux.diff --]
[-- Type: text/plain, Size: 10178 bytes --]
Some time ago, some changes were made to make security inode attributes
be atomically written during inode creation. ReiserFS fell behind in this
area, but with the reworking of the xattr code, it's now fairly easy to add.
The following patch adds the ability for security attributes to be added
automatically during inode creation.
Signed-off-by: Jeff Mahoney <jeffm@suse.com>
--
fs/reiserfs/inode.c | 16 +++++++++++-
fs/reiserfs/namei.c | 37 +++++++++++++++++++++++++---
fs/reiserfs/xattr_security.c | 54 +++++++++++++++++++++++++++++++++++++++++
include/linux/reiserfs_fs.h | 4 ++-
include/linux/reiserfs_xattr.h | 32 ++++++++++++++++++++++++
5 files changed, 137 insertions(+), 6 deletions(-)
--- a/fs/reiserfs/inode.c
+++ b/fs/reiserfs/inode.c
@@ -1756,7 +1756,8 @@ int reiserfs_new_inode(struct reiserfs_t
/* 0 for regular, EMTRY_DIR_SIZE for dirs,
strlen (symname) for symlinks) */
loff_t i_size, struct dentry *dentry,
- struct inode *inode)
+ struct inode *inode,
+ struct reiserfs_security_handle *security)
{
struct super_block *sb;
struct reiserfs_iget_args args;
@@ -1934,6 +1935,19 @@ int reiserfs_new_inode(struct reiserfs_t
} else if (IS_PRIVATE(dir))
inode->i_flags |= S_PRIVATE;
+ if (security->name) {
+ retval = reiserfs_security_write(th, inode, security);
+ if (retval) {
+ err = retval;
+ reiserfs_check_path(&path_to_key);
+ retval = journal_end(th, th->t_super,
+ th->t_blocks_allocated);
+ if (retval)
+ err = retval;
+ goto out_inserted_sd;
+ }
+ }
+
reiserfs_update_sd(th, inode);
reiserfs_check_path(&path_to_key);
--- a/fs/reiserfs/namei.c
+++ b/fs/reiserfs/namei.c
@@ -607,6 +607,7 @@ static int reiserfs_create(struct inode
2 * (REISERFS_QUOTA_INIT_BLOCKS(dir->i_sb) +
REISERFS_QUOTA_TRANS_BLOCKS(dir->i_sb));
struct reiserfs_transaction_handle th;
+ struct reiserfs_security_handle security;
if (!(inode = new_inode(dir->i_sb))) {
return -ENOMEM;
@@ -614,6 +615,12 @@ static int reiserfs_create(struct inode
new_inode_init(inode, dir, mode);
jbegin_count += reiserfs_cache_default_acl(dir);
+ retval = reiserfs_security_init(dir, inode, &security);
+ if (retval < 0) {
+ drop_new_inode(inode);
+ return retval;
+ }
+ jbegin_count += retval;
reiserfs_write_lock(dir->i_sb);
retval = journal_begin(&th, dir->i_sb, jbegin_count);
@@ -624,7 +631,7 @@ static int reiserfs_create(struct inode
retval =
reiserfs_new_inode(&th, dir, mode, NULL, 0 /*i_size */ , dentry,
- inode);
+ inode, &security);
if (retval)
goto out_failed;
@@ -662,6 +669,7 @@ static int reiserfs_mknod(struct inode *
int retval;
struct inode *inode;
struct reiserfs_transaction_handle th;
+ struct reiserfs_security_handle security;
/* We need blocks for transaction + (user+group)*(quotas for new inode + update of quota for directory owner) */
int jbegin_count =
JOURNAL_PER_BALANCE_CNT * 3 +
@@ -677,6 +685,12 @@ static int reiserfs_mknod(struct inode *
new_inode_init(inode, dir, mode);
jbegin_count += reiserfs_cache_default_acl(dir);
+ retval = reiserfs_security_init(dir, inode, &security);
+ if (retval < 0) {
+ drop_new_inode(inode);
+ return retval;
+ }
+ jbegin_count += retval;
reiserfs_write_lock(dir->i_sb);
retval = journal_begin(&th, dir->i_sb, jbegin_count);
@@ -687,7 +701,7 @@ static int reiserfs_mknod(struct inode *
retval =
reiserfs_new_inode(&th, dir, mode, NULL, 0 /*i_size */ , dentry,
- inode);
+ inode, &security);
if (retval) {
goto out_failed;
}
@@ -728,6 +742,7 @@ static int reiserfs_mkdir(struct inode *
int retval;
struct inode *inode;
struct reiserfs_transaction_handle th;
+ struct reiserfs_security_handle security;
/* We need blocks for transaction + (user+group)*(quotas for new inode + update of quota for directory owner) */
int jbegin_count =
JOURNAL_PER_BALANCE_CNT * 3 +
@@ -745,6 +760,12 @@ static int reiserfs_mkdir(struct inode *
new_inode_init(inode, dir, mode);
jbegin_count += reiserfs_cache_default_acl(dir);
+ retval = reiserfs_security_init(dir, inode, &security);
+ if (retval < 0) {
+ drop_new_inode(inode);
+ return retval;
+ }
+ jbegin_count += retval;
reiserfs_write_lock(dir->i_sb);
retval = journal_begin(&th, dir->i_sb, jbegin_count);
@@ -761,7 +782,7 @@ static int reiserfs_mkdir(struct inode *
retval = reiserfs_new_inode(&th, dir, mode, NULL /*symlink */ ,
old_format_only(dir->i_sb) ?
EMPTY_DIR_SIZE_V1 : EMPTY_DIR_SIZE,
- dentry, inode);
+ dentry, inode, &security);
if (retval) {
dir->i_nlink--;
goto out_failed;
@@ -1002,6 +1023,7 @@ static int reiserfs_symlink(struct inode
char *name;
int item_len;
struct reiserfs_transaction_handle th;
+ struct reiserfs_security_handle security;
int mode = S_IFLNK | S_IRWXUGO;
/* We need blocks for transaction + (user+group)*(quotas for new inode + update of quota for directory owner) */
int jbegin_count =
@@ -1014,6 +1036,13 @@ static int reiserfs_symlink(struct inode
}
new_inode_init(inode, parent_dir, mode);
+ retval = reiserfs_security_init(parent_dir, inode, &security);
+ if (retval < 0) {
+ drop_new_inode(inode);
+ return retval;
+ }
+ jbegin_count += retval;
+
reiserfs_write_lock(parent_dir->i_sb);
item_len = ROUND_UP(strlen(symname));
if (item_len > MAX_DIRECT_ITEM_LEN(parent_dir->i_sb->s_blocksize)) {
@@ -1040,7 +1069,7 @@ static int reiserfs_symlink(struct inode
retval =
reiserfs_new_inode(&th, parent_dir, mode, name, strlen(symname),
- dentry, inode);
+ dentry, inode, &security);
kfree(name);
if (retval) { /* reiserfs_new_inode iputs for us */
goto out_failed;
--- a/fs/reiserfs/xattr_security.c
+++ b/fs/reiserfs/xattr_security.c
@@ -4,6 +4,7 @@
#include <linux/pagemap.h>
#include <linux/xattr.h>
#include <linux/reiserfs_xattr.h>
+#include <linux/security.h>
#include <asm/uaccess.h>
static int
@@ -47,6 +48,59 @@ static size_t security_list(struct inode
return len;
}
+/* Initializes the security context for a new inode and returns the number
+ * of blocks needed for the transaction. If successful, reiserfs_security
+ * must be released using reiserfs_security_free when the caller is done. */
+int reiserfs_security_init(struct inode *dir, struct inode *inode,
+ struct reiserfs_security_handle *sec)
+{
+ int blocks = 0;
+ int error = security_inode_init_security(inode, dir, &sec->name,
+ &sec->value, &sec->length);
+ if (error) {
+ if (error == -EOPNOTSUPP)
+ error = 0;
+
+ sec->name = NULL;
+ sec->value = NULL;
+ sec->length = 0;
+ return error;
+ }
+
+ if (sec->length) {
+ blocks = reiserfs_xattr_jcreate_nblocks(inode) +
+ reiserfs_xattr_nblocks(inode, sec->length);
+ /* We don't want to count the directories twice if we have
+ * a default ACL. */
+ REISERFS_I(inode)->i_flags |= i_has_xattr_dir;
+ }
+ return blocks;
+}
+
+int reiserfs_security_write(struct reiserfs_transaction_handle *th,
+ struct inode *inode,
+ struct reiserfs_security_handle *sec)
+{
+ int error;
+ if (strlen(sec->name) < sizeof(XATTR_SECURITY_PREFIX))
+ return -EINVAL;
+
+ error = reiserfs_xattr_set_handle(th, inode, sec->name, sec->value,
+ sec->length, XATTR_CREATE);
+ if (error == -ENODATA || error == -EOPNOTSUPP)
+ error = 0;
+
+ return error;
+}
+
+void reiserfs_security_free(struct reiserfs_security_handle *sec)
+{
+ kfree(sec->name);
+ kfree(sec->value);
+ sec->name = NULL;
+ sec->value = NULL;
+}
+
struct xattr_handler reiserfs_xattr_security_handler = {
.prefix = XATTR_SECURITY_PREFIX,
.get = security_get,
--- a/include/linux/reiserfs_fs.h
+++ b/include/linux/reiserfs_fs.h
@@ -1915,10 +1915,12 @@ void make_le_item_head(struct item_head
loff_t offset, int type, int length, int entry_count);
struct inode *reiserfs_iget(struct super_block *s, const struct cpu_key *key);
+struct reiserfs_security_handle;
int reiserfs_new_inode(struct reiserfs_transaction_handle *th,
struct inode *dir, int mode,
const char *symname, loff_t i_size,
- struct dentry *dentry, struct inode *inode);
+ struct dentry *dentry, struct inode *inode,
+ struct reiserfs_security_handle *security);
void reiserfs_update_sd_size(struct reiserfs_transaction_handle *th,
struct inode *inode, loff_t size);
--- a/include/linux/reiserfs_xattr.h
+++ b/include/linux/reiserfs_xattr.h
@@ -15,6 +15,12 @@ struct reiserfs_xattr_header {
__le32 h_hash; /* hash of the value */
};
+struct reiserfs_security_handle {
+ char *name;
+ void *value;
+ size_t length;
+};
+
#ifdef __KERNEL__
#include <linux/init.h>
@@ -54,6 +60,14 @@ int reiserfs_xattr_set_handle(struct rei
extern struct xattr_handler reiserfs_xattr_user_handler;
extern struct xattr_handler reiserfs_xattr_trusted_handler;
extern struct xattr_handler reiserfs_xattr_security_handler;
+#ifdef CONFIG_REISERFS_FS_SECURITY
+int reiserfs_security_init(struct inode *dir, struct inode *inode,
+ struct reiserfs_security_handle *sec);
+int reiserfs_security_write(struct reiserfs_transaction_handle *th,
+ struct inode *inode,
+ struct reiserfs_security_handle *sec);
+void reiserfs_security_free(struct reiserfs_security_handle *sec);
+#endif
#define xattr_size(size) ((size) + sizeof(struct reiserfs_xattr_header))
static inline loff_t reiserfs_xattr_nblocks(struct inode *inode, loff_t size)
@@ -109,6 +123,24 @@ static inline void reiserfs_init_xattr_r
}
#endif /* CONFIG_REISERFS_FS_XATTR */
+#ifndef CONFIG_REISERFS_FS_SECURITY
+static inline int reiserfs_security_init(struct inode *dir,
+ struct inode *inode,
+ struct reiserfs_security_handle *sec)
+{
+ return 0;
+}
+static inline int
+reiserfs_security_write(struct reiserfs_transaction_handle *th,
+ struct inode *inode,
+ struct reiserfs_security_handle *sec)
+{
+ return 0;
+}
+static inline void reiserfs_security_free(struct reiserfs_security_handle *sec)
+{}
+#endif
+
#endif /* __KERNEL__ */
#endif /* _LINUX_REISERFS_XATTR_H */
next prev parent reply other threads:[~2009-03-30 18:25 UTC|newest]
Thread overview: 49+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-03-30 18:02 [patch 00/35] Jeff's ReiserFS Patch Queue Jeff Mahoney
2009-03-30 18:02 ` [patch 01/35 quick-fixes] reiserfs: add support for mount count incrementing Jeff Mahoney
2009-03-30 18:02 ` [patch 02/35 quick-fixes] reiserfs: audit transaction ids to always be unsigned ints Jeff Mahoney
2009-03-30 18:02 ` [patch 03/35 error-handling] reiserfs: use buffer_info for leaf_paste_entries Jeff Mahoney
2009-03-30 18:02 ` [patch 04/35 error-handling] reiserfs: use more consistent printk formatting Jeff Mahoney
2009-03-30 18:02 ` [patch 05/35 error-handling] reiserfs: make some warnings informational Jeff Mahoney
2009-03-30 18:02 ` [patch 06/35 error-handling] reiserfs: rework reiserfs_warning Jeff Mahoney
2009-03-30 18:02 ` [patch 07/35 error-handling] reiserfs: prepare_error_buf wrongly consumes va_arg Jeff Mahoney
2009-03-30 18:02 ` [patch 08/35 error-handling] reiserfs: eliminate reiserfs_warning from uniqueness functions Jeff Mahoney
2009-03-30 18:02 ` [patch 09/35 error-handling] reiserfs: add locking around error buffer Jeff Mahoney
2009-03-30 18:48 ` Andi Kleen
2009-03-30 19:32 ` Jeff Mahoney
2009-03-30 18:02 ` [patch 10/35 error-handling] reiserfs: rework reiserfs_panic Jeff Mahoney
2009-03-30 18:02 ` [patch 11/35 error-handling] reiserfs: rearrange journal abort Jeff Mahoney
2009-03-30 18:02 ` [patch 12/35 error-handling] reiserfs: introduce reiserfs_error() Jeff Mahoney
2009-03-30 18:02 ` [patch 13/35 error-handling] reiserfs: use reiserfs_error() Jeff Mahoney
2009-03-30 18:02 ` [patch 14/35 xattr-rework] reiserfs: small variable cleanup Jeff Mahoney
2009-03-30 18:02 ` [patch 15/35 xattr-rework] reiserfs: xattr reiserfs_get_page takes offset instead of index Jeff Mahoney
2009-03-30 18:02 ` [patch 16/35 xattr-rework] reiserfs: remove link detection code Jeff Mahoney
2009-03-30 18:02 ` [patch 17/35 xattr-rework] reiserfs: remove IS_PRIVATE helpers Jeff Mahoney
2009-03-30 18:02 ` [patch 18/35 xattr-rework] reiserfs: Clean up xattrs when REISERFS_FS_XATTR is unset Jeff Mahoney
2009-03-31 18:44 ` Christoph Hellwig
2009-03-30 18:02 ` [patch 19/35 xattr-rework] reiserfs: simplify xattr internal file lookups/opens Jeff Mahoney
2009-03-30 18:02 ` [patch 20/35 xattr-rework] reiserfs: eliminate per-super xattr lock Jeff Mahoney
2009-03-30 18:02 ` [patch 21/35 xattr-rework] reiserfs: make per-inode xattr locking more fine grained Jeff Mahoney
2009-03-30 18:02 ` [patch 22/35 xattr-rework] reiserfs: remove i_has_xattr_dir Jeff Mahoney
2009-03-30 18:02 ` [patch 23/35 xattr-rework] reiserfs: use generic xattr handlers Jeff Mahoney
2009-03-30 18:02 ` [patch 24/35 xattr-rework] reiserfs: journaled xattrs Jeff Mahoney
2009-03-30 18:02 ` [patch 25/35 xattr-rework] reiserfs: use generic readdir for operations across all xattrs Jeff Mahoney
2009-03-30 18:02 ` Jeff Mahoney [this message]
2009-03-30 18:02 ` [patch 27/35 code-cleanup] reiserfs: factor out buffer_info initialization Jeff Mahoney
2009-03-30 18:02 ` [patch 28/35 code-cleanup] reiserfs: cleanup path functions Jeff Mahoney
2009-03-30 18:02 ` [patch 29/35 code-cleanup] reiserfs: strip trailing whitespace Jeff Mahoney
2009-03-30 18:02 ` [patch 30/35 code-cleanup] reiserfs: rename p_s_sb to sb Jeff Mahoney
2009-03-30 18:02 ` [patch 31/35 code-cleanup] reiserfs: rename p_s_bh to bh Jeff Mahoney
2009-03-30 18:02 ` [patch 32/35 code-cleanup] reiserfs: rename p_s_inode to inode Jeff Mahoney
2009-03-30 18:50 ` Andi Kleen
2009-03-30 19:18 ` Jeff Mahoney
2009-03-30 18:02 ` [patch 33/35 code-cleanup] reiserfs: rename p_s_tb to tb Jeff Mahoney
2009-03-30 18:02 ` [patch 34/35 code-cleanup] reiserfs: rename p_._ variables Jeff Mahoney
2009-03-30 18:02 ` [patch 35/35 code-cleanup] reiserfs: rename [cn]_* variables Jeff Mahoney
2009-03-30 19:38 ` [patch 00/35] Jeff's ReiserFS Patch Queue Linus Torvalds
2009-03-30 19:59 ` Jeff Mahoney
2009-04-01 16:16 ` Ingo Molnar
2009-04-01 16:28 ` Jeff Mahoney
2009-04-01 16:34 ` Ingo Molnar
2009-04-01 16:51 ` Frederic Weisbecker
2009-04-01 22:18 ` Bron Gondwana
2009-04-01 23:59 ` Frederic Weisbecker
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20090330181012.635299114@suse.com \
--to=jeffm@suse.com \
--cc=akpm@linux-foundation.org \
--cc=linux-kernel@vger.kernel.org \
--cc=reiserfs-devel@vger.kernel.org \
--cc=torvalds@linux-foundation.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox