Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Souldn't it also work, if /proc/version" is read from an other process into buffer? #7

Closed
sebeka opened this issue Jan 5, 2018 · 6 comments

Comments

@sebeka
Copy link

sebeka commented Jan 5, 2018

Just for understanding,

you open (proc-)file "/proc/version" and to get one bit of output you read 10000 times 256bit of it (always at the same position)
(void) pread(fd, buf, sizeof(buf), 0);

I don't understand it completly, but I mean reading a file while opening it, is no big deal.
Should it not also work, if /proc/version is read for some seconds by an other process?
I put the read file stuff into an other file and recompiled both. With running read process I started
./run.sh but I only get:
ffffffffbbe00060 = 0
ffffffffbbe00061 = 0
ffffffffbbe00062 = 0
...

@paboldin
Copy link
Owner

paboldin commented Jan 5, 2018

Should it not also work, if /proc/version is read for some seconds by an other process

I'm not sure and must be depending on the environment.

I put the read file stuff into an other file and recompiled both

I can't tell without the source code.

@sebeka
Copy link
Author

sebeka commented Jan 5, 2018

As quick example, something like:
comment lines 163 to 167:
ret = pread(fd, buf, sizeof(buf), 0);
if (ret < 0) {
perror("pread");
break;
}

and in an other terminal run:

while [ 1 ]; do cat /proc/version > /dev/null; done

Maybe I miss understood the whole thing but in my opinion the code is accessing data for which it has permission anyways. Is it possible to output /proc/version without
fd = open("/proc/version", O_RDONLY);
in the same process?

So thanks for your test, but I don't get it at the moment.

@paboldin
Copy link
Owner

paboldin commented Jan 5, 2018

The kernel has the access to this memory, but not the userspace. But userspace can "read" it via cache accesses.

Try playing with processes affinities. Maybe try change the criteria of the success (I believe checking that hist[i] > 2 may be enough). Try enabling debug and show the results again.

@sebeka
Copy link
Author

sebeka commented Jan 5, 2018

OK, I played with the thresholds
Now, even with reading /proc/version in a C loop and enabling DEBUG:
#ifdef DEBUG
for (i = 0; i < BITS_BY_READ; i++) {
if (hist[i] > 0)
printf("addr %lx hist[%x] = %d\n", addr, i, hist[i]);
}
#endif
There are only zeros.

Maybe, it is really some timing problem. Secondly I changed your original code, but while reading one bit, I load the file only once in buf, there are already random changes/mistakes in output.
So could be hard to exploit the bug in real world. Maybe it is also very cpu / architecture depending as you told.
Tried on "Intel(R) Core(TM) i5-4670 CPU @ 3.40GHz"
(your given example is working fine)

@sebeka sebeka closed this as completed Jan 5, 2018
@paboldin
Copy link
Owner

paboldin commented Jan 5, 2018

I updated the code, it now reads whole bytes and uses a different approach to see what is the value read (a histogram).

If you read the /proc/version and run new code it from the same CPU it should work (use taskset). Don't forget to disable the pread().

$ cat readversion.c 

#include <unistd.h>
#include <fcntl.h>

int main()
{
	char buf[256];
	int fd;

	fd = open("/proc/version", O_RDONLY);
	while (1)
		(void) pread(fd, buf, sizeof(buf), 0);
	close(fd);
}

@paboldin
Copy link
Owner

paboldin commented Jan 5, 2018

@sebeka Please, next time just show the code by forking original and commiting in your fork. It is easy and it improves sociability. Git is a wonderful thing for this ability.

This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants