sysctl(3) and behaviour of KERN_PROC/KERN_PROC2 children

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

sysctl(3) and behaviour of KERN_PROC/KERN_PROC2 children

Kristaps Johnson-2
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1


Hello-

The sysctl function has undocumented (bad?) behaviour when responding to
the following sequence:

   CTL_KERN, KERN_PROC/KERN_PROC2, KERN_PROC_PID

...with a nonexisting PID.  Instead of returning ESRCH, no error is
reported and the structure is filled with zeros:


void
foo(pid_t pid)
{
  int name[CTL_MAXNAME];
  u_int namel;
  struct kinfo_proc2 proc;
  size_t procl;

  namel = 0;
  name[namel++] = CTL_KERN;
  name[namel++] = KERN_PROC2;
  name[namel++] = KERN_PROC_PID;
  name[namel++] = pid;
  name[namel++] = (procl = sizeof(struct kinfo_proc2));
  name[namel++] = 1;

  if (sysctl(name, namel, &proc, &procl, NULL, (u_long)0) == -1)
  err(1, "sysctl: KERN_PROC2, %d", pid);

  (void)printf("ppid = %d (puid = %d) (want = %d)\n",
      proc.p_pid, proc.p_uid, pid);
}

Yields:
ppid = 0 (puid = 0) (want = -1)

// run with a pid of -1

Contrast this to KERN_PROC_ARGS, which returns ESRCH when the given
process is not found (which, incidentally, is not documented in sysctl.3).

In perusing kern_sysctl.c, similar behaviour will be exhibited by most
choice-components of the switch in kern_sysctl.c:sysctl_doproc.

Be good,
   Kristaps
iD8DBQFFB/IGK0ldVyV4920RAnLFAKCwtfhIoqHnvxNsGJMiRlm608UPdgCgzPHu
I4f8WCB/ItwGeivRiRb2EL4=
=xB8P
-----END PGP SIGNATURE-----

Reply | Threaded
Open this post in threaded view
|

Re: sysctl(3) and behaviour of KERN_PROC/KERN_PROC2 children

Otto Moerbeek
On Wed, 13 Sep 2006, Kristaps Johnson wrote:

> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
>
> Hello-
>
> The sysctl function has undocumented (bad?) behaviour when responding to the
> following sequence:
>
>   CTL_KERN, KERN_PROC/KERN_PROC2, KERN_PROC_PID
>
> ...with a nonexisting PID.  Instead of returning ESRCH, no error is reported
> and the structure is filled with zeros:
>
>
> void
> foo(pid_t pid)
> {
> int name[CTL_MAXNAME];
> u_int namel;
> struct kinfo_proc2 proc;
> size_t procl;
>
> namel = 0;
> name[namel++] = CTL_KERN;
> name[namel++] = KERN_PROC2;
> name[namel++] = KERN_PROC_PID;
> name[namel++] = pid;
> name[namel++] = (procl = sizeof(struct kinfo_proc2));
> name[namel++] = 1;
>
> if (sysctl(name, namel, &proc, &procl, NULL, (u_long)0) == -1)
> err(1, "sysctl: KERN_PROC2, %d", pid);
>
> (void)printf("ppid = %d (puid = %d) (want = %d)\n",
>     proc.p_pid, proc.p_uid, pid);
> }
>
> Yields:
> ppid = 0 (puid = 0) (want = -1)

You should check the returned value of procl, which determined how
many proc structs were filled.

> // run with a pid of -1
>
> Contrast this to KERN_PROC_ARGS, which returns ESRCH when the given process is
> not found (which, incidentally, is not documented in sysctl.3).

Good catch

        -Otto

>
> In perusing kern_sysctl.c, similar behaviour will be exhibited by most
> choice-components of the switch in kern_sysctl.c:sysctl_doproc.
>
> Be good,
>   Kristaps
> iD8DBQFFB/IGK0ldVyV4920RAnLFAKCwtfhIoqHnvxNsGJMiRlm608UPdgCgzPHu
> I4f8WCB/ItwGeivRiRb2EL4=
> =xB8P
> -----END PGP SIGNATURE-----