Now patch builds, but apparently unsharing still does not work because, even if the parameter is set via option, this->unshare_net is not updated with the correct value.
Suggestions welcome :)
Description: Add support for unshare(CLONE_NEWNET) Author: Luca Falavigna <dktrkr...@debian.org> Bug-Debian: https://bugs.debian.org/802849 Index: schroot-1.6.10/CMakeLists.txt =================================================================== --- schroot-1.6.10.orig/CMakeLists.txt +++ schroot-1.6.10/CMakeLists.txt @@ -274,6 +274,18 @@ endif (DOXYGEN_EXECUTABLE) option(doxygen "Enable doxygen documentation" ${DOXYGEN_DEFAULT}) set(BUILD_DOXYGEN ${doxygen}) +# Namespace unshare feature +# sched.h ==> UNSHARE_HEADER +check_include_file_cxx (sched.h UNSHARE_HEADER) +check_function_exists(unshare UNSHARE_FUNC) +set(UNSHARE_DEFAULT OFF) +if (UNSHARE_HEADER AND UNSHARE_FUNC) + set (UNSHARE_DEFAULT ON) +endif (UNSHARE_HEADER AND UNSHARE_FUNC) +option(unshare "Enable unshare support (Linux only)" ${UNSHARE_DEFAULT}) +set(BUILD_UNSHARE ${unshare}) +set(SBUILD_FEATURE_UNSHARE ${unshare}) + # Kernel personality feature # sys/personality.h ==> PERSONALITY_HEADER check_include_file_cxx (sys/personality.h PERSONALITY_HEADER) Index: schroot-1.6.10/sbuild/CMakeLists.txt =================================================================== --- schroot-1.6.10.orig/sbuild/CMakeLists.txt +++ schroot-1.6.10/sbuild/CMakeLists.txt @@ -80,6 +80,13 @@ if(BUILD_UNION) sbuild-chroot-facet-union.cc) endif(BUILD_UNION) +if(BUILD_UNSHARE) + set(public_unshare_h_sources + sbuild-chroot-facet-unshare.h) + set(public_unshare_cc_sources + sbuild-chroot-facet-unshare.cc) +endif(BUILD_UNSHARE) + set(public_h_sources sbuild-basic-keyfile.h sbuild-basic-keyfile.tcc Index: schroot-1.6.10/sbuild/sbuild-chroot-facet-unshare.cc =================================================================== --- /dev/null +++ schroot-1.6.10/sbuild/sbuild-chroot-facet-unshare.cc @@ -0,0 +1,159 @@ +/* Copyright © 2005-2009 Roger Leigh <rle...@debian.org> + * + * schroot is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * schroot is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + * + *********************************************************************/ + +#include <config.h> + +#include "sbuild-chroot.h" +#include "sbuild-chroot-facet-unshare.h" +#include "sbuild-feature.h" + +#include <boost/format.hpp> + +#ifdef SBUILD_FEATURE_UNSHARE +#include <sched.h> +#endif // SBUILD_FEATURE_UNSHARE + +using boost::format; +using namespace sbuild; + +namespace +{ + + typedef std::pair<chroot_facet_unshare::error_code,const char *> emap; + + /** + * This is a list of the supported error codes. It's used to + * construct the real error codes map. + */ + emap init_errors[] = + { + // TRANSLATORS: %1% = integer personality ID + emap(chroot_facet_unshare::UNSHARE, + N_("Could not unshare process execution context")) + }; + +#ifdef SBUILD_FEATURE_UNSHARE + sbuild::feature feature_unshare + ("UNSHARE", + N_("Linux dissassociation of shared execution context")); +#endif + +} + +template<> +error<chroot_facet_unshare::error_code>::map_type +error<chroot_facet_unshare::error_code>::error_strings +(init_errors, + init_errors + (sizeof(init_errors) / sizeof(init_errors[0]))); + +chroot_facet_unshare::chroot_facet_unshare (): + chroot_facet(), + unshare_net(false) +{ +} + +chroot_facet_unshare::~chroot_facet_unshare () +{ +} + +chroot_facet_unshare::ptr +chroot_facet_unshare::create () +{ + return ptr(new chroot_facet_unshare()); +} + +chroot_facet::ptr +chroot_facet_unshare::clone () const +{ + return ptr(new chroot_facet_unshare(*this)); +} + +std::string const& +chroot_facet_unshare::get_name () const +{ + static const std::string name("unshare"); + + return name; +} + +bool +chroot_facet_unshare::get_unshare_net () const +{ + return this->unshare_net; +} + +void +chroot_facet_unshare::set_unshare_net (bool unshare_net) +{ + this->unshare_net = unshare_net; +} + +void +chroot_facet_unshare::unshare () const +{ + if (this->unshare_net) + { + log_debug(DEBUG_INFO) << "Unsharing network" << std::endl; + if (::unshare(CLONE_NEWNET) < 0) + throw error(UNSHARE, strerror(errno)); + } +} + +void +chroot_facet_unshare::setup_env (chroot const& chroot, + environment& env) const +{ +} + +sbuild::chroot::session_flags +chroot_facet_unshare::get_session_flags (chroot const& chroot) const +{ + return sbuild::chroot::SESSION_NOFLAGS; +} + +void +chroot_facet_unshare::get_details (chroot const& chroot, + format_detail& detail) const +{ + detail.add(_("Unshare Networking"), get_unshare_net()); +} + +void +chroot_facet_unshare::get_used_keys (string_list& used_keys) const +{ + used_keys.push_back("unshare.net"); +} + +void +chroot_facet_unshare::get_keyfile (chroot const& chroot, + keyfile& keyfile) const +{ + keyfile::set_object_value(*this, &chroot_facet_unshare::get_unshare_net, + keyfile, chroot.get_name(), "unshare.net"); +} + +void +chroot_facet_unshare::set_keyfile (chroot& chroot, + keyfile const& keyfile, + string_list& used_keys) +{ + keyfile::get_object_value(*this, &chroot_facet_unshare::set_unshare_net, + keyfile, chroot.get_name(), "unshare.net", + keyfile::PRIORITY_OPTIONAL); +} + Index: schroot-1.6.10/sbuild/sbuild-chroot-facet-unshare.h =================================================================== --- /dev/null +++ schroot-1.6.10/sbuild/sbuild-chroot-facet-unshare.h @@ -0,0 +1,129 @@ +/* Copyright © 2005-2009 Roger Leigh <rle...@debian.org> + * + * schroot is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * schroot is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + * + *********************************************************************/ + +#ifndef SBUILD_CHROOT_FACET_UNSHARE_H +#define SBUILD_CHROOT_FACET_UNSHARE_H + +#include <sbuild/sbuild-chroot-facet.h> + +namespace sbuild +{ + + /** + * Chroot support for unsharing process execution context + */ + class chroot_facet_unshare : public chroot_facet + { + public: + /// A shared_ptr to a chroot facet object. + typedef std::shared_ptr<chroot_facet_unshare> ptr; + + /// A shared_ptr to a const chroot facet object. + typedef std::shared_ptr<const chroot_facet_unshare> const_ptr; + + /// Error codes. + enum error_code + { + UNSHARE ///< Could not unshare process execution context + }; + + /// Exception type. + typedef custom_error<error_code> error; + + private: + /// The constructor. + chroot_facet_unshare (); + + public: + /// The destructor. + virtual ~chroot_facet_unshare (); + + /** + * Create a chroot facet. + * + * @returns a shared_ptr to the new chroot facet. + */ + static ptr + create (); + + virtual chroot_facet::ptr + clone () const; + + virtual std::string const& + get_name () const; + + /** + * Is networking unshared? + * + * @returns true if unsharing networking, otherwise false. + */ + bool + get_unshare_net () const; + + /** + * Set network unsharing. + * + * @param unshare unshare networking? + */ + void + set_unshare_net (bool unshare); + + /** + * Unshare process execution context. + */ + void + unshare () const; + + virtual void + setup_env (chroot const& chroot, + environment& env) const; + + virtual chroot::session_flags + get_session_flags (chroot const& chroot) const; + + virtual void + get_details (chroot const& chroot, + format_detail& detail) const; + + virtual void + get_used_keys (string_list& used_keys) const; + + virtual void + get_keyfile (chroot const& chroot, + keyfile& keyfile) const; + + virtual void + set_keyfile (chroot& chroot, + keyfile const& keyfile, + string_list& used_keys); + + private: + /// Unshare networking. + bool unshare_net; + }; + +} + +#endif /* SBUILD_CHROOT_FACET_UNSHARE_H */ + +/* + * Local Variables: + * mode:C++ + * End: + */ + Index: schroot-1.6.10/sbuild/sbuild-chroot.cc =================================================================== --- schroot-1.6.10.orig/sbuild/sbuild-chroot.cc +++ schroot-1.6.10/sbuild/sbuild-chroot.cc @@ -42,6 +42,9 @@ #include "sbuild-chroot-facet-session-clonable.h" #include "sbuild-chroot-facet-source.h" #include "sbuild-chroot-facet-userdata.h" +#ifdef SBUILD_FEATURE_UNSHARE +#include <sbuild-chroot-facet-unshare.h> +#endif // SBUILD_FEATURE_UNSHARE #include "sbuild-fdstream.h" #include "sbuild-lock.h" @@ -126,6 +129,9 @@ sbuild::chroot::chroot (): facets() { add_facet(sbuild::chroot_facet_personality::create()); +#ifdef SBUILD_FEATURE_UNSHARE + add_facet(sbuild::chroot_facet_unshare::create()); +#endif // SBUILD_FEATURE_UNSHARE add_facet(sbuild::chroot_facet_session_clonable::create()); add_facet(sbuild::chroot_facet_userdata::create()); Index: schroot-1.6.10/sbuild/sbuild-session.cc =================================================================== --- schroot-1.6.10.orig/sbuild/sbuild-session.cc +++ schroot-1.6.10/sbuild/sbuild-session.cc @@ -23,6 +23,9 @@ #include "sbuild-chroot-facet-session.h" #include "sbuild-chroot-facet-session-clonable.h" #include "sbuild-chroot-facet-userdata.h" +#ifdef SBUILD_FEATURE_UNSHARE +#include "sbuild-chroot-facet-unshare.h" +#endif // SBUILD_FEATURE_UNSHARE #ifdef SBUILD_FEATURE_PAM #include "sbuild-auth-pam.h" #include "sbuild-auth-pam-conv.h" @@ -723,6 +726,13 @@ session::run_impl () /* Run recover scripts. */ setup_chroot(chroot, chroot::SETUP_RECOVER); +#ifdef SBUILD_FEATURE_UNSHARE + /* Unshare execution context */ + chroot_facet_unshare::const_ptr pu = chroot->get_facet<chroot_facet_unshare>(); + if (pu) + pu->unshare(); +#endif // SBUILD_FEATURE_UNSHARE + /* Run session if setup succeeded. */ if (this->session_operation == OPERATION_AUTOMATIC || this->session_operation == OPERATION_RUN) Index: schroot-1.6.10/sbuild/Makefile.am =================================================================== --- schroot-1.6.10.orig/sbuild/Makefile.am +++ schroot-1.6.10/sbuild/Makefile.am @@ -108,6 +108,11 @@ sbuild_public_union_h_sources = \ sbuild-chroot-facet-union.h endif +if BUILD_UNSHARE +sbuild_public_unshare_h_sources = \ + sbuild-chroot-facet-unshare.h +endif + sbuild_public_cc_sources = \ sbuild-auth.cc \ sbuild-auth-null.cc \ @@ -179,6 +184,11 @@ sbuild_public_union_cc_sources = \ sbuild-chroot-facet-union.cc endif +if BUILD_UNSHARE +sbuild_public_unshare_cc_sources = \ + sbuild-chroot-facet-unshare.cc +endif + pkgincludedir = $(includedir)/sbuild pkginclude_HEADERS = \ @@ -188,7 +198,8 @@ pkginclude_HEADERS = \ $(sbuild_public_lvmsnap_h_sources) \ $(sbuild_public_btrfssnap_h_sources) \ $(sbuild_public_loopback_h_sources) \ - $(sbuild_public_union_h_sources) + $(sbuild_public_union_h_sources) \ + $(sbuild_public_unshare_h_sources) libsbuild_la_SOURCES = \ $(sbuild_public_h_sources) \ @@ -206,7 +217,9 @@ libsbuild_la_SOURCES = \ $(sbuild_public_loopback_h_sources) \ $(sbuild_public_loopback_cc_sources) \ $(sbuild_public_union_h_sources) \ - $(sbuild_public_union_cc_sources) + $(sbuild_public_union_cc_sources) \ + $(sbuild_public_unshare_h_sources) \ + $(sbuild_public_unshare_cc_sources) nodist_libsbuild_la_SOURCES = \ sbuild-config.h Index: schroot-1.6.10/etc/setup.d/60unshare =================================================================== --- /dev/null +++ schroot-1.6.10/etc/setup.d/60unshare @@ -0,0 +1,40 @@ +#!/bin/sh +# Copyright © 2012 Roger Leigh <rle...@debian.org> +# +# schroot is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# schroot is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see +# <http://www.gnu.org/licenses/>. +# +##################################################################### + +# Disassociates process execution context inside the chroot. +# If unsharing network CLONE_NEWNET, this has stopped all networking. +# We therefore need to bring up the lo interface to have working +# loopback. + +set -e + +. "$SETUP_DATA_DIR/common-data" +. "$SETUP_DATA_DIR/common-functions" +. "$SETUP_DATA_DIR/common-config" + +if [ $STAGE = "exec-start" ]; then + + if [ "$UNSHARE_NEWNET" = "true" ]; then + info "Bringing up netdev lo" + ip link set dev lo up + fi + +fi + + Index: schroot-1.6.10/test/test-sbuild-chroot.h =================================================================== --- schroot-1.6.10.orig/test/test-sbuild-chroot.h +++ schroot-1.6.10/test/test-sbuild-chroot.h @@ -29,6 +29,9 @@ #ifdef SBUILD_FEATURE_UNION #include <sbuild/sbuild-chroot-facet-union.h> #endif // SBUILD_FEATURE_UNION +#ifdef SBUILD_FEATURE_UNSHARE +#include <sbuild/sbuild-chroot-facet-unshare.h> +#endif // SBUILD_FEATURE_UNSHARE #include <sbuild/sbuild-chroot-facet-userdata.h> #include <sbuild/sbuild-i18n.h> #include <sbuild/sbuild-types.h> @@ -269,6 +272,10 @@ public: keyfile.set_value(group, "setup.fstab", "default/fstab"); keyfile.set_value(group, "setup.nssdatabases", "default/nssdatabases"); keyfile.set_value(group, "custom.test1", "testval"); +#ifdef SBUILD_FEATURE_UNSHARE + keyfile.set_value(group, "unshare.net", "false"); +#endif // SBUILD_FEATURE_UNSHARE + } void setup_keyfile_session (sbuild::keyfile& keyfile,