1 From: Jeff Mahoney <jeffm@suse.com>
2 Subject: reiserfs: add atomic addition of selinux attributes during inode creation
4 Some time ago, some changes were made to make security inode attributes
5 be atomically written during inode creation. ReiserFS fell behind in this
6 area, but with the reworking of the xattr code, it's now fairly easy to add.
8 The following patch adds the ability for security attributes to be added
9 automatically during inode creation.
11 Signed-off-by: Jeff Mahoney <jeffm@suse.com>
14 fs/reiserfs/inode.c | 16 +++++++++++-
15 fs/reiserfs/namei.c | 37 +++++++++++++++++++++++++---
16 fs/reiserfs/xattr_security.c | 54 +++++++++++++++++++++++++++++++++++++++++
17 include/linux/reiserfs_fs.h | 4 ++-
18 include/linux/reiserfs_xattr.h | 32 ++++++++++++++++++++++++
19 5 files changed, 137 insertions(+), 6 deletions(-)
21 --- a/fs/reiserfs/inode.c
22 +++ b/fs/reiserfs/inode.c
23 @@ -1756,7 +1756,8 @@ int reiserfs_new_inode(struct reiserfs_t
24 /* 0 for regular, EMTRY_DIR_SIZE for dirs,
25 strlen (symname) for symlinks) */
26 loff_t i_size, struct dentry *dentry,
27 - struct inode *inode)
28 + struct inode *inode,
29 + struct reiserfs_security_handle *security)
31 struct super_block *sb;
32 INITIALIZE_PATH(path_to_key);
33 @@ -1934,6 +1935,19 @@ int reiserfs_new_inode(struct reiserfs_t
34 } else if (IS_PRIVATE(dir))
35 inode->i_flags |= S_PRIVATE;
37 + if (security->name) {
38 + retval = reiserfs_security_write(th, inode, security);
41 + reiserfs_check_path(&path_to_key);
42 + retval = journal_end(th, th->t_super,
43 + th->t_blocks_allocated);
46 + goto out_inserted_sd;
50 insert_inode_hash(inode);
51 reiserfs_update_sd(th, inode);
52 reiserfs_check_path(&path_to_key);
53 --- a/fs/reiserfs/namei.c
54 +++ b/fs/reiserfs/namei.c
55 @@ -607,6 +607,7 @@ static int reiserfs_create(struct inode
56 2 * (REISERFS_QUOTA_INIT_BLOCKS(dir->i_sb) +
57 REISERFS_QUOTA_TRANS_BLOCKS(dir->i_sb));
58 struct reiserfs_transaction_handle th;
59 + struct reiserfs_security_handle security;
61 if (!(inode = new_inode(dir->i_sb))) {
63 @@ -614,6 +615,12 @@ static int reiserfs_create(struct inode
64 new_inode_init(inode, dir, mode);
66 jbegin_count += reiserfs_cache_default_acl(dir);
67 + retval = reiserfs_security_init(dir, inode, &security);
69 + drop_new_inode(inode);
72 + jbegin_count += retval;
73 reiserfs_write_lock(dir->i_sb);
75 retval = journal_begin(&th, dir->i_sb, jbegin_count);
76 @@ -624,7 +631,7 @@ static int reiserfs_create(struct inode
79 reiserfs_new_inode(&th, dir, mode, NULL, 0 /*i_size */ , dentry,
85 @@ -662,6 +669,7 @@ static int reiserfs_mknod(struct inode *
88 struct reiserfs_transaction_handle th;
89 + struct reiserfs_security_handle security;
90 /* We need blocks for transaction + (user+group)*(quotas for new inode + update of quota for directory owner) */
92 JOURNAL_PER_BALANCE_CNT * 3 +
93 @@ -677,6 +685,12 @@ static int reiserfs_mknod(struct inode *
94 new_inode_init(inode, dir, mode);
96 jbegin_count += reiserfs_cache_default_acl(dir);
97 + retval = reiserfs_security_init(dir, inode, &security);
99 + drop_new_inode(inode);
102 + jbegin_count += retval;
103 reiserfs_write_lock(dir->i_sb);
105 retval = journal_begin(&th, dir->i_sb, jbegin_count);
106 @@ -687,7 +701,7 @@ static int reiserfs_mknod(struct inode *
109 reiserfs_new_inode(&th, dir, mode, NULL, 0 /*i_size */ , dentry,
115 @@ -728,6 +742,7 @@ static int reiserfs_mkdir(struct inode *
118 struct reiserfs_transaction_handle th;
119 + struct reiserfs_security_handle security;
120 /* We need blocks for transaction + (user+group)*(quotas for new inode + update of quota for directory owner) */
122 JOURNAL_PER_BALANCE_CNT * 3 +
123 @@ -745,6 +760,12 @@ static int reiserfs_mkdir(struct inode *
124 new_inode_init(inode, dir, mode);
126 jbegin_count += reiserfs_cache_default_acl(dir);
127 + retval = reiserfs_security_init(dir, inode, &security);
129 + drop_new_inode(inode);
132 + jbegin_count += retval;
133 reiserfs_write_lock(dir->i_sb);
135 retval = journal_begin(&th, dir->i_sb, jbegin_count);
136 @@ -761,7 +782,7 @@ static int reiserfs_mkdir(struct inode *
137 retval = reiserfs_new_inode(&th, dir, mode, NULL /*symlink */ ,
138 old_format_only(dir->i_sb) ?
139 EMPTY_DIR_SIZE_V1 : EMPTY_DIR_SIZE,
141 + dentry, inode, &security);
145 @@ -1002,6 +1023,7 @@ static int reiserfs_symlink(struct inode
148 struct reiserfs_transaction_handle th;
149 + struct reiserfs_security_handle security;
150 int mode = S_IFLNK | S_IRWXUGO;
151 /* We need blocks for transaction + (user+group)*(quotas for new inode + update of quota for directory owner) */
153 @@ -1014,6 +1036,13 @@ static int reiserfs_symlink(struct inode
155 new_inode_init(inode, parent_dir, mode);
157 + retval = reiserfs_security_init(parent_dir, inode, &security);
159 + drop_new_inode(inode);
162 + jbegin_count += retval;
164 reiserfs_write_lock(parent_dir->i_sb);
165 item_len = ROUND_UP(strlen(symname));
166 if (item_len > MAX_DIRECT_ITEM_LEN(parent_dir->i_sb->s_blocksize)) {
167 @@ -1040,7 +1069,7 @@ static int reiserfs_symlink(struct inode
170 reiserfs_new_inode(&th, parent_dir, mode, name, strlen(symname),
172 + dentry, inode, &security);
174 if (retval) { /* reiserfs_new_inode iputs for us */
176 --- a/fs/reiserfs/xattr_security.c
177 +++ b/fs/reiserfs/xattr_security.c
179 #include <linux/pagemap.h>
180 #include <linux/xattr.h>
181 #include <linux/reiserfs_xattr.h>
182 +#include <linux/security.h>
183 #include <asm/uaccess.h>
186 @@ -47,6 +48,59 @@ static size_t security_list(struct inode
190 +/* Initializes the security context for a new inode and returns the number
191 + * of blocks needed for the transaction. If successful, reiserfs_security
192 + * must be released using reiserfs_security_free when the caller is done. */
193 +int reiserfs_security_init(struct inode *dir, struct inode *inode,
194 + struct reiserfs_security_handle *sec)
197 + int error = security_inode_init_security(inode, dir, &sec->name,
198 + &sec->value, &sec->length);
200 + if (error == -EOPNOTSUPP)
210 + blocks = reiserfs_xattr_jcreate_nblocks(inode) +
211 + reiserfs_xattr_nblocks(inode, sec->length);
212 + /* We don't want to count the directories twice if we have
213 + * a default ACL. */
214 + REISERFS_I(inode)->i_flags |= i_has_xattr_dir;
219 +int reiserfs_security_write(struct reiserfs_transaction_handle *th,
220 + struct inode *inode,
221 + struct reiserfs_security_handle *sec)
224 + if (strlen(sec->name) < sizeof(XATTR_SECURITY_PREFIX))
227 + error = reiserfs_xattr_set_handle(th, inode, sec->name, sec->value,
228 + sec->length, XATTR_CREATE);
229 + if (error == -ENODATA || error == -EOPNOTSUPP)
235 +void reiserfs_security_free(struct reiserfs_security_handle *sec)
243 struct xattr_handler reiserfs_xattr_security_handler = {
244 .prefix = XATTR_SECURITY_PREFIX,
246 --- a/include/linux/reiserfs_fs.h
247 +++ b/include/linux/reiserfs_fs.h
248 @@ -1915,10 +1915,12 @@ void make_le_item_head(struct item_head
249 loff_t offset, int type, int length, int entry_count);
250 struct inode *reiserfs_iget(struct super_block *s, const struct cpu_key *key);
252 +struct reiserfs_security_handle;
253 int reiserfs_new_inode(struct reiserfs_transaction_handle *th,
254 struct inode *dir, int mode,
255 const char *symname, loff_t i_size,
256 - struct dentry *dentry, struct inode *inode);
257 + struct dentry *dentry, struct inode *inode,
258 + struct reiserfs_security_handle *security);
260 void reiserfs_update_sd_size(struct reiserfs_transaction_handle *th,
261 struct inode *inode, loff_t size);
262 --- a/include/linux/reiserfs_xattr.h
263 +++ b/include/linux/reiserfs_xattr.h
264 @@ -15,6 +15,12 @@ struct reiserfs_xattr_header {
265 __le32 h_hash; /* hash of the value */
268 +struct reiserfs_security_handle {
276 #include <linux/init.h>
277 @@ -54,6 +60,14 @@ int reiserfs_xattr_set_handle(struct rei
278 extern struct xattr_handler reiserfs_xattr_user_handler;
279 extern struct xattr_handler reiserfs_xattr_trusted_handler;
280 extern struct xattr_handler reiserfs_xattr_security_handler;
281 +#ifdef CONFIG_REISERFS_FS_SECURITY
282 +int reiserfs_security_init(struct inode *dir, struct inode *inode,
283 + struct reiserfs_security_handle *sec);
284 +int reiserfs_security_write(struct reiserfs_transaction_handle *th,
285 + struct inode *inode,
286 + struct reiserfs_security_handle *sec);
287 +void reiserfs_security_free(struct reiserfs_security_handle *sec);
290 #define xattr_size(size) ((size) + sizeof(struct reiserfs_xattr_header))
291 static inline loff_t reiserfs_xattr_nblocks(struct inode *inode, loff_t size)
292 @@ -109,6 +123,24 @@ static inline void reiserfs_init_xattr_r
294 #endif /* CONFIG_REISERFS_FS_XATTR */
296 +#ifndef CONFIG_REISERFS_FS_SECURITY
297 +static inline int reiserfs_security_init(struct inode *dir,
298 + struct inode *inode,
299 + struct reiserfs_security_handle *sec)
304 +reiserfs_security_write(struct reiserfs_transaction_handle *th,
305 + struct inode *inode,
306 + struct reiserfs_security_handle *sec)
310 +static inline void reiserfs_security_free(struct reiserfs_security_handle *sec)
314 #endif /* __KERNEL__ */
316 #endif /* _LINUX_REISERFS_XATTR_H */