diff options
Diffstat (limited to 'fs/cifs/link.c')
| -rw-r--r-- | fs/cifs/link.c | 58 |
1 files changed, 49 insertions, 9 deletions
diff --git a/fs/cifs/link.c b/fs/cifs/link.c index 306769de2fb..02cd60aefbf 100644 --- a/fs/cifs/link.c +++ b/fs/cifs/link.c | |||
| @@ -28,7 +28,6 @@ | |||
| 28 | #include "cifsproto.h" | 28 | #include "cifsproto.h" |
| 29 | #include "cifs_debug.h" | 29 | #include "cifs_debug.h" |
| 30 | #include "cifs_fs_sb.h" | 30 | #include "cifs_fs_sb.h" |
| 31 | #include "md5.h" | ||
| 32 | 31 | ||
| 33 | #define CIFS_MF_SYMLINK_LEN_OFFSET (4+1) | 32 | #define CIFS_MF_SYMLINK_LEN_OFFSET (4+1) |
| 34 | #define CIFS_MF_SYMLINK_MD5_OFFSET (CIFS_MF_SYMLINK_LEN_OFFSET+(4+1)) | 33 | #define CIFS_MF_SYMLINK_MD5_OFFSET (CIFS_MF_SYMLINK_LEN_OFFSET+(4+1)) |
| @@ -47,6 +46,44 @@ | |||
| 47 | md5_hash[12], md5_hash[13], md5_hash[14], md5_hash[15] | 46 | md5_hash[12], md5_hash[13], md5_hash[14], md5_hash[15] |
| 48 | 47 | ||
| 49 | static int | 48 | static int |
| 49 | symlink_hash(unsigned int link_len, const char *link_str, u8 *md5_hash) | ||
| 50 | { | ||
| 51 | int rc; | ||
| 52 | unsigned int size; | ||
| 53 | struct crypto_shash *md5; | ||
| 54 | struct sdesc *sdescmd5; | ||
| 55 | |||
| 56 | md5 = crypto_alloc_shash("md5", 0, 0); | ||
| 57 | if (IS_ERR(md5)) { | ||
| 58 | cERROR(1, "%s: Crypto md5 allocation error %d\n", __func__, rc); | ||
| 59 | return PTR_ERR(md5); | ||
| 60 | } | ||
| 61 | size = sizeof(struct shash_desc) + crypto_shash_descsize(md5); | ||
| 62 | sdescmd5 = kmalloc(size, GFP_KERNEL); | ||
| 63 | if (!sdescmd5) { | ||
| 64 | rc = -ENOMEM; | ||
| 65 | cERROR(1, "%s: Memory allocation failure\n", __func__); | ||
| 66 | goto symlink_hash_err; | ||
| 67 | } | ||
| 68 | sdescmd5->shash.tfm = md5; | ||
| 69 | sdescmd5->shash.flags = 0x0; | ||
| 70 | |||
| 71 | rc = crypto_shash_init(&sdescmd5->shash); | ||
| 72 | if (rc) { | ||
| 73 | cERROR(1, "%s: Could not init md5 shash\n", __func__); | ||
| 74 | goto symlink_hash_err; | ||
| 75 | } | ||
| 76 | crypto_shash_update(&sdescmd5->shash, link_str, link_len); | ||
| 77 | rc = crypto_shash_final(&sdescmd5->shash, md5_hash); | ||
| 78 | |||
| 79 | symlink_hash_err: | ||
| 80 | crypto_free_shash(md5); | ||
| 81 | kfree(sdescmd5); | ||
| 82 | |||
| 83 | return rc; | ||
| 84 | } | ||
| 85 | |||
| 86 | static int | ||
| 50 | CIFSParseMFSymlink(const u8 *buf, | 87 | CIFSParseMFSymlink(const u8 *buf, |
| 51 | unsigned int buf_len, | 88 | unsigned int buf_len, |
| 52 | unsigned int *_link_len, | 89 | unsigned int *_link_len, |
| @@ -56,7 +93,6 @@ CIFSParseMFSymlink(const u8 *buf, | |||
| 56 | unsigned int link_len; | 93 | unsigned int link_len; |
| 57 | const char *md5_str1; | 94 | const char *md5_str1; |
| 58 | const char *link_str; | 95 | const char *link_str; |
| 59 | struct MD5Context md5_ctx; | ||
| 60 | u8 md5_hash[16]; | 96 | u8 md5_hash[16]; |
| 61 | char md5_str2[34]; | 97 | char md5_str2[34]; |
| 62 | 98 | ||
| @@ -70,9 +106,11 @@ CIFSParseMFSymlink(const u8 *buf, | |||
| 70 | if (rc != 1) | 106 | if (rc != 1) |
| 71 | return -EINVAL; | 107 | return -EINVAL; |
| 72 | 108 | ||
| 73 | cifs_MD5_init(&md5_ctx); | 109 | rc = symlink_hash(link_len, link_str, md5_hash); |
| 74 | cifs_MD5_update(&md5_ctx, (const u8 *)link_str, link_len); | 110 | if (rc) { |
| 75 | cifs_MD5_final(md5_hash, &md5_ctx); | 111 | cFYI(1, "%s: MD5 hash failure: %d\n", __func__, rc); |
| 112 | return rc; | ||
| 113 | } | ||
| 76 | 114 | ||
| 77 | snprintf(md5_str2, sizeof(md5_str2), | 115 | snprintf(md5_str2, sizeof(md5_str2), |
| 78 | CIFS_MF_SYMLINK_MD5_FORMAT, | 116 | CIFS_MF_SYMLINK_MD5_FORMAT, |
| @@ -94,9 +132,9 @@ CIFSParseMFSymlink(const u8 *buf, | |||
| 94 | static int | 132 | static int |
| 95 | CIFSFormatMFSymlink(u8 *buf, unsigned int buf_len, const char *link_str) | 133 | CIFSFormatMFSymlink(u8 *buf, unsigned int buf_len, const char *link_str) |
| 96 | { | 134 | { |
| 135 | int rc; | ||
| 97 | unsigned int link_len; | 136 | unsigned int link_len; |
| 98 | unsigned int ofs; | 137 | unsigned int ofs; |
| 99 | struct MD5Context md5_ctx; | ||
| 100 | u8 md5_hash[16]; | 138 | u8 md5_hash[16]; |
| 101 | 139 | ||
| 102 | if (buf_len != CIFS_MF_SYMLINK_FILE_SIZE) | 140 | if (buf_len != CIFS_MF_SYMLINK_FILE_SIZE) |
| @@ -107,9 +145,11 @@ CIFSFormatMFSymlink(u8 *buf, unsigned int buf_len, const char *link_str) | |||
| 107 | if (link_len > CIFS_MF_SYMLINK_LINK_MAXLEN) | 145 | if (link_len > CIFS_MF_SYMLINK_LINK_MAXLEN) |
| 108 | return -ENAMETOOLONG; | 146 | return -ENAMETOOLONG; |
| 109 | 147 | ||
| 110 | cifs_MD5_init(&md5_ctx); | 148 | rc = symlink_hash(link_len, link_str, md5_hash); |
| 111 | cifs_MD5_update(&md5_ctx, (const u8 *)link_str, link_len); | 149 | if (rc) { |
| 112 | cifs_MD5_final(md5_hash, &md5_ctx); | 150 | cFYI(1, "%s: MD5 hash failure: %d\n", __func__, rc); |
| 151 | return rc; | ||
| 152 | } | ||
| 113 | 153 | ||
| 114 | snprintf(buf, buf_len, | 154 | snprintf(buf, buf_len, |
| 115 | CIFS_MF_SYMLINK_LEN_FORMAT CIFS_MF_SYMLINK_MD5_FORMAT, | 155 | CIFS_MF_SYMLINK_LEN_FORMAT CIFS_MF_SYMLINK_MD5_FORMAT, |
