aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCôme Chilliet <come.chilliet@nextcloud.com>2025-07-03 11:02:06 +0200
committerCôme Chilliet <91878298+come-nc@users.noreply.github.com>2025-07-03 15:19:34 +0200
commit4427050f840afee97a0de8d5e58d8ca5f5eb6196 (patch)
tree9289fa98b47323bc0dc0f1c96f8c9a84bc229ef6
parent58e8626f5f331b5e28ea8658763493cac4dcf70c (diff)
downloadnextcloud-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.php9
-rw-r--r--lib/private/Files/Storage/Wrapper/Encryption.php20
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);