# Copyright 2014 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import("//build/config/features.gni")

declare_args() {
  compile_suid_client = is_linux

  compile_credentials = is_linux

  compile_seccomp_bpf_demo =
    (is_linux && (cpu_arch == "x86" || cpu_arch == "x64"))
}

# We have two principal targets: sandbox and sandbox_linux_unittests
# All other targets are listed as dependencies.
# There is one notable exception: for historical reasons, chrome_sandbox is
# the setuid sandbox and is its own target.

group("sandbox") {
  deps = [
    ":sandbox_services",
  ]

  if (compile_suid_client) {
    deps += [ ":suid_sandbox_client" ]
  }
  if (use_seccomp_bpf) {
    deps += [
      ":seccomp_bpf",
      ":seccomp_bpf_helpers",
    ]
  }
}

source_set("sandbox_linux_test_utils") {
  sources = [
    "tests/sandbox_test_runner.cc",
    "tests/sandbox_test_runner.h",
    "tests/sandbox_test_runner_function_pointer.cc",
    "tests/sandbox_test_runner_function_pointer.h",
    "tests/test_utils.cc",
    "tests/test_utils.h",
    "tests/unit_tests.cc",
    "tests/unit_tests.h",
  ]

  deps = [
    "//testing/gtest",
  ]

  if (use_seccomp_bpf) {
    sources += [
      "seccomp-bpf/bpf_tester_compatibility_delegate.h",
      "seccomp-bpf/bpf_tests.h",
      "seccomp-bpf/sandbox_bpf_test_runner.cc",
      "seccomp-bpf/sandbox_bpf_test_runner.h",
    ]
    deps += [
      ":seccomp_bpf",
    ]
  }
}

# The main sandboxing test target.
test("sandbox_linux_unittests") {
  sources = [
    "tests/main.cc",
    "tests/unit_tests_unittest.cc",
    "services/broker_process_unittest.cc",
    "services/scoped_process_unittest.cc",
    "services/thread_helpers_unittests.cc",
    "services/yama_unittests.cc",
  ]

  deps = [
    ":sandbox",
    ":sandbox_linux_test_utils",
    "//base",
    "//base/test:test_support",
    "//testing/gtest",
  ]

  if (compile_suid_client) {
    sources += [
      "suid/client/setuid_sandbox_client_unittest.cc",
    ]
  }
  if (use_seccomp_bpf) {
    sources += [
      "seccomp-bpf-helpers/baseline_policy_unittest.cc",
      "seccomp-bpf/bpf_tests_unittest.cc",
      "seccomp-bpf/codegen_unittest.cc",
      "seccomp-bpf/errorcode_unittest.cc",
      "seccomp-bpf/sandbox_bpf_unittest.cc",
      "seccomp-bpf/syscall_iterator_unittest.cc",
      "seccomp-bpf/syscall_unittest.cc",
    ]
  }
  if (compile_credentials) {
    sources += [
      "services/credentials_unittest.cc",
      "services/unix_domain_socket_unittest.cc",
    ]
  }
}

# TODO(GYP) Android version of this test.
#    {
#      # This target is the shared library used by Android APK (i.e.
#      # JNI-friendly) tests.
#      "target_name": "sandbox_linux_jni_unittests",
#      "includes": [
#        "sandbox_linux_test_sources.gypi",
#      ],
#      "type": "shared_library",
#      "conditions": [
#        [ "OS == "android"", {
#          "dependencies": [
#            "../testing/android/native_test.gyp:native_test_native_code",
#          ],
#        }],
#      ],
#    },

component("seccomp_bpf") {
  sources = [
    "seccomp-bpf/basicblock.cc",
    "seccomp-bpf/basicblock.h",
    "seccomp-bpf/codegen.cc",
    "seccomp-bpf/codegen.h",
    "seccomp-bpf/die.cc",
    "seccomp-bpf/die.h",
    "seccomp-bpf/errorcode.cc",
    "seccomp-bpf/errorcode.h",
    "seccomp-bpf/instruction.h",
    "seccomp-bpf/linux_seccomp.h",
    "seccomp-bpf/sandbox_bpf.cc",
    "seccomp-bpf/sandbox_bpf.h",
    "seccomp-bpf/sandbox_bpf_compatibility_policy.h",
    "seccomp-bpf/sandbox_bpf_policy.cc",
    "seccomp-bpf/sandbox_bpf_policy.h",
    "seccomp-bpf/syscall.cc",
    "seccomp-bpf/syscall.h",
    "seccomp-bpf/syscall_iterator.cc",
    "seccomp-bpf/syscall_iterator.h",
    "seccomp-bpf/trap.cc",
    "seccomp-bpf/trap.h",
    "seccomp-bpf/verifier.cc",
    "seccomp-bpf/verifier.h",
  ]
  defines = [ "SANDBOX_IMPLEMENTATION" ]

  deps = [
    ":sandbox_services_headers",
    "//base",
  ]
}

component("seccomp_bpf_helpers") {
  sources = [
    "seccomp-bpf-helpers/baseline_policy.cc",
    "seccomp-bpf-helpers/baseline_policy.h",
    "seccomp-bpf-helpers/sigsys_handlers.cc",
    "seccomp-bpf-helpers/sigsys_handlers.h",
    "seccomp-bpf-helpers/syscall_parameters_restrictions.cc",
    "seccomp-bpf-helpers/syscall_parameters_restrictions.h",
    "seccomp-bpf-helpers/syscall_sets.cc",
    "seccomp-bpf-helpers/syscall_sets.h",
  ]
  defines = [ "SANDBOX_IMPLEMENTATION" ]

  deps = [
    "//base",
    ":seccomp_bpf",
  ]
}

if (compile_seccomp_bpf_demo) {
  # A demonstration program for the seccomp-bpf sandbox.
  executable("seccomp_bpf_demo") {
    sources = [
      "seccomp-bpf/demo.cc",
    ]
    deps = [
      ":seccomp_bpf",
    ]
  }
}

# The setuid sandbox for Linux.
executable("chrome_sandbox") {
  sources = [
    "suid/common/sandbox.h",
    "suid/common/suid_unsafe_environment_variables.h",
    "suid/linux_util.c",
    "suid/linux_util.h",
    "suid/process_util.h",
    "suid/process_util_linux.c",
    "suid/sandbox.c",
  ]

  cflags = [
    # For ULLONG_MAX
    "-std=gnu99",
    # These files have a suspicious comparison.
    # TODO fix this and re-enable this warning.
    "-Wno-sign-compare",
  ]
}

component("sandbox_services") {
  sources = [
    "services/broker_process.cc",
    "services/broker_process.h",
    "services/init_process_reaper.cc",
    "services/init_process_reaper.h",
    "services/scoped_process.cc",
    "services/scoped_process.h",
    "services/thread_helpers.cc",
    "services/thread_helpers.h",
    "services/yama.h",
    "services/yama.cc",
  ]

  defines = [ "SANDBOX_IMPLEMENTATION" ]

  if (compile_credentials) {
    sources += [
      "services/credentials.cc",
      "services/credentials.h",
    ]
    # For capabilities.cc.
    configs += [ "//build/config/linux:libcap" ]
  }

  deps = [
    "//base",
  ]
}

source_set("sandbox_services_headers") {
  sources = [
    "services/android_arm_ucontext.h",
    "services/android_futex.h",
    "services/android_ucontext.h",
    "services/android_i386_ucontext.h",
    "services/arm_linux_syscalls.h",
    "services/linux_syscalls.h",
    "services/x86_32_linux_syscalls.h",
    "services/x86_64_linux_syscalls.h",
  ]
}

# We make this its own target so that it does not interfere with our tests.
source_set("libc_urandom_override") {
  sources = [
    "services/libc_urandom_override.cc",
    "services/libc_urandom_override.h",
  ]
  deps = [
    "//base",
  ]
}

component("suid_sandbox_client") {
  sources = [
    "suid/common/sandbox.h",
    "suid/common/suid_unsafe_environment_variables.h",
    "suid/client/setuid_sandbox_client.cc",
    "suid/client/setuid_sandbox_client.h",
  ]
  defines = [ "SANDBOX_IMPLEMENTATION" ]

  deps = [
    ":sandbox_services",
    "//base",
  ]
}

if (is_android) {
  # TODO(GYP) enable this. Needs an android_strip wrapper python script.
  #action("sandbox_linux_unittests_stripped") {
  #  script = "android_stip.py"
  #
  #  in_file = "$root_out_dir/sandbox_linux_unittests"
  #
  #  out_file = "$root_out_dir/sandbox_linux_unittests_stripped"
  #  outputs = [ out_file ]
  #
  #  args = [
  #    rebase_path(in_file, root_build_dir),
  #    "-o", rebase_path(out_file, root_build_dir),
  #  ]
  #
  #  deps = [
  #    ":sandbox_linux_unittests",
  #  ]
  #}

  # TODO(GYP) convert this.
  #      {
  #      'target_name': 'sandbox_linux_jni_unittests_apk',
  #      'type': 'none',
  #      'variables': {
  #        'test_suite_name': 'sandbox_linux_jni_unittests',
  #      },
  #      'dependencies': [
  #        'sandbox_linux_jni_unittests',
  #      ],
  #      'includes': [ '../../build/apk_test.gypi' ],
  #      }
}
