/* *MakesurethatthisreallyisanSMB,thatitisaresponse, *andthatthemessageidsmatch.
*/ if ((shdr->ProtocolId == SMB2_PROTO_NUMBER) &&
(mid == wire_mid)) { if (shdr->Flags & SMB2_FLAGS_SERVER_TO_REDIR) return0; else { /* only one valid case where server sends us request */ if (shdr->Command == SMB2_OPLOCK_BREAK) return0; else
cifs_dbg(VFS, "Received Request not response\n");
}
} else { /* bad signature or mid */ if (shdr->ProtocolId != SMB2_PROTO_NUMBER)
cifs_dbg(VFS, "Bad protocol string signature header %x\n",
le32_to_cpu(shdr->ProtocolId)); if (mid != wire_mid)
cifs_dbg(VFS, "Mids do not match: %llu and %llu\n",
mid, wire_mid);
}
cifs_dbg(VFS, "Bad SMB detected. The Mid=%llu\n", wire_mid); return1;
}
/* Verify that at least minimal negotiate contexts fit within frame */ if (len < nc_offset + (neg_count * sizeof(struct smb2_neg_context))) {
pr_warn_once("negotiate context goes beyond end\n"); return0;
}
cifs_dbg(FYI, "length of negcontexts %d pad %d\n",
len - nc_offset, size_of_pad_before_neg_ctxts);
/* length of negcontexts including pad from end of sec blob to them */ return (len - nc_offset) + size_of_pad_before_neg_ctxts;
}
/* decrypt frame now that it is completely read in */
spin_lock(&cifs_tcp_ses_lock);
list_for_each_entry(iter, &pserver->smb_ses_list, smb_ses_list) { if (iter->Suid == le64_to_cpu(thdr->SessionId)) {
ses = iter; break;
}
}
spin_unlock(&cifs_tcp_ses_lock); if (!ses) {
cifs_dbg(VFS, "no decryption - session id not found\n"); return1;
}
}
mid = le64_to_cpu(shdr->MessageId); if (check_smb2_hdr(shdr, mid)) return1;
if (len < pdu_size) { if ((len >= hdr_size)
&& (shdr->Status != 0)) {
pdu->StructureSize2 = 0; /* *AswithSMB/CIFS,onsomeerrorcasesserversmay *notreturnwctproperly
*/ return0;
} else {
cifs_dbg(VFS, "Length less than SMB header size\n");
} return1;
} if (len > CIFSMaxBufSize + MAX_SMB2_HDR_SIZE) {
cifs_dbg(VFS, "SMB length greater than maximum, mid=%llu\n",
mid); return1;
}
if (smb2_rsp_struct_sizes[command] != pdu->StructureSize2) { if (command != SMB2_OPLOCK_BREAK_HE && (shdr->Status == 0 ||
pdu->StructureSize2 != SMB2_ERROR_STRUCTURE_SIZE2_LE)) { /* error packets have 9 byte structure size */
cifs_dbg(VFS, "Invalid response size %u for command %d\n",
le16_to_cpu(pdu->StructureSize2), command); return1;
} elseif (command == SMB2_OPLOCK_BREAK_HE
&& (shdr->Status == 0)
&& (le16_to_cpu(pdu->StructureSize2) != 44)
&& (le16_to_cpu(pdu->StructureSize2) != 36)) { /* special case for SMB2.1 lease break message */
cifs_dbg(VFS, "Invalid response size %d for oplock break\n",
le16_to_cpu(pdu->StructureSize2)); return1;
}
}
calc_len = smb2_calc_size(buf);
/* For SMB2_IOCTL, OutputOffset and OutputLength are optional, so might
* be 0, and not a real miscalculation */ if (command == SMB2_IOCTL_HE && calc_len == 0) return0;
if (command == SMB2_NEGOTIATE_HE)
calc_len += get_neg_ctxt_len(shdr, len, calc_len);
if (len != calc_len) { /* create failed on symlink */ if (command == SMB2_CREATE_HE &&
shdr->Status == STATUS_STOPPED_ON_SYMLINK) return0; /* Windows 7 server returns 24 bytes more */ if (calc_len + 24 == len && command == SMB2_OPLOCK_BREAK_HE) return0; /* server can return one byte more due to implied bcc[0] */ if (calc_len == len + 1) return0;
/* *Somewindowsservers(win2016)willpadalsothefinal *PDUinacompoundto8bytes.
*/ if (ALIGN(calc_len, 8) == len) return0;
/* error responses do not have data area */ if (shdr->Status && shdr->Status != STATUS_MORE_PROCESSING_REQUIRED &&
(((struct smb2_err_rsp *)shdr)->StructureSize) ==
SMB2_ERROR_STRUCTURE_SIZE2_LE) return NULL;
/* return pointer to beginning of data area, ie offset from SMB start */ if (*off > 0 && *len > 0) return (char *)shdr + *off; return NULL;
}
/* *CalculatethesizeoftheSMBmessagebasedonthefixedheader *portion,thenumberofwordparametersandthedataportionofthemessage.
*/ unsignedint
smb2_calc_size(void *buf)
{ struct smb2_pdu *pdu = buf; struct smb2_hdr *shdr = &pdu->hdr; int offset; /* the offset from the beginning of SMB to data area */ int data_length; /* the length of the variable length data area */ /* Structure Size has already been checked to make sure it is 64 */ int len = le16_to_cpu(shdr->StructureSize);
/* *StructureSize2,ielengthoffixedparameterareahasalready *beencheckedtomakesureitisthecorrectlength.
*/
len += le16_to_cpu(pdu->StructureSize2);
if (has_smb2_data_area[le16_to_cpu(shdr->Command)] == false) goto calc_size_exit;
/* If server is a channel, select the primary channel */
pserver = SERVER_IS_CHAN(server) ? server->primary_server : server;
/* look up tcon based on tid & uid */
spin_lock(&cifs_tcp_ses_lock);
list_for_each_entry(ses, &pserver->smb_ses_list, smb_ses_list) { if (cifs_ses_exiting(ses)) continue;
list_for_each_entry(tcon, &ses->tcon_list, tcon_list) {
if (tcon->ses) {
server = tcon->ses->server;
cifs_server_dbg(FYI, "tid=0x%x: tcon is closing, skipping async close retry of fid %llu %llu\n",
tcon->tid, persistent_fid, volatile_fid);
}
/** *smb311_update_preauth_hash-update@seshashwiththepacketdatain@iov * *Assumes@iovdoesnotcontaintherfc1002lengthandiov[0]hasthe *SMB2header. * *@ses:serversessionstructure *@server:pointertoserverinfo *@iov:arraycontainingtheSMBrequestwewillsendtotheserver *@nvec:numberofarrayentriesfortheiov
*/ int
smb311_update_preauth_hash(struct cifs_ses *ses, struct TCP_Server_Info *server, struct kvec *iov, int nvec)
{ int i, rc; struct smb2_hdr *hdr; struct shash_desc *sha512 = NULL;
hdr = (struct smb2_hdr *)iov[0].iov_base; /* neg prot are always taken */ if (hdr->Command == SMB2_NEGOTIATE) goto ok;
/* *Ifweprocessacommandwhichwasn'tanegprotitmeansthe *negprotwasalreadydone,sotheserverdialectwasset *andwecantestit.Preauthrequires3.1.1fornow.
*/ if (server->dialect != SMB311_PROT_ID) return0;
if (hdr->Command != SMB2_SESSION_SETUP) return0;
/* skip last sess setup response */ if ((hdr->Flags & SMB2_FLAGS_SERVER_TO_REDIR)
&& (hdr->Status == NT_STATUS_OK
|| (hdr->Status !=
cpu_to_le32(NT_STATUS_MORE_PROCESSING_REQUIRED)))) return0;
ok:
rc = smb311_crypto_shash_allocate(server); if (rc) return rc;
sha512 = server->secmech.sha512;
rc = crypto_shash_init(sha512); if (rc) {
cifs_dbg(VFS, "%s: Could not init sha512 shash\n", __func__); return rc;
}
rc = crypto_shash_update(sha512, ses->preauth_sha_hash,
SMB2_PREAUTH_HASH_SIZE); if (rc) {
cifs_dbg(VFS, "%s: Could not update sha512 shash\n", __func__); return rc;
}
for (i = 0; i < nvec; i++) {
rc = crypto_shash_update(sha512, iov[i].iov_base, iov[i].iov_len); if (rc) {
cifs_dbg(VFS, "%s: Could not update sha512 shash\n",
__func__); return rc;
}
}
rc = crypto_shash_final(sha512, ses->preauth_sha_hash); if (rc) {
cifs_dbg(VFS, "%s: Could not finalize sha512 shash\n",
__func__); return rc;
}
return0;
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.15 Sekunden
(vorverarbeitet am 2026-09-30)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.