Coverage Report

Created: 2025-06-13 06:55

/src/glib/gio/gsandbox.c
Line
Count
Source (jump to first uncovered line)
1
/* GIO - GLib Input, Output and Streaming Library
2
 *
3
 * Copyright 2022 Canonical Ltd
4
 *
5
 * SPDX-License-Identifier: LGPL-2.1-or-later
6
 *
7
 * This library is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU Lesser General Public
9
 * License as published by the Free Software Foundation; either
10
 * version 2.1 of the License, or (at your option) any later version.
11
 *
12
 * This library is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
 * Lesser General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Lesser General
18
 * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
19
 */
20
21
#include "config.h"
22
23
#include "gsandbox.h"
24
25
#include <string.h>
26
27
0
#define SNAP_CONFINEMENT_PREFIX "confinement:"
28
29
static gboolean
30
is_flatpak (void)
31
0
{
32
0
  const char *flatpak_info = "/.flatpak-info";
33
0
  gboolean found;
34
35
#ifdef G_PORTAL_SUPPORT_TEST
36
        char *test_key_file =
37
          g_build_filename (g_get_user_runtime_dir (), flatpak_info, NULL);
38
        flatpak_info = test_key_file;
39
#endif
40
41
0
  found = g_file_test (flatpak_info, G_FILE_TEST_EXISTS);
42
43
#ifdef G_PORTAL_SUPPORT_TEST
44
  g_clear_pointer (&test_key_file, g_free);
45
#endif
46
47
0
  return found;
48
0
}
49
50
static gchar *
51
get_snap_confinement (const char  *snap_yaml,
52
                      GError     **error)
53
0
{
54
0
  char *confinement = NULL;
55
0
  char *yaml_contents;
56
57
0
  if (g_file_get_contents (snap_yaml, &yaml_contents, NULL, error))
58
0
    {
59
0
      const char *line = yaml_contents;
60
61
0
      do
62
0
        {
63
0
          if (g_str_has_prefix (line, SNAP_CONFINEMENT_PREFIX))
64
0
            break;
65
66
0
          line = strchr (line, '\n');
67
0
          if (line)
68
0
            line += 1;
69
0
        }
70
0
      while (line != NULL);
71
72
0
      if (line)
73
0
        {
74
0
          const char *start = line + strlen (SNAP_CONFINEMENT_PREFIX);
75
0
          const char *end = strchr (start, '\n');
76
77
0
          confinement =
78
0
            g_strstrip (end ? g_strndup (start, end-start) : g_strdup (start));
79
0
        }
80
81
0
      g_free (yaml_contents);
82
0
    }
83
84
0
  return g_steal_pointer (&confinement);
85
0
}
86
87
static gboolean
88
is_snap (void)
89
0
{
90
0
  GError *error = NULL;
91
0
  const gchar *snap_path;
92
0
  gchar *yaml_path;
93
0
  char *confinement;
94
0
  gboolean result;
95
96
0
  snap_path = g_getenv ("SNAP");
97
0
  if (snap_path == NULL)
98
0
    return FALSE;
99
100
0
  result = FALSE;
101
0
  yaml_path = g_build_filename (snap_path, "meta", "snap.yaml", NULL);
102
0
  confinement = get_snap_confinement (yaml_path, &error);
103
0
  g_free (yaml_path);
104
105
  /* Classic snaps are de-facto no sandboxed apps, so we can ignore them */
106
0
  if (!error && g_strcmp0 (confinement, "classic") != 0)
107
0
    result = TRUE;
108
109
0
  g_clear_error (&error);
110
0
  g_free (confinement);
111
112
0
  return result;
113
0
}
114
115
/*
116
 * glib_get_sandbox_type:
117
 *
118
 * Gets the type of sandbox this process is running inside.
119
 *
120
 * Checking for sandboxes may involve doing blocking I/O calls, but should not take
121
 * any significant time.
122
 *
123
 * The sandbox will not change over the lifetime of the process, so calling this
124
 * function once and reusing the result is valid.
125
 *
126
 * If this process is not sandboxed then @G_SANDBOX_TYPE_UNKNOWN will be returned.
127
 * This is because this function only detects known sandbox types in #GSandboxType.
128
 * It may be updated in the future if new sandboxes come into use.
129
 *
130
 * Returns: a #GSandboxType.
131
 */
132
GSandboxType
133
glib_get_sandbox_type (void)
134
0
{
135
0
  if (is_flatpak ())
136
0
    return G_SANDBOX_TYPE_FLATPAK;
137
0
  else if (is_snap ())
138
0
    return G_SANDBOX_TYPE_SNAP;
139
0
  else
140
0
    return G_SANDBOX_TYPE_UNKNOWN;
141
0
}