diff options
author | Taesoo Kim <tsgatesv@gmail.com> | 2015-03-21 19:08:30 -0400 |
---|---|---|
committer | Steve French <smfrench@gmail.com> | 2015-03-21 13:01:50 -0400 |
commit | 2bd50fb3d4d31f5168ecea221f291534cd0a96e9 (patch) | |
tree | fbc079983364b9d761b111f52d7a581cf7fc5b48 /fs/cifs | |
parent | e1e9bda22d7ddf88515e8fe401887e313922823e (diff) |
cifs: potential memory leaks when parsing mnt opts
For example, when mount opt is redundently specified
(e.g., "user=A,user=B,user=C"), kernel kept allocating new key/val
with kstrdup() and overwrite previous ptr (to be freed).
Althouhg mount.cifs in userspace performs a bit of sanitization
(e.g., forcing one user option), current implementation is not
robust. Other options such as iocharset and domainanme are similarly
vulnerable.
Signed-off-by: Taesoo Kim <tsgatesv@gmail.com>
Signed-off-by: Steve French <smfrench@gmail.com>
Diffstat (limited to 'fs/cifs')
-rw-r--r-- | fs/cifs/connect.c | 4 |
1 files changed, 4 insertions, 0 deletions
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index d3aa999ab785..4cb8450e081b 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c | |||
@@ -1599,6 +1599,8 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, | |||
1599 | pr_warn("CIFS: username too long\n"); | 1599 | pr_warn("CIFS: username too long\n"); |
1600 | goto cifs_parse_mount_err; | 1600 | goto cifs_parse_mount_err; |
1601 | } | 1601 | } |
1602 | |||
1603 | kfree(vol->username); | ||
1602 | vol->username = kstrdup(string, GFP_KERNEL); | 1604 | vol->username = kstrdup(string, GFP_KERNEL); |
1603 | if (!vol->username) | 1605 | if (!vol->username) |
1604 | goto cifs_parse_mount_err; | 1606 | goto cifs_parse_mount_err; |
@@ -1700,6 +1702,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, | |||
1700 | goto cifs_parse_mount_err; | 1702 | goto cifs_parse_mount_err; |
1701 | } | 1703 | } |
1702 | 1704 | ||
1705 | kfree(vol->domainname); | ||
1703 | vol->domainname = kstrdup(string, GFP_KERNEL); | 1706 | vol->domainname = kstrdup(string, GFP_KERNEL); |
1704 | if (!vol->domainname) { | 1707 | if (!vol->domainname) { |
1705 | pr_warn("CIFS: no memory for domainname\n"); | 1708 | pr_warn("CIFS: no memory for domainname\n"); |
@@ -1731,6 +1734,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, | |||
1731 | } | 1734 | } |
1732 | 1735 | ||
1733 | if (strncasecmp(string, "default", 7) != 0) { | 1736 | if (strncasecmp(string, "default", 7) != 0) { |
1737 | kfree(vol->iocharset); | ||
1734 | vol->iocharset = kstrdup(string, | 1738 | vol->iocharset = kstrdup(string, |
1735 | GFP_KERNEL); | 1739 | GFP_KERNEL); |
1736 | if (!vol->iocharset) { | 1740 | if (!vol->iocharset) { |