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


Quellcode-Bibliothek

© Kompilation durch diese Firma

[Weder Korrektheit noch Funktionsfähigkeit der Software werden zugesichert.]

Datei: SATestUtils.java   Sprache: JAVA

/*
 * 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;

import jdk.test.lib.JDKToolLauncher;
import jdk.test.lib.Platform;
import jtreg.SkippedException;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.concurrent.TimeUnit;
import java.util.List;

public class SATestUtils {
    /**
     * Creates a ProcessBuilder, adding privileges (sudo) if needed.
     */

    public static ProcessBuilder createProcessBuilder(JDKToolLauncher launcher) {
        List<String> cmdStringList = Arrays.asList(launcher.getCommand());
        if (needsPrivileges()) {
            cmdStringList = addPrivileges(cmdStringList);
        }
        return new ProcessBuilder(cmdStringList);
    }

    /**
     * Checks if SA Attach is expected to work.
     * @throws SkippedException if SA Attach is not expected to work.
    */

    public static void skipIfCannotAttach() {
        if (!Platform.hasSA()) {
            throw new SkippedException("SA not supported.");
        }
        try {
            if (Platform.isLinux()) {
                if (!canPtraceAttachLinux()) {
                    throw new SkippedException("SA Attach not expected to work. Ptrace attach not supported.");
                }
            } else if (Platform.isOSX()) {
                if (Platform.isHardenedOSX()) {
                    throw new SkippedException("SA Attach not expected to work. JDK is hardened.");
                }
                if (!Platform.isRoot() && !canAddPrivileges()) {
                    throw new SkippedException("SA Attach not expected to work. Insufficient privileges (not root and can't use sudo).");
                }
            }
        } catch (IOException e) {
            throw new RuntimeException("skipIfCannotAttach() failed due to IOException.", e);
        }
    }

    /**
     * Returns true if this platform is expected to require extra privileges (running using sudo).
     */

    public static boolean needsPrivileges() {
        return Platform.isOSX() && !Platform.isRoot();
    }

    /**
     * Returns true if a no-password sudo is expected to work properly.
     */

    private static boolean 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();
               throw new RuntimeException("Timed out waiting for sudo to execute.");
           }
       } catch (InterruptedException e) {
           throw new RuntimeException("sudo process interrupted", e);
       }

       if (echoProcess.exitValue() == 0) {
           return true;
       }
       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")) {
           return false;
       } else {
           throw new RuntimeException("Unknown error from 'sudo': " + err);
       }
    }

    /**
     * Adds privileges (sudo) to the command.
     */

    private static List<String> addPrivileges(List<String> cmdStringList) {
        if (!Platform.isOSX()) {
            throw new 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.
     */

    public static void addPrivilegesIfNeeded(ProcessBuilder pb) {
        if (!Platform.isOSX()) {
            return;
        }

        if (needsPrivileges()) {
            List<String> cmdStringList = pb.command();
            cmdStringList = addPrivileges(cmdStringList);
            pb.command(cmdStringList);
        }
    }

    /**
     * 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")
    private static boolean 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) {
                    throw new Error("deny_ptrace is empty");
                }
                if (bb[0] != '0') {
                    return false;
                }
            } 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) {
                    throw new Error("ptrace_scope is empty");
                }
                byte yama_scope = bb[0];
                if (yama_scope == '3') {
                    return false;
                }

                if (!Platform.isRoot() && yama_scope != '0') {
                    return false;
                }
            } catch (PrivilegedActionException e) {
                IOException t = (IOException) e.getException();
                throw t;
            }
        }
        // Otherwise expect to be permitted:
        return true;
    }

    /**
     * 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.
     */

    public static void validateSADebugDPrivileges() {
        if (needsPrivileges()) {
            throw new SkippedException("Cannot run this test on OSX if adding privileges is required.");
        }
    }
}

¤ Dauer der Verarbeitung: 0.3 Sekunden  (vorverarbeitet)  ¤





Download des
Quellennavigators
Download des
sprechenden Kalenders

in der Quellcodebibliothek suchen




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 ist noch experimentell.


Bot Zugriff



                                                                                                                                                                                                                                                                                                                                                                                                     


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