BKEHOE@widener (08/16/90)
/* * This is being run on a Sun SS1 under 4.0.3. * Theoretically, according to the Design & Implementation of 4.3BSD Unix, * this should print out the ascii version of each process's current * directory...instead, it chokes on u->u_cwd->cw_dir, which is in the * u struct in sys/user.h .. any help, suggestions, etc would be greatly * appreciated. */ /* * cc -o cwd cwd.c -lkvm */ #include <stdio.h> #include <kvm.h> #include <fcntl.h> #include <ctype.h> #include <pwd.h> #include <sys/param.h> #include <sys/time.h> #include <sys/proc.h> #include <sys/user.h> main (argc, argv) { *argv); exit (1); } (void) printf("Name\t\tDir\n"); kvm_setproc (kd); while ((proc = kvm_nextproc (kd))) if (proc->p_stat != SZOMB && proc->p_uid) { if (!(user = kvm_getu(kd, proc))) continue; (void) printf("%s\n", (getpwuid(proc->p_uid))->pw_name); /* Curtains & Slow Music */ (void) printf("%s\n", user->u_cwd->cw_dir); /* It dies, but the user structure's fine (printing user->u_comm works); I stepped thru it with gdb & discovered that the pointer user->u_cwd is off in never-never-land; is it a valid entry in the user structure? */ } }
kucharsk@number6.Solbourne.COM (William Kucharski) (08/16/90)
In article <24183@adm.BRL.MIL> BKEHOE@widener writes: >/* > * This is being run on a Sun SS1 under 4.0.3. > * Theoretically, according to the Design & Implementation of 4.3BSD Unix, > * this should print out the ascii version of each process's current > * directory...instead, it chokes on u->u_cwd->cw_dir, which is in the > * u struct in sys/user.h .. any help, suggestions, etc would be greatly > * appreciated. > > */ > >/* > * cc -o cwd cwd.c -lkvm > */ > >#include <stdio.h> >#include <kvm.h> >#include <fcntl.h> >#include <ctype.h> >#include <pwd.h> >#include <sys/param.h> >#include <sys/time.h> >#include <sys/proc.h> >#include <sys/user.h> ... > (void) printf("Name\t\tDir\n"); > kvm_setproc (kd); > while ((proc = kvm_nextproc (kd))) > if (proc->p_stat != SZOMB && proc->p_uid) { > if (!(user = kvm_getu(kd, proc))) > continue; > (void) printf("%s\n", (getpwuid(proc->p_uid))->pw_name); >/* Curtains & Slow Music */ > (void) printf("%s\n", user->u_cwd->cw_dir); >/* It dies, but the user structure's fine (printing user->u_comm works); I > stepped thru it with gdb & discovered that the pointer user->u_cwd is off in > never-never-land; is it a valid entry in >the user structure? */ > } >} That's because the user->u_cwd pointer is really a pointer into the kernel's memory space, rather than user memory space. You need to do something like the following to read the contents of the kernel memory in question into user space: ... char dir[MAXPATHLEN]; char rootdir[MAXPATHLEN]; struct ucwd cwd; if (kvm_read(kd, (unsigned long)userp->u_cwd, (char *)&cwd, sizeof(struct ucwd)) == sizeof(struct ucwd)) { if ((kvm_read(kd, (unsigned long)cwd.cw_dir, dir, MAXPATHLEN) == MAXPATHLEN) && (kvm_read(kd, (unsigned long)cwd.cw_root, rootdir, MAXPATHLEN) == MAXPATHLEN)) { if ((*rootdir) || (*dir)) printf("cwd: %s%s\n", rootdir, dir); else printf("cwd: /\n"); } } ... -- =============================================================================== | Internet: kucharsk@Solbourne.COM | William Kucharski | | uucp: ...!{boulder,sun,uunet}!stan!kucharsk | Solbourne Computer, Inc. | === The sentiments expressed above are MY opinions, NOT those of Solbourne. ===
guy@auspex.auspex.com (Guy Harris) (08/17/90)
"BKEHOE@widener" isn't a very usable email address, and the Path: line ended with "news", so I was unable to mail this. Methinks you should have a talk with your mail or netnews administrator, asking them to fix the From: line on outgoing postings.... >/* > * This is being run on a Sun SS1 under 4.0.3. > * Theoretically, according to the Design & Implementation of 4.3BSD Unix, > * this should print out the ascii version of each process's current > * directory...instead, it chokes on u->u_cwd->cw_dir, which is in the > * u struct in sys/user.h .. any help, suggestions, etc would be greatly > * appreciated. Well, actually, 4.3BSD UNIX doesn't *have* a "u_cwd" member of the "u" structure, so I'd hope that the BSD book *doesn't* suggest that it should work. That field is a SunOS-ism, introduced as part of the C2 security stuff so that the auditing code can get the full pathname of a file. > while ((proc = kvm_nextproc (kd))) > if (proc->p_stat != SZOMB && proc->p_uid) { > if (!(user = kvm_getu(kd, proc))) > continue; > (void) printf("%s\n", (getpwuid(proc->p_uid))->pw_name); Well, you probably want to call "getpwuid()" and store the result somewhere, and then check if it's NULL, before using it; it may not be *likely* to fail, but it *can* fail. >/* Curtains & Slow Music */ > (void) printf("%s\n", user->u_cwd->cw_dir); >/* It dies, but the user structure's fine (printing user->u_comm works); I > stepped thru it with gdb & discovered that the pointer user->u_cwd > is off in never-never-land; is it a valid entry in the user structure? */ Do you mean "is 'u_cwd' a valid entry in the user structure?" Well, maybe. I'm not sure if it's kept up-to-date if you haven't configured the C2 security stuff into your kernel (SYSAUDIT). However, even if it *is* kept up-to-date, it doesn't quite point into user-mode data, obviously. You'll have to grab the pointer value from "u_cwd" and use "kvm_read()" to read it from the *kernel's* address space into a private copy. Then, once you've done that, bear in mind that the "cw_dir" and "cw_root" members of the structure pointed to by "u_cwd" are *themselves* pointers into the kernel's address space, and read the strings to which they point using "kvm_read()" as well. Stepping through kernel data structures is more subtle than you might think. Pointers in kernel data structures *cannot*, in most systems, simply be dereferenced; even if the kernel-mode and user-mode address spaces are common, the kernel data is probably read-protected (for obvious reasons!).