Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  linux-oom-score.ts

  Sprache: JAVA
 

Spracherkennung für: .ts vermutete Sprache: Unknown {[0] [0] [0]} [Methode: Schwerpunktbildung, einfache Gewichte, sechs Dimensionen]

import fs from "node:fs";

/**
 * On Linux, children spawned by a long-lived parent (e.g., the gateway) inherit
 * the parent's `oom_score_adj`. Under cgroup memory pressure the kernel tends
 * to pick the largest-RSS process as the OOM victim, which is usually the
 * gateway rather than its transient workers. See issue #70404.
 *
 * Since Linux 2.6.20 any unprivileged process may voluntarily *raise* its own
 * `oom_score_adj` without `CAP_SYS_RESOURCE`. We exploit that by wrapping the
 * child argv in a tiny `/bin/sh` shim that raises the score in the post-fork
 * child and then `exec`s the real command, so there is no extra long-lived
 * shell process and no change to the final process identity.
 *
 * Opt out per-process by setting `OPENCLAW_CHILD_OOM_SCORE_ADJ=0` (also
 * accepts `false`/`no`/`off`). Callers may also provide the key via
 * `params.env` for per-child overrides.
 */

export const CHILD_OOM_SCORE_ADJ_ENV_KEY = "OPENCLAW_CHILD_OOM_SCORE_ADJ";
const OOM_SCORE_WRAP_SHELL = "/bin/sh";
const OOM_SCORE_WRAP_SCRIPT = 'echo 1000 > /proc/self/oom_score_adj 2>/dev/null; exec "$0" "$@"';

// Env keys that can cause /bin/sh (especially bash invoked as sh) to source
// caller-influenced startup files before the final `exec`. Stripped when we
// wrap so the shim can't become an env-controlled code-exec primitive.
const SHELL_INIT_ENV_KEYS = ["BASH_ENV", "ENV", "CDPATH"] as const;

function isDisabled(value: string | undefined): boolean {
  switch (value?.trim().toLowerCase()) {
    case "0":
    case "false":
    case "no":
    case "off":
      return true;
    default:
      return false;
  }
}

let cachedShellAvailable: boolean | null = null;
function defaultShellAvailable(): boolean {
  if (cachedShellAvailable !== null) {
    return cachedShellAvailable;
  }
  try {
    cachedShellAvailable = fs.statSync(OOM_SCORE_WRAP_SHELL).isFile();
  } catch {
    cachedShellAvailable = false;
  }
  return cachedShellAvailable;
}

export type OomWrapOptions = {
  platform?: NodeJS.Platform;
  env?: NodeJS.ProcessEnv;
  shellAvailable?: () => boolean;
};

export type OomScoreAdjustedSpawn = {
  command: string;
  args: string[];
  env: NodeJS.ProcessEnv | undefined;
  wrapped: boolean;
};

function shouldWrapChildForOomScore(options: OomWrapOptions | undefined): boolean {
  const platform = options?.platform ?? process.platform;
  if (platform !== "linux") {
    return false;
  }
  const env = options?.env ?? process.env;
  if (isDisabled(env[CHILD_OOM_SCORE_ADJ_ENV_KEY])) {
    return false;
  }
  return (options?.shellAvailable ?? defaultShellAvailable)();
}

function isWrapped(command: string, args: readonly string[]): boolean {
  return command === OOM_SCORE_WRAP_SHELL && args[0] === "-c" && args[1] === OOM_SCORE_WRAP_SCRIPT;
}

function canUseShellExecCommand(command: string): boolean {
  // POSIX sh implementations such as dash do not support `exec --`. A command
  // starting with "-" could be parsed as an exec option, so keep that rare
  // shape on the original direct-spawn path instead of wrapping it.
  return !command.startsWith("-");
}

function hardenShellEnv(baseEnv: NodeJS.ProcessEnv | undefined): NodeJS.ProcessEnv {
  const next: NodeJS.ProcessEnv = { ...(baseEnv ?? process.env) };
  for (const key of SHELL_INIT_ENV_KEYS) {
    delete next[key];
  }
  return next;
}

export function prepareOomScoreAdjustedSpawn(
  command: string,
  args: readonly string[] = [],
  options?: OomWrapOptions,
): OomScoreAdjustedSpawn {
  const copy = [...args];
  if (!command || !canUseShellExecCommand(command) || !shouldWrapChildForOomScore(options)) {
    return { command, args: copy, env: options?.env, wrapped: false };
  }
  if (isWrapped(command, copy)) {
    return { command, args: copy, env: hardenShellEnv(options?.env), wrapped: true };
  }
  return {
    command: OOM_SCORE_WRAP_SHELL,
    args: ["-c", OOM_SCORE_WRAP_SCRIPT, command, ...copy],
    env: hardenShellEnv(options?.env),
    wrapped: true,
  };
}

export function wrapArgvForChildOomScoreRaise(
  argv: readonly string[],
  options?: OomWrapOptions,
): string[] {
  const copy = [...argv];
  if (copy.length === 0) {
    return copy;
  }
  const spawn = prepareOomScoreAdjustedSpawn(copy[0] ?? "", copy.slice(1), options);
  return [spawn.command, ...spawn.args];
}

/**
 * Returns `baseEnv` with shell-init keys stripped when argv will be wrapped.
 * Unchanged (including `undefined`) when no wrap applies, so non-Linux and
 * opted-out paths keep exact inherited-env semantics.
 */
export function hardenedEnvForChildOomWrap(
  baseEnv: NodeJS.ProcessEnv | undefined,
  options?: OomWrapOptions,
): NodeJS.ProcessEnv | undefined {
  if (!shouldWrapChildForOomScore(options)) {
    return baseEnv;
  }
  return hardenShellEnv(baseEnv);
}

¤ Dauer der Verarbeitung: 0.23 Sekunden  (vorverarbeitet am  2026-04-27) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge