Skip to content

Commit

Permalink
Port the extended_attributes table to Linux, add support for Linux ca…
Browse files Browse the repository at this point in the history
…pabilities (osquery#6195)
  • Loading branch information
alessandrogario authored Nov 24, 2020
1 parent 8a79e7c commit 76c7733
Show file tree
Hide file tree
Showing 17 changed files with 812 additions and 6 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -133,3 +133,6 @@
[submodule "libraries/cmake/source/expat/src"]
path = libraries/cmake/source/expat/src
url = https://github.com/libexpat/libexpat
[submodule "libraries/cmake/source/libcap/src"]
path = libraries/cmake/source/libcap/src
url = https://git.kernel.org/pub/scm/libs/libcap/libcap.git
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ function(importLibraries)
"Linux,Darwin,Windows:icu"
"Linux:expat"
"Linux:dbus"
"Linux:libcap"
)

if(OSQUERY_BUILD_BPF)
Expand Down
48 changes: 48 additions & 0 deletions libraries/cmake/source/libcap/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Copyright (c) 2014-present, The osquery authors
#
# This source code is licensed as defined by the LICENSE file found in the
# root directory of this source tree.
#
# SPDX-License-Identifier: (Apache-2.0 OR GPL-2.0-only)

function(libcapMain)
set(library_root "${CMAKE_CURRENT_SOURCE_DIR}/src/libcap")

add_library(thirdparty_libcap
"${library_root}/cap_alloc.c"
"${library_root}/cap_extint.c"
"${library_root}/cap_file.c"
"${library_root}/cap_flag.c"
"${library_root}/cap_proc.c"
"${library_root}/cap_text.c"
"${library_root}/psx.c"
"${library_root}/libcap.h"

"${CMAKE_CURRENT_SOURCE_DIR}/generated/cap_names.h"
"${CMAKE_CURRENT_SOURCE_DIR}/generated/cap_names.list.h"
)

target_compile_definitions(thirdparty_libcap PRIVATE
PIC
_LARGEFILE64_SOURCE=1
_FILE_OFFSET_BITS=64
)

target_link_libraries(thirdparty_libcap PRIVATE
thirdparty_c_settings
)

target_include_directories(thirdparty_libcap PRIVATE
"${library_root}"
"${library_root}/include"
"${library_root}/include/uapi"
"${CMAKE_CURRENT_SOURCE_DIR}/generated"
)

target_include_directories(thirdparty_libcap SYSTEM INTERFACE
"${library_root}/include"
"${library_root}/include/uapi"
)
endfunction()

libcapMain()
53 changes: 53 additions & 0 deletions libraries/cmake/source/libcap/generated/cap_names.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
* DO NOT EDIT: this file is generated automatically from
*
* <uapi/linux/capability.h>
*/

#define __CAP_BITS 38
#define __CAP_NAME_SIZE 21

#ifdef LIBCAP_PLEASE_INCLUDE_ARRAY
char const *_cap_names[__CAP_BITS] = {
/* 0 */ "cap_chown",
/* 1 */ "cap_dac_override",
/* 2 */ "cap_dac_read_search",
/* 3 */ "cap_fowner",
/* 4 */ "cap_fsetid",
/* 5 */ "cap_kill",
/* 6 */ "cap_setgid",
/* 7 */ "cap_setuid",
/* 8 */ "cap_setpcap",
/* 9 */ "cap_linux_immutable",
/* 10 */ "cap_net_bind_service",
/* 11 */ "cap_net_broadcast",
/* 12 */ "cap_net_admin",
/* 13 */ "cap_net_raw",
/* 14 */ "cap_ipc_lock",
/* 15 */ "cap_ipc_owner",
/* 16 */ "cap_sys_module",
/* 17 */ "cap_sys_rawio",
/* 18 */ "cap_sys_chroot",
/* 19 */ "cap_sys_ptrace",
/* 20 */ "cap_sys_pacct",
/* 21 */ "cap_sys_admin",
/* 22 */ "cap_sys_boot",
/* 23 */ "cap_sys_nice",
/* 24 */ "cap_sys_resource",
/* 25 */ "cap_sys_time",
/* 26 */ "cap_sys_tty_config",
/* 27 */ "cap_mknod",
/* 28 */ "cap_lease",
/* 29 */ "cap_audit_write",
/* 30 */ "cap_audit_control",
/* 31 */ "cap_setfcap",
/* 32 */ "cap_mac_override",
/* 33 */ "cap_mac_admin",
/* 34 */ "cap_syslog",
/* 35 */ "cap_wake_alarm",
/* 36 */ "cap_block_suspend",
/* 37 */ "cap_audit_read",
};
#endif /* LIBCAP_PLEASE_INCLUDE_ARRAY */

/* END OF FILE */
38 changes: 38 additions & 0 deletions libraries/cmake/source/libcap/generated/cap_names.list.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{"cap_chown",0},
{"cap_dac_override",1},
{"cap_dac_read_search",2},
{"cap_fowner",3},
{"cap_fsetid",4},
{"cap_kill",5},
{"cap_setgid",6},
{"cap_setuid",7},
{"cap_setpcap",8},
{"cap_linux_immutable",9},
{"cap_net_bind_service",10},
{"cap_net_broadcast",11},
{"cap_net_admin",12},
{"cap_net_raw",13},
{"cap_ipc_lock",14},
{"cap_ipc_owner",15},
{"cap_sys_module",16},
{"cap_sys_rawio",17},
{"cap_sys_chroot",18},
{"cap_sys_ptrace",19},
{"cap_sys_pacct",20},
{"cap_sys_admin",21},
{"cap_sys_boot",22},
{"cap_sys_nice",23},
{"cap_sys_resource",24},
{"cap_sys_time",25},
{"cap_sys_tty_config",26},
{"cap_mknod",27},
{"cap_lease",28},
{"cap_audit_write",29},
{"cap_audit_control",30},
{"cap_setfcap",31},
{"cap_mac_override",32},
{"cap_mac_admin",33},
{"cap_syslog",34},
{"cap_wake_alarm",35},
{"cap_block_suspend",36},
{"cap_audit_read",37},
1 change: 1 addition & 0 deletions libraries/cmake/source/libcap/src
Submodule src added at 5aa8f0
16 changes: 16 additions & 0 deletions libraries/cmake/source/modules/Findlibcap.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Copyright (c) 2014-present, The osquery authors
#
# This source code is licensed as defined by the LICENSE file found in the
# root directory of this source tree.
#
# SPDX-License-Identifier: (Apache-2.0 OR GPL-2.0-only)

cmake_minimum_required(VERSION 3.14.6)
include("${CMAKE_CURRENT_LIST_DIR}/utils.cmake")

importSourceSubmodule(
NAME "libcap"

SHALLOW_SUBMODULES
"src"
)
21 changes: 16 additions & 5 deletions osquery/filesystem/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ function(generateOsqueryFilesystem)
filesystem.cpp
)

set(public_header_files
fileops.h
filesystem.h
)

if(DEFINED PLATFORM_MACOS)
list(APPEND source_files
darwin/bsd_file_flags.cpp
Expand All @@ -30,6 +35,11 @@ function(generateOsqueryFilesystem)
if(DEFINED PLATFORM_POSIX)
list(APPEND source_files
posix/fileops.cpp
posix/xattrs.cpp
)

list(APPEND public_header_files
posix/xattrs.h
)
endif()

Expand Down Expand Up @@ -63,11 +73,6 @@ function(generateOsqueryFilesystem)
thirdparty_zstd
)

set(public_header_files
fileops.h
filesystem.h
)

if(DEFINED PLATFORM_LINUX)
list(APPEND public_header_files
linux/proc.h
Expand Down Expand Up @@ -110,6 +115,12 @@ function(generateOsqueryFilesystemTest)
tests/filesystem.cpp
)

if(DEFINED PLATFORM_POSIX)
list(APPEND source_files
tests/posix/xattrs.cpp
)
endif()

if(DEFINED PLATFORM_MACOS)
list(APPEND source_files
tests/darwin/plist_tests.cpp
Expand Down
142 changes: 142 additions & 0 deletions osquery/filesystem/posix/xattrs.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
/**
* Copyright (c) 2014-present, The osquery authors
*
* This source code is licensed as defined by the LICENSE file found in the
* root directory of this source tree.
*
* SPDX-License-Identifier: (Apache-2.0 OR GPL-2.0-only)
*/

#include <osquery/filesystem/posix/xattrs.h>
#include <osquery/logger/logger.h>

#include <sys/xattr.h>

namespace osquery {
#if defined(__APPLE__)
#define listxattr(path, buffer, buffer_size) \
::listxattr(path, buffer, buffer_size, 0)

#define getxattr(path, attr_name, buffer, buffer_size) \
::getxattr(path, attr_name, buffer, buffer_size, 0, 0)
#endif

Status getExtendedAttributeNameList(std::vector<std::string>& name_list,
const std::string& path) {
name_list = {};

auto buffer_size = listxattr(path.c_str(), nullptr, 0);
if (buffer_size == 0) {
return Status::success();

} else if (buffer_size < 0) {
return Status::failure(
"Failed to determine the length the extended attribute list for the "
"following path: " +
path);
}

std::vector<char> buffer(static_cast<std::size_t>(buffer_size), 0);

auto err = listxattr(path.c_str(), buffer.data(), buffer.size());
if (err == 0) {
return Status::success();

} else if (err < 0) {
return Status::failure(
"Failed to list the extended attributes for the following path: " +
path);
}

if (err < buffer_size) {
buffer.resize(static_cast<std::size_t>(err));

} else if (err > buffer_size) {
return Status::failure(
"Failed to list the extended attributes for the following path: " +
path +
". The list of extended attributes has changed while it was being "
"acquired.");
}

std::size_t start_index{0U};
for (std::size_t i{0U}; i < buffer.size(); ++i) {
if (buffer.at(i) != 0) {
continue;
}

const char* name_ptr = buffer.data() + start_index;
auto name_length = i - start_index;
start_index = i + 1U;

auto name = std::string(name_ptr, name_length);
name_list.push_back(std::move(name));
}

return Status::success();
}

Status getExtendedAttributeValue(ExtendedAttributeValue& value,
const std::string& path,
const std::string& name) {
value = {};

auto buffer_size = getxattr(path.c_str(), name.c_str(), nullptr, 0);
if (buffer_size == 0) {
return Status::success();

} else if (buffer_size < 0) {
return Status::failure(
"Failed to determine the length of the extended attribute named '" +
name + "' from the following path: " + path);
}

ExtendedAttributeValue buffer(static_cast<std::size_t>(buffer_size), 0U);

auto err = getxattr(path.c_str(), name.c_str(), buffer.data(), buffer.size());
if (err == 0) {
return Status::success();

} else if (err < 0) {
return Status::failure("Failed to acquire the extended attribute named '" +
name + "' from the following path: " + path);
}

if (err < buffer_size) {
buffer.resize(static_cast<std::size_t>(err));

} else if (err > buffer_size) {
return Status::failure("Failed to acquire the extended attribute named '" +
name + "' from the following path: " + path +
". The extended attribute value has been changed "
"while it was being acquired.");
}

value = std::move(buffer);
return Status::success();
}

Status getExtendedAttributes(ExtendedAttributeMap& xattr_map,
const std::string& path) {
xattr_map = {};

std::vector<std::string> name_list;
auto status = getExtendedAttributeNameList(name_list, path);
if (!status.ok()) {
return status;
}

for (const auto& name : name_list) {
ExtendedAttributeValue value;
status = getExtendedAttributeValue(value, path, name);
if (!status.ok()) {
LOG(ERROR) << status.getMessage();
continue;
}

xattr_map.insert({name, std::move(value)});
}

return Status::success();
}
} // namespace osquery
27 changes: 27 additions & 0 deletions osquery/filesystem/posix/xattrs.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/**
* Copyright (c) 2014-present, The osquery authors
*
* This source code is licensed as defined by the LICENSE file found in the
* root directory of this source tree.
*
* SPDX-License-Identifier: (Apache-2.0 OR GPL-2.0-only)
*/

#pragma once

#include <cstdint>
#include <string>
#include <unordered_map>
#include <vector>

#include <osquery/utils/status/status.h>

namespace osquery {
using ExtendedAttributeValue = std::vector<std::uint8_t>;

using ExtendedAttributeMap =
std::unordered_map<std::string, ExtendedAttributeValue>;

Status getExtendedAttributes(ExtendedAttributeMap& xattr_map,
const std::string& path);
} // namespace osquery
Loading

0 comments on commit 76c7733

Please sign in to comment.