ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Hokay, long long time ago, I worked on a Vax machine.
It had a nifty OS call that allowed you to probe a memory address and find out if you could read or write to it. (They were based on machine code instructions PROBER and PROBEW, power pc architecture has 'em too.)
Sure you can do...
int isWritable( int * p)
int tmp = *p;
int result = 0;
*p = tmp+1;
result = *p == (tmp+1);
*p = tmp;
return result;
}
but if there is nothing there you'll segfault, and if there is DMA hardware there... who knows what will happen.
Is there a linux routine I can invoke to work out if an address is writable?
I'm missing why you discard pmap and its Linux implementation. All the information you need is there, isn't it ?
Ok, let me take a step back.
I want to implement the following two asserts...
assert( IsValidDataPointer(pointer));
assert( IsValidFunctionPointer(pointer));
So what on ye olde 1980's Vax was a single machine code instruction, using the /proc/PID/maps solution will be open a file, scanf about 100 lines, close file. And scanf is an extraordinarily heavyweight function involving 10's of thousands of machine instructions.
Distribution: Solaris 11.4, Oracle Linux, Mint, Debian/WSL
Posts: 9,789
Rep:
I agree it is heavyweight compared to a single machine code instruction but given the fact the x86 architecture is missing these instructions, it has to be done another way. The pmap solution is also probably inaccurate as the pseudo file content might be partially obsoleted by its own parsing. Beware too that a read-only memory address doesn't imply it is executable nor it necessarily points to a valid instruction.
Anyway, here is a quick and dirty portable implementation I just wrote to see if it was doable in C. Make sure compiler optimizations are disabled for the write probe to work.
Anyway, here is a quick and dirty portable implementation I just wrote to see if it was doable in C. Make sure compiler optimizations are disabled for the write probe to work.
Nah. Don't need to disable optimization, just need volatile....
Code:
int probew(void *p)
{
volatile unsigned char *c=(volatile char *)p;
unsigned char temp;
if(setjmp(env)!=0) return(1);
// Preserve *c, may segfault if can't read
temp = *c;
*c = 0;
if (*c == 0) // That write seems to have worked,
if(temp !=0) // Maybe it was 0 anyway
{
*c = temp; // Put it back.
return 0; // Say it is writable.
}
// Well try write a 0xff instead
*c=0xff;
if (*c != 0xff) // Whoops, that didn't work
return 1; // Say not writable.
*c = temp; // Put it back
return(0); // Say writable.
}
main(int argc, char **argv)
{
char s[]="hi there";
signal(SIGSEGV,handler);
printf("%s\n", (prober((void *)s))?"Not readable":"Readable");
printf("%s\n", (probew((void *)s))?"Not writable":"Writable");
printf("%s\n", (prober((void *)main))?"Not readable":"Readable");
printf("%s\n", (probew((void *)main))?"Not writable":"Writable");
}
Distribution: Solaris 11.4, Oracle Linux, Mint, Debian/WSL
Posts: 9,789
Rep:
Your probew implementation is doing unnecessary tests if your goal is to implement the VAX original instructions and might be destructive too if you are unlucky.
Your probew implementation is doing unnecessary tests if your goal is to implement the VAX original instructions and might be destructive too if you are unlucky.
The program I want to use this on also runs on an embedded device without MMU, and your test would pass erroneously on areas with no ram. Hmm. But it would screw up DMA devices.
As to the unlucky, I doubt if your test is atomic either. Your test probably also compiles to load to register, do something in register, store to memory.
The sad thing is the routine I want is available in the kernel... It is called "access_ok". It just doesn't seem to be exported into userland.
Distribution: Solaris 11.4, Oracle Linux, Mint, Debian/WSL
Posts: 9,789
Rep:
Every program that writes something to a random address might screw up itself of worst, especially if it writes something different than what was there before.
On your embedded device, access_ok might be implemented by using a similar approach than the initial solution I suggested, according to its documentation.
Note that, depending on architecture, this function probably just checks that the pointer is in the user space range - after calling this function, memory access functions may still return -EFAULT.
I'm afraid what you are after has no perfect solution.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.