tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

LinuxCapabilities.h (3869B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
      5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #ifndef mozilla_LinuxCapabilities_h
      8 #define mozilla_LinuxCapabilities_h
      9 
     10 #include <linux/capability.h>
     11 #include <stdint.h>
     12 
     13 #include "mozilla/Assertions.h"
     14 #include "mozilla/Attributes.h"
     15 #include "mozilla/PodOperations.h"
     16 
     17 // This class is a relatively simple interface to manipulating the
     18 // capabilities of a Linux process/thread; see the capabilities(7) man
     19 // page for background information.
     20 
     21 // Unfortunately, Android's kernel headers omit some definitions
     22 // needed for the low-level capability interface.  They're part of the
     23 // stable syscall ABI, so it's safe to include them here.
     24 #ifndef _LINUX_CAPABILITY_VERSION_3
     25 #  define _LINUX_CAPABILITY_VERSION_3 0x20080522
     26 #  define _LINUX_CAPABILITY_U32S_3 2
     27 #endif
     28 #ifndef CAP_TO_INDEX
     29 #  define CAP_TO_INDEX(x) ((x) >> 5)
     30 #  define CAP_TO_MASK(x) (1 << ((x) & 31))
     31 #endif
     32 
     33 namespace mozilla {
     34 
     35 class LinuxCapabilities final {
     36 public:
     37  // A class to represent a bit within the capability sets as an lvalue.
     38  class BitRef {
     39    __u32& mWord;
     40    __u32 mMask;
     41    friend class LinuxCapabilities;
     42    BitRef(__u32& aWord, uint32_t aMask) : mWord(aWord), mMask(aMask) {}
     43    BitRef(const BitRef& aBit) = default;
     44 
     45   public:
     46    MOZ_IMPLICIT operator bool() const { return mWord & mMask; }
     47    BitRef& operator=(bool aSetTo) {
     48      if (aSetTo) {
     49        mWord |= mMask;
     50      } else {
     51        mWord &= mMask;
     52      }
     53      return *this;
     54    }
     55  };
     56 
     57  // The default value is the empty set.
     58  LinuxCapabilities() { PodArrayZero(mBits); }
     59 
     60  // Get the current thread's capability sets and assign them to this
     61  // object.  Returns whether it succeeded and sets errno on failure.
     62  // Shouldn't fail unless the kernel is very old.
     63  bool GetCurrent();
     64 
     65  // Try to set the current thread's capability sets to those
     66  // specified in this object.  Returns whether it succeeded and sets
     67  // errno on failure.
     68  bool SetCurrentRaw() const;
     69 
     70  // The capability model requires that the permitted set always be a
     71  // superset of the effective and inheritable sets.  This method
     72  // expands the permitted set as needed and then sets the current
     73  // thread's capabilities, as described above.
     74  bool SetCurrent() {
     75    Normalize();
     76    return SetCurrentRaw();
     77  }
     78 
     79  void Normalize() {
     80    for (size_t i = 0; i < _LINUX_CAPABILITY_U32S_3; ++i) {
     81      mBits[i].permitted |= mBits[i].effective | mBits[i].inheritable;
     82    }
     83  }
     84 
     85  bool AnyEffective() const {
     86    for (size_t i = 0; i < _LINUX_CAPABILITY_U32S_3; ++i) {
     87      if (mBits[i].effective != 0) {
     88        return true;
     89      }
     90    }
     91    return false;
     92  }
     93 
     94  // These three methods expose individual bits in the three
     95  // capability sets as objects that can be used as bool lvalues.
     96  // The argument is the capability number, as defined in
     97  // the <linux/capability.h> header.
     98  BitRef Effective(unsigned aCap) {
     99    return GenericBitRef(&__user_cap_data_struct::effective, aCap);
    100  }
    101 
    102  BitRef Permitted(unsigned aCap) {
    103    return GenericBitRef(&__user_cap_data_struct::permitted, aCap);
    104  }
    105 
    106  BitRef Inheritable(unsigned aCap) {
    107    return GenericBitRef(&__user_cap_data_struct::inheritable, aCap);
    108  }
    109 
    110 private:
    111  __user_cap_data_struct mBits[_LINUX_CAPABILITY_U32S_3];
    112 
    113  BitRef GenericBitRef(__u32 __user_cap_data_struct::* aField, unsigned aCap) {
    114    // Please don't pass untrusted data as the capability number.
    115    MOZ_ASSERT(CAP_TO_INDEX(aCap) < _LINUX_CAPABILITY_U32S_3);
    116    return BitRef(mBits[CAP_TO_INDEX(aCap)].*aField, CAP_TO_MASK(aCap));
    117  }
    118 };
    119 
    120 }  // namespace mozilla
    121 
    122 #endif  // mozilla_LinuxCapabilities_h