Commit 6b19560d authored by Alan Screen's avatar Alan Screen Committed by Chromium LUCI CQ

Parse PPD in a sandbox compliant manner

The Linux sandbox causes created files to be automatically deleted once
they are closed.  This means that creating a file without leaving an
open file handle is useless afterwards for any subsequent calls
expecting it to exist with results of previous work.

Change ParsePpdCapabilities() to open a stream for a temporary file and
keep that open for the duration of the file operations, instead of
doing multiple open/close operations against a common filename.  This
is necessary for supporting sandboxing of the print backend in a
utility process.

Bug: 809738
Change-Id: Id16dc686873decad7be980ce4621747b4233184a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2597143Reviewed-by: default avatarRebekah Potter <rbpotter@chromium.org>
Reviewed-by: default avatarDaniel Hosseinian <dhoss@chromium.org>
Commit-Queue: Alan Screen <awscreen@chromium.org>
Cr-Commit-Position: refs/heads/master@{#839166}
parent c4225c3f
......@@ -9,7 +9,9 @@
#include <vector>
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/files/scoped_file.h"
#include "base/logging.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
......@@ -518,6 +520,27 @@ bool GetColorModelSettings(ppd_file_t* ppd,
// Default port for IPP print servers.
const int kDefaultIPPServerPort = 631;
// Provide scoping of a temporary file to be used by a FILE stream. This is
// akin to base::ScopedFILE but provides access to an open FILE handle, which
// is needed when performing multiple operations from within a sandbox.
class ScopedTempFile {
public:
ScopedTempFile() { file_ = base::CreateAndOpenTemporaryStream(&path_); }
ScopedTempFile(const ScopedTempFile&) = delete;
ScopedTempFile& operator=(const ScopedTempFile&) = delete;
~ScopedTempFile() {
file_.reset(); // Closes the file if it is open.
if (base::PathExists(path_))
base::DeleteFile(path_);
}
FILE* handle() { return file_.get(); }
private:
base::FilePath path_;
base::ScopedFILE file_;
};
} // namespace
// Helper wrapper around http_t structure, with connection and cleanup
......@@ -569,23 +592,23 @@ bool ParsePpdCapabilities(cups_dest_t* dest,
base::StringPiece locale,
base::StringPiece printer_capabilities,
PrinterSemanticCapsAndDefaults* printer_info) {
base::FilePath ppd_file_path;
if (!base::CreateTemporaryFile(&ppd_file_path))
ScopedTempFile ppd_file;
if (!ppd_file.handle())
return false;
if (!base::WriteFile(ppd_file_path, printer_capabilities)) {
base::DeleteFile(ppd_file_path);
const size_t caps_size = printer_capabilities.size();
if (fwrite(printer_capabilities.data(), 1, caps_size, ppd_file.handle()) !=
caps_size) {
return false;
}
ppd_file_t* ppd = ppdOpenFile(ppd_file_path.value().c_str());
if (!ppd) {
int line = 0;
ppd_status_t ppd_status = ppdLastError(&line);
LOG(ERROR) << "Failed to open PDD file: error " << ppd_status << " at line "
<< line << ", " << ppdErrorString(ppd_status);
if (fseek(ppd_file.handle(), 0, SEEK_SET) != 0)
return false;
}
ppd_file_t* ppd = ppdOpen(ppd_file.handle());
if (!ppd)
return false;
ppdMarkDefaults(ppd);
if (dest)
cupsMarkOptions(ppd, dest->num_options, dest->options);
......@@ -665,7 +688,6 @@ bool ParsePpdCapabilities(cups_dest_t* dest,
}
ppdClose(ppd);
base::DeleteFile(ppd_file_path);
*printer_info = caps;
return true;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment