kiss-flatpak

Flatpak for KISS Linux.
git clone https://git.stjo.hn/kiss-flatpak
Log | Files | Refs | README | LICENSE

no-libcap.patch (8974B)


      1 diff --git a/app/flatpak-builtins-enter.c b/app/flatpak-builtins-enter.c
      2 index 44e14e9..26ea6b0 100644
      3 --- a/app/flatpak-builtins-enter.c
      4 +++ b/app/flatpak-builtins-enter.c
      5 @@ -36,21 +36,11 @@
      6  #include "flatpak-dbus-generated.h"
      7  #include "flatpak-run-private.h"
      8  #include "flatpak-instance.h"
      9 -#include <sys/capability.h>
     10  
     11  static GOptionEntry options[] = {
     12    { NULL }
     13  };
     14  
     15 -static void
     16 -drop_all_caps (void)
     17 -{
     18 -  struct __user_cap_header_struct hdr = { _LINUX_CAPABILITY_VERSION_3, 0 };
     19 -  struct __user_cap_data_struct data[2] = { { 0 } };
     20 -
     21 -  capset (&hdr, data);
     22 -}
     23 -
     24  gboolean
     25  flatpak_builtin_enter (int           argc,
     26                         char        **argv,
     27 @@ -242,8 +232,6 @@ flatpak_builtin_enter (int           argc,
     28    if (setuid (uid))
     29      return flatpak_fail (error, _("Can't switch uid"));
     30  
     31 -  drop_all_caps ();
     32 -
     33    envp_array = g_ptr_array_new_with_free_func (g_free);
     34    for (e = environment; e < environment + environment_len; e = e + strlen (e) + 1)
     35      {
     36 diff --git a/subprojects/bubblewrap/bubblewrap.c b/subprojects/bubblewrap/bubblewrap.c
     37 index fc2edbb..704e9e8 100644
     38 --- a/subprojects/bubblewrap/bubblewrap.c
     39 +++ b/subprojects/bubblewrap/bubblewrap.c
     40 @@ -28,7 +28,6 @@
     41  #include <sys/eventfd.h>
     42  #include <sys/fsuid.h>
     43  #include <sys/signalfd.h>
     44 -#include <sys/capability.h>
     45  #include <sys/prctl.h>
     46  #include <linux/sched.h>
     47  #include <linux/seccomp.h>
     48 @@ -593,70 +592,17 @@ static uint32_t requested_caps[2] = {0, 0};
     49  static void
     50  set_required_caps (void)
     51  {
     52 -  struct __user_cap_header_struct hdr = { _LINUX_CAPABILITY_VERSION_3, 0 };
     53 -  struct __user_cap_data_struct data[2] = { { 0 } };
     54 -
     55 -  /* Drop all non-require capabilities */
     56 -  data[0].effective = REQUIRED_CAPS_0;
     57 -  data[0].permitted = REQUIRED_CAPS_0;
     58 -  data[0].inheritable = 0;
     59 -  data[1].effective = REQUIRED_CAPS_1;
     60 -  data[1].permitted = REQUIRED_CAPS_1;
     61 -  data[1].inheritable = 0;
     62 -  if (capset (&hdr, data) < 0)
     63 -    die_with_error ("capset failed");
     64  }
     65  
     66  static void
     67  drop_all_caps (bool keep_requested_caps)
     68  {
     69 -  struct __user_cap_header_struct hdr = { _LINUX_CAPABILITY_VERSION_3, 0 };
     70 -  struct __user_cap_data_struct data[2] = { { 0 } };
     71 -
     72 -  if (keep_requested_caps)
     73 -    {
     74 -      /* Avoid calling capset() unless we need to; currently
     75 -       * systemd-nspawn at least is known to install a seccomp
     76 -       * policy denying capset() for dubious reasons.
     77 -       * <https://github.com/projectatomic/bubblewrap/pull/122>
     78 -       */
     79 -      if (!opt_cap_add_or_drop_used && real_uid == 0)
     80 -        {
     81 -          assert (!is_privileged);
     82 -          return;
     83 -        }
     84 -      data[0].effective = requested_caps[0];
     85 -      data[0].permitted = requested_caps[0];
     86 -      data[0].inheritable = requested_caps[0];
     87 -      data[1].effective = requested_caps[1];
     88 -      data[1].permitted = requested_caps[1];
     89 -      data[1].inheritable = requested_caps[1];
     90 -    }
     91 -
     92 -  if (capset (&hdr, data) < 0)
     93 -    {
     94 -      /* While the above logic ensures we don't call capset() for the primary
     95 -       * process unless configured to do so, we still try to drop privileges for
     96 -       * the init process unconditionally. Since due to the systemd seccomp
     97 -       * filter that will fail, let's just ignore it.
     98 -       */
     99 -      if (errno == EPERM && real_uid == 0 && !is_privileged)
    100 -        return;
    101 -      else
    102 -        die_with_error ("capset failed");
    103 -    }
    104  }
    105  
    106  static bool
    107  has_caps (void)
    108  {
    109 -  struct __user_cap_header_struct hdr = { _LINUX_CAPABILITY_VERSION_3, 0 };
    110 -  struct __user_cap_data_struct data[2] = { { 0 } };
    111 -
    112 -  if (capget (&hdr, data)  < 0)
    113 -    die_with_error ("capget failed");
    114 -
    115 -  return data[0].permitted != 0 || data[1].permitted != 0;
    116 +  return 0;
    117  }
    118  
    119  /* Most of the code here is used both to add caps to the ambient capabilities
    120 @@ -666,49 +612,6 @@ has_caps (void)
    121  static void
    122  prctl_caps (uint32_t *caps, bool do_cap_bounding, bool do_set_ambient)
    123  {
    124 -  unsigned long cap;
    125 -
    126 -  /* We ignore both EINVAL and EPERM, as we are actually relying
    127 -   * on PR_SET_NO_NEW_PRIVS to ensure the right capabilities are
    128 -   * available.  EPERM in particular can happen with old, buggy
    129 -   * kernels.  See:
    130 -   *  https://github.com/projectatomic/bubblewrap/pull/175#issuecomment-278051373
    131 -   *  https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/security/commoncap.c?id=160da84dbb39443fdade7151bc63a88f8e953077
    132 -   */
    133 -  for (cap = 0; cap <= CAP_LAST_CAP; cap++)
    134 -    {
    135 -      bool keep = FALSE;
    136 -      if (cap < 32)
    137 -        {
    138 -          if (CAP_TO_MASK_0 (cap) & caps[0])
    139 -            keep = TRUE;
    140 -        }
    141 -      else
    142 -        {
    143 -          if (CAP_TO_MASK_1 (cap) & caps[1])
    144 -            keep = TRUE;
    145 -        }
    146 -
    147 -      if (keep && do_set_ambient)
    148 -        {
    149 -#ifdef PR_CAP_AMBIENT
    150 -          int res = prctl (PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, cap, 0, 0);
    151 -          if (res == -1 && !(errno == EINVAL || errno == EPERM))
    152 -            die_with_error ("Adding ambient capability %ld", cap);
    153 -#else
    154 -          /* We ignore the EINVAL that results from not having PR_CAP_AMBIENT
    155 -           * in the current kernel at runtime, so also ignore not having it
    156 -           * in the current kernel headers at compile-time */
    157 -#endif
    158 -        }
    159 -
    160 -      if (!keep && do_cap_bounding)
    161 -        {
    162 -          int res = prctl (PR_CAPBSET_DROP, cap, 0, 0, 0);
    163 -          if (res == -1 && !(errno == EINVAL || errno == EPERM))
    164 -            die_with_error ("Dropping capability %ld from bounds", cap);
    165 -        }
    166 -    }
    167  }
    168  
    169  static void
    170 @@ -755,10 +658,6 @@ acquire_privs (void)
    171    /* Are we setuid ? */
    172    if (real_uid != euid)
    173      {
    174 -      if (euid != 0)
    175 -        die ("Unexpected setuid user %d, should be 0", euid);
    176 -
    177 -      is_privileged = TRUE;
    178        /* We want to keep running as euid=0 until at the clone()
    179         * operation because doing so will make the user namespace be
    180         * owned by root, which makes it not ptrace:able by the user as
    181 @@ -770,19 +669,7 @@ acquire_privs (void)
    182         * escalated filesystem access before the clone(), so we set
    183         * fsuid to the uid.
    184         */
    185 -      if (setfsuid (real_uid) < 0)
    186 -        die_with_error ("Unable to set fsuid");
    187 -
    188 -      /* setfsuid can't properly report errors, check that it worked (as per manpage) */
    189 -      new_fsuid = setfsuid (-1);
    190 -      if (new_fsuid != real_uid)
    191 -        die ("Unable to set fsuid (was %d)", (int)new_fsuid);
    192 -
    193 -      /* We never need capabilities after execve(), so lets drop everything from the bounding set */
    194 -      drop_cap_bounding_set (TRUE);
    195 -
    196 -      /* Keep only the required capabilities for setup */
    197 -      set_required_caps ();
    198 +      die_with_error ("suid disabled, enable user namespaces in the kernel.");
    199      }
    200    else if (real_uid != 0 && has_caps ())
    201      {
    202 @@ -793,18 +680,6 @@ acquire_privs (void)
    203      }
    204    else if (real_uid == 0)
    205      {
    206 -      /* If our uid is 0, default to inheriting all caps; the caller
    207 -       * can drop them via --cap-drop.  This is used by at least rpm-ostree.
    208 -       * Note this needs to happen before the argument parsing of --cap-drop.
    209 -       */
    210 -      struct __user_cap_header_struct hdr = { _LINUX_CAPABILITY_VERSION_3, 0 };
    211 -      struct __user_cap_data_struct data[2] = { { 0 } };
    212 -
    213 -      if (capget (&hdr, data) < 0)
    214 -        die_with_error ("capget (for uid == 0) failed");
    215 -
    216 -      requested_caps[0] = data[0].effective;
    217 -      requested_caps[1] = data[1].effective;
    218      }
    219  
    220    /* Else, we try unprivileged user namespaces */
    221 @@ -2187,53 +2062,17 @@ parse_args_recurse (int          *argcp,
    222          }
    223        else if (strcmp (arg, "--cap-add") == 0)
    224          {
    225 -          cap_value_t cap;
    226            if (argc < 2)
    227              die ("--cap-add takes an argument");
    228  
    229 -          opt_cap_add_or_drop_used = TRUE;
    230 -
    231 -          if (strcasecmp (argv[1], "ALL") == 0)
    232 -            {
    233 -              requested_caps[0] = requested_caps[1] = 0xFFFFFFFF;
    234 -            }
    235 -          else
    236 -            {
    237 -              if (cap_from_name (argv[1], &cap) < 0)
    238 -                die ("unknown cap: %s", argv[1]);
    239 -
    240 -              if (cap < 32)
    241 -                requested_caps[0] |= CAP_TO_MASK_0 (cap);
    242 -              else
    243 -                requested_caps[1] |= CAP_TO_MASK_1 (cap - 32);
    244 -            }
    245 -
    246            argv += 1;
    247            argc -= 1;
    248          }
    249        else if (strcmp (arg, "--cap-drop") == 0)
    250          {
    251 -          cap_value_t cap;
    252            if (argc < 2)
    253              die ("--cap-drop takes an argument");
    254  
    255 -          opt_cap_add_or_drop_used = TRUE;
    256 -
    257 -          if (strcasecmp (argv[1], "ALL") == 0)
    258 -            {
    259 -              requested_caps[0] = requested_caps[1] = 0;
    260 -            }
    261 -          else
    262 -            {
    263 -              if (cap_from_name (argv[1], &cap) < 0)
    264 -                die ("unknown cap: %s", argv[1]);
    265 -
    266 -              if (cap < 32)
    267 -                requested_caps[0] &= ~CAP_TO_MASK_0 (cap);
    268 -              else
    269 -                requested_caps[1] &= ~CAP_TO_MASK_1 (cap - 32);
    270 -            }
    271 -
    272            argv += 1;
    273            argc -= 1;
    274          }