Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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>

authored by

Suresh Jayaraman and committed by
Steve French
e73f843a 94fa83c4

+17 -15
+17 -15
fs/cifs/connect.c
··· 1653 1653 * If yes, we have encountered a double deliminator 1654 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 1657 tmp_end[0] = delim; 1658 1658 1659 - /* Keep iterating until we get to a single deliminator 1660 - * OR the end 1661 - */ 1662 - while ((tmp_end = strchr(tmp_end, delim)) != NULL && 1663 - (tmp_end[1] == delim)) { 1664 - tmp_end = (char *) &tmp_end[2]; 1665 - } 1659 + /* Keep iterating until we get to a single 1660 + * deliminator OR the end 1661 + */ 1662 + while ((tmp_end = strchr(tmp_end, delim)) 1663 + != NULL && (tmp_end[1] == delim)) { 1664 + tmp_end = (char *) &tmp_end[2]; 1665 + } 1666 1666 1667 - /* Reset var options to point to next element */ 1668 - if (tmp_end) { 1669 - tmp_end[0] = '\0'; 1670 - options = (char *) &tmp_end[1]; 1671 - } else 1672 - /* Reached the end of the mount option string */ 1673 - options = end; 1667 + /* Reset var options to point to next element */ 1668 + if (tmp_end) { 1669 + tmp_end[0] = '\0'; 1670 + options = (char *) &tmp_end[1]; 1671 + } else 1672 + /* Reached the end of the mount option 1673 + * string */ 1674 + options = end; 1675 + } 1674 1676 1675 1677 /* Now build new password string */ 1676 1678 temp_len = strlen(value);