| From: Steve French <smfrench@gmail.com> |
| Date: Fri, 20 Apr 2018 12:19:07 -0500 |
| Subject: cifs: do not allow creating sockets except with SMB1 posix exensions |
| |
| commit 1d0cffa674cfa7d185a302c8c6850fc50b893bed upstream. |
| |
| RHBZ: 1453123 |
| |
| Since at least the 3.10 kernel and likely a lot earlier we have |
| not been able to create unix domain sockets in a cifs share |
| when mounted using the SFU mount option (except when mounted |
| with the cifs unix extensions to Samba e.g.) |
| Trying to create a socket, for example using the af_unix command from |
| xfstests will cause : |
| BUG: unable to handle kernel NULL pointer dereference at 00000000 |
| 00000040 |
| |
| Since no one uses or depends on being able to create unix domains sockets |
| on a cifs share the easiest fix to stop this vulnerability is to simply |
| not allow creation of any other special files than char or block devices |
| when sfu is used. |
| |
| Added update to Ronnie's patch to handle a tcon link leak, and |
| to address a buf leak noticed by Gustavo and Colin. |
| |
| Acked-by: Gustavo A. R. Silva <gustavo@embeddedor.com> |
| CC: Colin Ian King <colin.king@canonical.com> |
| Reviewed-by: Pavel Shilovsky <pshilov@microsoft.com> |
| Reported-by: Eryu Guan <eguan@redhat.com> |
| Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com> |
| Signed-off-by: Steve French <smfrench@gmail.com> |
| [bwh: Backported to 3.16: adjust context] |
| Signed-off-by: Ben Hutchings <ben@decadent.org.uk> |
| --- |
| fs/cifs/dir.c | 9 +++++---- |
| 1 file changed, 5 insertions(+), 4 deletions(-) |
| |
| --- a/fs/cifs/dir.c |
| +++ b/fs/cifs/dir.c |
| @@ -665,6 +665,9 @@ int cifs_mknod(struct inode *inode, stru |
| goto mknod_out; |
| } |
| |
| + if (!S_ISCHR(mode) && !S_ISBLK(mode)) |
| + goto mknod_out; |
| + |
| if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL)) |
| goto mknod_out; |
| |
| @@ -673,10 +676,8 @@ int cifs_mknod(struct inode *inode, stru |
| |
| buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL); |
| if (buf == NULL) { |
| - kfree(full_path); |
| rc = -ENOMEM; |
| - free_xid(xid); |
| - return rc; |
| + goto mknod_out; |
| } |
| |
| if (backup_cred(cifs_sb)) |
| @@ -718,7 +719,7 @@ int cifs_mknod(struct inode *inode, stru |
| pdev->minor = cpu_to_le64(MINOR(device_number)); |
| rc = CIFSSMBWrite(xid, &io_parms, &bytes_written, (char *)pdev, |
| NULL, 0); |
| - } /* else if (S_ISFIFO) */ |
| + } |
| CIFSSMBClose(xid, tcon, fid.netfid); |
| d_drop(direntry); |
| |