From: Eric Biggers Date: Thu, 22 Aug 2019 05:54:41 +0000 (-0700) Subject: smack: use GFP_NOFS while holding inode_smack::smk_lock X-Git-Tag: v3.16.79~50 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f631e928c09cc62f5123d817b71cb1ce7238ad36;p=thirdparty%2Fkernel%2Fstable.git smack: use GFP_NOFS while holding inode_smack::smk_lock commit e5bfad3d7acc5702f32aafeb388362994f4d7bd0 upstream. inode_smack::smk_lock is taken during smack_d_instantiate(), which is called during a filesystem transaction when creating a file on ext4. Therefore to avoid a deadlock, all code that takes this lock must use GFP_NOFS, to prevent memory reclaim from waiting for the filesystem transaction to complete. Reported-by: syzbot+0eefc1e06a77d327a056@syzkaller.appspotmail.com Signed-off-by: Eric Biggers Signed-off-by: Casey Schaufler [bwh: Backported to 3.16: - Drop change to smk_netlbl_mls(), where GFP_ATOMIC is used - Adjust context] Signed-off-by: Ben Hutchings --- diff --git a/security/smack/smack_access.c b/security/smack/smack_access.c index c062e9467b62f..f5ef20e8fddf2 100644 --- a/security/smack/smack_access.c +++ b/security/smack/smack_access.c @@ -430,7 +430,7 @@ char *smk_parse_smack(const char *string, int len) if (i == 0 || i >= SMK_LONGLABEL) return NULL; - smack = kzalloc(i + 1, GFP_KERNEL); + smack = kzalloc(i + 1, GFP_NOFS); if (smack != NULL) { strncpy(smack, string, i + 1); smack[i] = '\0'; @@ -502,7 +502,7 @@ struct smack_known *smk_import_entry(const char *string, int len) if (skp != NULL) goto freeout; - skp = kzalloc(sizeof(*skp), GFP_KERNEL); + skp = kzalloc(sizeof(*skp), GFP_NOFS); if (skp == NULL) goto freeout; diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index 6392a6d933acc..b4043b7c144a7 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -70,7 +70,7 @@ static struct smack_known *smk_fetch(const char *name, struct inode *ip, if (ip->i_op->getxattr == NULL) return NULL; - buffer = kzalloc(SMK_LONGLABEL, GFP_KERNEL); + buffer = kzalloc(SMK_LONGLABEL, GFP_NOFS); if (buffer == NULL) return NULL;