aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeff Layton <jlayton@redhat.com>2012-09-18 19:20:34 -0400
committerSteve French <smfrench@gmail.com>2012-09-24 22:46:30 -0400
commitbf5ea0e2f29b00d4fe5f203d8e59120f797ce451 (patch)
treeaddbc8640de6368c2f13aca0bdafa63a64b0c3b9
parent6fc05c25ca35e65ee1759dd803f23576a268f5ec (diff)
cifs: change signing routines to deal with smb_rqst structs
We need a way to represent a call to be sent on the wire that does not require having all of the page data kmapped. Behold the smb_rqst struct. This new struct represents an array of kvecs immediately followed by an array of pages. Convert the signing routines to use these structs under the hood and turn the existing functions for this into wrappers around that. For now, we're just changing these functions to take different args. Later, we'll teach them how to deal with arrays of pages. Reviewed-by: Pavel Shilovsky <pshilovsky@samba.org> Signed-off-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: Steve French <smfrench@gmail.com>
-rw-r--r--fs/cifs/cifsencrypt.c26
-rw-r--r--fs/cifs/cifsglob.h14
-rw-r--r--fs/cifs/cifsproto.h7
-rw-r--r--fs/cifs/cifssmb.c7
-rw-r--r--fs/cifs/transport.c4
5 files changed, 44 insertions, 14 deletions
diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c
index 724738c1a560..af520522ef20 100644
--- a/fs/cifs/cifsencrypt.c
+++ b/fs/cifs/cifsencrypt.c
@@ -37,11 +37,13 @@
37 * the sequence number before this function is called. Also, this function 37 * the sequence number before this function is called. Also, this function
38 * should be called with the server->srv_mutex held. 38 * should be called with the server->srv_mutex held.
39 */ 39 */
40static int cifs_calc_signature(const struct kvec *iov, int n_vec, 40static int cifs_calc_signature(struct smb_rqst *rqst,
41 struct TCP_Server_Info *server, char *signature) 41 struct TCP_Server_Info *server, char *signature)
42{ 42{
43 int i; 43 int i;
44 int rc; 44 int rc;
45 struct kvec *iov = rqst->rq_iov;
46 int n_vec = rqst->rq_nvec;
45 47
46 if (iov == NULL || signature == NULL || server == NULL) 48 if (iov == NULL || signature == NULL || server == NULL)
47 return -EINVAL; 49 return -EINVAL;
@@ -99,12 +101,12 @@ static int cifs_calc_signature(const struct kvec *iov, int n_vec,
99} 101}
100 102
101/* must be called with server->srv_mutex held */ 103/* must be called with server->srv_mutex held */
102int cifs_sign_smbv(struct kvec *iov, int n_vec, struct TCP_Server_Info *server, 104int cifs_sign_rqst(struct smb_rqst *rqst, struct TCP_Server_Info *server,
103 __u32 *pexpected_response_sequence_number) 105 __u32 *pexpected_response_sequence_number)
104{ 106{
105 int rc = 0; 107 int rc = 0;
106 char smb_signature[20]; 108 char smb_signature[20];
107 struct smb_hdr *cifs_pdu = (struct smb_hdr *)iov[0].iov_base; 109 struct smb_hdr *cifs_pdu = (struct smb_hdr *)rqst->rq_iov[0].iov_base;
108 110
109 if ((cifs_pdu == NULL) || (server == NULL)) 111 if ((cifs_pdu == NULL) || (server == NULL))
110 return -EINVAL; 112 return -EINVAL;
@@ -125,7 +127,7 @@ int cifs_sign_smbv(struct kvec *iov, int n_vec, struct TCP_Server_Info *server,
125 *pexpected_response_sequence_number = server->sequence_number++; 127 *pexpected_response_sequence_number = server->sequence_number++;
126 server->sequence_number++; 128 server->sequence_number++;
127 129
128 rc = cifs_calc_signature(iov, n_vec, server, smb_signature); 130 rc = cifs_calc_signature(rqst, server, smb_signature);
129 if (rc) 131 if (rc)
130 memset(cifs_pdu->Signature.SecuritySignature, 0, 8); 132 memset(cifs_pdu->Signature.SecuritySignature, 0, 8);
131 else 133 else
@@ -134,6 +136,15 @@ int cifs_sign_smbv(struct kvec *iov, int n_vec, struct TCP_Server_Info *server,
134 return rc; 136 return rc;
135} 137}
136 138
139int cifs_sign_smbv(struct kvec *iov, int n_vec, struct TCP_Server_Info *server,
140 __u32 *pexpected_response_sequence)
141{
142 struct smb_rqst rqst = { .rq_iov = iov,
143 .rq_nvec = n_vec };
144
145 return cifs_sign_rqst(&rqst, server, pexpected_response_sequence);
146}
147
137/* must be called with server->srv_mutex held */ 148/* must be called with server->srv_mutex held */
138int cifs_sign_smb(struct smb_hdr *cifs_pdu, struct TCP_Server_Info *server, 149int cifs_sign_smb(struct smb_hdr *cifs_pdu, struct TCP_Server_Info *server,
139 __u32 *pexpected_response_sequence_number) 150 __u32 *pexpected_response_sequence_number)
@@ -147,14 +158,14 @@ int cifs_sign_smb(struct smb_hdr *cifs_pdu, struct TCP_Server_Info *server,
147 pexpected_response_sequence_number); 158 pexpected_response_sequence_number);
148} 159}
149 160
150int cifs_verify_signature(struct kvec *iov, unsigned int nr_iov, 161int cifs_verify_signature(struct smb_rqst *rqst,
151 struct TCP_Server_Info *server, 162 struct TCP_Server_Info *server,
152 __u32 expected_sequence_number) 163 __u32 expected_sequence_number)
153{ 164{
154 unsigned int rc; 165 unsigned int rc;
155 char server_response_sig[8]; 166 char server_response_sig[8];
156 char what_we_think_sig_should_be[20]; 167 char what_we_think_sig_should_be[20];
157 struct smb_hdr *cifs_pdu = (struct smb_hdr *)iov[0].iov_base; 168 struct smb_hdr *cifs_pdu = (struct smb_hdr *)rqst->rq_iov[0].iov_base;
158 169
159 if (cifs_pdu == NULL || server == NULL) 170 if (cifs_pdu == NULL || server == NULL)
160 return -EINVAL; 171 return -EINVAL;
@@ -186,8 +197,7 @@ int cifs_verify_signature(struct kvec *iov, unsigned int nr_iov,
186 cifs_pdu->Signature.Sequence.Reserved = 0; 197 cifs_pdu->Signature.Sequence.Reserved = 0;
187 198
188 mutex_lock(&server->srv_mutex); 199 mutex_lock(&server->srv_mutex);
189 rc = cifs_calc_signature(iov, nr_iov, server, 200 rc = cifs_calc_signature(rqst, server, what_we_think_sig_should_be);
190 what_we_think_sig_should_be);
191 mutex_unlock(&server->srv_mutex); 201 mutex_unlock(&server->srv_mutex);
192 202
193 if (rc) 203 if (rc)
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index 3c007fe641f9..5ea50dd316c5 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -162,6 +162,20 @@ struct cifs_cred {
162 ***************************************************************** 162 *****************************************************************
163 */ 163 */
164 164
165/*
166 * A smb_rqst represents a complete request to be issued to a server. It's
167 * formed by a kvec array, followed by an array of pages. Page data is assumed
168 * to start at the beginning of the first page.
169 */
170struct smb_rqst {
171 struct kvec *rq_iov; /* array of kvecs */
172 unsigned int rq_nvec; /* number of kvecs in array */
173 struct page **rq_pages; /* pointer to array of page ptrs */
174 unsigned int rq_npages; /* number pages in array */
175 unsigned int rq_pagesz; /* page size to use */
176 unsigned int rq_tailsz; /* length of last page */
177};
178
165enum smb_version { 179enum smb_version {
166 Smb_1 = 1, 180 Smb_1 = 1,
167 Smb_21, 181 Smb_21,
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index c7ad9a8cf82a..8e071a5a7da4 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -24,6 +24,7 @@
24 24
25struct statfs; 25struct statfs;
26struct smb_vol; 26struct smb_vol;
27struct smb_rqst;
27 28
28/* 29/*
29 ***************************************************************** 30 *****************************************************************
@@ -394,10 +395,12 @@ extern void sesInfoFree(struct cifs_ses *);
394extern struct cifs_tcon *tconInfoAlloc(void); 395extern struct cifs_tcon *tconInfoAlloc(void);
395extern void tconInfoFree(struct cifs_tcon *); 396extern void tconInfoFree(struct cifs_tcon *);
396 397
397extern int cifs_sign_smb(struct smb_hdr *, struct TCP_Server_Info *, __u32 *); 398extern int cifs_sign_rqst(struct smb_rqst *rqst, struct TCP_Server_Info *server,
399 __u32 *pexpected_response_sequence_number);
398extern int cifs_sign_smbv(struct kvec *iov, int n_vec, struct TCP_Server_Info *, 400extern int cifs_sign_smbv(struct kvec *iov, int n_vec, struct TCP_Server_Info *,
399 __u32 *); 401 __u32 *);
400extern int cifs_verify_signature(struct kvec *iov, unsigned int nr_iov, 402extern int cifs_sign_smb(struct smb_hdr *, struct TCP_Server_Info *, __u32 *);
403extern int cifs_verify_signature(struct smb_rqst *rqst,
401 struct TCP_Server_Info *server, 404 struct TCP_Server_Info *server,
402 __u32 expected_sequence_number); 405 __u32 expected_sequence_number);
403extern int SMBNTencrypt(unsigned char *, unsigned char *, unsigned char *, 406extern int SMBNTencrypt(unsigned char *, unsigned char *, unsigned char *,
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index c4f43cf671dc..6786b5ee5326 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -1541,6 +1541,8 @@ cifs_readv_callback(struct mid_q_entry *mid)
1541 struct cifs_readdata *rdata = mid->callback_data; 1541 struct cifs_readdata *rdata = mid->callback_data;
1542 struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink); 1542 struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
1543 struct TCP_Server_Info *server = tcon->ses->server; 1543 struct TCP_Server_Info *server = tcon->ses->server;
1544 struct smb_rqst rqst = { .rq_iov = rdata->iov,
1545 .rq_nvec = rdata->nr_iov };
1544 1546
1545 cFYI(1, "%s: mid=%llu state=%d result=%d bytes=%u", __func__, 1547 cFYI(1, "%s: mid=%llu state=%d result=%d bytes=%u", __func__,
1546 mid->mid, mid->mid_state, rdata->result, rdata->bytes); 1548 mid->mid, mid->mid_state, rdata->result, rdata->bytes);
@@ -1552,9 +1554,8 @@ cifs_readv_callback(struct mid_q_entry *mid)
1552 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) { 1554 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) {
1553 int rc = 0; 1555 int rc = 0;
1554 1556
1555 rc = cifs_verify_signature(rdata->iov, rdata->nr_iov, 1557 rc = cifs_verify_signature(&rqst, server,
1556 server, 1558 mid->sequence_number + 1);
1557 mid->sequence_number + 1);
1558 if (rc) 1559 if (rc)
1559 cERROR(1, "SMB signature verification returned " 1560 cERROR(1, "SMB signature verification returned "
1560 "error = %d", rc); 1561 "error = %d", rc);
diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c
index c4d7825dfc0a..bc9ccddad937 100644
--- a/fs/cifs/transport.c
+++ b/fs/cifs/transport.c
@@ -504,11 +504,13 @@ cifs_check_receive(struct mid_q_entry *mid, struct TCP_Server_Info *server,
504 if (server->sec_mode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) { 504 if (server->sec_mode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) {
505 struct kvec iov; 505 struct kvec iov;
506 int rc = 0; 506 int rc = 0;
507 struct smb_rqst rqst = { .rq_iov = &iov,
508 .rq_nvec = 1 };
507 509
508 iov.iov_base = mid->resp_buf; 510 iov.iov_base = mid->resp_buf;
509 iov.iov_len = len; 511 iov.iov_len = len;
510 /* FIXME: add code to kill session */ 512 /* FIXME: add code to kill session */
511 rc = cifs_verify_signature(&iov, 1, server, 513 rc = cifs_verify_signature(&rqst, server,
512 mid->sequence_number + 1); 514 mid->sequence_number + 1);
513 if (rc) 515 if (rc)
514 cERROR(1, "SMB signature verification returned error = " 516 cERROR(1, "SMB signature verification returned error = "