patchpanel: directly use chown() syscall

After:
localhost ~ # ls -ld /sys/class/xt_idletimer
drwxr-xr-x. 2 android-root android-root 0 Mar  5 13:19 /sys/class/xt_idletimer
localhost ~ # android-sh -c "ls -ld /sys/class/xt_idletimer"
drwxr-xr-x 2 root root 0 2021-03-05 13:19 /sys/class/xt_idletimer

Also refactor ScopedNS to support both CLONE_NEWNET and CLONE_NEWNS.

BUG=b:178980566
TEST=Compiled, flashed patchpanel on rammus, started ARC container,
checked that /sys/class/xt_idletimer owner shows as android_root on the
host (xt_idletimer is not namespaced), check /sys/class/xt_idletimer
owner shows as root inside ARC.

Change-Id: Ia799dda263da996fa4880e1cf676556845e7f622
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform2/+/2738497
Reviewed-by: Garrick Evans <garrick@chromium.org>
Reviewed-by: Mike Frysinger <vapier@chromium.org>
Tested-by: Hugo Benichi <hugobenichi@google.com>
Commit-Queue: Hugo Benichi <hugobenichi@google.com>
diff --git a/patchpanel/scoped_ns.h b/patchpanel/scoped_ns.h
index a8f90eb..a77a8f1 100644
--- a/patchpanel/scoped_ns.h
+++ b/patchpanel/scoped_ns.h
@@ -10,19 +10,26 @@
 
 namespace patchpanel {
 
-// Utility class for running code blocks within the network namespace.
+// Utility class for running code blocks within a network namespace or a mount
+// namespace.
 class ScopedNS {
  public:
-  explicit ScopedNS(pid_t pid);
+  enum Type {
+    Network = 1,
+    Mount,
+  };
+
+  explicit ScopedNS(pid_t pid, Type type);
   ScopedNS(const ScopedNS&) = delete;
   ScopedNS& operator=(const ScopedNS&) = delete;
 
   ~ScopedNS();
 
-  // Returns whether or not the object was able to enter the network namespace.
+  // Returns whether or not the object was able to enter the target namespace.
   bool IsValid() const { return valid_; }
 
  private:
+  int nstype_;
   bool valid_;
   base::ScopedFD ns_fd_;
   base::ScopedFD self_fd_;