/* * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions.
*/ package jdk.test.lib.SA;
/** * Checks if SA Attach is expected to work. * @throws SkippedException if SA Attach is not expected to work.
*/ publicstaticvoid skipIfCannotAttach() { if (!Platform.hasSA()) { thrownew SkippedException("SA not supported.");
} try { if (Platform.isLinux()) { if (!canPtraceAttachLinux()) { thrownew SkippedException("SA Attach not expected to work. Ptrace attach not supported.");
}
} elseif (Platform.isOSX()) { if (Platform.isHardenedOSX()) { thrownew SkippedException("SA Attach not expected to work. JDK is hardened.");
} if (!Platform.isRoot() && !canAddPrivileges()) { thrownew SkippedException("SA Attach not expected to work. Insufficient privileges (not root and can't use sudo).");
}
}
} catch (IOException e) { thrownew RuntimeException("skipIfCannotAttach() failed due to IOException.", e);
}
}
/** * Returns true if this platform is expected to require extra privileges (running using sudo).
*/ publicstaticboolean needsPrivileges() { return Platform.isOSX() && !Platform.isRoot();
}
/** * Returns true if a no-password sudo is expected to work properly.
*/ privatestaticboolean canAddPrivileges() throws IOException {
List<String> sudoList = new ArrayList<String>();
sudoList.add("sudo");
sudoList.add("-E"); // Preserve existing environment variables.
sudoList.add("-n"); // non-interactive. Don't prompt for password. Must be cached or not required.
sudoList.add("/bin/echo");
sudoList.add("'Checking for sudo'");
ProcessBuilder pb = new ProcessBuilder(sudoList);
Process echoProcess = pb.start(); try { if (echoProcess.waitFor(60, TimeUnit.SECONDS) == false) { // Due to using the "-n" option, sudo should complete almost immediately. 60 seconds // is more than generous. If it didn't complete in that time, something went very wrong.
echoProcess.destroyForcibly(); thrownew RuntimeException("Timed out waiting for sudo to execute.");
}
} catch (InterruptedException e) { thrownew RuntimeException("sudo process interrupted", e);
}
if (echoProcess.exitValue() == 0) { returntrue;
}
java.io.InputStream is = echoProcess.getErrorStream();
String err = new String(is.readAllBytes());
System.out.println(err); // 'sudo' has been run, but did not succeed, probably because the cached credentials // have expired, or we don't have a no-password entry for the user in the /etc/sudoers list. // Check the sudo error message and skip the test. if (err.contains("no tty present") || err.contains("a password is required")) { returnfalse;
} else { thrownew RuntimeException("Unknown error from 'sudo': " + err);
}
}
/** * Adds privileges (sudo) to the command.
*/ privatestatic List<String> addPrivileges(List<String> cmdStringList) { if (!Platform.isOSX()) { thrownew RuntimeException("Can only add privileges on OSX.");
}
System.out.println("Adding 'sudo -E -n' to the command.");
List<String> outStringList = new ArrayList<String>();
outStringList.add("sudo");
outStringList.add("-E"); // Preserve existing environment variables.
outStringList.add("-n"); // non-interactive. Don't prompt for password. Must be cached or not required.
outStringList.addAll(cmdStringList); return outStringList;
}
/** * Adds privileges (sudo) to the command already setup for the ProcessBuilder.
*/ publicstaticvoid addPrivilegesIfNeeded(ProcessBuilder pb) { if (!Platform.isOSX()) { return;
}
/** * On Linux, first check the SELinux boolean "deny_ptrace" and return false * as we expect to be denied if that is "1". Then expect permission to attach * if we are root, so return true. Then return false for an expected denial * if "ptrace_scope" is 1, and true otherwise.
*/
@SuppressWarnings("removal") privatestaticboolean canPtraceAttachLinux() throws IOException { // SELinux deny_ptrace: var deny_ptrace = Paths.get("/sys/fs/selinux/booleans/deny_ptrace"); if (Files.exists(deny_ptrace)) { try { var bb = AccessController.doPrivileged(
(PrivilegedExceptionAction<byte[]>) () -> Files.readAllBytes(deny_ptrace)); if (bb.length == 0) { thrownew Error("deny_ptrace is empty");
} if (bb[0] != '0') { returnfalse;
}
} catch (PrivilegedActionException e) {
IOException t = (IOException) e.getException(); throw t;
}
}
// YAMA enhanced security ptrace_scope: // 0 - a process can PTRACE_ATTACH to any other process running under the same uid // 1 - restricted ptrace: a process must be a children of the inferior or user is root // 2 - only processes with CAP_SYS_PTRACE may use ptrace or user is root // 3 - no attach: no processes may use ptrace with PTRACE_ATTACH var ptrace_scope = Paths.get("/proc/sys/kernel/yama/ptrace_scope"); if (Files.exists(ptrace_scope)) { try { var bb = AccessController.doPrivileged(
(PrivilegedExceptionAction<byte[]>) () -> Files.readAllBytes(ptrace_scope)); if (bb.length == 0) { thrownew Error("ptrace_scope is empty");
} byte yama_scope = bb[0]; if (yama_scope == '3') { returnfalse;
}
if (!Platform.isRoot() && yama_scope != '0') { returnfalse;
}
} catch (PrivilegedActionException e) {
IOException t = (IOException) e.getException(); throw t;
}
} // Otherwise expect to be permitted: returntrue;
}
/** * This tests has issues if you try adding privileges on OSX. The debugd process cannot * be killed if you do this (because it is a root process and the test is not), so the destroy() * call fails to do anything, and then waitFor() will time out. If you try to manually kill it with * a "sudo kill" command, that seems to work, but then leaves the LingeredApp it was * attached to in a stuck state for some unknown reason, causing the stopApp() call * to timeout. For that reason we don't run this test when privileges are needed. Note * it does appear to run fine as root, so we still allow it to run on OSX when privileges * are not required.
*/ publicstaticvoid validateSADebugDPrivileges() { if (needsPrivileges()) { thrownew SkippedException("Cannot run this test on OSX if adding privileges is required.");
}
}
}
Messung V0.5
¤ Dauer der Verarbeitung: 0.17 Sekunden
(vorverarbeitet)
¤
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.