Go to main content

man pages section 3: Library Interfaces and Headers

Exit Print View

Updated: Wednesday, July 27, 2022
 
 

libproc (3LIB)

Name

libproc - process control library

Description

The /proc interface provides access to the state of each user-level process and thread also known as lightweight process or lwp in the system. It also provides the ability to control such processes and threads. It is a low-level interface.

The libproc library provides a higher-level interface to the features of the /proc interface as well as access to information such as symbol tables which is necessary for the examination and control of processes and threads. For more information, see the proc(5) man page.

A controlling process using libproc can perform the following functions:

  • Grab a victim process, suspending its execution.

  • Examine the state of a victim process.

  • Examine and modify the address space of the victim process.

  • Make the victim process execute system calls on behalf of the controlling process.

  • Release the victim process to run again unmolested.

Similarly, a controlling process using libproc can create a controlled victim process in order to control it from the moment of creation.

A controlling process can also grab a core file for post-mortem inspection. However, it cannot cause the dead process to execute anything.

In short, libproc provides all the mechanisms needed by a breakpoint debugger to do its job, but also facilitates the creation of simple one-shot controlling applications to do simple things to victim processes without them being aware of the intrusion.

For example, there is nothing in the /proc interface that exposes a file creation mask of a victim process. However, libproc provides an interface, pr_umask(), that will force a victim process to execute the umask() system call on behalf of a controlling process. For more information, see umask(2).

Here is an example program to do that. (It could be improved; it is pared down to essentials for demonstration purposes.)

#include <stdio.h>
#include <string.h>
#include <libproc.h>

static void __NORETURN
usage(const char *command)
{
    (void) fprintf(stderr,
    "usage:\t%s [-m mask] pid ...\n"
    "  default: report the file creation mask of each process\n"
    "  -m: set the file creation mask of each process to mask\n",
    command);
    exit(2);
}

int
main(int argc, char **argv)
{
    char *command = argv[0];
    int exitcode = 0;
    int mflag = 0;
    mode_t mask;
    int opt;

    while ((opt = getopt(argc, argv, "m:")) != EOF) {
         if (opt != 'm')
             usage(command);
         mflag = 1;
         mask = (mode_t)strtol(optarg, NULL, 8) & 0777;
    }
    argc -= optind;
    argv += optind;
    if (argc <= 0)
        usage(command);

    while (--argc >= 0) {
        pid_t pid = (pid_t)atoi(*argv++);
        ps_prochandle_t *Pr;
        mode_t omask;
        int gret;

        if ((Pr = Pgrab(pid, 0, &gret)) == NULL) {
            (void) fprintf(stderr, "%s: cannot examine %d: %s\n",
                 command, (int)pid, Pgrab_error(gret));
            exitcode = 1;
        } else {
            if (mflag)
                omask = pr_umask(Pr, mask);
            else
               (void) pr_umask(Pr, omask = pr_umask(Pr, 0));
            Prelease(Pr, 0);
            if (mflag)
                (void) printf("%d:\t0%3.3o (was 0%3.3o)\n",
                    (int)pid, (int)mask, (int)omask);
            else
                (void) printf("%d:\t0%3.3o\n",
                    (int)pid, (int)omask);
        }
    }

    return (exitcode);
}
#include <stdio.h>
     #include <string.h>
     #include <libproc.h>

     static void __NORETURN
     usage(const char *command)
     {
         (void) fprintf(stderr,
             "usage:\t%s [-m mask] pid ...\n"
             "  default: report the file creation mask of each process\n"
             "  -m: set the file creation mask of each process to mask\n",
             command);
         exit(2);
     }

     int
     main(int argc, char **argv)
     {
         char *command = argv[0];
         int exitcode = 0;
         int mflag = 0;
         mode_t mask;
         int opt;

         while ((opt = getopt(argc, argv, "m:")) != EOF) {
             if (opt != 'm')
                 usage(command);
             mflag = 1;
             mask = (mode_t)strtol(optarg, NULL, 8) & 0777;
         }
         argc -= optind;
         argv += optind;
         if (argc <= 0)
             usage(command);

         while (--argc >= 0) {
             pid_t pid = (pid_t)atoi(*argv++);
             ps_prochandle_t *Pr;
             mode_t omask;
             int gret;

             if ((Pr = Pgrab(pid, 0, &gret)) == NULL) {
                 (void) fprintf(stderr, "%s: cannot examine %d: %s\n",
                     command, (int)pid, Pgrab_error(gret));
                 exitcode = 1;
             } else {
                 if (mflag)
                     omask = pr_umask(Pr, mask);
                 else
                     (void) pr_umask(Pr, omask = pr_umask(Pr, 0));
                 Prelease(Pr, 0);
                 if (mflag)
                     (void) printf("%d:\t0%3.3o (was 0%3.3o)\n",
                         (int)pid, (int)mask, (int)omask);
                 else
                     (void) printf("%d:\t0%3.3o\n",
                         (int)pid, (int)omask);
             }
         }

         return (exitcode);
     }

libproc currently provides the following functions to cause a victim process to execute the corresponding system calls on behalf of a controlling process. More such interfaces may be added in the future.

  pr_access()         pr_chmod()          pr_chown()
         pr_close()          pr_door_info()      pr_exit()
         pr_faccessat()      pr_fchmod()         pr_fchmodat()
         pr_fchown()         pr_fchownat()       pr_fcntl()
         pr_fstat()          pr_fstat64()        pr_fstatat()
         pr_fstatat64()      pr_fstatvfs()       pr_fstatvfs64()
         pr_futimens()       pr_getitimer()      pr_getpeername()
         pr_getpeerucred()   pr_getrlimit()      pr_getrlimit64()
         pr_getsockname()    pr_getsockopt()     pr_getzoneid()
         pr_ioctl()          pr_lchown()         pr_link()
         pr_linkat()         pr_llseek()         pr_lseek()
         pr_lstat()          pr_lstat64()        pr_memcntl()
         pr_meminfo()        pr_mkdir()          pr_mkdirat()
         pr_mkfifo()         pr_mkfifoat()       pr_mknod()
         pr_mknodat()        pr_mmap()           pr_munmap()
         pr_open()           pr_open64()         pr_openat()
         pr_openat64()       pr_readlink()       pr_readlinkat()
         pr_rename()         pr_renameat()       pr_rmdir()
         pr_setitimer()      pr_setrlimit()      pr_setrlimit64()
         pr_sigaction()      pr_stat()           pr_stat64()
         pr_statvfs()        pr_statvfs64()      pr_symlink()
         pr_symlinkat()      pr_umask()          pr_unlink()
         pr_unlinkat()       pr_utimensat()      pr_waitid()

Interface Level

The shared object libproc.so.1 provides the public interfaces listed below. See the individual manual pages in section 3PROC for their descriptions. For additional information about shared object interfaces, see the intro(3) man page.

  Lclearfault()                  Lclearsig()
         Lctlfd()                       Ldstop()
         Lfree()                        Lgetareg()
         Lgrab()                        Lgrab_error()
         Lprochandle()                  Lpsinfo()
         Lputareg()                     Lrefresh()
         Lsetrun()                      Lstate()
         Lstatus()                      Lstop()
         Lsync()                        Lwait()
         Lxecbkpt()                     Lxecwapt()
         Paction()                      Paddr_to_loadobj()
         Paddr_to_map()                 Paddr_to_text_map()
         Pasfd()                        Pbrandname()
         Pclearfault()                  Pclearsig()
         Pcontent()                     Pcreate()
         Pcreate_agent()                Pcreate_error()
         Pcred()                        Pctlfd()
         Pdelbkpt()                     Pdelwapt()
         Pdestroy_agent()               Pdirfd()
         Pdstop()                       Penv_iter()
         Pexecname()                    Pfault()
         Pfdinfolist()                  Pfgcore()
         Pfgrab_core()                  Pfree()
         Pgcore()                       Pgetareg()
         Pgetauxval()                   Pgetauxvec()
         Pgetenv()                      Pgrab()
         Pgrab_core()                   Pgrab_error()
         Pgrab_file()                   Pisprocdir()
         Plookup_by_addr()              Plookup_by_name()
         Plwp_alt_stack()               Plwp_getfpregs()
         Plwp_getpsinfo()               Plwp_getregs()
         Plwp_getstatus()               Plwp_getxregs()
         Plwp_iter()                    Plwp_iter_all()
         Plwp_main_stack()              Plwp_setfpregs()
         Plwp_setregs()                 Plwp_setxregs()
         Plwp_stack()                   Pmapping_iter()
         Pname_to_loadobj()             Pname_to_map()
         Pnsig()                        Pobject_iter()
         Pobjname()                     Pplatform()
         Ppriv()                        Ppsinfo()
         Pputareg()                     Prd_agent()
         Pread()                        Pread_string()
         Prefresh()                     Prelease()
         Preopen()                      Preset_maps()
         Psetbkpt()                     Psetcred()
         Psetfault()                    Psetflags()
         Psetpriv()                     Psetrun()
         Psetsignal()                   Psetsysentry()
         Psetsysexit()                  Psetwapt()
         Psetzoneid()                   Psignal()
         Pstack_iter()                  Pstate()
         Pstatus()                      Pstop()
         Psymbol_iter()                 Psymbol_iter_by_addr()
         Psymbol_iter_by_name()         Psync()
         Psyscall()                     Psysentry()
         Psysexit()                     Puname()
         Punsetflags()                  Pupdate_maps()
         Pwait()                        Pwrite()
         Pxecbkpt()                     Pxecwapt()
         Pzonename()                    Pzonepath()
         Pzoneroot()                    pr_access()
         pr_chmod()                     pr_chown()
         pr_close()                     pr_door_info()
         pr_exit()                      pr_faccessat()
         pr_fchmod()                    pr_fchmodat()
         pr_fchown()                    pr_fchownat()
         pr_fcntl()                     pr_fstat()
         pr_fstat64()                   pr_fstatat()
         pr_fstatat64()                 pr_fstatvfs()
         pr_fstatvfs64()                pr_futimens()
         pr_getitimer()                 pr_getpeername()
         pr_getpeerucred()              pr_getrlimit()
         pr_getrlimit64()               pr_getsockname()
         pr_getsockopt()                pr_getzoneid()
         pr_ioctl()                     pr_lchown()
         pr_link()                      pr_linkat()
         pr_llseek()                    pr_lseek()
         pr_lstat()                     pr_lstat64()
         pr_memcntl()                   pr_meminfo()
         pr_mkdir()                     pr_mkdirat()
         pr_mkfifo()                    pr_mkfifoat()
         pr_mknod()                     pr_mknodat()
         pr_mmap()                      pr_munmap()
         pr_open()                      pr_open64()
         pr_openat()                    pr_openat64()
         pr_readlink()                  pr_readlinkat()
         pr_rename()                    pr_renameat()
         pr_rmdir()                     pr_setitimer()
         pr_setrlimit()                 pr_setrlimit64()
         pr_sigaction()                 pr_stat()
         pr_stat64()                    pr_statvfs()
         pr_statvfs64()                 pr_symlink()
         pr_symlinkat()                 pr_umask()
         pr_unlink()                    pr_unlinkat()
         pr_utimensat()                 pr_waitid()
         proc_arg_grab()                proc_arg_psinfo()
         proc_content2str()             proc_finistdio()
         proc_fltname()                 proc_flushstdio()
         proc_get_psinfo()              proc_initstdio()
         proc_lwp_in_set()              proc_lwp_range_valid()
         proc_signame()                 proc_str2content()
         proc_str2flt()                 proc_str2sig()
         proc_str2sys()                 proc_sysname()
         proc_unctrl_psinfo()           proc_walk()

The following interface is unique to the x86 version of libproc:

Pldt()

The following interfaces are unique to the SPARC version of libproc:

Plwp_getasrs()                 Plwp_getgwindows()
Plwp_setasrs()

Files

/lib/libproc.so.1

32-bit shared object

/lib/64/libproc.so.1

64-bit shared object

Attributes

See attributes(7) for descriptions of the following attributes:

ATTRIBUTE TYPE
ATTRIBUTE VALUE
Interface Stability
Committed
Availability
system/library
MT-Level
Unsafe

See Also

proc(1), truss(1), umask(2), intro(3), libproc.h(3HEAD), proc(5), attributes(7)

Notes

All programs linked with libproc should be compiled in 64-bit mode because 32-bit /proc tools cannot examine 64-bit processes, but 64-bit /proc tools can examine and control both 32-bit and 64-bit processes.

A program compiled in 32-bit mode and linked with libproc cannot be compiled in the large file compilation environment. Such programs can however use the transitional compilation environment.

Because the interfaces provided by libproc are intended for the control of other processes, they are unsafe to be used by more than one thread at a time on any one victim process unless the controlling process implements the necessary mutual exclusion protocol. Their use in signal handlers is deprecated.