org.elasticsearch.nativeaccess.MacNativeAccess Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of elasticsearch-native Show documentation
Show all versions of elasticsearch-native Show documentation
Elasticsearch subproject :libs:elasticsearch-native
The newest version!
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the "Elastic License
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
* Public License v 1"; you may not use this file except in compliance with, at
* your election, the "Elastic License 2.0", the "GNU Affero General Public
* License v3.0 only", or the "Server Side Public License, v 1".
*/
package org.elasticsearch.nativeaccess;
import org.elasticsearch.core.IOUtils;
import org.elasticsearch.core.SuppressForbidden;
import org.elasticsearch.nativeaccess.lib.MacCLibrary;
import org.elasticsearch.nativeaccess.lib.NativeLibraryProvider;
import org.elasticsearch.nativeaccess.lib.PosixCLibrary.RLimit;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Collections;
class MacNativeAccess extends PosixNativeAccess {
private static final int F_PREALLOCATE = 42;
private static final int F_ALLOCATECONTIG = 0x2; // allocate contiguous space
private static final int F_ALLOCATEALL = 0x4; // allocate all the requested space or no space at all
private static final int F_PEOFPOSMODE = 3; // allocate from the physical end of the file
/** The only supported flag... */
static final int SANDBOX_NAMED = 1;
/** Allow everything except process fork and execution */
static final String SANDBOX_RULES = "(version 1) (allow default) (deny process-fork) (deny process-exec)";
private final MacCLibrary macLibc;
MacNativeAccess(NativeLibraryProvider libraryProvider) {
super("MacOS", libraryProvider, new PosixConstants(9223372036854775807L, 5, 1, 6, 512, 144, 96, 104));
this.macLibc = libraryProvider.getLibrary(MacCLibrary.class);
}
@Override
protected long getMaxThreads() {
return ProcessLimits.UNKNOWN;
}
@Override
protected void logMemoryLimitInstructions() {
// we don't have instructions for macos
}
@Override
protected boolean nativePreallocate(int fd, long currentSize, long newSize) {
var fst = libc.newFStore();
fst.set_flags(F_ALLOCATECONTIG);
fst.set_posmode(F_PEOFPOSMODE);
fst.set_offset(0);
fst.set_length(newSize);
// first, try allocating contiguously
if (libc.fcntl(fd, F_PREALLOCATE, fst) != 0) {
// TODO: log warning?
// that failed, so let us try allocating non-contiguously
fst.set_flags(F_ALLOCATEALL);
if (libc.fcntl(fd, F_PREALLOCATE, fst) != 0) {
// i'm afraid captain dale had to bail
logger.warn("Could not allocate non-contiguous size: " + libc.strerror(libc.errno()));
return false;
}
}
if (libc.ftruncate(fd, newSize) != 0) {
logger.warn("Could not truncate file: " + libc.strerror(libc.errno()));
return false;
}
return true;
}
/**
* Installs exec system call filtering on MacOS.
*
* Two different methods of filtering are used. Since MacOS is BSD based, process creation
* is first restricted with {@code setrlimit(RLIMIT_NPROC)}.
*
* Additionally, on Mac OS X Leopard or above, a custom {@code sandbox(7)} ("Seatbelt") profile is installed that
* denies the following rules:
*
* - {@code process-fork}
* - {@code process-exec}
*
* @see
* * https://reverse.put.as/wp-content/uploads/2011/06/The-Apple-Sandbox-BHDC2011-Paper.pdf
*/
@Override
public void tryInstallExecSandbox() {
initBsdSandbox();
initMacSandbox();
execSandboxState = ExecSandboxState.ALL_THREADS;
}
@SuppressForbidden(reason = "Java tmp dir is ok")
private static Path createTempRulesFile() throws IOException {
return Files.createTempFile("es", "sb");
}
private void initMacSandbox() {
// write rules to a temporary file, which will be passed to sandbox_init()
Path rules;
try {
rules = createTempRulesFile();
Files.write(rules, Collections.singleton(SANDBOX_RULES));
} catch (IOException e) {
throw new UncheckedIOException(e);
}
try {
var errorRef = macLibc.newErrorReference();
int ret = macLibc.sandbox_init(rules.toAbsolutePath().toString(), SANDBOX_NAMED, errorRef);
// if sandbox_init() fails, add the message from the OS (e.g. syntax error) and free the buffer
if (ret != 0) {
RuntimeException e = new UnsupportedOperationException("sandbox_init(): " + errorRef.toString());
macLibc.sandbox_free_error(errorRef);
throw e;
}
logger.debug("OS X seatbelt initialization successful");
} finally {
IOUtils.deleteFilesIgnoringExceptions(rules);
}
}
private void initBsdSandbox() {
RLimit limit = libc.newRLimit();
limit.rlim_cur(0);
limit.rlim_max(0);
// not a standard limit, means something different on linux, etc!
final int RLIMIT_NPROC = 7;
if (libc.setrlimit(RLIMIT_NPROC, limit) != 0) {
throw new UnsupportedOperationException("RLIMIT_NPROC unavailable: " + libc.strerror(libc.errno()));
}
logger.debug("BSD RLIMIT_NPROC initialization successful");
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy