In article <3EA60A90.D1360...@team.telstra.com>, Adam Skeggs <adam.ske...@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:
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
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;
In article <vafns2at5pq...@corp.supernews.com>, rlha...@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
CHANGES: give up setuid or setgid if any files were user-specified -- rlha...@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>
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 (namelist!=NULL || corefile!=NULL || swapfile!=NULL) { /* give up any setuid or setgid if accessing any explicitly user-specified file */ setgid(getgid()); setuid(getuid()); }
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 ======================
>In article <3EA60A90.D1360...@team.telstra.com>, > Adam Skeggs <adam.ske...@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.
In article <vaftojaa84h...@corp.supernews.com>, rlha...@smart.net (Richard L. Hamilton) writes:
> In article <vafns2at5pq...@corp.supernews.com>, > rlha...@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
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]);
if (namelist!=NULL || corefile!=NULL || swapfile!=NULL) { /* give up any setuid or setgid if accessing any explicitly user-specified file */ setgid(getgid()); setuid(getuid()); }
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 ======================