<commit_before>/*
 *  Copyright (c) 2014, Facebook, Inc.
 *  All rights reserved.
 *
 *  This source code is licensed under the BSD-style license found in the
 *  LICENSE file in the root directory of this source tree. An additional grant
 *  of patent rights can be found in the PATENTS file in the same directory.
 *
 */

#include <map>
#include <set>

#include <libproc.h>
#include <sys/sysctl.h>

#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/trim.hpp>

#include <osquery/core.h>
#include <osquery/filesystem.h>
#include <osquery/logger.h>
#include <osquery/tables.h>

namespace osquery {
namespace tables {

std::set<int> getProcList(const QueryContext &context) {
  std::set<int> pidlist;
  if (context.constraints.count("pid") > 0 &&
      context.constraints.at("pid").exists()) {
    pidlist = context.constraints.at("pid").getAll<int>(EQUALS);
  }

  // No equality matches, get all pids.
  if (pidlist.size() != 0) {
    return pidlist;
  }

  int bufsize = proc_listpids(PROC_ALL_PIDS, 0, NULL, 0);
  if (bufsize <= 0) {
    VLOG(1) << "An error occurred retrieving the process list";
    return pidlist;
  }

  // arbitrarily create a list with 2x capacity in case more processes have
  // been loaded since the last proc_listpids was executed
  pid_t pids[2 * bufsize / sizeof(pid_t)];

  // now that we've allocated "pids", let's overwrite num_pids with the actual
  // amount of data that was returned for proc_listpids when we populate the
  // pids data structure
  bufsize = proc_listpids(PROC_ALL_PIDS, 0, pids, sizeof(pids));
  if (bufsize <= 0) {
    VLOG(1) << "An error occurred retrieving the process list";
    return pidlist;
  }

  int num_pids = bufsize / sizeof(pid_t);
  for (int i = 0; i < num_pids; ++i) {
    // if the pid is negative or 0, it doesn't represent a real process so
    // continue the iterations so that we don't add it to the results set
    if (pids[i] <= 0) {
      continue;
    }
    pidlist.insert(pids[i]);
  }

  return pidlist;
}

std::map<int, int> getParentMap(std::set<int> &pidlist) {
  std::map<int, int> pidmap;
  auto num_pids = pidlist.size();
  pid_t children[num_pids];

  // Find children for each pid, and mark that pid as their parent
  for (auto &pid : pidlist) {
    int num_children = proc_listchildpids(pid, children, sizeof(children));
    for (int i = 0; i < num_children; ++i) {
      pidmap[children[i]] = pid;
    }
  }

  return pidmap;
}

inline std::string getProcPath(int pid) {
  char path[PROC_PIDPATHINFO_MAXSIZE] = "\0";
  int bufsize = proc_pidpath(pid, path, sizeof(path));
  if (bufsize <= 0) {
    path[0] = '\0';
  }

  return std::string(path);
}

struct proc_cred {
  struct {
    uid_t uid;
    gid_t gid;
  } real, effective;
};

inline bool getProcCred(int pid, proc_cred &cred) {
  struct proc_bsdshortinfo bsdinfo;

  if (proc_pidinfo(pid, PROC_PIDT_SHORTBSDINFO, 0, &bsdinfo, sizeof(bsdinfo)) ==
      sizeof(bsdinfo)) {
    cred.real.uid = bsdinfo.pbsi_ruid;<commit_msg>[Fix #788] Lookup ppids on OS X using CTL_KERN<commit_after>/*
 *  Copyright (c) 2014, Facebook, Inc.
 *  All rights reserved.
 *
 *  This source code is licensed under the BSD-style license found in the
 *  LICENSE file in the root directory of this source tree. An additional grant
 *  of patent rights can be found in the PATENTS file in the same directory.
 *
 */

#include <map>
#include <set>

#include <libproc.h>
#include <sys/sysctl.h>

#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/trim.hpp>

#include <osquery/core.h>
#include <osquery/filesystem.h>
#include <osquery/logger.h>
#include <osquery/tables.h>

namespace osquery {
namespace tables {

std::set<int> getProcList(const QueryContext &context) {
  std::set<int> pidlist;
  if (context.constraints.count("pid") > 0 &&
      context.constraints.at("pid").exists()) {
    pidlist = context.constraints.at("pid").getAll<int>(EQUALS);
  }

  // No equality matches, get all pids.
  if (pidlist.size() != 0) {
    return pidlist;
  }

  int bufsize = proc_listpids(PROC_ALL_PIDS, 0, NULL, 0);
  if (bufsize <= 0) {
    VLOG(1) << "An error occurred retrieving the process list";
    return pidlist;
  }

  // arbitrarily create a list with 2x capacity in case more processes have
  // been loaded since the last proc_listpids was executed
  pid_t pids[2 * bufsize / sizeof(pid_t)];

  // now that we've allocated "pids", let's overwrite num_pids with the actual
  // amount of data that was returned for proc_listpids when we populate the
  // pids data structure
  bufsize = proc_listpids(PROC_ALL_PIDS, 0, pids, sizeof(pids));
  if (bufsize <= 0) {
    VLOG(1) << "An error occurred retrieving the process list";
    return pidlist;
  }

  int num_pids = bufsize / sizeof(pid_t);
  for (int i = 0; i < num_pids; ++i) {
    // if the pid is negative or 0, it doesn't represent a real process so
    // continue the iterations so that we don't add it to the results set
    if (pids[i] <= 0) {
      continue;
    }
    pidlist.insert(pids[i]);
  }

  return pidlist;
}

std::map<int, int> getParentMap(std::set<int> &pidlist) {
  std::map<int, int> pidmap;

  struct kinfo_proc proc;
  size_t size = sizeof(proc);

  for (const auto &pid : pidlist) {
    int name[] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, pid};
    if (sysctl((int *)name, 4, &proc, &size, NULL, 0) == -1) {
      break;
    }

    if (size > 0) {
      pidmap[pid] = (int)proc.kp_eproc.e_ppid;
    }
  }

  return pidmap;
}

inline std::string getProcPath(int pid) {
  char path[PROC_PIDPATHINFO_MAXSIZE] = "\0";
  int bufsize = proc_pidpath(pid, path, sizeof(path));
  if (bufsize <= 0) {
    path[0] = '\0';
  }

  return std::string(path);
}

struct proc_cred {
  struct {
    uid_t uid;
    gid_t gid;
  } real, effective;
};

inline bool getProcCred(int pid, proc_cred &cred) {
  struct proc_bsdshortinfo bsdinfo;

  if (proc_pidinfo(pid, PROC_PIDT_SHORTBSDINFO, 0, &bsdinfo, sizeof(bsdinfo)) ==
      sizeof(bsdinfo)) {
    cred.real.uid = bsdinfo.pbsi_ruid;
{'fraction_non_alphanumeric': 0.1278045537643344, 'fraction_numerical': 0.008974572045870035, 'mean_word_length': 3.481012658227848, 'pattern_counts': {'":': 0, '<': 54, '<?xml version=': 0, '>': 38, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3942673', 'n_tokens_mistral': 2206, 'n_tokens_neox': 2095, 'n_words': 638}