[NetworkManager-fortisslvpn] pppd: chroot into an empty directory when /dev/ppp is open
- From: Lubomir Rintel <lkundrak src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [NetworkManager-fortisslvpn] pppd: chroot into an empty directory when /dev/ppp is open
- Date: Tue, 26 Mar 2019 09:45:28 +0000 (UTC)
commit 62db6d97bb545395ce6ad140bd4507569585e14c
Author: Lubomir Rintel <lkundrak v3 sk>
Date: Tue Mar 26 10:30:12 2019 +0100
pppd: chroot into an empty directory when /dev/ppp is open
This reduces the chance pppd does something stupid. It almost always does,
by executing /etc/ppp/ip-up, and it can not be told not to.
src/nm-fortisslvpn-pppd-plugin.c | 60 ++++++++++++++++++++++++++++++++++++++--
1 file changed, 58 insertions(+), 2 deletions(-)
---
diff --git a/src/nm-fortisslvpn-pppd-plugin.c b/src/nm-fortisslvpn-pppd-plugin.c
index 251b062..e957b54 100644
--- a/src/nm-fortisslvpn-pppd-plugin.c
+++ b/src/nm-fortisslvpn-pppd-plugin.c
@@ -34,7 +34,10 @@
#include <netinet/in.h>
#include <arpa/inet.h>
#include <dlfcn.h>
+#include <fcntl.h>
#include <stdlib.h>
+#include <unistd.h>
+#include <glib/gstdio.h>
#include "nm-fortisslvpn-pppd-service-dbus.h"
#include "nm-fortisslvpn-service.h"
@@ -77,6 +80,57 @@ int plugin_init (void);
char pppd_version[] = VERSION;
+static void
+chroot_sandbox (void)
+{
+ static int chrooted = 0;
+ GError *error = NULL;
+ int parentfd = -1;
+ gchar *tmpdir;
+ gchar *tmp;
+
+ if (chrooted)
+ return;
+ chrooted = 1;
+
+ tmpdir = g_dir_make_tmp (NULL, &error);
+ if (tmpdir == NULL) {
+ _LOGW ("Can't create a temporary directory name: %s", error->message);
+ g_error_free (error);
+ return;
+ }
+
+ tmp = g_path_get_dirname (tmpdir);
+ g_printerr ("{%s} {%s}\n", tmpdir, tmp);
+ parentfd = open (tmp, 0);
+ if (parentfd == -1) {
+ _LOGW ("Can't open '%s': %s", tmp, strerror (errno));
+ goto cleanup;
+ }
+ g_clear_pointer (&tmp, g_free);
+
+ if (chroot (tmpdir) == -1) {
+ _LOGW ("Chroot to '%s' failed: %s", tmpdir, strerror (errno));
+ goto cleanup;
+ }
+
+ tmp = g_path_get_basename (tmpdir);
+ g_printerr ("{%s} {%s}\n", tmpdir, tmp);
+ if (unlinkat (parentfd, tmp, AT_REMOVEDIR) == -1) {
+ _LOGW ("Unlink of '%s' failed: %s", tmpdir, strerror (errno));
+ }
+ g_clear_pointer (&tmpdir, g_free);
+
+cleanup:
+ g_clear_pointer (&tmp, g_free);
+ if (parentfd != -1)
+ close (parentfd);
+ if (tmpdir) {
+ g_remove (tmpdir);
+ g_free (tmpdir);
+ }
+}
+
static void
nm_phasechange (void *data, int arg)
{
@@ -144,8 +198,10 @@ nm_phasechange (void *data, int arg)
break;
}
- _LOGI ("phasechange: status %d / phase '%s'",
- ppp_status, ppp_phase);
+ _LOGI ("phasechange: status %d / phase '%s'", ppp_status, ppp_phase);
+
+ if (ppp_status > NM_PPP_STATUS_SERIALCONN)
+ chroot_sandbox ();
if (ppp_status != NM_PPP_STATUS_UNKNOWN) {
nmdbus_fortisslvpn_ppp_call_set_state (gl.proxy,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]