Commit cc73df2b authored by Steve French's avatar Steve French Committed by Steve French

[CIFS] Various fixes to bugs pointed out by Stanford checker SWAT tool (mostly...

[CIFS] Various fixes to bugs pointed out by Stanford checker SWAT tool (mostly missing checks on small kmallocs and some
out of order null pointer checks)

Signed-off-by: Steve French (sfrench@us.ibm.com)
parent 4e3d5bc1
......@@ -375,7 +375,7 @@ asn1_subid_decode(struct asn1_ctx *ctx, unsigned long *subid)
return 1;
}
static unsigned char
static int
asn1_oid_decode(struct asn1_ctx *ctx,
unsigned char *eoc, unsigned long **oid, unsigned int *len)
{
......@@ -454,11 +454,11 @@ decode_negTokenInit(unsigned char *security_blob, int length,
struct asn1_ctx ctx;
unsigned char *end;
unsigned char *sequence_end;
unsigned long *oid;
unsigned long *oid = NULL;
unsigned int cls, con, tag, oidlen, rc;
int use_ntlmssp = FALSE;
*secType = NTLM; /* BB eventually make Kerberos or NLTMSSP the default */
*secType = NTLM; /* BB eventually make Kerberos or NLTMSSP the default */
/* cifs_dump_mem(" Received SecBlob ", security_blob, length); */
......@@ -543,16 +543,19 @@ decode_negTokenInit(unsigned char *security_blob, int length,
return 0;
}
if ((tag == ASN1_OJI) && (con == ASN1_PRI)) {
asn1_oid_decode(&ctx, end, &oid, &oidlen);
cFYI(1,
("OID len = %d oid = 0x%lx 0x%lx 0x%lx 0x%lx",
oidlen, *oid, *(oid + 1), *(oid + 2),
*(oid + 3)));
rc = compare_oid(oid, oidlen, NTLMSSP_OID,
rc = asn1_oid_decode(&ctx, end, &oid, &oidlen);
if(rc) {
cFYI(1,
("OID len = %d oid = 0x%lx 0x%lx 0x%lx 0x%lx",
oidlen, *oid, *(oid + 1), *(oid + 2),
*(oid + 3)));
rc = compare_oid(oid, oidlen, NTLMSSP_OID,
NTLMSSP_OID_LEN);
kfree(oid);
if (rc)
use_ntlmssp = TRUE;
if(oid)
kfree(oid);
if (rc)
use_ntlmssp = TRUE;
}
} else {
cFYI(1,("This should be an oid what is going on? "));
}
......
......@@ -255,12 +255,14 @@ cifs_show_options(struct seq_file *s, struct vfsmount *m)
if (cifs_sb) {
if (cifs_sb->tcon) {
seq_printf(s, ",unc=%s", cifs_sb->tcon->treeName);
if ((cifs_sb->tcon->ses) && (cifs_sb->tcon->ses->userName))
seq_printf(s, ",username=%s",
if (cifs_sb->tcon->ses) {
if (cifs_sb->tcon->ses->userName)
seq_printf(s, ",username=%s",
cifs_sb->tcon->ses->userName);
if(cifs_sb->tcon->ses->domainName)
seq_printf(s, ",domain=%s",
cifs_sb->tcon->ses->domainName);
if(cifs_sb->tcon->ses->domainName)
seq_printf(s, ",domain=%s",
cifs_sb->tcon->ses->domainName);
}
}
seq_printf(s, ",rsize=%d",cifs_sb->rsize);
seq_printf(s, ",wsize=%d",cifs_sb->wsize);
......
......@@ -366,9 +366,12 @@ CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses)
rc = smb_init(SMB_COM_LOGOFF_ANDX, 2, NULL /* no tcon anymore */,
(void **) &pSMB, (void **) &smb_buffer_response);
if(ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
if(ses->server) {
if(ses->server->secMode &
(SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
}
if (rc) {
up(&ses->sesSem);
......@@ -2174,6 +2177,10 @@ CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses,
/* BB add check for name_len bigger than bcc */
*targetUNCs =
kmalloc(name_len+1+ (*number_of_UNC_in_array),GFP_KERNEL);
if(*targetUNCs == NULL) {
rc = -ENOMEM;
goto GetDFSRefExit;
}
/* copy the ref strings */
referrals =
(struct dfs_referral_level_3 *)
......@@ -2197,6 +2204,7 @@ CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses,
}
}
GetDFSRefExit:
if (pSMB)
cifs_buf_release(pSMB);
......
......@@ -1506,15 +1506,18 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
SESSION_SETUP_ANDX *pSMB;
SESSION_SETUP_ANDX *pSMBr;
char *bcc_ptr;
char *user = ses->userName;
char *domain = ses->domainName;
char *user;
char *domain;
int rc = 0;
int remaining_words = 0;
int bytes_returned = 0;
int len;
cFYI(1, ("In sesssetup "));
if(ses == NULL)
return -EINVAL;
user = ses->userName;
domain = ses->domainName;
smb_buffer = cifs_buf_get();
if (smb_buffer == 0) {
return -ENOMEM;
......@@ -1633,111 +1636,104 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
pSMBr->resp.Action = le16_to_cpu(pSMBr->resp.Action);
if (pSMBr->resp.Action & GUEST_LOGIN)
cFYI(1, (" Guest login")); /* do we want to mark SesInfo struct ? */
if (ses) {
ses->Suid = smb_buffer_response->Uid; /* UID left in wire format (le) */
cFYI(1, ("UID = %d ", ses->Suid));
ses->Suid = smb_buffer_response->Uid; /* UID left in wire format (le) */
cFYI(1, ("UID = %d ", ses->Suid));
/* response can have either 3 or 4 word count - Samba sends 3 */
bcc_ptr = pByteArea(smb_buffer_response);
if ((pSMBr->resp.hdr.WordCount == 3)
|| ((pSMBr->resp.hdr.WordCount == 4)
&& (pSMBr->resp.SecurityBlobLength <
pSMBr->resp.ByteCount))) {
if (pSMBr->resp.hdr.WordCount == 4)
bcc_ptr +=
pSMBr->resp.SecurityBlobLength;
if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
if ((long) (bcc_ptr) % 2) {
remaining_words =
(BCC(smb_buffer_response)
- 1) / 2;
bcc_ptr++; /* Unicode strings must be word aligned */
} else {
remaining_words =
BCC
(smb_buffer_response) / 2;
}
len =
UniStrnlen((wchar_t *) bcc_ptr,
remaining_words - 1);
bcc_ptr = pByteArea(smb_buffer_response);
if ((pSMBr->resp.hdr.WordCount == 3)
|| ((pSMBr->resp.hdr.WordCount == 4)
&& (pSMBr->resp.SecurityBlobLength <
pSMBr->resp.ByteCount))) {
if (pSMBr->resp.hdr.WordCount == 4)
bcc_ptr +=
pSMBr->resp.SecurityBlobLength;
if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
if ((long) (bcc_ptr) % 2) {
remaining_words =
(BCC(smb_buffer_response) - 1) /2;
bcc_ptr++; /* Unicode strings must be word aligned */
} else {
remaining_words =
BCC(smb_buffer_response) / 2;
}
len =
UniStrnlen((wchar_t *) bcc_ptr,
remaining_words - 1);
/* We look for obvious messed up bcc or strings in response so we do not go off
the end since (at least) WIN2K and Windows XP have a major bug in not null
terminating last Unicode string in response */
ses->serverOS = cifs_kcalloc(2 * (len + 1), GFP_KERNEL);
cifs_strfromUCS_le(ses->serverOS,
(wchar_t *)bcc_ptr, len,nls_codepage);
ses->serverOS = cifs_kcalloc(2 * (len + 1), GFP_KERNEL);
cifs_strfromUCS_le(ses->serverOS,
(wchar_t *)bcc_ptr, len,nls_codepage);
bcc_ptr += 2 * (len + 1);
remaining_words -= len + 1;
ses->serverOS[2 * len] = 0;
ses->serverOS[1 + (2 * len)] = 0;
if (remaining_words > 0) {
len = UniStrnlen((wchar_t *)bcc_ptr,
remaining_words-1);
ses->serverNOS =cifs_kcalloc(2 * (len + 1),GFP_KERNEL);
cifs_strfromUCS_le(ses->serverNOS,
(wchar_t *)bcc_ptr,len,nls_codepage);
bcc_ptr += 2 * (len + 1);
ses->serverNOS[2 * len] = 0;
ses->serverNOS[1 + (2 * len)] = 0;
remaining_words -= len + 1;
ses->serverOS[2 * len] = 0;
ses->serverOS[1 + (2 * len)] = 0;
if (remaining_words > 0) {
len = UniStrnlen((wchar_t *)bcc_ptr,
remaining_words
- 1);
ses->serverNOS =cifs_kcalloc(2 * (len + 1),GFP_KERNEL);
cifs_strfromUCS_le(ses->serverNOS,
(wchar_t *)bcc_ptr,len,nls_codepage);
bcc_ptr += 2 * (len + 1);
ses->serverNOS[2 * len] = 0;
ses->serverNOS[1 + (2 * len)] = 0;
remaining_words -= len + 1;
if (remaining_words > 0) {
len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words);
len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words);
/* last string is not always null terminated (for e.g. for Windows XP & 2000) */
ses->serverDomain =
cifs_kcalloc(2*(len+1),GFP_KERNEL);
cifs_strfromUCS_le(ses->serverDomain,
(wchar_t *)bcc_ptr,len,nls_codepage);
bcc_ptr += 2 * (len + 1);
ses->serverDomain[2*len] = 0;
ses->serverDomain[1+(2*len)] = 0;
} /* else no more room so create dummy domain string */
else
ses->serverDomain =
cifs_kcalloc(2,
GFP_KERNEL);
} else { /* no room so create dummy domain and NOS string */
ses->serverDomain =
cifs_kcalloc(2, GFP_KERNEL);
ses->serverNOS =
cifs_kcalloc(2, GFP_KERNEL);
}
} else { /* ASCII */
len = strnlen(bcc_ptr, 1024);
if (((long) bcc_ptr + len) - (long)
pByteArea(smb_buffer_response)
cifs_kcalloc(2*(len+1),GFP_KERNEL);
cifs_strfromUCS_le(ses->serverDomain,
(wchar_t *)bcc_ptr,len,nls_codepage);
bcc_ptr += 2 * (len + 1);
ses->serverDomain[2*len] = 0;
ses->serverDomain[1+(2*len)] = 0;
} /* else no more room so create dummy domain string */
else
ses->serverDomain =
cifs_kcalloc(2,
GFP_KERNEL);
} else { /* no room so create dummy domain and NOS string */
ses->serverDomain =
cifs_kcalloc(2, GFP_KERNEL);
ses->serverNOS =
cifs_kcalloc(2, GFP_KERNEL);
}
} else { /* ASCII */
len = strnlen(bcc_ptr, 1024);
if (((long) bcc_ptr + len) - (long)
pByteArea(smb_buffer_response)
<= BCC(smb_buffer_response)) {
ses->serverOS = cifs_kcalloc(len + 1,GFP_KERNEL);
strncpy(ses->serverOS,bcc_ptr, len);
ses->serverOS = cifs_kcalloc(len + 1,GFP_KERNEL);
strncpy(ses->serverOS,bcc_ptr, len);
bcc_ptr += len;
bcc_ptr[0] = 0; /* null terminate the string */
bcc_ptr++;
bcc_ptr += len;
bcc_ptr[0] = 0; /* null terminate the string */
bcc_ptr++;
len = strnlen(bcc_ptr, 1024);
ses->serverNOS = cifs_kcalloc(len + 1,GFP_KERNEL);
strncpy(ses->serverNOS, bcc_ptr, len);
bcc_ptr += len;
bcc_ptr[0] = 0;
bcc_ptr++;
len = strnlen(bcc_ptr, 1024);
ses->serverNOS = cifs_kcalloc(len + 1,GFP_KERNEL);
strncpy(ses->serverNOS, bcc_ptr, len);
bcc_ptr += len;
bcc_ptr[0] = 0;
bcc_ptr++;
len = strnlen(bcc_ptr, 1024);
ses->serverDomain = cifs_kcalloc(len + 1,GFP_KERNEL);
strncpy(ses->serverDomain, bcc_ptr, len);
bcc_ptr += len;
bcc_ptr[0] = 0;
bcc_ptr++;
} else
cFYI(1,
("Variable field of length %d extends beyond end of smb ",
len));
}
} else {
cERROR(1,
(" Security Blob Length extends beyond end of SMB"));
len = strnlen(bcc_ptr, 1024);
ses->serverDomain = cifs_kcalloc(len + 1,GFP_KERNEL);
strncpy(ses->serverDomain, bcc_ptr, len);
bcc_ptr += len;
bcc_ptr[0] = 0;
bcc_ptr++;
} else
cFYI(1,
("Variable field of length %d extends beyond end of smb ",
len));
}
} else {
cERROR(1, ("No session structure passed in."));
cERROR(1,
(" Security Blob Length extends beyond end of SMB"));
}
} else {
cERROR(1,
......@@ -1762,14 +1758,18 @@ CIFSSpnegoSessSetup(unsigned int xid, struct cifsSesInfo *ses,
SESSION_SETUP_ANDX *pSMB;
SESSION_SETUP_ANDX *pSMBr;
char *bcc_ptr;
char *user = ses->userName;
char *domain = ses->domainName;
char *user;
char *domain;
int rc = 0;
int remaining_words = 0;
int bytes_returned = 0;
int len;
cFYI(1, ("In spnego sesssetup "));
if(ses == NULL)
return -EINVAL;
user = ses->userName;
domain = ses->domainName;
smb_buffer = cifs_buf_get();
if (smb_buffer == 0) {
......@@ -2021,7 +2021,7 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
SESSION_SETUP_ANDX *pSMB;
SESSION_SETUP_ANDX *pSMBr;
char *bcc_ptr;
char *domain = ses->domainName;
char *domain;
int rc = 0;
int remaining_words = 0;
int bytes_returned = 0;
......@@ -2031,6 +2031,9 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
PCHALLENGE_MESSAGE SecurityBlob2;
cFYI(1, ("In NTLMSSP sesssetup (negotiate) "));
if(ses == NULL)
return -EINVAL;
domain = ses->domainName;
*pNTLMv2_flag = FALSE;
smb_buffer = cifs_buf_get();
if (smb_buffer == 0) {
......@@ -2361,8 +2364,8 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
SESSION_SETUP_ANDX *pSMB;
SESSION_SETUP_ANDX *pSMBr;
char *bcc_ptr;
char *user = ses->userName;
char *domain = ses->domainName;
char *user;
char *domain;
int rc = 0;
int remaining_words = 0;
int bytes_returned = 0;
......@@ -2371,7 +2374,10 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
PAUTHENTICATE_MESSAGE SecurityBlob;
cFYI(1, ("In NTLMSSPSessSetup (Authenticate)"));
if(ses == NULL)
return -EINVAL;
user = ses->userName;
domain = ses->domainName;
smb_buffer = cifs_buf_get();
if (smb_buffer == 0) {
return -ENOMEM;
......
......@@ -148,7 +148,7 @@ cifs_open(struct inode *inode, struct file *file)
and the first handle has writebehind data, we might be
able to simply do a filemap_fdatawrite/filemap_fdatawait first */
buf = kmalloc(sizeof(FILE_ALL_INFO),GFP_KERNEL);
if(buf==0) {
if(buf== NULL) {
if (full_path)
kfree(full_path);
FreeXid(xid);
......@@ -1687,8 +1687,12 @@ cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
}
data = kmalloc(bufsize, GFP_KERNEL);
pfindData = (FILE_DIRECTORY_INFO *) data;
if(data == NULL) {
FreeXid(xid);
return -ENOMEM;
}
if(file->f_dentry == NULL) {
kfree(data);
FreeXid(xid);
return -EIO;
}
......@@ -1696,7 +1700,11 @@ cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
full_path = build_wildcard_path_from_dentry(file->f_dentry);
up(&file->f_dentry->d_sb->s_vfs_rename_sem);
if(full_path == NULL) {
kfree(data);
FreeXid(xid);
return -ENOMEM;
}
cFYI(1, ("Full path: %s start at: %lld ", full_path, file->f_pos));
switch ((int) file->f_pos) {
......@@ -1784,6 +1792,10 @@ cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
cFYI(1,("Last file: %s with name %d bytes long",
lastFindData->FileName,
cifsFile->resume_name_length));
if(cifsFile->search_resume_name == NULL) {
rc = -ENOMEM;
break;
}
memcpy(cifsFile->search_resume_name,
lastFindData->FileName,
cifsFile->resume_name_length);
......@@ -1813,6 +1825,10 @@ cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
cFYI(1,("Last file: %s with name %d bytes long",
pfindDataUnix->FileName,
cifsFile->resume_name_length));
if(cifsFile->search_resume_name == NULL) {
rc = -ENOMEM;
break;
}
memcpy(cifsFile->search_resume_name,
pfindDataUnix->FileName,
cifsFile->resume_name_length);
......@@ -1966,6 +1982,11 @@ cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
cFYI(1,("Last file: %s with name %d bytes long",
lastFindData->FileName,
cifsFile->resume_name_length));
if(cifsFile->search_resume_name == NULL) {
rc = -ENOMEM;
break;
}
memcpy(cifsFile->search_resume_name,
lastFindData->FileName,
cifsFile->resume_name_length);
......@@ -2001,6 +2022,10 @@ cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
cFYI(1,("fnext last file: %s with name %d bytes long",
pfindDataUnix->FileName,
cifsFile->resume_name_length));
if(cifsFile->search_resume_name == NULL) {
rc = -ENOMEM;
break;
}
memcpy(cifsFile->search_resume_name,
pfindDataUnix->FileName,
cifsFile->resume_name_length);
......
......@@ -276,7 +276,7 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ ,
}
if (treeCon->Flags & SMB_SHARE_IS_IN_DFS)
buffer->Flags2 |= SMBFLG2_DFS;
if(treeCon->ses->server)
if((treeCon->ses) && (treeCon->ses->server))
if(treeCon->ses->server->secMode &
(SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment