diff options
author | Côme Chilliet <come.chilliet@nextcloud.com> | 2025-07-03 11:02:06 +0200 |
---|---|---|
committer | Côme Chilliet <91878298+come-nc@users.noreply.github.com> | 2025-07-03 15:19:34 +0200 |
commit | 4427050f840afee97a0de8d5e58d8ca5f5eb6196 (patch) | |
tree | 9289fa98b47323bc0dc0f1c96f8c9a84bc229ef6 | |
parent | 58e8626f5f331b5e28ea8658763493cac4dcf70c (diff) | |
download | nextcloud-server-fix/catch-exception-in-encrypt-all.tar.gz nextcloud-server-fix/catch-exception-in-encrypt-all.zip |
fix(encryption): Correctly handle file opening and copying failuresfix/catch-exception-in-encrypt-all
Signed-off-by: Côme Chilliet <come.chilliet@nextcloud.com>
-rw-r--r-- | apps/encryption/lib/Crypto/EncryptAll.php | 9 | ||||
-rw-r--r-- | lib/private/Files/Storage/Wrapper/Encryption.php | 20 |
2 files changed, 25 insertions, 4 deletions
diff --git a/apps/encryption/lib/Crypto/EncryptAll.php b/apps/encryption/lib/Crypto/EncryptAll.php index 6454c7d6e13..d9db616e6f1 100644 --- a/apps/encryption/lib/Crypto/EncryptAll.php +++ b/apps/encryption/lib/Crypto/EncryptAll.php @@ -249,7 +249,14 @@ class EncryptAll { $target = $path . '.encrypted.' . time(); try { - $this->rootView->copy($source, $target); + $copySuccess = $this->rootView->copy($source, $target); + if ($copySuccess === false) { + /* Copy failed, abort */ + if ($this->rootView->file_exists($target)) { + $this->rootView->unlink($target); + } + throw new \Exception('Copy failed for ' . $source); + } $this->rootView->rename($target, $source); } catch (DecryptionFailedException $e) { if ($this->rootView->file_exists($target)) { diff --git a/lib/private/Files/Storage/Wrapper/Encryption.php b/lib/private/Files/Storage/Wrapper/Encryption.php index 51a5f99908d..58bd4dfddcf 100644 --- a/lib/private/Files/Storage/Wrapper/Encryption.php +++ b/lib/private/Files/Storage/Wrapper/Encryption.php @@ -23,6 +23,7 @@ use OCP\Encryption\IManager; use OCP\Encryption\Keys\IStorage; use OCP\Files; use OCP\Files\Cache\ICacheEntry; +use OCP\Files\GenericFileException; use OCP\Files\Mount\IMountPoint; use OCP\Files\Storage; use Psr\Log\LoggerInterface; @@ -685,12 +686,16 @@ class Encryption extends Wrapper { try { $source = $sourceStorage->fopen($sourceInternalPath, 'r'); $target = $this->fopen($targetInternalPath, 'w'); - [, $result] = Files::streamCopy($source, $target, true); + if ($source === false || $target === false) { + $result = false; + } else { + [, $result] = Files::streamCopy($source, $target, true); + } } finally { - if (is_resource($source)) { + if (isset($source) && $source !== false) { fclose($source); } - if (is_resource($target)) { + if (isset($target) && $target !== false) { fclose($target); } } @@ -740,6 +745,9 @@ class Encryption extends Wrapper { public function hash(string $type, string $path, bool $raw = false): string|false { $fh = $this->fopen($path, 'rb'); + if ($fh === false) { + return false; + } $ctx = hash_init($type); hash_update_stream($ctx, $fh); fclose($fh); @@ -764,6 +772,9 @@ class Encryption extends Wrapper { $firstBlock = ''; if ($this->storage->is_file($path)) { $handle = $this->storage->fopen($path, 'r'); + if ($handle === false) { + return ''; + } $firstBlock = fread($handle, $this->util->getHeaderSize()); fclose($handle); } @@ -894,6 +905,9 @@ class Encryption extends Wrapper { public function writeStream(string $path, $stream, ?int $size = null): int { // always fall back to fopen $target = $this->fopen($path, 'w'); + if ($target === false) { + throw new GenericFileException("Failed to open $path for writing"); + } [$count, $result] = Files::streamCopy($stream, $target, true); fclose($stream); fclose($target); |