From patchwork Tue Jan 18 20:33:19 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeff Layton X-Patchwork-Id: 487471 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id p0IKkIkY008377 for ; Tue, 18 Jan 2011 20:46:21 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753418Ab1ARUdb (ORCPT ); Tue, 18 Jan 2011 15:33:31 -0500 Received: from mail-qw0-f46.google.com ([209.85.216.46]:58438 "EHLO mail-qw0-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752780Ab1ARUda (ORCPT ); Tue, 18 Jan 2011 15:33:30 -0500 Received: by mail-qw0-f46.google.com with SMTP id 26so30239qwa.19 for ; Tue, 18 Jan 2011 12:33:30 -0800 (PST) Received: by 10.224.179.210 with SMTP id br18mr5430789qab.357.1295382810276; Tue, 18 Jan 2011 12:33:30 -0800 (PST) Received: from salusa.poochiereds.net (cpe-071-070-153-003.nc.res.rr.com [71.70.153.3]) by mx.google.com with ESMTPS id e29sm4083259qck.39.2011.01.18.12.33.29 (version=SSLv3 cipher=RC4-MD5); Tue, 18 Jan 2011 12:33:29 -0800 (PST) From: Jeff Layton To: smfrench@gmail.com Cc: linux-cifs@vger.kernel.org Subject: [PATCH 5/5] cifs: fix unaligned accesses in cifsConvertToUCS Date: Tue, 18 Jan 2011 15:33:19 -0500 Message-Id: <1295382799-7902-6-git-send-email-jlayton@redhat.com> X-Mailer: git-send-email 1.7.3.4 In-Reply-To: <1295382799-7902-1-git-send-email-jlayton@redhat.com> References: <1295382799-7902-1-git-send-email-jlayton@redhat.com> Sender: linux-cifs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter1.kernel.org [140.211.167.41]); Tue, 18 Jan 2011 20:46:21 +0000 (UTC) diff --git a/fs/cifs/cifs_unicode.c b/fs/cifs/cifs_unicode.c index 8134443..6a5090d 100644 --- a/fs/cifs/cifs_unicode.c +++ b/fs/cifs/cifs_unicode.c @@ -257,3 +257,79 @@ cifs_strndup_from_ucs(const char *src, const int maxlen, const bool is_unicode, return dst; } +/* + * Convert 16 bit Unicode pathname to wire format from string in current code + * page. Conversion may involve remapping up the six characters that are + * only legal in POSIX-like OS (if they are present in the string). Path + * names are little endian 16 bit Unicode on the wire + */ +int +cifsConvertToUCS(__le16 *target, const char *source, int maxlen, + const struct nls_table *cp, int mapChars) +{ + int i, j, charlen; + int len_remaining = maxlen; + char src_char; + __u16 temp; + + if (!mapChars) + return cifs_strtoUCS(target, source, PATH_MAX, cp); + + for (i = 0, j = 0; i < maxlen; j++) { + src_char = source[i]; + switch (src_char) { + case 0: + put_unaligned_le16(0, &target[j]); + goto ctoUCS_out; + case ':': + temp = UNI_COLON; + break; + case '*': + temp = UNI_ASTERIK; + break; + case '?': + temp = UNI_QUESTION; + break; + case '<': + temp = UNI_LESSTHAN; + break; + case '>': + temp = UNI_GRTRTHAN; + break; + case '|': + temp = UNI_PIPE; + break; + /* + * FIXME: We can not handle remapping backslash (UNI_SLASH) + * until all the calls to build_path_from_dentry are modified, + * as they use backslash as separator. + */ + default: + charlen = cp->char2uni(source+i, len_remaining, + &temp); + /* + * if no match, use question mark, which at least in + * some cases serves as wild card + */ + if (charlen < 1) { + temp = 0x003f; + charlen = 1; + } + len_remaining -= charlen; + /* + * character may take more than one byte in the source + * string, but will take exactly two bytes in the + * target string + */ + i += charlen; + continue; + } + put_unaligned_le16(temp, &target[j]); + i++; /* move to next char in source string */ + len_remaining--; + } + +ctoUCS_out: + return i; +} + diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c index c1f2a51..2036757 100644 --- a/fs/cifs/misc.c +++ b/fs/cifs/misc.c @@ -626,77 +626,6 @@ dump_smb(struct smb_hdr *smb_buf, int smb_buf_length) return; } -/* Convert 16 bit Unicode pathname to wire format from string in current code - page. Conversion may involve remapping up the seven characters that are - only legal in POSIX-like OS (if they are present in the string). Path - names are little endian 16 bit Unicode on the wire */ -int -cifsConvertToUCS(__le16 *target, const char *source, int maxlen, - const struct nls_table *cp, int mapChars) -{ - int i, j, charlen; - int len_remaining = maxlen; - char src_char; - __u16 temp; - - if (!mapChars) - return cifs_strtoUCS(target, source, PATH_MAX, cp); - - for (i = 0, j = 0; i < maxlen; j++) { - src_char = source[i]; - switch (src_char) { - case 0: - target[j] = 0; - goto ctoUCS_out; - case ':': - target[j] = cpu_to_le16(UNI_COLON); - break; - case '*': - target[j] = cpu_to_le16(UNI_ASTERIK); - break; - case '?': - target[j] = cpu_to_le16(UNI_QUESTION); - break; - case '<': - target[j] = cpu_to_le16(UNI_LESSTHAN); - break; - case '>': - target[j] = cpu_to_le16(UNI_GRTRTHAN); - break; - case '|': - target[j] = cpu_to_le16(UNI_PIPE); - break; - /* BB We can not handle remapping slash until - all the calls to build_path_from_dentry - are modified, as they use slash as separator BB */ - /* case '\\': - target[j] = cpu_to_le16(UNI_SLASH); - break;*/ - default: - charlen = cp->char2uni(source+i, - len_remaining, &temp); - /* if no match, use question mark, which - at least in some cases servers as wild card */ - if (charlen < 1) { - target[j] = cpu_to_le16(0x003f); - charlen = 1; - } else - target[j] = cpu_to_le16(temp); - len_remaining -= charlen; - /* character may take more than one byte in the - the source string, but will take exactly two - bytes in the target string */ - i += charlen; - continue; - } - i++; /* move to next char in source string */ - len_remaining--; - } - -ctoUCS_out: - return i; -} - void cifs_autodisable_serverino(struct cifs_sb_info *cifs_sb) {