< prev index next >

src/os/posix/vm/os_posix.cpp

Print this page
rev 12741 : 8173848: realpath is unsafe
Summary: Fix occurrences of realpath in hotspot to use safe POSIX.1-2008 form.
Reviewed-by: dsamersoff, dholmes, clanger

*** 1,7 **** /* ! * Copyright (c) 1999, 2016, 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. --- 1,7 ---- /* ! * Copyright (c) 1999, 2017, 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.
*** 1103,1112 **** --- 1103,1154 ---- stack_size / 1024, guard_size / 1024, (detachstate == PTHREAD_CREATE_DETACHED ? "detached" : "joinable")); return buf; } + char* os::Posix::realpath(const char* filename, char* outbuf, size_t outbuflen) { + + if (filename == NULL || outbuf == NULL || outbuflen < 1) { + assert(false, "os::Posix::realpath: invalid arguments."); + errno = EINVAL; + return NULL; + } + + char* result = NULL; + + // This assumes platform realpath() is implemented according to POSIX.1-2008. + // POSIX.1-2008 allows to specify NULL for the output buffer, in which case + // output buffer is dynamically allocated and must be ::free()'d by the caller. + char* p = ::realpath(filename, NULL); + if (p != NULL) { + if (strlen(p) < outbuflen) { + strcpy(outbuf, p); + result = outbuf; + } else { + errno = ENAMETOOLONG; + } + ::free(p); // *not* os::free + } else { + // Fallback for platforms struggling with modern Posix standards (AIX 5.3, 6.1). If realpath + // returns EINVAL, this may indicate that realpath is not POSIX.1-2008 compatible and + // that it complains about the NULL we handed down as user buffer. + // In this case, use the user provided buffer but at least check whether realpath caused + // a memory overwrite. + if (errno == EINVAL) { + outbuf[outbuflen - 1] = '\0'; + p = ::realpath(filename, outbuf); + if (p != NULL) { + guarantee(outbuf[outbuflen - 1] == '\0', "realpath buffer overwrite detected."); + result = p; + } + } + } + return result; + + } + + // Check minimum allowable stack sizes for thread creation and to initialize // the java system classes, including StackOverflowError - depends on page // size. // The space needed for frames during startup is platform dependent. It // depends on word size, platform calling conventions, C frame layout and
< prev index next >