Skip to content

Commit f04ff5a

Browse files
committed
Merge tag '6.12rc-more-smb3-client-fixes' of git://git.samba.org/sfrench/cifs-2.6
Pull xmb client fixes from Steve French: - Noisy log message cleanup - Important netfs fix for cifs crash in generic/074 - Three minor improvements to use of hashing (multichannel and mount improvements) - Fix decryption crash for large read with small esize * tag '6.12rc-more-smb3-client-fixes' of git://git.samba.org/sfrench/cifs-2.6: smb: client: make SHA-512 TFM ephemeral smb: client: make HMAC-MD5 TFM ephemeral smb: client: stop flooding dmesg in smb2_calc_signature() smb: client: allocate crypto only for primary server smb: client: fix UAF in async decryption netfs: Fix write oops in generic/346 (9p) and generic/074 (cifs)
2 parents ad46e8f + 220d83b commit f04ff5a

File tree

11 files changed

+182
-179
lines changed

11 files changed

+182
-179
lines changed

fs/netfs/internal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ static inline void netfs_proc_del_rreq(struct netfs_io_request *rreq) {}
5858
/*
5959
* misc.c
6060
*/
61+
struct folio_queue *netfs_buffer_make_space(struct netfs_io_request *rreq);
6162
int netfs_buffer_append_folio(struct netfs_io_request *rreq, struct folio *folio,
6263
bool needs_put);
6364
struct folio_queue *netfs_delete_buffer_head(struct netfs_io_request *wreq);

fs/netfs/misc.c

Lines changed: 53 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -9,34 +9,66 @@
99
#include "internal.h"
1010

1111
/*
12-
* Append a folio to the rolling queue.
12+
* Make sure there's space in the rolling queue.
1313
*/
14-
int netfs_buffer_append_folio(struct netfs_io_request *rreq, struct folio *folio,
15-
bool needs_put)
14+
struct folio_queue *netfs_buffer_make_space(struct netfs_io_request *rreq)
1615
{
17-
struct folio_queue *tail = rreq->buffer_tail;
18-
unsigned int slot, order = folio_order(folio);
16+
struct folio_queue *tail = rreq->buffer_tail, *prev;
17+
unsigned int prev_nr_slots = 0;
1918

2019
if (WARN_ON_ONCE(!rreq->buffer && tail) ||
2120
WARN_ON_ONCE(rreq->buffer && !tail))
22-
return -EIO;
23-
24-
if (!tail || folioq_full(tail)) {
25-
tail = kmalloc(sizeof(*tail), GFP_NOFS);
26-
if (!tail)
27-
return -ENOMEM;
28-
netfs_stat(&netfs_n_folioq);
29-
folioq_init(tail);
30-
tail->prev = rreq->buffer_tail;
31-
if (tail->prev)
32-
tail->prev->next = tail;
33-
rreq->buffer_tail = tail;
34-
if (!rreq->buffer) {
35-
rreq->buffer = tail;
36-
iov_iter_folio_queue(&rreq->io_iter, ITER_SOURCE, tail, 0, 0, 0);
21+
return ERR_PTR(-EIO);
22+
23+
prev = tail;
24+
if (prev) {
25+
if (!folioq_full(tail))
26+
return tail;
27+
prev_nr_slots = folioq_nr_slots(tail);
28+
}
29+
30+
tail = kmalloc(sizeof(*tail), GFP_NOFS);
31+
if (!tail)
32+
return ERR_PTR(-ENOMEM);
33+
netfs_stat(&netfs_n_folioq);
34+
folioq_init(tail);
35+
tail->prev = prev;
36+
if (prev)
37+
/* [!] NOTE: After we set prev->next, the consumer is entirely
38+
* at liberty to delete prev.
39+
*/
40+
WRITE_ONCE(prev->next, tail);
41+
42+
rreq->buffer_tail = tail;
43+
if (!rreq->buffer) {
44+
rreq->buffer = tail;
45+
iov_iter_folio_queue(&rreq->io_iter, ITER_SOURCE, tail, 0, 0, 0);
46+
} else {
47+
/* Make sure we don't leave the master iterator pointing to a
48+
* block that might get immediately consumed.
49+
*/
50+
if (rreq->io_iter.folioq == prev &&
51+
rreq->io_iter.folioq_slot == prev_nr_slots) {
52+
rreq->io_iter.folioq = tail;
53+
rreq->io_iter.folioq_slot = 0;
3754
}
38-
rreq->buffer_tail_slot = 0;
3955
}
56+
rreq->buffer_tail_slot = 0;
57+
return tail;
58+
}
59+
60+
/*
61+
* Append a folio to the rolling queue.
62+
*/
63+
int netfs_buffer_append_folio(struct netfs_io_request *rreq, struct folio *folio,
64+
bool needs_put)
65+
{
66+
struct folio_queue *tail;
67+
unsigned int slot, order = folio_order(folio);
68+
69+
tail = netfs_buffer_make_space(rreq);
70+
if (IS_ERR(tail))
71+
return PTR_ERR(tail);
4072

4173
rreq->io_iter.count += PAGE_SIZE << order;
4274

fs/netfs/write_issue.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,12 +153,22 @@ static void netfs_prepare_write(struct netfs_io_request *wreq,
153153
loff_t start)
154154
{
155155
struct netfs_io_subrequest *subreq;
156+
struct iov_iter *wreq_iter = &wreq->io_iter;
157+
158+
/* Make sure we don't point the iterator at a used-up folio_queue
159+
* struct being used as a placeholder to prevent the queue from
160+
* collapsing. In such a case, extend the queue.
161+
*/
162+
if (iov_iter_is_folioq(wreq_iter) &&
163+
wreq_iter->folioq_slot >= folioq_nr_slots(wreq_iter->folioq)) {
164+
netfs_buffer_make_space(wreq);
165+
}
156166

157167
subreq = netfs_alloc_subrequest(wreq);
158168
subreq->source = stream->source;
159169
subreq->start = start;
160170
subreq->stream_nr = stream->stream_nr;
161-
subreq->io_iter = wreq->io_iter;
171+
subreq->io_iter = *wreq_iter;
162172

163173
_enter("R=%x[%x]", wreq->debug_id, subreq->debug_index);
164174

0 commit comments

Comments
 (0)