aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs
diff options
context:
space:
mode:
authorSuresh Jayaraman <sjayaraman@suse.com>2012-06-11 21:45:50 -0400
committerSteve French <sfrench@us.ibm.com>2012-06-12 13:53:02 -0400
commite73f843a3235a19de38359c91586e9eadef12238 (patch)
treedf8d0de120898fa505d57bf2ac80d1303711e8c7 /fs/cifs
parent94fa83c424321189ca24fb6cb4c0d224cdedc72d (diff)
cifs: fix parsing of password mount option
The double delimiter check that allows a comma in the password parsing code is unconditional. We set "tmp_end" to the end of the string and we continue to check for double delimiter. In the case where the password doesn't contain a comma we end up setting tmp_end to NULL and eventually setting "options" to "end". This results in the premature termination of the options string and hence the values of UNCip and UNC are being set to NULL. This results in mount failure with "Connecting to DFS root not implemented yet" error. This error is usually not noticable as we have password as the last option in the superblock mountdata. But when we call expand_dfs_referral() from cifs_mount() and try to compose mount options for the submount, the resulting mountdata will be of the form ",ver=1,user=foo,pass=bar,ip=x.x.x.x,unc=\\server\share" and hence results in the above error. This bug has been seen with older NAS servers running Samba 3.0.24. Fix this by moving the double delimiter check inside the conditional loop. Changes since -v1 - removed the wrong strlen() micro optimization. Signed-off-by: Suresh Jayaraman <sjayaraman@suse.com> Acked-by: Sachin Prabhu <sprabhu@redhat.com> Cc: stable@vger.kernel.org [3.1+] Signed-off-by: Steve French <sfrench@us.ibm.com>
Diffstat (limited to 'fs/cifs')
-rw-r--r--fs/cifs/connect.c32
1 files changed, 17 insertions, 15 deletions
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 78db68a5cf44..5b3840725d01 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -1653,24 +1653,26 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
1653 * If yes, we have encountered a double deliminator 1653 * If yes, we have encountered a double deliminator
1654 * reset the NULL character to the deliminator 1654 * reset the NULL character to the deliminator
1655 */ 1655 */
1656 if (tmp_end < end && tmp_end[1] == delim) 1656 if (tmp_end < end && tmp_end[1] == delim) {
1657 tmp_end[0] = delim; 1657 tmp_end[0] = delim;
1658 1658
1659 /* Keep iterating until we get to a single deliminator 1659 /* Keep iterating until we get to a single
1660 * OR the end 1660 * deliminator OR the end
1661 */ 1661 */
1662 while ((tmp_end = strchr(tmp_end, delim)) != NULL && 1662 while ((tmp_end = strchr(tmp_end, delim))
1663 (tmp_end[1] == delim)) { 1663 != NULL && (tmp_end[1] == delim)) {
1664 tmp_end = (char *) &tmp_end[2]; 1664 tmp_end = (char *) &tmp_end[2];
1665 } 1665 }
1666 1666
1667 /* Reset var options to point to next element */ 1667 /* Reset var options to point to next element */
1668 if (tmp_end) { 1668 if (tmp_end) {
1669 tmp_end[0] = '\0'; 1669 tmp_end[0] = '\0';
1670 options = (char *) &tmp_end[1]; 1670 options = (char *) &tmp_end[1];
1671 } else 1671 } else
1672 /* Reached the end of the mount option string */ 1672 /* Reached the end of the mount option
1673 options = end; 1673 * string */
1674 options = end;
1675 }
1674 1676
1675 /* Now build new password string */ 1677 /* Now build new password string */
1676 temp_len = strlen(value); 1678 temp_len = strlen(value);