mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* zram: block_state returns premature EOF with short read buffers
@ 2026-09-20 16:27 Pooyan Azadparvar
  2026-09-28 16:48 ` [PATCH] zram: fix short reads from block_state Pooyan Azad
  2026-09-29  4:13 ` zram: block_state returns premature EOF with short read buffers Sergey Senozhatsky
  0 siblings, 2 replies; 7+ messages in thread
From: Pooyan Azadparvar @ 2026-09-20 16:27 UTC (permalink / raw)
  To: Minchan Kim, Sergey Senozhatsky; +Cc: Jens Axboe, linux-kernel, linux-block

Hello,

The zram debugfs block_state file returns zero bytes when it is read
with a buffer smaller than one formatted record.

The issue appears to be in read_block_state() in
drivers/block/zram/zram_drv.c:

        copied = snprintf(kbuf + written, count, ...);

        if (count <= copied) {
                slot_unlock(zram, index);
                break;
        }

When the supplied buffer is too small, snprintf() returns the length
that would have been written, rather than the number of bytes copied.
Since copied is then greater than or equal to count, the function breaks
out of the loop without advancing *ppos or increasing written. It
returns zero even though the file contains an allocated block-state
record.

I reproduced this on:

        Linux debian-Utah-1gb 6.12.63+deb13-cloud-amd64
        x86_64

The relevant kernel configuration is:

        CONFIG_ZRAM=m
        CONFIG_ZRAM_MEMORY_TRACKING=y
        CONFIG_DEBUG_FS=y

Reproducer:

        # modprobe zram
        # echo 16M > /sys/block/zram0/disksize
        # dd if=/dev/urandom of=/dev/zram0 bs=4096 count=1 conv=fsync

The slot is allocated:

        # cat /sys/block/zram0/mm_stat
             4096     4096     4096        0        4096        0
  0        1        1

A normal read returns a record:

        # cat /sys/kernel/debug/zram/zram0/block_state
                   0         1161.269400 ..h...

However, reading the same file with a one-byte buffer returns zero
bytes:

        # python3 - <<'PY'
        import os

        path = "/sys/kernel/debug/zram/zram0/block_state"
        fd = os.open(path, os.O_RDONLY)

        try:
            for attempt in range(3):
                data = os.read(fd, 1)
                offset = os.lseek(fd, 0, os.SEEK_CUR)
                print(
                    f"read {attempt}: bytes={len(data)}, "
                    f"data={data!r}, offset={offset}"
                )
        finally:
            os.close(fd)
        PY

        read 0: bytes=0, data=b'', offset=0
        read 1: bytes=0, data=b'', offset=0
        read 2: bytes=0, data=b'', offset=0

The file contains a valid record, but the short-buffer reads return zero
bytes repeatedly and the file position remains unchanged.

This does not appear to be a memory-safety or security issue. The
observed impact is that userspace readers using a short buffer receive
zero bytes and cannot make progress through this debugfs file.

Could you please confirm whether this short-read behavior is expected
for block_state? If it is not expected, should this be fixed directly
in read_block_state(), or should the file be converted to use seq_file?

Thanks for your time and for maintaining zram.

Pooyan Azad

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2026-09-29  8:36 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-20 16:27 zram: block_state returns premature EOF with short read buffers Pooyan Azadparvar
2026-09-28 16:48 ` [PATCH] zram: fix short reads from block_state Pooyan Azad
2026-09-29  4:52   ` Sergey Senozhatsky
2026-09-29  7:18   ` [PATCH v2] " Pooyan Azad
2026-09-29  8:36     ` Sergey Senozhatsky
2026-09-29  4:13 ` zram: block_state returns premature EOF with short read buffers Sergey Senozhatsky
2026-09-29  4:28   ` Sergey Senozhatsky

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®