selinux: Convert isec->lock into a spinlock
Convert isec->lock from a mutex into a spinlock. Instead of holding the lock while sleeping in inode_doinit_with_dentry, set isec->initialized to LABEL_PENDING and release the lock. Then, when the sid has been determined, re-acquire the lock. If isec->initialized is still set to LABEL_PENDING, set isec->sid; otherwise, the sid has been set by another task (LABEL_INITIALIZED) or invalidated (LABEL_INVALID) in the meantime. This fixes a deadlock on gfs2 where * one task is in inode_doinit_with_dentry -> gfs2_getxattr, holds isec->lock, and tries to acquire the inode's glock, and * another task is in do_xmote -> inode_go_inval -> selinux_inode_invalidate_secctx, holds the inode's glock, and tries to acquire isec->lock. Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com> [PM: minor tweaks to keep checkpatch.pl happy] Signed-off-by: Paul Moore <paul@paul-moore.com>
This commit is contained in:

committed by
Paul Moore

parent
3322d0d64f
commit
9287aed2ad
@@ -39,7 +39,8 @@ struct task_security_struct {
|
||||
|
||||
enum label_initialized {
|
||||
LABEL_INVALID, /* invalid or not initialized */
|
||||
LABEL_INITIALIZED /* initialized */
|
||||
LABEL_INITIALIZED, /* initialized */
|
||||
LABEL_PENDING
|
||||
};
|
||||
|
||||
struct inode_security_struct {
|
||||
@@ -52,7 +53,7 @@ struct inode_security_struct {
|
||||
u32 sid; /* SID of this object */
|
||||
u16 sclass; /* security class of this object */
|
||||
unsigned char initialized; /* initialization flag */
|
||||
struct mutex lock;
|
||||
spinlock_t lock;
|
||||
};
|
||||
|
||||
struct file_security_struct {
|
||||
|
Reference in New Issue
Block a user