Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

umask of running process

966 views
Skip to first unread message

Adam Skeggs

unread,
Apr 22, 2003, 11:37:52 PM4/22/03
to
Hi,

Either I have forgotten or I never knew how to find out the umask of a
running process. I have a half memory of doing this with a standard
command ...

Anyone?

Adam.

Richard L. Hamilton

unread,
Apr 24, 2003, 8:58:42 AM4/24/03
to
In article <3EA60A90...@team.telstra.com>,

Well, /proc doesn't provide that info (as far as I can tell from proc(4)
or the contents of sys/procfs.h), so I suppose you'd have to use (as root
or a member of group sys) the "crash" command:

# crash
dumpfile = /dev/mem, namelist = /dev/ksyms, outfile = stdout
> proc
PROC TABLE SIZE = 17802
SLOT ST PID PPID PGID SID UID PRI NAME FLAGS
0 t 0 0 0 0 0 96 sched load sys lock
[many proc table entries skipped]
240 s 23264 5432 5432 2491 0 58 sh load
> user 240
PER PROCESS USER AREA FOR PROCESS 240
PROCESS MISC:
command: sh, psargs: sh
start: Thu Apr 24 06:51:01 2003
mem: 8a, type: exec
vnode of current directory: 300060c8ba0
OPEN FILES, FLAGS, AND THREAD REFCNT:
[0]: F 300033a2048, 0, 0 [1]: F 300033a2048, 0, 0
[2]: F 300033a2048, 0, 0 [19]: F 300029f1ae8, 1, 0
cmask: 0022
RESOURCE LIMITS:
cpu time: unlimited/unlimited
file size: unlimited/unlimited
swap size: unlimited/unlimited
stack size: 8388608/unlimited
coredump size: unlimited/unlimited
file descriptors: 256/1024
address space: unlimited/unlimited
SIGNAL DISPOSITION:
1: 4281460948 2: 4281460948 3: 4281460948 4: 4281460948
5: 4281460948 6: 4281460948 7: 4281460948 8: 4281460948
9: default 10: 4281460948 11: 4281460948 12: 4281460948
13: 4281460948 14: 4281460948 15: 4281460948 16: 4281460948
17: 4281460948 18: default 19: 4281460948 20: default
21: 4281460948 22: 4281460948 23: default 24: default
25: default 26: default 27: ignore 28: 4281460948
29: 4281460948 30: 4281460948 31: 4281460948 32: default
33: default 34: default 35: default 36: default
37: default 38: 4281460948 39: 4281460948 40: 4281460948
41: 4281460948 42: 4281460948 43: 4281460948 44: 4281460948
45: 4281460948

The line "cmask: 022" above is the umask for that process.

On Solaris 8 and later, it should also be possible to use "mdb" to do
this (also as root or group sys), although I haven't figured out quite
the mystical utterances needed to do it; eventually I'll have to, since
"crash" is supposed to go away one day in favor of "mdb".

I exchanged email with a Sun guy once on the topic of retrieving the umask
of a running process, and he seemed to agree that it was odd that /proc
didn't make that information available (to allow a trivial utility to be
able to retrieve it, for instance). I think he was inclined to see if
something could be done about it, but I'm sure they have lots of other
priorities to juggle, so I don't know when/if anything will become
available. I don't mention his name here, 'cause I appreciate that some
of 'em will actually talk to me once in awhile, and I don't want to get
them ganged up on and have them clam up on me.

Last but not least, this can also be done using libkvm, although that's
inherently ugly (see libkvm(3lib)); I just now wrote something to do it
(source follows). It must be compiled with -lkvm, and if to be run on a
64-bit kernel, must be compiled as a 64-bit program (one could compile it
both ways and use a 32-bit wrapper program to choose the appropriate
version; on SPARC Solaris 8, one could use the same wrapper they use, e.g.
put the 64-bit version in /usr/bin/sparcv9/pumask and the 32-bit version
in /usr/bin/sparcv7/pumask, and in /usr/bin, ln /usr/lib/isaexec pumask).
The real binaries (not the wrapper!) would still have to run as root (or
better yet, setgid sys). It worked for me (on 64-bit Solaris 8), but I've
only run it on a few different processes, so there's no guarantee that
it's either safe or reliable. If Sun ever does it right (e.g. with a
/proc interface) and also provides a command something like this, it
probably will _not_ have the -n/-c/-s options, so don't get used to them
(and they're untested anyway).

Sun, if you want to give folks a command like this and don't get around to
doing it right, you're free to use mine (I wouldn't refuse credit in the
man page, but don't require it). But I'd rather you did it right, with
/proc support for obtaining the umask of running processes. And in terms
of avoiding new dependencies on libkvm with whatever maintenance problems
that might imply, I'd think you'd rather do it right too.

========================= cut here ======================
/* pumask.c
get the umask of a running process

* must be linked with -lkvm (on older Solaris, also with -lelf)

* since libkvm is inherently ugly, this could be broken at any time
in the future; I'd tend to also feel more comfortable if it were
compiled specifically for the Solaris version it was to run on; in
particular, the binary I compiled on 32-bit SPARC Solaris 2.5.1 did
_not_ work on 32-bit SPARC Solaris 8, although a recompiled binary
worked fine

* must be compiled as 64-bit executable if to be run on a 64-bit kernel

* options to specify alternate corefile, namelist, swapfile (e.g. to
work against a kernel crash dump) have not been tested at all; this
is as best I can remember the first time I've used libkvm, so it's
sheer good luck if I did it right!

* use strictly at your own risk!

* only minimally tested on 64-bit and 32-bit SPARC Solaris 8
(and separately compiled, on 32-bit SPARC Solaris 2.5.1)

* no support, although I _may_ read e-mailed bug reports

rlh...@mindwarp.smart.net Apr 24, 2003

*/
#define _KMEMUSER 1
#include <kvm.h>
#include <fcntl.h>
#include <sys/param.h>
#include <sys/time.h>
#include <sys/user.h>
#include <sys/proc.h>
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv)
{
static char options[] = "c:n:s:";
kvm_t *kd;
extern char *optarg;
extern int optind;
char error_flag=0;
int curopt;
char *namelist=NULL, *corefile=NULL, *swapfile=NULL, *p;
pid_t pid;
struct proc *procp;
struct user *userp;

while ((curopt=getopt(argc,argv,options))!=EOF)
switch(curopt) {
case 'c':
corefile=optarg;
break;
case 'n':
namelist=optarg;
break;
case 's':
swapfile=optarg;
break;
case '?':
default:
error_flag=1;
break;
}

pid=strtol(argv[optind],&p,10);
if (p==argv[optind] || *p!='\0')
error_flag=1;

if (error_flag || argc<=optind) {
fprintf(stderr,
"usage: %s [-n namelist ] [-c corefile] [-s swapfile] pid \n",
argv[0]);
return 1;
}

if ((kd=kvm_open(namelist,corefile,swapfile,O_RDONLY,argv[0])) == NULL) {
perror("kvm_open() failed");
return 2;
}
if ((procp=kvm_getproc(kd,pid))==NULL) {
fprintf(stderr,"%s: kvm_getproc() for pid %ld failed\n",argv[0],
(long) pid);
kvm_close(kd);
return 3;
}
if ((userp=kvm_getu(kd,procp))==NULL) {
fprintf(stderr,"%s: kvm_getu() for pid %ld failed\n",argv[0],
(long) pid);
kvm_close(kd);
return 4;
}
printf("%04lo\n",(unsigned long)userp->u_cmask);
kvm_close(kd);
return 0;
}
========================= cut here ======================

--
mailto:rlh...@mindwarp.smart.net http://www.smart.net/~rlhamil

Richard L. Hamilton

unread,
Apr 24, 2003, 10:39:15 AM4/24/03
to
In article <vafns2a...@corp.supernews.com>,
rlh...@smart.net (Richard L. Hamilton) writes:
[...]

> Last but not least, this can also be done using libkvm, although that's
> inherently ugly (see libkvm(3lib)); I just now wrote something to do it
> (source follows). It must be compiled with -lkvm, and if to be run on a
[...]

and already, the first update. Just occurred to me that is really should
give up any setuid or setgid if the user specified namelist, corefile, or
swapfile (to keep 'em from trying to read something they're not supposed to
with it). If you intend to install this setgid sys (or setuid root, but
that shouldn't be necessary or advisable), then this update should be if
not safe, at least less unsafe.

========================= cut here ======================
/* pumask.c
get the umask of a running process

* must be linked with -lkvm (on older Solaris, also with -lelf)

* since libkvm is inherently ugly, this could be broken at any time
in the future; I'd tend to also feel more comfortable if it were
compiled specifically for the Solaris version it was to run on; in
particular, the binary I compiled on 32-bit SPARC Solaris 2.5.1 did
_not_ work on 32-bit SPARC Solaris 8, although a recompiled binary
worked fine

* must be compiled as 64-bit executable if to be run on a 64-bit kernel

* options to specify alternate corefile, namelist, swapfile (e.g. to
work against a kernel crash dump) have not been tested at all; this
is as best I can remember the first time I've used libkvm, so it's
sheer good luck if I did it right!

* use strictly at your own risk!

* only minimally tested on 64-bit SPARC Solaris 8
(and 32-bit SPARC Solaris 2.5.1)

* no support, although I _may_ read e-mailed bug reports

rlh...@mindwarp.smart.net Apr 24, 2003

CHANGES:
give up setuid or setgid if any files were user-specified
-- rlh...@mindwarp.smart.net Apr 24, 2003


*/
#define _KMEMUSER 1
#include <kvm.h>
#include <fcntl.h>
#include <sys/param.h>
#include <sys/time.h>
#include <sys/user.h>
#include <sys/proc.h>
#include <stdio.h>
#include <stdlib.h>

#include <unistd.h>

if (namelist!=NULL || corefile!=NULL || swapfile!=NULL) {
/* give up any setuid or setgid if accessing any explicitly user-specified
file */
setgid(getgid());
setuid(getuid());

Casper H.S. Dik

unread,
Apr 24, 2003, 10:58:08 AM4/24/03
to
rlh...@smart.net (Richard L. Hamilton) writes:

>In article <3EA60A90...@team.telstra.com>,
> Adam Skeggs <adam....@team.telstra.com> writes:
>> Hi,
>>
>> Either I have forgotten or I never knew how to find out the umask of a
>> running process. I have a half memory of doing this with a standard
>> command ...
>>
>> Anyone?

>Well, /proc doesn't provide that info (as far as I can tell from proc(4)
>or the contents of sys/procfs.h), so I suppose you'd have to use (as root
>or a member of group sys) the "crash" command:


S9 mdb -k:

0t556::pid2proc | ::print proc_t p_user.u_cmask

Casper
--
Expressed in this posting are my opinions. They are in no way related
to opinions held by my employer, Sun Microsystems.
Statements on Sun products included here are not gospel and may
be fiction rather than truth.

Richard L. Hamilton

unread,
Apr 24, 2003, 3:58:33 PM4/24/03
to
In article <vaftoja...@corp.supernews.com>,

rlh...@smart.net (Richard L. Hamilton) writes:
> In article <vafns2a...@corp.supernews.com>,
> rlh...@smart.net (Richard L. Hamilton) writes:
> [...]
>> Last but not least, this can also be done using libkvm, although that's
>> inherently ugly (see libkvm(3lib)); I just now wrote something to do it
>> (source follows). It must be compiled with -lkvm, and if to be run on a
> [...]
>
> and already, the first update. Just occurred to me that is really should
> give up any setuid or setgid if the user specified namelist, corefile, or
> swapfile (to keep 'em from trying to read something they're not supposed to
> with it). If you intend to install this setgid sys (or setuid root, but
> that shouldn't be necessary or advisable), then this update should be if
> not safe, at least less unsafe.

One more, hopefully the last. Could've dereferenced a NULL pointer if
pid arg wasn't supplied, resulting in a totally stupid segfault.



========================= cut here ======================
/* pumask.c
get the umask of a running process

* must be linked with -lkvm (on older Solaris, also with -lelf)

* since libkvm is inherently ugly, this could be broken at any time
in the future; I'd tend to also feel more comfortable if it were
compiled specifically for the Solaris version it was to run on; in
particular, the binary I compiled on 32-bit SPARC Solaris 2.5.1 did
_not_ work on 32-bit SPARC Solaris 8, although a recompiled binary
worked fine

* must be compiled as 64-bit executable if to be run on a 64-bit kernel

* options to specify alternate corefile, namelist, swapfile (e.g. to
work against a kernel crash dump) have not been tested at all; this
is as best I can remember the first time I've used libkvm, so it's
sheer good luck if I did it right!

* use strictly at your own risk!

* only minimally tested on 64-bit SPARC Solaris 8
(and 32-bit SPARC Solaris 2.5.1)

* no support, although I _may_ read e-mailed bug reports

rlh...@mindwarp.smart.net Apr 24, 2003

CHANGES:
* give up setuid or setgid if any files were user-specified
* change arg checking to avoid segfault


-- rlh...@mindwarp.smart.net Apr 24, 2003
*/
#define _KMEMUSER 1
#include <kvm.h>
#include <fcntl.h>
#include <sys/param.h>
#include <sys/time.h>
#include <sys/user.h>
#include <sys/proc.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

void usage(char *argv0)


{
fprintf(stderr,
"usage: %s [-n namelist ] [-c corefile] [-s swapfile] pid \n",

argv0);
exit(1);
/*NOTREACHED*/
}

int main(int argc, char **argv)
{
static char options[] = "c:n:s:";
kvm_t *kd;
extern char *optarg;
extern int optind;

int curopt;
char *namelist=NULL, *corefile=NULL, *swapfile=NULL, *p;
pid_t pid;
struct proc *procp;
struct user *userp;

while ((curopt=getopt(argc,argv,options))!=EOF)
switch(curopt) {
case 'c':
corefile=optarg;
break;
case 'n':
namelist=optarg;
break;
case 's':
swapfile=optarg;
break;
case '?':
default:

usage(argv[0]);
break;
}

if (argc<=optind)
usage(argv[0]);


pid=strtol(argv[optind],&p,10);
if (p==argv[optind] || *p!='\0')

usage(argv[0]);

0 new messages