Skip to content

Commit

Permalink
bridge: re-introduce the max_read_size limit
Browse files Browse the repository at this point in the history
This is a regression from our port of the bridge from C to Python. The C
bridge had a limit and as fsread1 is not blocking implemented this
prevents issues of accidentally reading /dev/zero or /dev/sda which will
fill up ram endlessly.
  • Loading branch information
jelly committed Jan 27, 2025
1 parent 53b9468 commit 27d0145
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 3 deletions.
4 changes: 2 additions & 2 deletions src/cockpit/channels/filesystem.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,14 +124,14 @@ class FsReadChannel(GeneratorChannel):

def do_yield_data(self, options: JsonObject) -> Generator[bytes, None, JsonObject]:
path = get_str(options, 'path')
max_read_size = get_int(options, 'max_read_size', None)
max_read_size = get_int(options, 'max_read_size', 16 * 1024 * 1024)

logger.debug('Opening file "%s" for reading', path)

try:
with open(path, 'rb') as filep:
buf = os.stat(filep.fileno())
if max_read_size is not None and buf.st_size > max_read_size:
if buf.st_size > max_read_size:
raise ChannelError('too-large')

if self.is_binary and stat.S_ISREG(buf.st_mode):
Expand Down
8 changes: 7 additions & 1 deletion test/pytest/test_bridge.py
Original file line number Diff line number Diff line change
Expand Up @@ -416,7 +416,7 @@ async def test_internal_metrics(transport: MockTransport) -> None:


@pytest.mark.asyncio
async def test_fsread1_errors(transport: MockTransport) -> None:
async def test_fsread1_errors(transport: MockTransport, tmp_path: Path) -> None:
await transport.check_open('fsread1', path='/etc/shadow', problem='access-denied')
await transport.check_open('fsread1', path='/', problem='internal-error',
reply_keys={'message': "[Errno 21] Is a directory: '/'"})
Expand All @@ -425,6 +425,12 @@ async def test_fsread1_errors(transport: MockTransport) -> None:
reply_keys={'message': "attribute 'max_read_size': must have type int"})
await transport.check_open('fsread1', path='/etc/passwd', max_read_size=1,
problem='too-large')
# default read size limit
big_file = tmp_path / 'bigfile.img'
fd = os.open(big_file, os.O_RDWR | os.O_CREAT)
os.posix_fallocate(fd, 0, 17 * 1024 * 1024)
await transport.check_open('fsread1', path=str(big_file),
problem='too-large')


@pytest.mark.asyncio
Expand Down

0 comments on commit 27d0145

Please sign in to comment.