mirror of
https://gitlab.isc.org/isc-projects/kea
synced 2025-08-31 05:55:28 +00:00
[#1680] added check for execurtable permissions
This commit is contained in:
@@ -4,6 +4,7 @@ AM_CPPFLAGS = -I$(top_builddir)/src/lib -I$(top_srcdir)/src/lib
|
||||
AM_CPPFLAGS += -I$(top_builddir)/src/hooks/dhcp/run_script -I$(top_srcdir)/src/hooks/dhcp/run_script
|
||||
AM_CPPFLAGS += $(BOOST_INCLUDES)
|
||||
AM_CPPFLAGS += -DLIBRUN_SCRIPT_SO=\"$(abs_top_builddir)/src/hooks/dhcp/run_script/.libs/libdhcp_run_script.so\"
|
||||
AM_CPPFLAGS += -DRUN_SCRIPT_TEST_SH=\"$(abs_top_builddir)/src/hooks/dhcp/run_script/tests/run_script_test.sh\"
|
||||
AM_CPPFLAGS += -DINSTALL_PROG=\"$(abs_top_srcdir)/install-sh\"
|
||||
|
||||
AM_CXXFLAGS = $(KEA_CXXFLAGS)
|
||||
|
@@ -75,7 +75,7 @@ public:
|
||||
TEST_F(LibLoadTest, validLoad) {
|
||||
// Prepare parameters for the callout parameters library.
|
||||
ElementPtr params = Element::createMap();
|
||||
ElementPtr name = Element::create("test_script.sh");
|
||||
ElementPtr name = Element::create(RUN_SCRIPT_TEST_SH);
|
||||
params->set("name", name);
|
||||
ElementPtr sync = Element::create(false);
|
||||
params->set("sync", sync);
|
||||
@@ -104,12 +104,16 @@ TEST_F(LibLoadTest, invalidLoad) {
|
||||
params->set("name", name);
|
||||
EXPECT_FALSE(loadLibs());
|
||||
|
||||
// Use valid name parameter type but use invalid sync parameter type.
|
||||
// Use invalid name parameter.
|
||||
name = Element::create("script_name.sh");
|
||||
params->set("name", name);
|
||||
EXPECT_FALSE(loadLibs());
|
||||
|
||||
// Use valid name parameter type but use invalid sync parameter type.
|
||||
name = Element::create(RUN_SCRIPT_TEST_SH);
|
||||
params->set("name", name);
|
||||
ElementPtr sync = Element::create("data");
|
||||
params->set("sync", sync);
|
||||
|
||||
EXPECT_FALSE(loadLibs());
|
||||
}
|
||||
|
||||
|
@@ -32,6 +32,15 @@ RunScriptImpl::configure(LibraryHandle& handle) {
|
||||
if (name->getType() != Element::string) {
|
||||
isc_throw(InvalidParameter, "The 'name' parameter must be a string");
|
||||
}
|
||||
IOServicePtr io_service(new asiolink::IOService());
|
||||
try {
|
||||
ProcessSpawn process(io_service, name->stringValue());
|
||||
if (!process.checkPermissions()) {
|
||||
isc_throw(InvalidParameter, "The 'name' parameter must point to an executable");
|
||||
}
|
||||
} catch (const isc::Exception& ex) {
|
||||
isc_throw(InvalidParameter, "Invalid 'name' parameter: " << ex.what());
|
||||
}
|
||||
setName(name->stringValue());
|
||||
ConstElementPtr sync = handle.getParameter("sync");
|
||||
if (sync) {
|
||||
|
@@ -17,6 +17,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
using namespace std;
|
||||
@@ -131,6 +132,12 @@ public:
|
||||
/// @param pid A process pid.
|
||||
void clearState(const pid_t pid);
|
||||
|
||||
/// @brief Check executable permissions.
|
||||
///
|
||||
/// @return true if file has executable permissions, false otherwise.
|
||||
/// @throw ProcessSpawnError if file does not exist.
|
||||
bool checkPermissions() const;
|
||||
|
||||
private:
|
||||
|
||||
/// @brief Copies the argument specified as a C++ string to the new
|
||||
@@ -357,6 +364,18 @@ ProcessSpawn::ProcessSpawn(IOServicePtr io_service,
|
||||
: impl_(new ProcessSpawnImpl(io_service, executable, args, vars)) {
|
||||
}
|
||||
|
||||
bool
|
||||
ProcessSpawnImpl::checkPermissions() const {
|
||||
struct stat st;
|
||||
if (stat(executable_.c_str(), &st)) {
|
||||
isc_throw(ProcessSpawnError, "File not found: " << executable_);
|
||||
}
|
||||
if (st.st_mode & S_IEXEC) {
|
||||
return (true);
|
||||
}
|
||||
return (false);
|
||||
}
|
||||
|
||||
std::string
|
||||
ProcessSpawn::getCommandLine() const {
|
||||
return (impl_->getCommandLine());
|
||||
@@ -387,5 +406,10 @@ ProcessSpawn::clearState(const pid_t pid) {
|
||||
return (impl_->clearState(pid));
|
||||
}
|
||||
|
||||
bool
|
||||
ProcessSpawn::checkPermissions() const {
|
||||
return (impl_->checkPermissions());
|
||||
}
|
||||
|
||||
} // namespace asiolink
|
||||
} // namespace isc
|
||||
|
@@ -137,6 +137,12 @@ public:
|
||||
/// @param pid A process pid.
|
||||
void clearState(const pid_t pid);
|
||||
|
||||
/// @brief Check executable permissions.
|
||||
///
|
||||
/// @return true if file has executable permissions, false otherwise.
|
||||
/// @throw ProcessSpawnError if file does not exist.
|
||||
bool checkPermissions() const;
|
||||
|
||||
private:
|
||||
|
||||
/// @brief A smart pointer to the implementation of this class.
|
||||
|
@@ -16,6 +16,8 @@
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <testutils/gtest_utils.h>
|
||||
|
||||
namespace {
|
||||
|
||||
using namespace isc;
|
||||
@@ -343,4 +345,19 @@ TEST_F(ProcessSpawnTest, isRunning) {
|
||||
ASSERT_EQ(SIGCHLD, processed_signals_[0]);
|
||||
}
|
||||
|
||||
// This test verifies that the checkPermissions function throws if the file does
|
||||
// not exist and returns true or false if the file is or it is not executable.
|
||||
TEST_F(ProcessSpawnTest, checkPermissions) {
|
||||
ProcessSpawn no_process(io_service_, "no-file");
|
||||
EXPECT_THROW_MSG(no_process.checkPermissions(), ProcessSpawnError,
|
||||
"File not found: no-file");
|
||||
|
||||
std::string name = TEST_SCRIPT_SH;
|
||||
name += ".in";
|
||||
ProcessSpawn invalid_process(io_service_, name);
|
||||
ASSERT_FALSE(invalid_process.checkPermissions());
|
||||
ProcessSpawn process(io_service_, TEST_SCRIPT_SH);
|
||||
ASSERT_TRUE(process.checkPermissions());
|
||||
}
|
||||
|
||||
} // end of anonymous namespace
|
||||
|
Reference in New Issue
Block a user