diff --git a/driver/main.c b/driver/main.c index e6675c0646..ff21d23be7 100644 --- a/driver/main.c +++ b/driver/main.c @@ -783,10 +783,16 @@ static long ppm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) ret = 0; goto cleanup_ioctl_nolock; } else if (cmd == PPM_IOCTL_GET_API_VERSION) { - ret = PPM_API_CURRENT_VERSION; + unsigned long long __user *out = (unsigned long long __user *) arg; + ret = 0; + if(put_user(PPM_API_CURRENT_VERSION, out)) + ret = -EINVAL; goto cleanup_ioctl_nolock; } else if (cmd == PPM_IOCTL_GET_SCHEMA_VERSION) { - ret = PPM_SCHEMA_CURRENT_VERSION; + unsigned long long __user *out = (unsigned long long __user *) arg; + ret = 0; + if(put_user(PPM_SCHEMA_CURRENT_VERSION, out)) + ret = -EINVAL; goto cleanup_ioctl_nolock; } diff --git a/driver/ppm_api_version.h b/driver/ppm_api_version.h index aa2ccf28e8..db0bbb69c6 100644 --- a/driver/ppm_api_version.h +++ b/driver/ppm_api_version.h @@ -11,16 +11,19 @@ * bits 0-23: patch version */ +#define PPM_VERSION_PACK(val, bits, shift) ((((unsigned long long)(val)) & ((1ULL << (bits)) - 1)) << (shift)) +#define PPM_VERSION_UNPACK(val, bits, shift) ((((unsigned long long)(val)) >> (shift)) & ((1ULL << (bits)) - 1)) + /* extract components from an API version number */ -#define PPM_API_VERSION_MAJOR(ver) ((((ver) >> 44)) & (((1 << 19) - 1))) -#define PPM_API_VERSION_MINOR(ver) (((ver) >> 24) & (((1 << 20) - 1))) -#define PPM_API_VERSION_PATCH(ver) (((ver) & ((1 << 24) - 1))) +#define PPM_API_VERSION_MAJOR(ver) PPM_VERSION_UNPACK(ver, 19, 44) +#define PPM_API_VERSION_MINOR(ver) PPM_VERSION_UNPACK(ver, 20, 24) +#define PPM_API_VERSION_PATCH(ver) PPM_VERSION_UNPACK(ver, 24, 0) /* build an API version number from components */ #define PPM_API_VERSION(major, minor, patch) \ - (((major) & (((1ULL << 19) - 1) << 44)) | \ - ((minor) & (((1ULL << 20) - 1) << 24)) | \ - ((major) & (((1ULL << 24) - 1)))) + PPM_VERSION_PACK(major, 19, 44) | \ + PPM_VERSION_PACK(minor, 20, 24) | \ + PPM_VERSION_PACK(patch, 24, 0) #define PPM_API_CURRENT_VERSION PPM_API_VERSION( \ PPM_API_CURRENT_VERSION_MAJOR, \ diff --git a/userspace/libscap/scap.c b/userspace/libscap/scap.c index 3f03b71214..46821ce9c2 100644 --- a/userspace/libscap/scap.c +++ b/userspace/libscap/scap.c @@ -431,8 +431,7 @@ scap_t* scap_open_live_int(char *error, int32_t *rc, } // Check the API version reported - api_version = ioctl(handle->m_devs[j].m_fd, PPM_IOCTL_GET_API_VERSION, 0); - if ((int64_t)api_version < 0) + if (ioctl(handle->m_devs[j].m_fd, PPM_IOCTL_GET_API_VERSION, &api_version) < 0) { snprintf(error, SCAP_LASTERR_SIZE, "Kernel module does not support PPM_IOCTL_GET_API_VERSION"); close(handle->m_devs[j].m_fd); @@ -443,7 +442,7 @@ scap_t* scap_open_live_int(char *error, int32_t *rc, // Make sure all devices report the same API version if (handle->m_api_version != 0 && handle->m_api_version != api_version) { - snprintf(error, SCAP_LASTERR_SIZE, "API version mismatch: device %s reports API version %lu.%lu.%lu, expected %lu.%lu.%lu", + snprintf(error, SCAP_LASTERR_SIZE, "API version mismatch: device %s reports API version %llu.%llu.%llu, expected %llu.%llu.%llu", filename, PPM_API_VERSION_MAJOR(api_version), PPM_API_VERSION_MINOR(api_version), @@ -462,8 +461,7 @@ scap_t* scap_open_live_int(char *error, int32_t *rc, handle->m_api_version = api_version; // Check the schema version reported - schema_version = ioctl(handle->m_devs[j].m_fd, PPM_IOCTL_GET_SCHEMA_VERSION, 0); - if ((int64_t)schema_version < 0) + if (ioctl(handle->m_devs[j].m_fd, PPM_IOCTL_GET_SCHEMA_VERSION, &schema_version) < 0) { snprintf(error, SCAP_LASTERR_SIZE, "Kernel module does not support PPM_IOCTL_GET_SCHEMA_VERSION"); close(handle->m_devs[j].m_fd); @@ -474,7 +472,7 @@ scap_t* scap_open_live_int(char *error, int32_t *rc, // Make sure all devices report the same schema version if (handle->m_schema_version != 0 && handle->m_schema_version != schema_version) { - snprintf(error, SCAP_LASTERR_SIZE, "Schema version mismatch: device %s reports schema version %lu.%lu.%lu, expected %lu.%lu.%lu", + snprintf(error, SCAP_LASTERR_SIZE, "Schema version mismatch: device %s reports schema version %llu.%llu.%llu, expected %llu.%llu.%llu", filename, PPM_API_VERSION_MAJOR(schema_version), PPM_API_VERSION_MINOR(schema_version), @@ -557,7 +555,7 @@ scap_t* scap_open_live_int(char *error, int32_t *rc, if(!scap_is_api_compatible(handle->m_api_version, SCAP_MINIMUM_DRIVER_API_VERSION)) { - snprintf(error, SCAP_LASTERR_SIZE, "Driver supports API version %lu.%lu.%lu, but running version needs %d.%d.%d", + snprintf(error, SCAP_LASTERR_SIZE, "Driver supports API version %llu.%llu.%llu, but running version needs %d.%d.%d", PPM_API_VERSION_MAJOR(handle->m_api_version), PPM_API_VERSION_MINOR(handle->m_api_version), PPM_API_VERSION_PATCH(handle->m_api_version), @@ -571,7 +569,7 @@ scap_t* scap_open_live_int(char *error, int32_t *rc, if(!scap_is_api_compatible(handle->m_schema_version, SCAP_MINIMUM_DRIVER_SCHEMA_VERSION)) { - snprintf(error, SCAP_LASTERR_SIZE, "Driver supports schema version %lu.%lu.%lu, but running version needs %d.%d.%d", + snprintf(error, SCAP_LASTERR_SIZE, "Driver supports schema version %llu.%llu.%llu, but running version needs %d.%d.%d", PPM_API_VERSION_MAJOR(handle->m_schema_version), PPM_API_VERSION_MINOR(handle->m_schema_version), PPM_API_VERSION_PATCH(handle->m_schema_version), diff --git a/userspace/libsinsp/test/CMakeLists.txt b/userspace/libsinsp/test/CMakeLists.txt index 6ba64637bb..db561f2cf6 100644 --- a/userspace/libsinsp/test/CMakeLists.txt +++ b/userspace/libsinsp/test/CMakeLists.txt @@ -22,13 +22,14 @@ if(NOT MINIMAL_BUILD) endif() # MINIMAL_BUILD include_directories("..") -include_directories(${LIBSCAP_INCLUDE_DIR}) +include_directories(${LIBSCAP_INCLUDE_DIR} ${LIBSCAP_DIR}/driver) set(LIBSINSP_UNIT_TESTS_SOURCES cgroup_list_counter.ut.cpp sinsp.ut.cpp evttype_filter.ut.cpp token_bucket.ut.cpp + ppm_api_version.ut.cpp ) if(NOT MINIMAL_BUILD) diff --git a/userspace/libsinsp/test/ppm_api_version.ut.cpp b/userspace/libsinsp/test/ppm_api_version.ut.cpp new file mode 100644 index 0000000000..f44f497062 --- /dev/null +++ b/userspace/libsinsp/test/ppm_api_version.ut.cpp @@ -0,0 +1,33 @@ +/* +Copyright (C) 2022 The Falco Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +*/ + +#include +#include + +TEST(api_version, unpack) +{ + uint64_t ver1_2_3 = (1ULL << 44) | (2ULL << 24) | 3; + ASSERT_EQ(ver1_2_3, PPM_API_VERSION(1, 2, 3)); +} + +TEST(api_version, pack) +{ + uint64_t ver1_2_3 = (1ULL << 44) | (2ULL << 24) | 3; + EXPECT_EQ(1u, PPM_API_VERSION_MAJOR(ver1_2_3)); + EXPECT_EQ(2u, PPM_API_VERSION_MINOR(ver1_2_3)); + EXPECT_EQ(3u, PPM_API_VERSION_PATCH(ver1_2_3)); +}