Hi!

I wanted to look at the process table of a crashed kernel from a dump.
ps(1) then segfaulted.

It seems that

 1) pr->ps_pgrp is kernel's (it's being kvm_read earlier in libkvm)
    and so is ps_session
 2) p_comm and s_login are part of their structs and not pointers,
    therefore kvm_read() a. k. a. copy_str() doesn't work on them.

I couldn't fix argv to display properly, but this is already better than
a segfault. Tested only on i386.

Reproduce:
 1) C-M-Esc, boot crash
 2) ps -N /var/crash/bsd.? -M /var/crash/bsd.?.core
 3) when trying the diff, don't forget to recompile libkvm AND ps

Anyone has anything to say or is willing to commit?

--
Martin Pelikan


Index: sys/sysctl.h
===================================================================
RCS file: /cvs/src/sys/sys/sysctl.h,v
retrieving revision 1.116
diff -u -p -r1.116 sysctl.h
--- sys/sysctl.h        8 Jul 2011 18:38:55 -0000       1.116
+++ sys/sysctl.h        18 Aug 2011 11:16:35 -0000
@@ -482,7 +482,7 @@ do {                                                        
                \
        (kp)->p_limit = PTRTOINT64((pr)->ps_limit);                     \
        (kp)->p_vmspace = PTRTOINT64((p)->p_vmspace);                   \
        (kp)->p_sigacts = PTRTOINT64((p)->p_sigacts);                   \
-       (kp)->p_sess = PTRTOINT64((pr)->ps_session);                    \
+       (kp)->p_sess = PTRTOINT64(sess);                                \
        (kp)->p_ru = PTRTOINT64((p)->p_ru);                             \
                                                                        \
        (kp)->p_exitsig = (p)->p_exitsig;                               \
@@ -528,11 +528,11 @@ do {                                                      
                \
        (kp)->p_xstat = (p)->p_xstat;                                   \
        (kp)->p_acflag = (p)->p_acflag;                                 \
                                                                        \
-       /* XXX depends on p_emul being an array and not a pointer */    \
+       /* p_emul is a pointer and not an array */                      \
        copy_str((kp)->p_emul, (char *)(p)->p_emul +                    \
            offsetof(struct emul, e_name), sizeof((kp)->p_emul));       \
-       copy_str((kp)->p_comm, (p)->p_comm, sizeof((kp)->p_comm));      \
-       copy_str((kp)->p_login, (sess)->s_login,                        \
+       (void) memcpy((kp)->p_comm, (p)->p_comm, sizeof((kp)->p_comm)); \
+       (void) memcpy((kp)->p_login, (sess)->s_login,                   \
            MIN(sizeof((kp)->p_login) - 1, sizeof((sess)->s_login)));   \
                                                                        \
        if ((sess)->s_ttyvp)                                            \

Reply via email to