RE: how to tell if a process is 64-bit

2017-09-08 Thread Terry Moore
Hi,

> In a cross-platform process utility tool the question came up how to
decide if a process is 64-bit.
>
> https://github.com/giampaolo/psutil/issues/1102
>
> What's the best answer for NetBSD?

If I understand correctly, you want psutil-based scripts -- which seem to 
be written in Python -- to be able to ask "is-64" about other processes? 
I suppose you are therefore interested in knowing the base ISA of a given 
process from outside the process?

(As others have mentioned, you might instead, or additionally, be interested

in the emulation that's in use.)

Are you looking for the system calls, or the python equivalents?

Can you clarify?

Best regards,
--Terry




re: how to tell if a process is 64-bit

2017-09-08 Thread matthew green
> > In addition to amd64/i386, it occurs to me that sparc64/sparc32 is
> > another case; IIRC it's possible to take sparc64 hardware and build a
> > (special? not sure) kernel that runs sparc32 userland.  I've never
> > tried it; I don't know whether sparc32 and sparc64 are as freely
> > mixable at runtime as amd64 and i386 are under amd64 kernels.
> 
> Yes, that's what compat/netbsd32 is for.  (Of course, there are still a 
> few things like mount I never bothered to get working across ABIs.)

there are a few supported cases here:  32 bit kernel on 64 bit cpu
(32 bit userland only).  64 bit kernel with either size userland.

eeh - matt@ fixed mount compat a few years ago, as well as a lot
of the remaining edge cases we'd never gotten to.  it was necessary
to run full n32 userland on n64 kernel (we still build all the
kvm-on-running-kernel-using programs as n64.)  so that generally
works fine now..


.mrg.


Re: how to tell if a process is 64-bit

2017-09-08 Thread Mouse
> That's why I asked "what does 'is 64-bit' mean".  Your previous reference to$

Any particular reason for the paragraph-length line?

Manually repairing it (and trimming to the part I'm replying to),

> [...] the question "does this program use 64 bit addresses".  There
> are at least two other possible questions: (a) does this program have
> access to 64 bit registers, and (b) can this program do operations
> such as arithmetic on 64 bit integers.

You would be hard-pressed to find a platform on which (b) is false (and
I'm not restricting that to NetBSD-supporting platforms, though I think
I would have to restrict it to devices that were designed to be
general-purpose computers).  Even things like the tiny little
MC68HC908QY4 8-bit microcontrollers in 16-pin DIP packages I've
currently lost my tube of can do 64-bit arithmetic.

Not fast (they don't do _anything_ fast), and not in single
instructions, but so what?  Even a sparc64 machine can't do a
general-purpose 64-bit add in a single instruction unless both inputs
are already in registers and leaving the output in a register is
acceptable.

/~\ The ASCII Mouse
\ / Ribbon Campaign
 X  Against HTMLmo...@rodents-montreal.org
/ \ Email!   7D C8 61 52 5D E7 2D 39  4E F1 31 3E E8 B3 27 4B


Re: how to tell if a process is 64-bit

2017-09-08 Thread Eduardo Horvath
On Fri, 8 Sep 2017, Mouse wrote:

> >> ([...] on most "64-bit" ports, a real question on amd64 (and others,
> >> if any) which support 32-bit userland.)
> > actually -- our mips64 ports largely use N32 userland, which is 64
> > bit registers and 32 bit addresses.
> 
> Oh!  Thank you.  Yes, that's an interesting case.
> 
> In addition to amd64/i386, it occurs to me that sparc64/sparc32 is
> another case; IIRC it's possible to take sparc64 hardware and build a
> (special? not sure) kernel that runs sparc32 userland.  I've never
> tried it; I don't know whether sparc32 and sparc64 are as freely
> mixable at runtime as amd64 and i386 are under amd64 kernels.

Yes, that's what compat/netbsd32 is for.  (Of course, there are still a 
few things like mount I never bothered to get working across ABIs.)

Eduardo


Re: how to tell if a process is 64-bit

2017-09-08 Thread Mouse
>> ([...] on most "64-bit" ports, a real question on amd64 (and others,
>> if any) which support 32-bit userland.)
> actually -- our mips64 ports largely use N32 userland, which is 64
> bit registers and 32 bit addresses.

Oh!  Thank you.  Yes, that's an interesting case.

In addition to amd64/i386, it occurs to me that sparc64/sparc32 is
another case; IIRC it's possible to take sparc64 hardware and build a
(special? not sure) kernel that runs sparc32 userland.  I've never
tried it; I don't know whether sparc32 and sparc64 are as freely
mixable at runtime as amd64 and i386 are under amd64 kernels.

/~\ The ASCII Mouse
\ / Ribbon Campaign
 X  Against HTMLmo...@rodents-montreal.org
/ \ Email!   7D C8 61 52 5D E7 2D 39  4E F1 31 3E E8 B3 27 4B


Re: how to tell if a process is 64-bit

2017-09-08 Thread Paul.Koning

> On Sep 8, 2017, at 4:00 PM, matthew green  wrote:
> 
>> Is the answer "it's using an ISA with 64-bit registers and addresses"?
>> This actually can be broken down into the "registers" and "addresses"
>> portion, but, in practice, the two tend to go together.  (Always true
>> on most "64-bit" ports, a real question on amd64 (and others, if any)
>> which support 32-bit userland.)
> 
> actually -- our mips64 ports largely use N32 userland, which
> is 64 bit registers and 32 bit addresses.  this is also what
> linux calls "x32" for x86 platforms.  obviously, this does
> require a 64 bit cpu.

That's why I asked "what does 'is 64-bit' mean".  Your previous reference to 
LP64 answers the question "does this program use 64 bit addresses".  There are 
at least two other possible questions: (a) does this program have access to 64 
bit registers, and (b) can this program do operations such as arithmetic on 64 
bit integers.  (a) presumably implies (b) but the two are not equivalent.  For 
example, N32 is (a) and (b) but O32 -- the old "mips32" port -- is (b) but not 
(a).

paul



re: how to tell if a process is 64-bit

2017-09-08 Thread matthew green
> Is the answer "it's using an ISA with 64-bit registers and addresses"?
> This actually can be broken down into the "registers" and "addresses"
> portion, but, in practice, the two tend to go together.  (Always true
> on most "64-bit" ports, a real question on amd64 (and others, if any)
> which support 32-bit userland.)

actually -- our mips64 ports largely use N32 userland, which
is 64 bit registers and 32 bit addresses.  this is also what
linux calls "x32" for x86 platforms.  obviously, this does
require a 64 bit cpu.


.mrg.


re: how to tell if a process is 64-bit

2017-09-08 Thread matthew green
> In a cross-platform process utility tool the question came up how to
> decide if a process is 64-bit.
> 
> https://github.com/giampaolo/psutil/issues/1102
> 
> What's the best answer for NetBSD?

in C:

internally, just check #ifdef _LP64.
externally, kvm_getprocs() with KERN_PROC_PID.

in other languages?  don't ask me.


.mrg.


Re: fork1 use-after-free of the child process

2017-09-08 Thread Kamil Rytarowski
On 08.09.2017 04:32, Mateusz Guzik wrote:
> The fork1 routine can wait for the child to exit (if vforked) and/or
> return the pointer to the child.
> 
> Neither case guarantees the safety of said operation. The key is that
> the parent can be ignoring SIGCHLD, which results in autoreaping the
> child and the child itself is made runnable. Thus in particular it can
> exit and get its struct proc freed. No prevention measures are taken
> AFAICS.
> 
> I did not test it on the NetBSD kernel, but it's a standard problem and
> the code definitely looks buggy.
> 
> 1. returning the pointer
> 
> The last parameter to fork1 is struct proc **rnewprocp. I found only 2
> uses:
> - linux_sys_clone - the parameter is populated from a local variable
>   which is not used afterwards, i.e. the func can as well start passing
>   NULL instead
> - creation of initproc - since this becomes the only remaining use of
>   the parameter I think it makes sense to get rid of it altogether. the
>   simplest hack which comes to mind will simply proc_find_raw the
>   process after fork return
> 
> 2. vfork
> 
> By the end there is:
> while (p2->p_lflag & PL_PPWAIT)
>     cv_wait(>p_waitcv, proc_lock);
> 
> Retesting after wake up triggers the bug.
> 
> The cleanest solution I'm aware of introduces a dedicated condvar to use
> by vfork. The parent uses a local variable for this purpose. Since the
> condvar is only used by vfork to signal exec/exit, there is no need
> to access the child after waking up. The downside is extention of struct
> proc with a pointer. Interestingly this is what they do in Linux.
> 
> FreeBSD does the obvious of grabbing a reference preventing the
> destruction of struct proc from going through.
> 
> Solaris suprisingly has a total hack: they look up the pid and see if
> found process (if any) has to be waited on. Apart from general ugliness
> it's also a minor scalability problem due to extra lock/unlock of the
> global process list lock.
> 
> -- 
> Mateusz Guzik http://gmail.com>>

Thank you for the analysis. There is also a correctness problem with
ptrace(2).

I had trouble to generate the PTRACE_VFORK event. The first one for the
parent that calls vfork(2) and reports child's PID; the second one that
is generated by vforkee and returns forker's PID.

When the child calls exec(2)/exit(2) and parent is resuming, there shall
be reported PTRACE_VFORK_DONE once with PID of vforkee.

Another topic is that we always want to get PTRACE_FORK and PTRACE_VFORK
generated by the parent first and followed by a signal from the child.
This deterministic order simplifies a debugger.

Once I will sort out bugs with threads (LWPs) under a tracer, I will be
back to this topic.



signature.asc
Description: OpenPGP digital signature


unsafe ->p_cwdi access in mount_checkdirs

2017-09-08 Thread Mateusz Guzik
In mount_checkdirs you can find a loop:

mutex_enter(proc_lock);
PROCLIST_FOREACH(p, ) {
if ((cwdi = p->p_cwdi) == NULL)
continue;
if (cwdi->cwdi_cdir != olddp &&
cwdi->cwdi_rdir != olddp)
continue;
retry = true;
rele1 = NULL;
rele2 = NULL;
atomic_inc_uint(>cwdi_refcnt);
mutex_exit(proc_lock);
rw_enter(>cwdi_lock, RW_WRITER);

The problem is that p_cwdi IS NOT protected by proc_lock. The exit path
uses reflock to destroy the object.

Since this function is not performance critical, my suggested fix is to
uncondionally take the p_lock and ref cwdi only if the process is alive
and constructed.

Alternatively, cwdi freeing can be split into 2 parts where actual freeing
of the cwdi object itself is postponed until after proc_lock lock/unlock
dance.

Pseudo-code:
struct cwdinfo *
cwddestroy(struct cwdinfo *cwdi)
{

if (atomic_dec_uint_nv(>cwdi_refcnt) > 0)
return NULL;

vrele(cwdi->cwdi_cdir);
if (cwdi->cwdi_rdir)
vrele(cwdi->cwdi_rdir);
if (cwdi->cwdi_edir)
vrele(cwdi->cwdi_edir);
return cwdi;
}

void
cwdfree(struct cwdinfo *cwdi)
{

pool_cache_put(cwdi_cache, cwdi);
}

Then the exit path would:
cwdi = cwddestroy(p->p_cwdi);
p->p_cwdi = NULL;

mutex_enter(proc_lock);

mutex_exit(proc_lock);
cwdfree(cwdi);



mount_checkdirs would then atomic_inc_not_zero (or however you have this
named).

With the above, if cwdi was spotted, it is guaranteeed to not get freed
until after proc_lock is dropped. A successfull non-zero -> non-zero + 1
refcount bump guarantees it wont get freed and the content will remain
valid.

-- 
Mateusz Guzik 


Re: how to tell if a process is 64-bit

2017-09-08 Thread Martin Husemann
On Fri, Sep 08, 2017 at 01:13:44PM +, Christos Zoulas wrote:
> If you can attach to it with ktrace, the first record is an emul record.
> If you have procfs cat /proc//emul

Yeah, but it would be interesting to see in something like kprocinfo2
(easily fetchable via sysctl or the kvm wrapper).

Martin


Re: how to tell if a process is 64-bit

2017-09-08 Thread Christos Zoulas
In article <20170908115647.ga29...@mail.duskware.de>,
Martin Husemann   wrote:
>On Fri, Sep 08, 2017 at 12:55:37PM +0200, Thomas Klausner wrote:
>> What's the best answer for NetBSD?
>
>If the kernel is 64bit:
>kvm_getproc2() and check the process flags for P_32.
>
>If not: all of them ;-}
>
>I would find it more interesting to answer "what is the emulation it runs
>under", so you have, say: netbsd native x86_64 processes, netbsd_compat32 
>i386 processes, 32 bit linux, 64 bit linux,  (but I don't know an
>easy answer for that).

If you can attach to it with ktrace, the first record is an emul record.
If you have procfs cat /proc//emul

christos



Re: how to tell if a process is 64-bit

2017-09-08 Thread Mouse
>> First, I have to ask: what does it mean to say that a particular
>> process is - or isn't - 64-bit?
> Many 64-bit ports support running 32-bit applications
> (compat_netbsd32, compat_linux32).

Exactly.

Is the answer "it can do arithmetic on 64-bit values"?  (Most - all, I
think - NetBSD ports qualify.  Indeed, I have trouble imagining any
machine with pretensions to general-purpose use, even 8-bitters like
the C=64, that doesn't.)

Is the answer "the CPU has 64-bit internal datapaths"?  (This is not a
per-process thing; it is probably true of some CPUs usually thought of
as 32-bit and probably false of some low-end "64-bit" CPUs.)

Is the answer "it's using an ISA with 64-bit registers and addresses"?
This actually can be broken down into the "registers" and "addresses"
portion, but, in practice, the two tend to go together.  (Always true
on most "64-bit" ports, a real question on amd64 (and others, if any)
which support 32-bit userland.)

Is the answer "it can address more than 4G of VM"?  (This is probably
equivalent, in practice, to the previous one.)

Is the answer "it can address VM above the 4G point"?  (For some ways
of looking at the questions, this is equiavlent to the previous one.  I
think amd64 CPUs can do this under some circumstances when executing
their 32-bit ISA, though I'd have to check the architecture document to
be sure, and they may be limited to something like the 64G point.)

I suspect the original question was thinking of the middle one,
probably with regard to amd64/i386.  I _think_ the CPU in that case can
switch its ISA on the fly; if so, the question may need to be more "is
it a 64-bit process at some particular moment?".  If not, "which
emulation is it using?" may be close enough to be useful, and is easy
to answer, though perhaps somewhat inconvenient (ktrace writes a record
with the emulation type; with no tracing points turned on that should
be all it writes).

/~\ The ASCII Mouse
\ / Ribbon Campaign
 X  Against HTMLmo...@rodents-montreal.org
/ \ Email!   7D C8 61 52 5D E7 2D 39  4E F1 31 3E E8 B3 27 4B


Re: how to tell if a process is 64-bit

2017-09-08 Thread Thomas Klausner
On Fri, Sep 08, 2017 at 07:38:24AM -0400, Mouse wrote:
> First, I have to ask: what does it mean to say that a particular
> process is - or isn't - 64-bit?

Many 64-bit ports support running 32-bit applications
(compat_netbsd32, compat_linux32).
 Thomas


Re: how to tell if a process is 64-bit

2017-09-08 Thread Martin Husemann
On Fri, Sep 08, 2017 at 12:55:37PM +0200, Thomas Klausner wrote:
> What's the best answer for NetBSD?

If the kernel is 64bit:
kvm_getproc2() and check the process flags for P_32.

If not: all of them ;-}

I would find it more interesting to answer "what is the emulation it runs
under", so you have, say: netbsd native x86_64 processes, netbsd_compat32 
i386 processes, 32 bit linux, 64 bit linux,  (but I don't know an
easy answer for that).

Martin


Re: how to tell if a process is 64-bit

2017-09-08 Thread coypu
At the risk of making people angry, this answer works for linux and netbsd:

$ file -L /proc/self/exe
/proc/self/exe: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), 
dynamically linked, interpreter /usr/libexec/ld.elf_so, for NetBSD 8.99.2, not 
stripped



Re: how to tell if a process is 64-bit

2017-09-08 Thread Mouse
> In a cross-platform process utility tool the question came up how to
> decide if a process is 64-bit.

First, I have to ask: what does it mean to say that a particular
process is - or isn't - 64-bit?

I started to write that on most of the 64-bit-supporting ports there
isn't even any question, but then I realized that, depending on the
answer to the above, that may not be true.

/~\ The ASCII Mouse
\ / Ribbon Campaign
 X  Against HTMLmo...@rodents-montreal.org
/ \ Email!   7D C8 61 52 5D E7 2D 39  4E F1 31 3E E8 B3 27 4B


how to tell if a process is 64-bit

2017-09-08 Thread Thomas Klausner
Hi!

In a cross-platform process utility tool the question came up how to
decide if a process is 64-bit.

https://github.com/giampaolo/psutil/issues/1102

What's the best answer for NetBSD?
 Thomas


fork1 use-after-free of the child process

2017-09-08 Thread Mateusz Guzik
The fork1 routine can wait for the child to exit (if vforked) and/or
return the pointer to the child.

Neither case guarantees the safety of said operation. The key is that
the parent can be ignoring SIGCHLD, which results in autoreaping the
child and the child itself is made runnable. Thus in particular it can
exit and get its struct proc freed. No prevention measures are taken
AFAICS.

I did not test it on the NetBSD kernel, but it's a standard problem and
the code definitely looks buggy.

1. returning the pointer

The last parameter to fork1 is struct proc **rnewprocp. I found only 2
uses:
- linux_sys_clone - the parameter is populated from a local variable
  which is not used afterwards, i.e. the func can as well start passing
  NULL instead
- creation of initproc - since this becomes the only remaining use of
  the parameter I think it makes sense to get rid of it altogether. the
  simplest hack which comes to mind will simply proc_find_raw the
  process after fork return

2. vfork

By the end there is:
while (p2->p_lflag & PL_PPWAIT)
cv_wait(>p_waitcv, proc_lock);

Retesting after wake up triggers the bug.

The cleanest solution I'm aware of introduces a dedicated condvar to use
by vfork. The parent uses a local variable for this purpose. Since the
condvar is only used by vfork to signal exec/exit, there is no need
to access the child after waking up. The downside is extention of struct
proc with a pointer. Interestingly this is what they do in Linux.

FreeBSD does the obvious of grabbing a reference preventing the
destruction of struct proc from going through.

Solaris suprisingly has a total hack: they look up the pid and see if
found process (if any) has to be waited on. Apart from general ugliness
it's also a minor scalability problem due to extra lock/unlock of the
global process list lock.

-- 
Mateusz Guzik