Add resolv-conf parser
This commit is contained in:
parent
1acfec6b12
commit
d35d98d551
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -22,3 +22,6 @@
|
||||
[submodule "deps/ringbuf"]
|
||||
path = deps/ringbuf
|
||||
url = https://github.com/agerasev/ringbuf.git
|
||||
[submodule "deps/resolv-conf"]
|
||||
path = deps/resolv-conf
|
||||
url = https://github.com/tailhook/resolv-conf.git
|
||||
|
1
Makefile
1
Makefile
@ -35,6 +35,7 @@ submodule: githooks
|
||||
@# Try to apply the patches. If failed, check if the patches are already applied
|
||||
cd deps/serde-json-sgx && git apply ../serde-json-sgx.patch >/dev/null 2>&1 || git apply ../serde-json-sgx.patch -R --check
|
||||
cd deps/ringbuf && git apply ../ringbuf.patch >/dev/null 2>&1 || git apply ../ringbuf.patch -R --check
|
||||
cd deps/resolv-conf && git apply ../resolv-conf.patch >/dev/null 2>&1 || git apply ../resolv-conf.patch -R --check
|
||||
|
||||
@# Enclaves used by tools are running in simulation mode by default to run faster.
|
||||
@rm -rf build build_sim
|
||||
|
@ -24,7 +24,6 @@ then
|
||||
fi
|
||||
|
||||
mkdir -p image/etc
|
||||
cp /etc/resolv.conf image/etc
|
||||
cp ../greeter_client image/bin
|
||||
cp $INSTALL_DIR/lib/libprotobuf.so.3.10.0.0 image/lib
|
||||
cp $INSTALL_DIR/lib/libcares.so.2 image/lib
|
||||
|
@ -23,7 +23,6 @@ then
|
||||
fi
|
||||
|
||||
mkdir -p image/etc
|
||||
cp /etc/resolv.conf image/etc
|
||||
cp ../greeter_server image/bin
|
||||
cp $INSTALL_DIR/lib/libprotobuf.so.3.10.0.0 image/lib
|
||||
cp $INSTALL_DIR/lib/libcares.so.2 image/lib
|
||||
|
1
deps/resolv-conf
vendored
Submodule
1
deps/resolv-conf
vendored
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit c0752810e748d496c2df161a2a90c3c229b65531
|
80
deps/resolv-conf.patch
vendored
Normal file
80
deps/resolv-conf.patch
vendored
Normal file
@ -0,0 +1,80 @@
|
||||
From 9faee3943a31e359e76c5dfce23918c35fd8f317 Mon Sep 17 00:00:00 2001
|
||||
From: ClawSeven <zehuan97@gmail.com>
|
||||
Date: Fri, 9 Jul 2021 13:28:42 +0800
|
||||
Subject: [PATCH] Transplant resolv-conf into sgx-world
|
||||
|
||||
---
|
||||
Cargo.toml | 3 ++-
|
||||
src/config.rs | 2 ++
|
||||
src/grammar.rs | 1 +
|
||||
src/ip.rs | 1 +
|
||||
src/lib.rs | 3 +++
|
||||
5 files changed, 9 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/Cargo.toml b/Cargo.toml
|
||||
index 0022252..617e319 100644
|
||||
--- a/Cargo.toml
|
||||
+++ b/Cargo.toml
|
||||
@@ -14,7 +14,8 @@ version = "0.7.0"
|
||||
authors = ["paul@colomiets.name"]
|
||||
|
||||
[dependencies]
|
||||
-quick-error = "1.0.0"
|
||||
+quick-error = { git = "https://github.com/mesalock-linux/quick-error-sgx.git" }
|
||||
+sgx_tstd = { git = "https://github.com/apache/teaclave-sgx-sdk.git" }
|
||||
hostname = { version = "^0.3", optional = true }
|
||||
|
||||
[features]
|
||||
diff --git a/src/config.rs b/src/config.rs
|
||||
index b6b6460..8389064 100644
|
||||
--- a/src/config.rs
|
||||
+++ b/src/config.rs
|
||||
@@ -3,6 +3,8 @@ use std::iter::{IntoIterator, Iterator};
|
||||
use std::slice::Iter;
|
||||
use {grammar, Network, ParseError, ScopedIp};
|
||||
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
|
||||
+use std::vec::Vec;
|
||||
+use std::string::String;
|
||||
|
||||
const NAMESERVER_LIMIT:usize = 3;
|
||||
const SEARCH_LIMIT:usize = 6;
|
||||
diff --git a/src/grammar.rs b/src/grammar.rs
|
||||
index 9a274a8..be85081 100644
|
||||
--- a/src/grammar.rs
|
||||
+++ b/src/grammar.rs
|
||||
@@ -1,5 +1,6 @@
|
||||
use std::net::{Ipv4Addr, Ipv6Addr};
|
||||
use std::str::{Utf8Error, from_utf8};
|
||||
+use std::string::ToString;
|
||||
|
||||
use {AddrParseError, Config, Network, Lookup, Family};
|
||||
|
||||
diff --git a/src/ip.rs b/src/ip.rs
|
||||
index c9cfa59..4b4bca2 100644
|
||||
--- a/src/ip.rs
|
||||
+++ b/src/ip.rs
|
||||
@@ -2,6 +2,7 @@ use std::error::Error;
|
||||
use std::fmt;
|
||||
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
|
||||
use std::str::FromStr;
|
||||
+use std::string::{String, ToString};
|
||||
|
||||
/// A network, that is an IP address and a mask
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
diff --git a/src/lib.rs b/src/lib.rs
|
||||
index a55a9d7..094a35a 100644
|
||||
--- a/src/lib.rs
|
||||
+++ b/src/lib.rs
|
||||
@@ -91,6 +91,9 @@
|
||||
#![warn(missing_debug_implementations)]
|
||||
#![warn(missing_docs)]
|
||||
|
||||
+#![no_std]
|
||||
+#[macro_use]
|
||||
+extern crate sgx_tstd as std;
|
||||
#[macro_use]
|
||||
extern crate quick_error;
|
||||
#[cfg(feature = "system")]
|
||||
--
|
||||
2.17.1
|
||||
|
@ -42,7 +42,7 @@ enclave {
|
||||
* EEXIST - The LibOS has already been initialized.
|
||||
* EINVAL - The value of an argument are invalid.
|
||||
*/
|
||||
public int occlum_ecall_init([in, string] const char* log_level, [in, string] const char* instance_dir);
|
||||
public int occlum_ecall_init([in, string] const char* log_level, [in, string] const char* instance_dir, [in, string] const char* resolv_conf_ptr);
|
||||
|
||||
/*
|
||||
* Create a new LibOS process to do the task specified by the given
|
||||
|
@ -22,6 +22,7 @@ rcore-fs-ramfs = { path = "../../deps/sefs/rcore-fs-ramfs" }
|
||||
rcore-fs-mountfs = { path = "../../deps/sefs/rcore-fs-mountfs" }
|
||||
rcore-fs-unionfs = { path = "../../deps/sefs/rcore-fs-unionfs" }
|
||||
rcore-fs-devfs = { path = "../../deps/sefs/rcore-fs-devfs" }
|
||||
resolv-conf = { path = "../../deps/resolv-conf" }
|
||||
serde = { path = "../../deps/serde-sgx/serde", features = ["derive"] }
|
||||
serde_json = { path = "../../deps/serde-json-sgx" }
|
||||
memoffset = "0.6.1"
|
||||
|
@ -12,6 +12,7 @@ use crate::signal::SigNum;
|
||||
use crate::time::up_time::init;
|
||||
use crate::util::log::LevelFilter;
|
||||
use crate::util::mem_util::from_untrusted::*;
|
||||
use crate::util::resolv_conf_util::{parse_resolv_conf, write_resolv_conf};
|
||||
use crate::util::sgx::allow_debug as sgx_allow_debug;
|
||||
use sgx_tse::*;
|
||||
|
||||
@ -23,6 +24,7 @@ lazy_static! {
|
||||
static ref HAS_INIT: AtomicBool = AtomicBool::new(false);
|
||||
pub static ref ENTRY_POINTS: RwLock<Vec<PathBuf>> =
|
||||
RwLock::new(config::LIBOS_CONFIG.entry_points.clone());
|
||||
pub static ref RESOLV_CONF_STR: RwLock<Option<String>> = RwLock::new(None);
|
||||
}
|
||||
|
||||
macro_rules! ecall_errno {
|
||||
@ -33,7 +35,11 @@ macro_rules! ecall_errno {
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn occlum_ecall_init(log_level: *const c_char, instance_dir: *const c_char) -> i32 {
|
||||
pub extern "C" fn occlum_ecall_init(
|
||||
log_level: *const c_char,
|
||||
instance_dir: *const c_char,
|
||||
resolv_conf_ptr: *const c_char,
|
||||
) -> i32 {
|
||||
if HAS_INIT.load(Ordering::SeqCst) == true {
|
||||
return ecall_errno!(EEXIST);
|
||||
}
|
||||
@ -87,6 +93,18 @@ pub extern "C" fn occlum_ecall_init(log_level: *const c_char, instance_dir: *con
|
||||
unsafe { backtrace::enable_backtrace(&ENCLAVE_PATH, PrintFormat::Short) };
|
||||
});
|
||||
|
||||
match parse_resolv_conf(resolv_conf_ptr) {
|
||||
Err(e) => {
|
||||
error!("failed to parse /etc/resolv.conf: {}", e.backtrace());
|
||||
}
|
||||
Ok(resolv_conf_str) => {
|
||||
*RESOLV_CONF_STR.write().unwrap() = Some(resolv_conf_str);
|
||||
if let Err(e) = write_resolv_conf() {
|
||||
error!("failed to write /etc/resolv.conf: {}", e.backtrace());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
0
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
use std::sync::Once;
|
||||
use util::resolv_conf_util::write_resolv_conf;
|
||||
|
||||
use super::rootfs::{mount_nonroot_fs_according_to, open_root_fs_according_to};
|
||||
use super::*;
|
||||
@ -27,5 +28,9 @@ pub fn do_mount_rootfs(
|
||||
*root_inode = new_root_inode;
|
||||
*ENTRY_POINTS.write().unwrap() = user_config.entry_points.to_owned();
|
||||
});
|
||||
// Write resolv.conf file into mounted file system
|
||||
write_resolv_conf()?;
|
||||
*RESOLV_CONF_STR.write().unwrap() = None;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -53,6 +53,7 @@ extern crate serde;
|
||||
extern crate serde_json;
|
||||
#[macro_use]
|
||||
extern crate memoffset;
|
||||
extern crate resolv_conf;
|
||||
|
||||
use sgx_trts::libc;
|
||||
use sgx_types::*;
|
||||
|
@ -5,5 +5,6 @@ pub mod log;
|
||||
pub mod mem_util;
|
||||
pub mod mpx_util;
|
||||
pub mod random;
|
||||
pub mod resolv_conf_util;
|
||||
pub mod sgx;
|
||||
pub mod sync;
|
||||
|
37
src/libos/src/util/resolv_conf_util.rs
Normal file
37
src/libos/src/util/resolv_conf_util.rs
Normal file
@ -0,0 +1,37 @@
|
||||
use super::*;
|
||||
use crate::fs::{AccessMode, CreationFlags, FsView};
|
||||
use resolv_conf::*;
|
||||
use std::ffi::CStr;
|
||||
use std::str;
|
||||
|
||||
pub fn write_resolv_conf() -> Result<()> {
|
||||
const RESOLV_CONF_PATH: &'static str = "/etc/resolv.conf";
|
||||
let fs_view = FsView::new();
|
||||
// overwrite /etc/resolv.conf if existed
|
||||
let resolv_conf_file = fs_view.open_file(
|
||||
RESOLV_CONF_PATH,
|
||||
AccessMode::O_RDWR as u32 | CreationFlags::O_CREAT.bits() | CreationFlags::O_TRUNC.bits(),
|
||||
0o666,
|
||||
)?;
|
||||
let resolv_conf_str = RESOLV_CONF_STR.read().unwrap();
|
||||
match &*resolv_conf_str {
|
||||
Some(str) => {
|
||||
resolv_conf_file.write(str.as_bytes());
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn parse_resolv_conf(resolv_conf_ptr: *const c_char) -> Result<String> {
|
||||
// Read resolv.conf file from host
|
||||
let resolv_conf_bytes = unsafe { CStr::from_ptr(resolv_conf_ptr).to_bytes() };
|
||||
let resolv_conf_str = str::from_utf8(resolv_conf_bytes)
|
||||
.map_err(|_| errno!(EINVAL, "/etc/resolv.conf contains non UTF-8 characters"))?;
|
||||
|
||||
// Parse and inspect resolv.conf file
|
||||
if let Err(_) = resolv_conf::Config::parse(resolv_conf_bytes) {
|
||||
return_errno!(EINVAL, "malformated host /etc/resolv.conf");
|
||||
}
|
||||
Ok(resolv_conf_str.to_string())
|
||||
}
|
@ -2,6 +2,7 @@
|
||||
#include "Enclave_u.h"
|
||||
#include "pal_enclave.h"
|
||||
#include "pal_error.h"
|
||||
#include "pal_load_resolv_conf.h"
|
||||
#include "pal_interrupt_thread.h"
|
||||
#include "pal_log.h"
|
||||
#include "pal_sig_handler.h"
|
||||
@ -103,8 +104,11 @@ int occlum_pal_init(const struct occlum_pal_attr *attr) {
|
||||
eid = pal_get_enclave_id();
|
||||
|
||||
int ecall_ret = 0;
|
||||
const char *resolv_conf_ptr = pal_load_resolv_conf();
|
||||
sgx_status_t ecall_status = occlum_ecall_init(eid, &ecall_ret, attr->log_level,
|
||||
resolved_path);
|
||||
resolved_path, resolv_conf_ptr);
|
||||
free((void *)resolv_conf_ptr);
|
||||
resolv_conf_ptr = NULL;
|
||||
if (ecall_status != SGX_SUCCESS) {
|
||||
const char *sgx_err = pal_get_sgx_error_msg(ecall_status);
|
||||
PAL_ERROR("Failed to do ECall with error code 0x%x: %s", ecall_status, sgx_err);
|
||||
|
24
src/pal/src/pal_load_resolv_conf.c
Normal file
24
src/pal/src/pal_load_resolv_conf.c
Normal file
@ -0,0 +1,24 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "pal_log.h"
|
||||
|
||||
char *pal_load_resolv_conf(void) {
|
||||
FILE *fp = fopen("/etc/resolv.conf", "rb");
|
||||
|
||||
if (fp == NULL) {
|
||||
PAL_WARN("Warning: Failed to open /etc/resolv.conf file");
|
||||
return NULL;
|
||||
}
|
||||
fseek(fp, 0, SEEK_END);
|
||||
long fsize = ftell(fp);
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
char *resolv_conf_buffer = malloc(fsize + 1);
|
||||
if (resolv_conf_buffer == NULL) {
|
||||
PAL_WARN("Warning: Failed to malloc for /etc/resolv.conf buffer");
|
||||
return NULL;
|
||||
}
|
||||
fread(resolv_conf_buffer, 1, fsize, fp);
|
||||
resolv_conf_buffer[fsize] = 0;
|
||||
fclose(fp);
|
||||
return resolv_conf_buffer;
|
||||
}
|
6
src/pal/src/pal_load_resolv_conf.h
Normal file
6
src/pal/src/pal_load_resolv_conf.h
Normal file
@ -0,0 +1,6 @@
|
||||
#ifndef __PAL_LOAD_RESOLV_CONF_H__
|
||||
#define __PAL_LOAD_RESOLV_CONF_H__
|
||||
|
||||
char *pal_load_resolv_conf(void);
|
||||
|
||||
#endif /* __PAL_LOAD_RESOLV_CONF_H__ */
|
@ -16,7 +16,7 @@ FAIL_LOG = $(BUILD_DIR)/test/.fail
|
||||
TEST_DEPS := client data_sink naughty_child
|
||||
# Tests: need to be compiled and run by test-% target
|
||||
TESTS ?= env empty hello_world malloc mmap file fs_perms getpid spawn sched pipe time timerfd \
|
||||
truncate readdir mkdir open stat link symlink chmod chown tls pthread system_info rlimit \
|
||||
truncate readdir mkdir open stat link symlink chmod chown tls pthread system_info resolv_conf rlimit \
|
||||
server server_epoll unix_socket cout hostfs cpuid rdtsc device sleep exit_group \
|
||||
ioctl fcntl eventfd emulate_syscall access signal sysinfo prctl rename procfs wait \
|
||||
spawn_attribute exec statfs
|
||||
|
5
test/resolv_conf/Makefile
Normal file
5
test/resolv_conf/Makefile
Normal file
@ -0,0 +1,5 @@
|
||||
include ../test_common.mk
|
||||
|
||||
EXTRA_C_FLAGS :=
|
||||
EXTRA_LINK_FLAGS :=
|
||||
BIN_ARGS :=
|
48
test/resolv_conf/main.c
Normal file
48
test/resolv_conf/main.c
Normal file
@ -0,0 +1,48 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "test.h"
|
||||
|
||||
// ============================================================================
|
||||
// Helper functions
|
||||
// ============================================================================
|
||||
char *read_resolv_conf(void) {
|
||||
FILE *fp = fopen("/etc/resolv.conf", "rb");
|
||||
fseek(fp, 0, SEEK_END);
|
||||
long fsize = ftell(fp);
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
char *resolv_conf_buffer = malloc(fsize + 1);
|
||||
if (resolv_conf_buffer == NULL) {
|
||||
printf("ERROR: Failed to malloc for /etc/resolv.conf buffer");
|
||||
return NULL;
|
||||
}
|
||||
fread(resolv_conf_buffer, 1, fsize, fp);
|
||||
fclose(fp);
|
||||
return resolv_conf_buffer;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Test cases for resolv.conf file
|
||||
// ============================================================================
|
||||
|
||||
int test_resolv_conf() {
|
||||
char *buffer = read_resolv_conf();
|
||||
if (buffer == NULL) {
|
||||
THROW_ERROR("failed to read resolv.conf");
|
||||
}
|
||||
printf("%s", buffer);
|
||||
free(buffer);
|
||||
buffer = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static test_case_t test_cases[] = {
|
||||
TEST_CASE(test_resolv_conf),
|
||||
};
|
||||
|
||||
// ============================================================================
|
||||
// Test suite main
|
||||
// ============================================================================
|
||||
|
||||
int main() {
|
||||
return test_suite_run(test_cases, ARRAY_SIZE(test_cases));
|
||||
}
|
Loading…
Reference in New Issue
Block a user