Skip to content

Commit 247a725

Browse files
torvaldsopsiff
authored andcommitted
fs/pipe: fix pipe buffer index use in FUSE
mainline inclusion from mainline-v6.14-rc4 category: bugfix This was another case that Rasmus pointed out where the direct access to the pipe head and tail pointers broke on 32-bit configurations due to the type changes. As with the pipe FIONREAD case, fix it by using the appropriate helper functions that deal with the right pipe index sizing. Reported-by: Rasmus Villemoes <ravi@prevas.dk> Link: https://lore.kernel.org/all/878qpi5wz4.fsf@prevas.dk/ Fixes: 3d25216 ("fs/pipe: Read pipe->{head,tail} atomically outside pipe->mutex")Cc: Oleg > Cc: Mateusz Guzik <mjguzik@gmail.com> Cc: K Prateek Nayak <kprateek.nayak@amd.com> Cc: Swapnil Sapkal <swapnil.sapkal@amd.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> (cherry picked from commit ebb0f38) Signed-off-by: Wentao Guan <guanwentao@uniontech.com> Change-Id: Ic3e35662fcf92645c667f80923a6c3e9a4281d70
1 parent fc21038 commit 247a725

1 file changed

Lines changed: 6 additions & 7 deletions

File tree

fs/fuse/dev.c

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1967,7 +1967,7 @@ static ssize_t fuse_dev_splice_write(struct pipe_inode_info *pipe,
19671967
struct file *out, loff_t *ppos,
19681968
size_t len, unsigned int flags)
19691969
{
1970-
unsigned int head, tail, mask, count;
1970+
unsigned int head, tail, count;
19711971
unsigned nbuf;
19721972
unsigned idx;
19731973
struct pipe_buffer *bufs;
@@ -1984,8 +1984,7 @@ static ssize_t fuse_dev_splice_write(struct pipe_inode_info *pipe,
19841984

19851985
head = pipe->head;
19861986
tail = pipe->tail;
1987-
mask = pipe->ring_size - 1;
1988-
count = head - tail;
1987+
count = pipe_occupancy(head, tail);
19891988

19901989
bufs = kvmalloc_array(count, sizeof(struct pipe_buffer), GFP_KERNEL);
19911990
if (!bufs) {
@@ -1995,8 +1994,8 @@ static ssize_t fuse_dev_splice_write(struct pipe_inode_info *pipe,
19951994

19961995
nbuf = 0;
19971996
rem = 0;
1998-
for (idx = tail; idx != head && rem < len; idx++)
1999-
rem += pipe->bufs[idx & mask].len;
1997+
for (idx = tail; !pipe_empty(head, idx) && rem < len; idx++)
1998+
rem += pipe_buf(pipe, idx)->len;
20001999

20012000
ret = -EINVAL;
20022001
if (rem < len)
@@ -2007,10 +2006,10 @@ static ssize_t fuse_dev_splice_write(struct pipe_inode_info *pipe,
20072006
struct pipe_buffer *ibuf;
20082007
struct pipe_buffer *obuf;
20092008

2010-
if (WARN_ON(nbuf >= count || tail == head))
2009+
if (WARN_ON(nbuf >= count || pipe_empty(head, tail)))
20112010
goto out_free;
20122011

2013-
ibuf = &pipe->bufs[tail & mask];
2012+
ibuf = pipe_buf(pipe, tail);
20142013
obuf = &bufs[nbuf];
20152014

20162015
if (rem >= ibuf->len) {

0 commit comments

Comments
 (0)