public inbox for frysk-cvs@sourceware.org help / color / mirror / Atom feed
From: cagney@sourceware.org To: frysk-cvs@sourceware.org Subject: [SCM] master: When /proc/PID/exe is invalid throw an exception. Date: Thu, 12 Jun 2008 20:32:00 -0000 [thread overview] Message-ID: <20080612203220.30387.qmail@sourceware.org> (raw) The branch, master has been updated via e7fe8b0edbf5bc538a3e7fbcd37997bc800d27a5 (commit) from 531115f2541df6ed1e8a8f16e24c519fb858b209 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email. - Log ----------------------------------------------------------------- commit e7fe8b0edbf5bc538a3e7fbcd37997bc800d27a5 Author: Andrew Cagney <cagney@toil.yyz.redhat.com> Date: Thu Jun 12 16:31:00 2008 -0400 When /proc/PID/exe is invalid throw an exception. frysk-core/frysk/bindir/ChangeLog 2008-06-12 Andrew Cagney <cagney@redhat.com> * TestFexe.java (testExeOfDeletedFile()): Enable. Match expected error. * fexe.java: Use Exe.getName. frysk-core/frysk/proc/live/ChangeLog 2008-06-12 Andrew Cagney <cagney@redhat.com> * LinuxPtraceProc.java (getExe()): Delete. frysk-sys/frysk/sys/ChangeLog 2008-06-12 Andrew Cagney <cagney@redhat.com> * cni/Errno.cxx (throwUserException): New. * cni/Errno.hxx (throwUserException): New. frysk-sys/frysk/sys/proc/ChangeLog 2008-06-12 Andrew Cagney <cagney@redhat.com> * Exe.java (getName): Rename get. (openReadOnly): New. * jni/Exe.cxx (Exe::getName): Update. * cni/Exe.cxx (Exe::getName): Update. frysk-sys/jnixx/ChangeLog 2008-06-12 Andrew Cagney <cagney@redhat.com> * exceptions.cxx (userException): Implement. * exceptions.hxx (userException): Declare. ----------------------------------------------------------------------- Summary of changes: frysk-core/frysk/bindir/ChangeLog | 4 ++ frysk-core/frysk/bindir/TestFexe.java | 4 +-- frysk-core/frysk/bindir/fexe.java | 4 +- frysk-core/frysk/proc/live/ChangeLog | 4 ++ frysk-core/frysk/proc/live/LinuxPtraceProc.java | 33 ++----------------- frysk-sys/frysk/sys/ChangeLog | 3 ++ frysk-sys/frysk/sys/cni/Errno.cxx | 8 +++++ frysk-sys/frysk/sys/cni/Errno.hxx | 4 ++ frysk-sys/frysk/sys/proc/ChangeLog | 7 ++++ frysk-sys/frysk/sys/proc/Exe.java | 9 ++--- frysk-sys/frysk/sys/proc/cni/Exe.cxx | 38 ++++++++++++++++++---- frysk-sys/frysk/sys/proc/jni/Exe.cxx | 29 +++++++++++++++-- frysk-sys/jnixx/ChangeLog | 5 +++ frysk-sys/jnixx/exceptions.cxx | 23 ++++++++++++++ frysk-sys/jnixx/exceptions.hxx | 4 ++ 15 files changed, 129 insertions(+), 50 deletions(-) First 500 lines of diff: diff --git a/frysk-core/frysk/bindir/ChangeLog b/frysk-core/frysk/bindir/ChangeLog index 5f57822..32b6db4 100644 --- a/frysk-core/frysk/bindir/ChangeLog +++ b/frysk-core/frysk/bindir/ChangeLog @@ -1,5 +1,9 @@ 2008-06-12 Andrew Cagney <cagney@redhat.com> + * TestFexe.java (testExeOfDeletedFile()): Enable. Match expected + error. + * fexe.java: Use Exe.getName. + * TestFexe.java (testExeOfDeletedFile()): New; mark as unresolved 6621. diff --git a/frysk-core/frysk/bindir/TestFexe.java b/frysk-core/frysk/bindir/TestFexe.java index d5aba64..5a37447 100644 --- a/frysk-core/frysk/bindir/TestFexe.java +++ b/frysk-core/frysk/bindir/TestFexe.java @@ -89,8 +89,6 @@ public class TestFexe extends TestLib { } public void testExeOfDeletedFile() { - if (unresolved(6621)) - return; TearDownExpect e = new TearDownExpect(); TearDownFile exe = TearDownFile.create(); // Create a copy of sleep that is executable. @@ -111,6 +109,6 @@ public class TestFexe extends TestLib { assertFalse("file exists", exe.stillExists()); // Try fexe with the executable deleted e.send(Prefix.binFile("fexe").getPath() + " $pid\r"); - e.expect(exe.getName() + " \\(deleted\\)\r\n\\$ "); + e.expect("The link /proc/[0-9]+/exe points to the deleted file .*" + exe.getName() + "\\r\n\\$ "); } } diff --git a/frysk-core/frysk/bindir/fexe.java b/frysk-core/frysk/bindir/fexe.java index 2bcb374..e6a0600 100644 --- a/frysk-core/frysk/bindir/fexe.java +++ b/frysk-core/frysk/bindir/fexe.java @@ -84,11 +84,11 @@ public class fexe if (verbose) { ProcessIdentifier pid = ProcessIdentifierFactory.create(proc.getPid()); - System.out.println( proc.getPid() + System.out.println(proc.getPid() + " " + proc.getExeFile().getFile().getAbsolutePath() + " " - + Exe.get(pid) + + Exe.getName(pid) + " " + sysRootedPath); } else diff --git a/frysk-core/frysk/proc/live/ChangeLog b/frysk-core/frysk/proc/live/ChangeLog index eee24c5..61ffa17 100644 --- a/frysk-core/frysk/proc/live/ChangeLog +++ b/frysk-core/frysk/proc/live/ChangeLog @@ -1,3 +1,7 @@ +2008-06-12 Andrew Cagney <cagney@redhat.com> + + * LinuxPtraceProc.java (getExe()): Delete. + 2008-06-06 Teresa Thomas <tthomas@redhat.com> * LinuxPtraceTaskState.java: Additional logging messages. diff --git a/frysk-core/frysk/proc/live/LinuxPtraceProc.java b/frysk-core/frysk/proc/live/LinuxPtraceProc.java index e854829..c7e1888 100644 --- a/frysk-core/frysk/proc/live/LinuxPtraceProc.java +++ b/frysk-core/frysk/proc/live/LinuxPtraceProc.java @@ -224,40 +224,15 @@ public class LinuxPtraceProc extends LiveProc { * and a second returning the exe as it should be (but possibly * isn't :-). Better yet have utrace handle it :-) */ - private String exe; - private String getExe() { + private SysRootFile exe; + public SysRootFile getExeFile() { if (exe == null) { - ProcessIdentifier pid - = ProcessIdentifierFactory.create(getPid()); - String exe = Exe.get(pid); - // Linux's /proc/$$/exe can get screwed up in several - // ways. Detect each here and return null. - if (exe.endsWith(" (deleted)")) - // Assume (possibly incorrectly) that a trailing - // "(deleted)" always indicates a deleted file. - return null; - if (exe.indexOf((char)0) >= 0) - // Assume that an EXE that has somehow ended up with - // an embedded NUL character is invalid. This happens - // when the kernel screws up "mv a-really-long-file - // $exe" leaving the updated EXE string with something - // like "$exe<NUL>ally-long-file (deleted)". - return null; - if (!new File(exe).exists()) - // Final sanity check; the above two should have covered - // all possible cases. But one never knows. - return null; - this.exe = exe; + File exeFile = new File(Exe.getName(pid)); + return new SysRootFile(SysRootCache.getSysRoot(exeFile.getName()), exeFile); } return exe; } - public SysRootFile getExeFile() { - String exe = getExe(); - File exeFile = new File(exe); - return new SysRootFile(SysRootCache.getSysRoot(exeFile.getName()), exeFile); - } - /** * If it hasn't already been read, read the stat structure. */ diff --git a/frysk-sys/frysk/sys/ChangeLog b/frysk-sys/frysk/sys/ChangeLog index c6c022a..aec7679 100644 --- a/frysk-sys/frysk/sys/ChangeLog +++ b/frysk-sys/frysk/sys/ChangeLog @@ -1,5 +1,8 @@ 2008-06-12 Andrew Cagney <cagney@redhat.com> + * cni/Errno.cxx (throwUserException): New. + * cni/Errno.hxx (throwUserException): New. + * Errno.java-sh: Extend ExternalException. * cni/Errno.cxx: Update. diff --git a/frysk-sys/frysk/sys/cni/Errno.cxx b/frysk-sys/frysk/sys/cni/Errno.cxx index 3af0e1b..4ccac23 100644 --- a/frysk-sys/frysk/sys/cni/Errno.cxx +++ b/frysk-sys/frysk/sys/cni/Errno.cxx @@ -163,6 +163,14 @@ throwErrno (int err, const char *prefix) throwErrno (err, ajprintf ("%s: %s", prefix, strerror (err))); } +void throwUserException(const char *format, ...) { + va_list ap; + va_start(ap, format); + jstring message = vajprintf(format, ap); + va_end(ap); + throw new frysk::UserException(message); +} + void throwRuntimeException (const char *message) { diff --git a/frysk-sys/frysk/sys/cni/Errno.hxx b/frysk-sys/frysk/sys/cni/Errno.hxx index 6bcde43..5838b0f 100644 --- a/frysk-sys/frysk/sys/cni/Errno.hxx +++ b/frysk-sys/frysk/sys/cni/Errno.hxx @@ -47,6 +47,10 @@ extern void throwErrno (int err, const char *prefix) extern void throwErrno (int err, const char *prefix, const char *suffix, ...) __attribute__ ((noreturn)) __attribute__((format (printf, 3, 4))); +// <<prefix>>: <<strerror(err)>> (<<suffix>> ...) +extern void throwUserException(const char *format, ...) + __attribute__ ((noreturn)) __attribute__((format (printf, 1, 2))); + // <<message>> extern void throwRuntimeException (const char *message) __attribute__ ((noreturn)); diff --git a/frysk-sys/frysk/sys/proc/ChangeLog b/frysk-sys/frysk/sys/proc/ChangeLog index 84cf92d..79c61d4 100644 --- a/frysk-sys/frysk/sys/proc/ChangeLog +++ b/frysk-sys/frysk/sys/proc/ChangeLog @@ -1,3 +1,10 @@ +2008-06-12 Andrew Cagney <cagney@redhat.com> + + * Exe.java (getName): Rename get. + (openReadOnly): New. + * jni/Exe.cxx (Exe::getName): Update. + * cni/Exe.cxx (Exe::getName): Update. + 2008-06-04 Andrew Cagney <cagney@redhat.com> * TestMaps.java (testNative()): New. diff --git a/frysk-sys/frysk/sys/proc/Exe.java b/frysk-sys/frysk/sys/proc/Exe.java index 07c9a05..23e33be 100644 --- a/frysk-sys/frysk/sys/proc/Exe.java +++ b/frysk-sys/frysk/sys/proc/Exe.java @@ -43,14 +43,11 @@ import frysk.sys.ProcessIdentifier; /** * The contents of <tt>/proc/PID/exe</tt>. - * - * XXX: Should this be more like a builder or like Stat where there's - * a refresh method that detects that the contents actually changed? */ public class Exe { - public static String get(ProcessIdentifier pid) { - return get(pid.intValue()); + public static String getName(ProcessIdentifier pid) { + return getName(pid.intValue()); } - private static native String get (int pid); + private static native String getName(int pid); } diff --git a/frysk-sys/frysk/sys/proc/cni/Exe.cxx b/frysk-sys/frysk/sys/proc/cni/Exe.cxx index 6f258c5..8b583fb 100644 --- a/frysk-sys/frysk/sys/proc/cni/Exe.cxx +++ b/frysk-sys/frysk/sys/proc/cni/Exe.cxx @@ -48,22 +48,46 @@ #include "frysk/sys/proc/Exe.h" jstring -frysk::sys::proc::Exe::get (jint pid) -{ +frysk::sys::proc::Exe::getName(jint pid) { char file[FILENAME_MAX]; if (::snprintf (file, sizeof file, "/proc/%d/exe", (int) pid) >= FILENAME_MAX) - throwRuntimeException ("snprintf: buffer overflow"); + throwRuntimeException("snprintf: buffer overflow"); // /proc/$$/exe contains a soft-link specifying the name of the // executable, possibly with "(deleted)" appended. That link's // upper bound is determined by FILENAME_MAX since that is the - // longest possible allowable file name. - const int maxLen = FILENAME_MAX + sizeof (" (deleted)") + 1; + // longest possible allowable file name. Note that readlink doesn't + // NUL terminate so need to leave space for that. + const char deleted[] = " (deleted)"; + const int maxLen = FILENAME_MAX + sizeof(deleted) + 1; char link[maxLen]; - int len = ::readlink (file, link, sizeof (link)); + int len = ::readlink(file, link, sizeof(link) - 1); if (len < 0 || len >= maxLen) - throwErrno (errno, "readlink"); + throwErrno(errno, "readlink"); + link[len] = '\0'; + + // Linux's /proc/$$/exe can get screwed up in several ways. Detect + // each here and return null. + if ((int) strlen(link) != len) { + // Assume that an EXE that has somehow ended up with an embedded + // NUL character is invalid. This happens when the kernel screws + // up "mv a-really-long-file $exe" leaving the updated EXE string + // with something like "$exe<NUL>ally-long-file (deleted)". + throwUserException("The link %s is corrupt", file); + } + + if (strstr(link, deleted) + strlen(deleted) - link == len) { + // Assume (possibly incorrectly) that a trailing "(deleted)" + // always indicates a deleted file. + link[len - strlen(deleted)] = '\0'; + throwUserException("The link %s points to the deleted file %s", + file, link); + } + + if (access(link, F_OK) != 0) { + throwErrno(errno, "file %s", link); + } // Note that some kernels have a "feature" where the link can become // corrupted. Just retun that, the caller needs to decide if the diff --git a/frysk-sys/frysk/sys/proc/jni/Exe.cxx b/frysk-sys/frysk/sys/proc/jni/Exe.cxx index 12745a8..112f363 100644 --- a/frysk-sys/frysk/sys/proc/jni/Exe.cxx +++ b/frysk-sys/frysk/sys/proc/jni/Exe.cxx @@ -49,7 +49,7 @@ using namespace java::lang; String -frysk::sys::proc::Exe::get(jnixx::env env, jint pid) { +frysk::sys::proc::Exe::getName(jnixx::env env, jint pid) { // Get the name of the EXE in /proc. char file[FILENAME_MAX]; if (::snprintf(file, sizeof file, "/proc/%d/exe", (int) pid) @@ -60,13 +60,36 @@ frysk::sys::proc::Exe::get(jnixx::env env, jint pid) { // executable, possibly with "(deleted)" appended. That link's // upper bound is determined by FILENAME_MAX since that is the // longest possible allowable file name. - const int maxLen = FILENAME_MAX + sizeof (" (deleted)") + 1; + const char deleted[] = " (deleted)"; + const int maxLen = FILENAME_MAX + sizeof(deleted) + 1; char link[maxLen]; - int len = ::readlink (file, link, sizeof (link) - 1); + int len = ::readlink (file, link, sizeof(link) - 1); if (len < 0 || len >= maxLen) errnoException(env, errno, "readlink"); link[len] = '\0'; + // Linux's /proc/$$/exe can get screwed up in several ways. Detect + // each here and return null. + if ((int) strlen(link) != len) { + // Assume that an EXE that has somehow ended up with an embedded + // NUL character is invalid. This happens when the kernel screws + // up "mv a-really-long-file $exe" leaving the updated EXE string + // with something like "$exe<NUL>ally-long-file (deleted)". + userException(env, "The link %s is corrupt", file); + } + + if (strstr(link, deleted) + strlen(deleted) - link == len) { + // Assume (possibly incorrectly) that a trailing "(deleted)" + // always indicates a deleted file. + link[len - strlen(deleted)] = '\0'; + userException(env, "The link %s points to the deleted file %s", + file, link); + } + + if (access(link, F_OK) != 0) { + errnoException(env, errno, "file %s", link); + } + // Note that some kernels have a "feature" where the link can become // corrupted. Just retun that, the caller needs to decide if the // extracted link is valid. diff --git a/frysk-sys/jnixx/ChangeLog b/frysk-sys/jnixx/ChangeLog index 7fdd6ba..8a2673e 100644 --- a/frysk-sys/jnixx/ChangeLog +++ b/frysk-sys/jnixx/ChangeLog @@ -1,3 +1,8 @@ +2008-06-12 Andrew Cagney <cagney@redhat.com> + + * exceptions.cxx (userException): Implement. + * exceptions.hxx (userException): Declare. + 2008-06-04 Andrew Cagney <cagney@redhat.com> * elements.cxx (slurp): Don't count the terminating NUL in the diff --git a/frysk-sys/jnixx/exceptions.cxx b/frysk-sys/jnixx/exceptions.cxx index 2f5ce80..928e0fd 100644 --- a/frysk-sys/jnixx/exceptions.cxx +++ b/frysk-sys/jnixx/exceptions.cxx @@ -150,3 +150,26 @@ runtimeException(::jnixx::env& env, const char *fmt, ...) { throw e; } } + + +void +userException(::jnixx::env& env, const char *fmt, ...) { + va_list ap; + va_start(ap, fmt); + char *message = NULL; + if (::vasprintf(&message, fmt, ap) < 0) { + // If this fails things are pretty much stuffed. + int err = errno; + fprintf(stderr, "warning: vasprintf in runtimeException failed: %s", + ::strerror(err)); + RuntimeException::ThrowNew(env, "vasprintf in runtimeException failed"); + } + va_end(ap); + try { + frysk::UserException::ThrowNew(env, message); + } catch (java::lang::Throwable e) { + // Always executed. + ::free(message); + throw e; + } +} diff --git a/frysk-sys/jnixx/exceptions.hxx b/frysk-sys/jnixx/exceptions.hxx index 877356c..36fde6f 100644 --- a/frysk-sys/jnixx/exceptions.hxx +++ b/frysk-sys/jnixx/exceptions.hxx @@ -52,3 +52,7 @@ extern void errnoException(::jnixx::env& env, int error, const char *prefix, extern void runtimeException(::jnixx::env& env, const char *fmt, ...) __attribute__((noreturn)) __attribute__((format (printf, 2, 3))); + +extern void userException(::jnixx::env& env, const char *fmt, ...) + __attribute__((noreturn)) + __attribute__((format (printf, 2, 3))); hooks/post-receive -- frysk system monitor/debugger
reply other threads:[~2008-06-12 20:32 UTC|newest] Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20080612203220.30387.qmail@sourceware.org \ --to=cagney@sourceware.org \ --cc=frysk-cvs@sourceware.org \ --cc=frysk@sourceware.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).