diff options
-rw-r--r-- | fs/cifs/cifsproto.h | 1 | ||||
-rw-r--r-- | fs/cifs/cifssmb.c | 197 | ||||
-rw-r--r-- | fs/cifs/connect.c | 7 | ||||
-rw-r--r-- | fs/cifs/dir.c | 5 | ||||
-rw-r--r-- | fs/cifs/misc.c | 22 | ||||
-rw-r--r-- | fs/cifs/sess.c | 26 |
6 files changed, 112 insertions, 146 deletions
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index e23234207fc2..592a6cea2b79 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h | |||
@@ -579,6 +579,7 @@ extern void rqst_page_get_length(struct smb_rqst *rqst, unsigned int page, | |||
579 | unsigned int *len, unsigned int *offset); | 579 | unsigned int *len, unsigned int *offset); |
580 | 580 | ||
581 | void extract_unc_hostname(const char *unc, const char **h, size_t *len); | 581 | void extract_unc_hostname(const char *unc, const char **h, size_t *len); |
582 | int copy_path_name(char *dst, const char *src); | ||
582 | 583 | ||
583 | #ifdef CONFIG_CIFS_DFS_UPCALL | 584 | #ifdef CONFIG_CIFS_DFS_UPCALL |
584 | static inline int get_dfs_path(const unsigned int xid, struct cifs_ses *ses, | 585 | static inline int get_dfs_path(const unsigned int xid, struct cifs_ses *ses, |
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index e2f95965065d..3907653e63c7 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c | |||
@@ -942,10 +942,8 @@ PsxDelete: | |||
942 | PATH_MAX, nls_codepage, remap); | 942 | PATH_MAX, nls_codepage, remap); |
943 | name_len++; /* trailing null */ | 943 | name_len++; /* trailing null */ |
944 | name_len *= 2; | 944 | name_len *= 2; |
945 | } else { /* BB add path length overrun check */ | 945 | } else { |
946 | name_len = strnlen(fileName, PATH_MAX); | 946 | name_len = copy_path_name(pSMB->FileName, fileName); |
947 | name_len++; /* trailing null */ | ||
948 | strncpy(pSMB->FileName, fileName, name_len); | ||
949 | } | 947 | } |
950 | 948 | ||
951 | params = 6 + name_len; | 949 | params = 6 + name_len; |
@@ -1015,10 +1013,8 @@ DelFileRetry: | |||
1015 | remap); | 1013 | remap); |
1016 | name_len++; /* trailing null */ | 1014 | name_len++; /* trailing null */ |
1017 | name_len *= 2; | 1015 | name_len *= 2; |
1018 | } else { /* BB improve check for buffer overruns BB */ | 1016 | } else { |
1019 | name_len = strnlen(name, PATH_MAX); | 1017 | name_len = copy_path_name(pSMB->fileName, name); |
1020 | name_len++; /* trailing null */ | ||
1021 | strncpy(pSMB->fileName, name, name_len); | ||
1022 | } | 1018 | } |
1023 | pSMB->SearchAttributes = | 1019 | pSMB->SearchAttributes = |
1024 | cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM); | 1020 | cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM); |
@@ -1062,10 +1058,8 @@ RmDirRetry: | |||
1062 | remap); | 1058 | remap); |
1063 | name_len++; /* trailing null */ | 1059 | name_len++; /* trailing null */ |
1064 | name_len *= 2; | 1060 | name_len *= 2; |
1065 | } else { /* BB improve check for buffer overruns BB */ | 1061 | } else { |
1066 | name_len = strnlen(name, PATH_MAX); | 1062 | name_len = copy_path_name(pSMB->DirName, name); |
1067 | name_len++; /* trailing null */ | ||
1068 | strncpy(pSMB->DirName, name, name_len); | ||
1069 | } | 1063 | } |
1070 | 1064 | ||
1071 | pSMB->BufferFormat = 0x04; | 1065 | pSMB->BufferFormat = 0x04; |
@@ -1107,10 +1101,8 @@ MkDirRetry: | |||
1107 | remap); | 1101 | remap); |
1108 | name_len++; /* trailing null */ | 1102 | name_len++; /* trailing null */ |
1109 | name_len *= 2; | 1103 | name_len *= 2; |
1110 | } else { /* BB improve check for buffer overruns BB */ | 1104 | } else { |
1111 | name_len = strnlen(name, PATH_MAX); | 1105 | name_len = copy_path_name(pSMB->DirName, name); |
1112 | name_len++; /* trailing null */ | ||
1113 | strncpy(pSMB->DirName, name, name_len); | ||
1114 | } | 1106 | } |
1115 | 1107 | ||
1116 | pSMB->BufferFormat = 0x04; | 1108 | pSMB->BufferFormat = 0x04; |
@@ -1157,10 +1149,8 @@ PsxCreat: | |||
1157 | PATH_MAX, nls_codepage, remap); | 1149 | PATH_MAX, nls_codepage, remap); |
1158 | name_len++; /* trailing null */ | 1150 | name_len++; /* trailing null */ |
1159 | name_len *= 2; | 1151 | name_len *= 2; |
1160 | } else { /* BB improve the check for buffer overruns BB */ | 1152 | } else { |
1161 | name_len = strnlen(name, PATH_MAX); | 1153 | name_len = copy_path_name(pSMB->FileName, name); |
1162 | name_len++; /* trailing null */ | ||
1163 | strncpy(pSMB->FileName, name, name_len); | ||
1164 | } | 1154 | } |
1165 | 1155 | ||
1166 | params = 6 + name_len; | 1156 | params = 6 + name_len; |
@@ -1324,11 +1314,9 @@ OldOpenRetry: | |||
1324 | fileName, PATH_MAX, nls_codepage, remap); | 1314 | fileName, PATH_MAX, nls_codepage, remap); |
1325 | name_len++; /* trailing null */ | 1315 | name_len++; /* trailing null */ |
1326 | name_len *= 2; | 1316 | name_len *= 2; |
1327 | } else { /* BB improve check for buffer overruns BB */ | 1317 | } else { |
1328 | count = 0; /* no pad */ | 1318 | count = 0; /* no pad */ |
1329 | name_len = strnlen(fileName, PATH_MAX); | 1319 | name_len = copy_path_name(pSMB->fileName, fileName); |
1330 | name_len++; /* trailing null */ | ||
1331 | strncpy(pSMB->fileName, fileName, name_len); | ||
1332 | } | 1320 | } |
1333 | if (*pOplock & REQ_OPLOCK) | 1321 | if (*pOplock & REQ_OPLOCK) |
1334 | pSMB->OpenFlags = cpu_to_le16(REQ_OPLOCK); | 1322 | pSMB->OpenFlags = cpu_to_le16(REQ_OPLOCK); |
@@ -1442,11 +1430,8 @@ openRetry: | |||
1442 | /* BB improve check for buffer overruns BB */ | 1430 | /* BB improve check for buffer overruns BB */ |
1443 | /* no pad */ | 1431 | /* no pad */ |
1444 | count = 0; | 1432 | count = 0; |
1445 | name_len = strnlen(path, PATH_MAX); | 1433 | name_len = copy_path_name(req->fileName, path); |
1446 | /* trailing null */ | ||
1447 | name_len++; | ||
1448 | req->NameLength = cpu_to_le16(name_len); | 1434 | req->NameLength = cpu_to_le16(name_len); |
1449 | strncpy(req->fileName, path, name_len); | ||
1450 | } | 1435 | } |
1451 | 1436 | ||
1452 | if (*oplock & REQ_OPLOCK) | 1437 | if (*oplock & REQ_OPLOCK) |
@@ -2812,15 +2797,10 @@ renameRetry: | |||
2812 | remap); | 2797 | remap); |
2813 | name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ; | 2798 | name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ; |
2814 | name_len2 *= 2; /* convert to bytes */ | 2799 | name_len2 *= 2; /* convert to bytes */ |
2815 | } else { /* BB improve the check for buffer overruns BB */ | 2800 | } else { |
2816 | name_len = strnlen(from_name, PATH_MAX); | 2801 | name_len = copy_path_name(pSMB->OldFileName, from_name); |
2817 | name_len++; /* trailing null */ | 2802 | name_len2 = copy_path_name(pSMB->OldFileName+name_len+1, to_name); |
2818 | strncpy(pSMB->OldFileName, from_name, name_len); | ||
2819 | name_len2 = strnlen(to_name, PATH_MAX); | ||
2820 | name_len2++; /* trailing null */ | ||
2821 | pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */ | 2803 | pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */ |
2822 | strncpy(&pSMB->OldFileName[name_len + 1], to_name, name_len2); | ||
2823 | name_len2++; /* trailing null */ | ||
2824 | name_len2++; /* signature byte */ | 2804 | name_len2++; /* signature byte */ |
2825 | } | 2805 | } |
2826 | 2806 | ||
@@ -2962,15 +2942,10 @@ copyRetry: | |||
2962 | toName, PATH_MAX, nls_codepage, remap); | 2942 | toName, PATH_MAX, nls_codepage, remap); |
2963 | name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ; | 2943 | name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ; |
2964 | name_len2 *= 2; /* convert to bytes */ | 2944 | name_len2 *= 2; /* convert to bytes */ |
2965 | } else { /* BB improve the check for buffer overruns BB */ | 2945 | } else { |
2966 | name_len = strnlen(fromName, PATH_MAX); | 2946 | name_len = copy_path_name(pSMB->OldFileName, fromName); |
2967 | name_len++; /* trailing null */ | ||
2968 | strncpy(pSMB->OldFileName, fromName, name_len); | ||
2969 | name_len2 = strnlen(toName, PATH_MAX); | ||
2970 | name_len2++; /* trailing null */ | ||
2971 | pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */ | 2947 | pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */ |
2972 | strncpy(&pSMB->OldFileName[name_len + 1], toName, name_len2); | 2948 | name_len2 = copy_path_name(pSMB->OldFileName+name_len+1, toName); |
2973 | name_len2++; /* trailing null */ | ||
2974 | name_len2++; /* signature byte */ | 2949 | name_len2++; /* signature byte */ |
2975 | } | 2950 | } |
2976 | 2951 | ||
@@ -3021,10 +2996,8 @@ createSymLinkRetry: | |||
3021 | name_len++; /* trailing null */ | 2996 | name_len++; /* trailing null */ |
3022 | name_len *= 2; | 2997 | name_len *= 2; |
3023 | 2998 | ||
3024 | } else { /* BB improve the check for buffer overruns BB */ | 2999 | } else { |
3025 | name_len = strnlen(fromName, PATH_MAX); | 3000 | name_len = copy_path_name(pSMB->FileName, fromName); |
3026 | name_len++; /* trailing null */ | ||
3027 | strncpy(pSMB->FileName, fromName, name_len); | ||
3028 | } | 3001 | } |
3029 | params = 6 + name_len; | 3002 | params = 6 + name_len; |
3030 | pSMB->MaxSetupCount = 0; | 3003 | pSMB->MaxSetupCount = 0; |
@@ -3044,10 +3017,8 @@ createSymLinkRetry: | |||
3044 | PATH_MAX, nls_codepage, remap); | 3017 | PATH_MAX, nls_codepage, remap); |
3045 | name_len_target++; /* trailing null */ | 3018 | name_len_target++; /* trailing null */ |
3046 | name_len_target *= 2; | 3019 | name_len_target *= 2; |
3047 | } else { /* BB improve the check for buffer overruns BB */ | 3020 | } else { |
3048 | name_len_target = strnlen(toName, PATH_MAX); | 3021 | name_len_target = copy_path_name(data_offset, toName); |
3049 | name_len_target++; /* trailing null */ | ||
3050 | strncpy(data_offset, toName, name_len_target); | ||
3051 | } | 3022 | } |
3052 | 3023 | ||
3053 | pSMB->MaxParameterCount = cpu_to_le16(2); | 3024 | pSMB->MaxParameterCount = cpu_to_le16(2); |
@@ -3109,10 +3080,8 @@ createHardLinkRetry: | |||
3109 | name_len++; /* trailing null */ | 3080 | name_len++; /* trailing null */ |
3110 | name_len *= 2; | 3081 | name_len *= 2; |
3111 | 3082 | ||
3112 | } else { /* BB improve the check for buffer overruns BB */ | 3083 | } else { |
3113 | name_len = strnlen(toName, PATH_MAX); | 3084 | name_len = copy_path_name(pSMB->FileName, toName); |
3114 | name_len++; /* trailing null */ | ||
3115 | strncpy(pSMB->FileName, toName, name_len); | ||
3116 | } | 3085 | } |
3117 | params = 6 + name_len; | 3086 | params = 6 + name_len; |
3118 | pSMB->MaxSetupCount = 0; | 3087 | pSMB->MaxSetupCount = 0; |
@@ -3131,10 +3100,8 @@ createHardLinkRetry: | |||
3131 | PATH_MAX, nls_codepage, remap); | 3100 | PATH_MAX, nls_codepage, remap); |
3132 | name_len_target++; /* trailing null */ | 3101 | name_len_target++; /* trailing null */ |
3133 | name_len_target *= 2; | 3102 | name_len_target *= 2; |
3134 | } else { /* BB improve the check for buffer overruns BB */ | 3103 | } else { |
3135 | name_len_target = strnlen(fromName, PATH_MAX); | 3104 | name_len_target = copy_path_name(data_offset, fromName); |
3136 | name_len_target++; /* trailing null */ | ||
3137 | strncpy(data_offset, fromName, name_len_target); | ||
3138 | } | 3105 | } |
3139 | 3106 | ||
3140 | pSMB->MaxParameterCount = cpu_to_le16(2); | 3107 | pSMB->MaxParameterCount = cpu_to_le16(2); |
@@ -3213,15 +3180,10 @@ winCreateHardLinkRetry: | |||
3213 | remap); | 3180 | remap); |
3214 | name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ; | 3181 | name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ; |
3215 | name_len2 *= 2; /* convert to bytes */ | 3182 | name_len2 *= 2; /* convert to bytes */ |
3216 | } else { /* BB improve the check for buffer overruns BB */ | 3183 | } else { |
3217 | name_len = strnlen(from_name, PATH_MAX); | 3184 | name_len = copy_path_name(pSMB->OldFileName, from_name); |
3218 | name_len++; /* trailing null */ | ||
3219 | strncpy(pSMB->OldFileName, from_name, name_len); | ||
3220 | name_len2 = strnlen(to_name, PATH_MAX); | ||
3221 | name_len2++; /* trailing null */ | ||
3222 | pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */ | 3185 | pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */ |
3223 | strncpy(&pSMB->OldFileName[name_len + 1], to_name, name_len2); | 3186 | name_len2 = copy_path_name(pSMB->OldFileName+name_len+1, to_name); |
3224 | name_len2++; /* trailing null */ | ||
3225 | name_len2++; /* signature byte */ | 3187 | name_len2++; /* signature byte */ |
3226 | } | 3188 | } |
3227 | 3189 | ||
@@ -3271,10 +3233,8 @@ querySymLinkRetry: | |||
3271 | remap); | 3233 | remap); |
3272 | name_len++; /* trailing null */ | 3234 | name_len++; /* trailing null */ |
3273 | name_len *= 2; | 3235 | name_len *= 2; |
3274 | } else { /* BB improve the check for buffer overruns BB */ | 3236 | } else { |
3275 | name_len = strnlen(searchName, PATH_MAX); | 3237 | name_len = copy_path_name(pSMB->FileName, searchName); |
3276 | name_len++; /* trailing null */ | ||
3277 | strncpy(pSMB->FileName, searchName, name_len); | ||
3278 | } | 3238 | } |
3279 | 3239 | ||
3280 | params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ; | 3240 | params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ; |
@@ -3691,10 +3651,8 @@ queryAclRetry: | |||
3691 | name_len *= 2; | 3651 | name_len *= 2; |
3692 | pSMB->FileName[name_len] = 0; | 3652 | pSMB->FileName[name_len] = 0; |
3693 | pSMB->FileName[name_len+1] = 0; | 3653 | pSMB->FileName[name_len+1] = 0; |
3694 | } else { /* BB improve the check for buffer overruns BB */ | 3654 | } else { |
3695 | name_len = strnlen(searchName, PATH_MAX); | 3655 | name_len = copy_path_name(pSMB->FileName, searchName); |
3696 | name_len++; /* trailing null */ | ||
3697 | strncpy(pSMB->FileName, searchName, name_len); | ||
3698 | } | 3656 | } |
3699 | 3657 | ||
3700 | params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ; | 3658 | params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ; |
@@ -3776,10 +3734,8 @@ setAclRetry: | |||
3776 | PATH_MAX, nls_codepage, remap); | 3734 | PATH_MAX, nls_codepage, remap); |
3777 | name_len++; /* trailing null */ | 3735 | name_len++; /* trailing null */ |
3778 | name_len *= 2; | 3736 | name_len *= 2; |
3779 | } else { /* BB improve the check for buffer overruns BB */ | 3737 | } else { |
3780 | name_len = strnlen(fileName, PATH_MAX); | 3738 | name_len = copy_path_name(pSMB->FileName, fileName); |
3781 | name_len++; /* trailing null */ | ||
3782 | strncpy(pSMB->FileName, fileName, name_len); | ||
3783 | } | 3739 | } |
3784 | params = 6 + name_len; | 3740 | params = 6 + name_len; |
3785 | pSMB->MaxParameterCount = cpu_to_le16(2); | 3741 | pSMB->MaxParameterCount = cpu_to_le16(2); |
@@ -4184,9 +4140,7 @@ QInfRetry: | |||
4184 | name_len++; /* trailing null */ | 4140 | name_len++; /* trailing null */ |
4185 | name_len *= 2; | 4141 | name_len *= 2; |
4186 | } else { | 4142 | } else { |
4187 | name_len = strnlen(search_name, PATH_MAX); | 4143 | name_len = copy_path_name(pSMB->FileName, search_name); |
4188 | name_len++; /* trailing null */ | ||
4189 | strncpy(pSMB->FileName, search_name, name_len); | ||
4190 | } | 4144 | } |
4191 | pSMB->BufferFormat = 0x04; | 4145 | pSMB->BufferFormat = 0x04; |
4192 | name_len++; /* account for buffer type byte */ | 4146 | name_len++; /* account for buffer type byte */ |
@@ -4321,10 +4275,8 @@ QPathInfoRetry: | |||
4321 | PATH_MAX, nls_codepage, remap); | 4275 | PATH_MAX, nls_codepage, remap); |
4322 | name_len++; /* trailing null */ | 4276 | name_len++; /* trailing null */ |
4323 | name_len *= 2; | 4277 | name_len *= 2; |
4324 | } else { /* BB improve the check for buffer overruns BB */ | 4278 | } else { |
4325 | name_len = strnlen(search_name, PATH_MAX); | 4279 | name_len = copy_path_name(pSMB->FileName, search_name); |
4326 | name_len++; /* trailing null */ | ||
4327 | strncpy(pSMB->FileName, search_name, name_len); | ||
4328 | } | 4280 | } |
4329 | 4281 | ||
4330 | params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */; | 4282 | params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */; |
@@ -4490,10 +4442,8 @@ UnixQPathInfoRetry: | |||
4490 | PATH_MAX, nls_codepage, remap); | 4442 | PATH_MAX, nls_codepage, remap); |
4491 | name_len++; /* trailing null */ | 4443 | name_len++; /* trailing null */ |
4492 | name_len *= 2; | 4444 | name_len *= 2; |
4493 | } else { /* BB improve the check for buffer overruns BB */ | 4445 | } else { |
4494 | name_len = strnlen(searchName, PATH_MAX); | 4446 | name_len = copy_path_name(pSMB->FileName, searchName); |
4495 | name_len++; /* trailing null */ | ||
4496 | strncpy(pSMB->FileName, searchName, name_len); | ||
4497 | } | 4447 | } |
4498 | 4448 | ||
4499 | params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */; | 4449 | params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */; |
@@ -4593,17 +4543,16 @@ findFirstRetry: | |||
4593 | pSMB->FileName[name_len+1] = 0; | 4543 | pSMB->FileName[name_len+1] = 0; |
4594 | name_len += 2; | 4544 | name_len += 2; |
4595 | } | 4545 | } |
4596 | } else { /* BB add check for overrun of SMB buf BB */ | 4546 | } else { |
4597 | name_len = strnlen(searchName, PATH_MAX); | 4547 | name_len = copy_path_name(pSMB->FileName, searchName); |
4598 | /* BB fix here and in unicode clause above ie | ||
4599 | if (name_len > buffersize-header) | ||
4600 | free buffer exit; BB */ | ||
4601 | strncpy(pSMB->FileName, searchName, name_len); | ||
4602 | if (msearch) { | 4548 | if (msearch) { |
4603 | pSMB->FileName[name_len] = CIFS_DIR_SEP(cifs_sb); | 4549 | if (WARN_ON_ONCE(name_len > PATH_MAX-2)) |
4604 | pSMB->FileName[name_len+1] = '*'; | 4550 | name_len = PATH_MAX-2; |
4605 | pSMB->FileName[name_len+2] = 0; | 4551 | /* overwrite nul byte */ |
4606 | name_len += 3; | 4552 | pSMB->FileName[name_len-1] = CIFS_DIR_SEP(cifs_sb); |
4553 | pSMB->FileName[name_len] = '*'; | ||
4554 | pSMB->FileName[name_len+1] = 0; | ||
4555 | name_len += 2; | ||
4607 | } | 4556 | } |
4608 | } | 4557 | } |
4609 | 4558 | ||
@@ -4898,10 +4847,8 @@ GetInodeNumberRetry: | |||
4898 | remap); | 4847 | remap); |
4899 | name_len++; /* trailing null */ | 4848 | name_len++; /* trailing null */ |
4900 | name_len *= 2; | 4849 | name_len *= 2; |
4901 | } else { /* BB improve the check for buffer overruns BB */ | 4850 | } else { |
4902 | name_len = strnlen(search_name, PATH_MAX); | 4851 | name_len = copy_path_name(pSMB->FileName, search_name); |
4903 | name_len++; /* trailing null */ | ||
4904 | strncpy(pSMB->FileName, search_name, name_len); | ||
4905 | } | 4852 | } |
4906 | 4853 | ||
4907 | params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ; | 4854 | params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ; |
@@ -5008,9 +4955,7 @@ getDFSRetry: | |||
5008 | name_len++; /* trailing null */ | 4955 | name_len++; /* trailing null */ |
5009 | name_len *= 2; | 4956 | name_len *= 2; |
5010 | } else { /* BB improve the check for buffer overruns BB */ | 4957 | } else { /* BB improve the check for buffer overruns BB */ |
5011 | name_len = strnlen(search_name, PATH_MAX); | 4958 | name_len = copy_path_name(pSMB->RequestFileName, search_name); |
5012 | name_len++; /* trailing null */ | ||
5013 | strncpy(pSMB->RequestFileName, search_name, name_len); | ||
5014 | } | 4959 | } |
5015 | 4960 | ||
5016 | if (ses->server->sign) | 4961 | if (ses->server->sign) |
@@ -5663,10 +5608,8 @@ SetEOFRetry: | |||
5663 | PATH_MAX, cifs_sb->local_nls, remap); | 5608 | PATH_MAX, cifs_sb->local_nls, remap); |
5664 | name_len++; /* trailing null */ | 5609 | name_len++; /* trailing null */ |
5665 | name_len *= 2; | 5610 | name_len *= 2; |
5666 | } else { /* BB improve the check for buffer overruns BB */ | 5611 | } else { |
5667 | name_len = strnlen(file_name, PATH_MAX); | 5612 | name_len = copy_path_name(pSMB->FileName, file_name); |
5668 | name_len++; /* trailing null */ | ||
5669 | strncpy(pSMB->FileName, file_name, name_len); | ||
5670 | } | 5613 | } |
5671 | params = 6 + name_len; | 5614 | params = 6 + name_len; |
5672 | data_count = sizeof(struct file_end_of_file_info); | 5615 | data_count = sizeof(struct file_end_of_file_info); |
@@ -5959,10 +5902,8 @@ SetTimesRetry: | |||
5959 | PATH_MAX, nls_codepage, remap); | 5902 | PATH_MAX, nls_codepage, remap); |
5960 | name_len++; /* trailing null */ | 5903 | name_len++; /* trailing null */ |
5961 | name_len *= 2; | 5904 | name_len *= 2; |
5962 | } else { /* BB improve the check for buffer overruns BB */ | 5905 | } else { |
5963 | name_len = strnlen(fileName, PATH_MAX); | 5906 | name_len = copy_path_name(pSMB->FileName, fileName); |
5964 | name_len++; /* trailing null */ | ||
5965 | strncpy(pSMB->FileName, fileName, name_len); | ||
5966 | } | 5907 | } |
5967 | 5908 | ||
5968 | params = 6 + name_len; | 5909 | params = 6 + name_len; |
@@ -6040,10 +5981,8 @@ SetAttrLgcyRetry: | |||
6040 | PATH_MAX, nls_codepage); | 5981 | PATH_MAX, nls_codepage); |
6041 | name_len++; /* trailing null */ | 5982 | name_len++; /* trailing null */ |
6042 | name_len *= 2; | 5983 | name_len *= 2; |
6043 | } else { /* BB improve the check for buffer overruns BB */ | 5984 | } else { |
6044 | name_len = strnlen(fileName, PATH_MAX); | 5985 | name_len = copy_path_name(pSMB->fileName, fileName); |
6045 | name_len++; /* trailing null */ | ||
6046 | strncpy(pSMB->fileName, fileName, name_len); | ||
6047 | } | 5986 | } |
6048 | pSMB->attr = cpu_to_le16(dos_attrs); | 5987 | pSMB->attr = cpu_to_le16(dos_attrs); |
6049 | pSMB->BufferFormat = 0x04; | 5988 | pSMB->BufferFormat = 0x04; |
@@ -6203,10 +6142,8 @@ setPermsRetry: | |||
6203 | PATH_MAX, nls_codepage, remap); | 6142 | PATH_MAX, nls_codepage, remap); |
6204 | name_len++; /* trailing null */ | 6143 | name_len++; /* trailing null */ |
6205 | name_len *= 2; | 6144 | name_len *= 2; |
6206 | } else { /* BB improve the check for buffer overruns BB */ | 6145 | } else { |
6207 | name_len = strnlen(file_name, PATH_MAX); | 6146 | name_len = copy_path_name(pSMB->FileName, file_name); |
6208 | name_len++; /* trailing null */ | ||
6209 | strncpy(pSMB->FileName, file_name, name_len); | ||
6210 | } | 6147 | } |
6211 | 6148 | ||
6212 | params = 6 + name_len; | 6149 | params = 6 + name_len; |
@@ -6298,10 +6235,8 @@ QAllEAsRetry: | |||
6298 | PATH_MAX, nls_codepage, remap); | 6235 | PATH_MAX, nls_codepage, remap); |
6299 | list_len++; /* trailing null */ | 6236 | list_len++; /* trailing null */ |
6300 | list_len *= 2; | 6237 | list_len *= 2; |
6301 | } else { /* BB improve the check for buffer overruns BB */ | 6238 | } else { |
6302 | list_len = strnlen(searchName, PATH_MAX); | 6239 | list_len = copy_path_name(pSMB->FileName, searchName); |
6303 | list_len++; /* trailing null */ | ||
6304 | strncpy(pSMB->FileName, searchName, list_len); | ||
6305 | } | 6240 | } |
6306 | 6241 | ||
6307 | params = 2 /* level */ + 4 /* reserved */ + list_len /* includes NUL */; | 6242 | params = 2 /* level */ + 4 /* reserved */ + list_len /* includes NUL */; |
@@ -6480,10 +6415,8 @@ SetEARetry: | |||
6480 | PATH_MAX, nls_codepage, remap); | 6415 | PATH_MAX, nls_codepage, remap); |
6481 | name_len++; /* trailing null */ | 6416 | name_len++; /* trailing null */ |
6482 | name_len *= 2; | 6417 | name_len *= 2; |
6483 | } else { /* BB improve the check for buffer overruns BB */ | 6418 | } else { |
6484 | name_len = strnlen(fileName, PATH_MAX); | 6419 | name_len = copy_path_name(pSMB->FileName, fileName); |
6485 | name_len++; /* trailing null */ | ||
6486 | strncpy(pSMB->FileName, fileName, name_len); | ||
6487 | } | 6420 | } |
6488 | 6421 | ||
6489 | params = 6 + name_len; | 6422 | params = 6 + name_len; |
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index ddefddeffd06..5299effa6f7d 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c | |||
@@ -4231,16 +4231,19 @@ build_unc_path_to_root(const struct smb_vol *vol, | |||
4231 | strlen(vol->prepath) + 1 : 0; | 4231 | strlen(vol->prepath) + 1 : 0; |
4232 | unsigned int unc_len = strnlen(vol->UNC, MAX_TREE_SIZE + 1); | 4232 | unsigned int unc_len = strnlen(vol->UNC, MAX_TREE_SIZE + 1); |
4233 | 4233 | ||
4234 | if (unc_len > MAX_TREE_SIZE) | ||
4235 | return ERR_PTR(-EINVAL); | ||
4236 | |||
4234 | full_path = kmalloc(unc_len + pplen + 1, GFP_KERNEL); | 4237 | full_path = kmalloc(unc_len + pplen + 1, GFP_KERNEL); |
4235 | if (full_path == NULL) | 4238 | if (full_path == NULL) |
4236 | return ERR_PTR(-ENOMEM); | 4239 | return ERR_PTR(-ENOMEM); |
4237 | 4240 | ||
4238 | strncpy(full_path, vol->UNC, unc_len); | 4241 | memcpy(full_path, vol->UNC, unc_len); |
4239 | pos = full_path + unc_len; | 4242 | pos = full_path + unc_len; |
4240 | 4243 | ||
4241 | if (pplen) { | 4244 | if (pplen) { |
4242 | *pos = CIFS_DIR_SEP(cifs_sb); | 4245 | *pos = CIFS_DIR_SEP(cifs_sb); |
4243 | strncpy(pos + 1, vol->prepath, pplen); | 4246 | memcpy(pos + 1, vol->prepath, pplen); |
4244 | pos += pplen; | 4247 | pos += pplen; |
4245 | } | 4248 | } |
4246 | 4249 | ||
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index f26a48dd2e39..be424e81e3ad 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c | |||
@@ -69,11 +69,10 @@ cifs_build_path_to_root(struct smb_vol *vol, struct cifs_sb_info *cifs_sb, | |||
69 | return full_path; | 69 | return full_path; |
70 | 70 | ||
71 | if (dfsplen) | 71 | if (dfsplen) |
72 | strncpy(full_path, tcon->treeName, dfsplen); | 72 | memcpy(full_path, tcon->treeName, dfsplen); |
73 | full_path[dfsplen] = CIFS_DIR_SEP(cifs_sb); | 73 | full_path[dfsplen] = CIFS_DIR_SEP(cifs_sb); |
74 | strncpy(full_path + dfsplen + 1, vol->prepath, pplen); | 74 | memcpy(full_path + dfsplen + 1, vol->prepath, pplen); |
75 | convert_delimiter(full_path, CIFS_DIR_SEP(cifs_sb)); | 75 | convert_delimiter(full_path, CIFS_DIR_SEP(cifs_sb)); |
76 | full_path[dfsplen + pplen] = 0; /* add trailing null */ | ||
77 | return full_path; | 76 | return full_path; |
78 | } | 77 | } |
79 | 78 | ||
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c index f383877a6511..5ad83bdb9bea 100644 --- a/fs/cifs/misc.c +++ b/fs/cifs/misc.c | |||
@@ -1011,3 +1011,25 @@ void extract_unc_hostname(const char *unc, const char **h, size_t *len) | |||
1011 | *h = unc; | 1011 | *h = unc; |
1012 | *len = end - unc; | 1012 | *len = end - unc; |
1013 | } | 1013 | } |
1014 | |||
1015 | /** | ||
1016 | * copy_path_name - copy src path to dst, possibly truncating | ||
1017 | * | ||
1018 | * returns number of bytes written (including trailing nul) | ||
1019 | */ | ||
1020 | int copy_path_name(char *dst, const char *src) | ||
1021 | { | ||
1022 | int name_len; | ||
1023 | |||
1024 | /* | ||
1025 | * PATH_MAX includes nul, so if strlen(src) >= PATH_MAX it | ||
1026 | * will truncate and strlen(dst) will be PATH_MAX-1 | ||
1027 | */ | ||
1028 | name_len = strscpy(dst, src, PATH_MAX); | ||
1029 | if (WARN_ON_ONCE(name_len < 0)) | ||
1030 | name_len = PATH_MAX-1; | ||
1031 | |||
1032 | /* we count the trailing nul */ | ||
1033 | name_len++; | ||
1034 | return name_len; | ||
1035 | } | ||
diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c index dcd49ad60c83..4c764ff7edd2 100644 --- a/fs/cifs/sess.c +++ b/fs/cifs/sess.c | |||
@@ -159,13 +159,16 @@ static void ascii_ssetup_strings(char **pbcc_area, struct cifs_ses *ses, | |||
159 | const struct nls_table *nls_cp) | 159 | const struct nls_table *nls_cp) |
160 | { | 160 | { |
161 | char *bcc_ptr = *pbcc_area; | 161 | char *bcc_ptr = *pbcc_area; |
162 | int len; | ||
162 | 163 | ||
163 | /* copy user */ | 164 | /* copy user */ |
164 | /* BB what about null user mounts - check that we do this BB */ | 165 | /* BB what about null user mounts - check that we do this BB */ |
165 | /* copy user */ | 166 | /* copy user */ |
166 | if (ses->user_name != NULL) { | 167 | if (ses->user_name != NULL) { |
167 | strncpy(bcc_ptr, ses->user_name, CIFS_MAX_USERNAME_LEN); | 168 | len = strscpy(bcc_ptr, ses->user_name, CIFS_MAX_USERNAME_LEN); |
168 | bcc_ptr += strnlen(ses->user_name, CIFS_MAX_USERNAME_LEN); | 169 | if (WARN_ON_ONCE(len < 0)) |
170 | len = CIFS_MAX_USERNAME_LEN - 1; | ||
171 | bcc_ptr += len; | ||
169 | } | 172 | } |
170 | /* else null user mount */ | 173 | /* else null user mount */ |
171 | *bcc_ptr = 0; | 174 | *bcc_ptr = 0; |
@@ -173,8 +176,10 @@ static void ascii_ssetup_strings(char **pbcc_area, struct cifs_ses *ses, | |||
173 | 176 | ||
174 | /* copy domain */ | 177 | /* copy domain */ |
175 | if (ses->domainName != NULL) { | 178 | if (ses->domainName != NULL) { |
176 | strncpy(bcc_ptr, ses->domainName, CIFS_MAX_DOMAINNAME_LEN); | 179 | len = strscpy(bcc_ptr, ses->domainName, CIFS_MAX_DOMAINNAME_LEN); |
177 | bcc_ptr += strnlen(ses->domainName, CIFS_MAX_DOMAINNAME_LEN); | 180 | if (WARN_ON_ONCE(len < 0)) |
181 | len = CIFS_MAX_DOMAINNAME_LEN - 1; | ||
182 | bcc_ptr += len; | ||
178 | } /* else we will send a null domain name | 183 | } /* else we will send a null domain name |
179 | so the server will default to its own domain */ | 184 | so the server will default to its own domain */ |
180 | *bcc_ptr = 0; | 185 | *bcc_ptr = 0; |
@@ -242,9 +247,10 @@ static void decode_ascii_ssetup(char **pbcc_area, __u16 bleft, | |||
242 | 247 | ||
243 | kfree(ses->serverOS); | 248 | kfree(ses->serverOS); |
244 | 249 | ||
245 | ses->serverOS = kzalloc(len + 1, GFP_KERNEL); | 250 | ses->serverOS = kmalloc(len + 1, GFP_KERNEL); |
246 | if (ses->serverOS) { | 251 | if (ses->serverOS) { |
247 | strncpy(ses->serverOS, bcc_ptr, len); | 252 | memcpy(ses->serverOS, bcc_ptr, len); |
253 | ses->serverOS[len] = 0; | ||
248 | if (strncmp(ses->serverOS, "OS/2", 4) == 0) | 254 | if (strncmp(ses->serverOS, "OS/2", 4) == 0) |
249 | cifs_dbg(FYI, "OS/2 server\n"); | 255 | cifs_dbg(FYI, "OS/2 server\n"); |
250 | } | 256 | } |
@@ -258,9 +264,11 @@ static void decode_ascii_ssetup(char **pbcc_area, __u16 bleft, | |||
258 | 264 | ||
259 | kfree(ses->serverNOS); | 265 | kfree(ses->serverNOS); |
260 | 266 | ||
261 | ses->serverNOS = kzalloc(len + 1, GFP_KERNEL); | 267 | ses->serverNOS = kmalloc(len + 1, GFP_KERNEL); |
262 | if (ses->serverNOS) | 268 | if (ses->serverNOS) { |
263 | strncpy(ses->serverNOS, bcc_ptr, len); | 269 | memcpy(ses->serverNOS, bcc_ptr, len); |
270 | ses->serverNOS[len] = 0; | ||
271 | } | ||
264 | 272 | ||
265 | bcc_ptr += len + 1; | 273 | bcc_ptr += len + 1; |
266 | bleft -= len + 1; | 274 | bleft -= len + 1; |