Merge branch 'fixes-v4.14-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security

Pull smack fix from James Morris:
 "It fixes a bug in xattr_getsecurity() where security_release_secctx()
  was being called instead of kfree(), which leads to a memory leak in
  the capabilities code. smack_inode_getsecurity is also fixed to behave
  correctly when called from there"

* 'fixes-v4.14-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security:
  lsm: fix smack_inode_removexattr and xattr_getsecurity memleak
This commit is contained in:
Linus Torvalds 2017-10-04 09:21:58 -07:00
Родитель 013a8ee628 57e7ba04d4
Коммит 6c795b30f4
2 изменённых файлов: 28 добавлений и 33 удалений

Просмотреть файл

@ -250,7 +250,7 @@ xattr_getsecurity(struct inode *inode, const char *name, void *value,
}
memcpy(value, buffer, len);
out:
security_release_secctx(buffer, len);
kfree(buffer);
out_noalloc:
return len;
}

Просмотреть файл

@ -1473,7 +1473,7 @@ static int smack_inode_removexattr(struct dentry *dentry, const char *name)
* @inode: the object
* @name: attribute name
* @buffer: where to put the result
* @alloc: unused
* @alloc: duplicate memory
*
* Returns the size of the attribute or an error code
*/
@ -1486,43 +1486,38 @@ static int smack_inode_getsecurity(struct inode *inode,
struct super_block *sbp;
struct inode *ip = (struct inode *)inode;
struct smack_known *isp;
int ilen;
int rc = 0;
if (strcmp(name, XATTR_SMACK_SUFFIX) == 0) {
if (strcmp(name, XATTR_SMACK_SUFFIX) == 0)
isp = smk_of_inode(inode);
ilen = strlen(isp->smk_known);
*buffer = isp->smk_known;
return ilen;
else {
/*
* The rest of the Smack xattrs are only on sockets.
*/
sbp = ip->i_sb;
if (sbp->s_magic != SOCKFS_MAGIC)
return -EOPNOTSUPP;
sock = SOCKET_I(ip);
if (sock == NULL || sock->sk == NULL)
return -EOPNOTSUPP;
ssp = sock->sk->sk_security;
if (strcmp(name, XATTR_SMACK_IPIN) == 0)
isp = ssp->smk_in;
else if (strcmp(name, XATTR_SMACK_IPOUT) == 0)
isp = ssp->smk_out;
else
return -EOPNOTSUPP;
}
/*
* The rest of the Smack xattrs are only on sockets.
*/
sbp = ip->i_sb;
if (sbp->s_magic != SOCKFS_MAGIC)
return -EOPNOTSUPP;
sock = SOCKET_I(ip);
if (sock == NULL || sock->sk == NULL)
return -EOPNOTSUPP;
ssp = sock->sk->sk_security;
if (strcmp(name, XATTR_SMACK_IPIN) == 0)
isp = ssp->smk_in;
else if (strcmp(name, XATTR_SMACK_IPOUT) == 0)
isp = ssp->smk_out;
else
return -EOPNOTSUPP;
ilen = strlen(isp->smk_known);
if (rc == 0) {
*buffer = isp->smk_known;
rc = ilen;
if (alloc) {
*buffer = kstrdup(isp->smk_known, GFP_KERNEL);
if (*buffer == NULL)
return -ENOMEM;
}
return rc;
return strlen(isp->smk_known);
}