Skip to content

Commit d8db5b1

Browse files
xiaoleilirichardweinberger
authored andcommitted
ubifs: Massage assert in ubifs_xattr_set() wrt. init_xattrs
The inode is not locked in init_xattrs when creating a new inode. Without this patch, there will occurs assert when booting or creating a new file, if the kernel config CONFIG_SECURITY_SMACK is enabled. Log likes: UBIFS assert failed in ubifs_xattr_set at 298 (pid 1156) CPU: 1 PID: 1156 Comm: ldconfig Tainted: G S 4.12.0-rc1-207440-g1e70b02 #2 Hardware name: MediaTek MT2712 evaluation board (DT) Call trace: [<ffff000008088538>] dump_backtrace+0x0/0x238 [<ffff000008088834>] show_stack+0x14/0x20 [<ffff0000083d98d4>] dump_stack+0x9c/0xc0 [<ffff00000835d524>] ubifs_xattr_set+0x374/0x5e0 [<ffff00000835d7ec>] init_xattrs+0x5c/0xb8 [<ffff000008385788>] security_inode_init_security+0x110/0x190 [<ffff00000835e058>] ubifs_init_security+0x30/0x68 [<ffff00000833ada0>] ubifs_mkdir+0x100/0x200 [<ffff00000820669c>] vfs_mkdir+0x11c/0x1b8 [<ffff00000820b73c>] SyS_mkdirat+0x74/0xd0 [<ffff000008082f8c>] __sys_trace_return+0x0/0x4 Signed-off-by: Xiaolei Li <xiaolei.li@mediatek.com> Signed-off-by: Richard Weinberger <richard@nod.at>
1 parent 4acadda commit d8db5b1

File tree

3 files changed

+15
-11
lines changed

3 files changed

+15
-11
lines changed

fs/ubifs/crypto.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,13 @@ static int ubifs_crypt_get_context(struct inode *inode, void *ctx, size_t len)
99
static int ubifs_crypt_set_context(struct inode *inode, const void *ctx,
1010
size_t len, void *fs_data)
1111
{
12+
/*
13+
* Creating an encryption context is done unlocked since we
14+
* operate on a new inode which is not visible to other users
15+
* at this point. So, no need to check whether inode is locked.
16+
*/
1217
return ubifs_xattr_set(inode, UBIFS_XATTR_NAME_ENCRYPTION_CONTEXT,
13-
ctx, len, 0);
18+
ctx, len, 0, false);
1419
}
1520

1621
static bool ubifs_crypt_empty_dir(struct inode *inode)

fs/ubifs/ubifs.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1755,7 +1755,7 @@ int ubifs_check_dir_empty(struct inode *dir);
17551755
extern const struct xattr_handler *ubifs_xattr_handlers[];
17561756
ssize_t ubifs_listxattr(struct dentry *dentry, char *buffer, size_t size);
17571757
int ubifs_xattr_set(struct inode *host, const char *name, const void *value,
1758-
size_t size, int flags);
1758+
size_t size, int flags, bool check_lock);
17591759
ssize_t ubifs_xattr_get(struct inode *host, const char *name, void *buf,
17601760
size_t size);
17611761
void ubifs_evict_xattr_inode(struct ubifs_info *c, ino_t xattr_inum);

fs/ubifs/xattr.c

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,7 @@ static struct inode *iget_xattr(struct ubifs_info *c, ino_t inum)
280280
}
281281

282282
int ubifs_xattr_set(struct inode *host, const char *name, const void *value,
283-
size_t size, int flags)
283+
size_t size, int flags, bool check_lock)
284284
{
285285
struct inode *inode;
286286
struct ubifs_info *c = host->i_sb->s_fs_info;
@@ -289,12 +289,7 @@ int ubifs_xattr_set(struct inode *host, const char *name, const void *value,
289289
union ubifs_key key;
290290
int err;
291291

292-
/*
293-
* Creating an encryption context is done unlocked since we
294-
* operate on a new inode which is not visible to other users
295-
* at this point.
296-
*/
297-
if (strcmp(name, UBIFS_XATTR_NAME_ENCRYPTION_CONTEXT) != 0)
292+
if (check_lock)
298293
ubifs_assert(inode_is_locked(host));
299294

300295
if (size > UBIFS_MAX_INO_DATA)
@@ -598,8 +593,12 @@ static int init_xattrs(struct inode *inode, const struct xattr *xattr_array,
598593
}
599594
strcpy(name, XATTR_SECURITY_PREFIX);
600595
strcpy(name + XATTR_SECURITY_PREFIX_LEN, xattr->name);
596+
/*
597+
* creating a new inode without holding the inode rwsem,
598+
* no need to check whether inode is locked.
599+
*/
601600
err = ubifs_xattr_set(inode, name, xattr->value,
602-
xattr->value_len, 0);
601+
xattr->value_len, 0, false);
603602
kfree(name);
604603
if (err < 0)
605604
break;
@@ -646,7 +645,7 @@ static int xattr_set(const struct xattr_handler *handler,
646645
name = xattr_full_name(handler, name);
647646

648647
if (value)
649-
return ubifs_xattr_set(inode, name, value, size, flags);
648+
return ubifs_xattr_set(inode, name, value, size, flags, true);
650649
else
651650
return ubifs_xattr_remove(inode, name);
652651
}

0 commit comments

Comments
 (0)