Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
setuid examples
  • Loading branch information
Jerry Shi committed Feb 26, 2024
1 parent 2f3d913 commit 14f774e
Showing 1 changed file with 153 additions and 0 deletions.
153 changes: 153 additions & 0 deletions examples/ex-setuid.c
@@ -0,0 +1,153 @@
#define _GNU_SOURCE

/*
To compile and make the exeutable a SUID program:
gcc -o suid ex-setuid.c && sudo chown root suid && sudo chmod +s suid
There are four demo modes: u, e, d, and o. For example,
./suid u
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <sys/types.h>
#include <unistd.h>
#include <errno.h>
#include <assert.h>

/* setuid examples */

uid_t my_uid, my_euid;

void print_uids();

void myerror(char *s)
{
fprintf(stderr, "myerror:\n");

uid_t ruid, euid, suid;
if (getresuid(&ruid, &euid, &suid)) {
fprintf(stderr, "myerror: getresuid() returned error.\n");
}
else {
fprintf(stderr, "myerror: ruid=%d euid=%d suid=%d\n", ruid, euid, suid);
}

if (errno) {
perror(s);
}
else {
fprintf(stderr, "Error: %s (errno==0)\n", s);
}
exit(EXIT_FAILURE);
}

void print_uids()
{
// printf("ruid=%d euid=%d\n", getuid(), geteuid());
// getresuid() is not in POSIX
uid_t ruid, euid, suid;
if (getresuid(&ruid, &euid, &suid)) {
myerror("getresuid()");
}
printf("ruid=%d euid=%d saved_uid=%d\n", ruid, euid, suid);
}

void my_setuid(int newid)
{
printf("calling setuid(%d) ...\n", newid);
int rv = setuid(newid);

if (rv != 0) {
myerror("setuid failed");
}
printf("New UIDs:\n");
print_uids();
}

void my_seteuid(int newid)
{
printf("calling seteuid(%d) ...\n", newid);
int rv = seteuid(newid);

if (rv != 0) {
myerror("seteuid failed");
}
printf("New UIDs:\n");
print_uids();
}

void demo_uid()
{
printf("setuid ...\n");
print_uids();
my_setuid(my_uid);
my_setuid(0);
}

void demo_euid()
{
printf("seteuid...\n");
print_uids();
my_seteuid(my_uid);
my_seteuid(0);
my_seteuid(2000);
my_seteuid(my_uid);
my_seteuid(2000);
}

void demo_dash()
{
printf("Call setuid(0) to change all UIDs to 0 ...\n");
printf("This defeats dash's countermeasure.\n");

print_uids();
my_setuid(my_euid);
}

void demo_other()
{
print_uids();
my_seteuid(2000); // success
my_seteuid(my_uid); // success
my_seteuid(2000); // fail
}

int main(int argc,char* argv[])
{
my_uid = getuid();
my_euid = geteuid();

int mode = 0;

if (argc != 2 ) {
printf("Usage: suid mode\nmode is u, e, d, or 4\n");
printf("u: setuid, e: seteuid, d: dash, o: other\n");
return 1;
}

mode = argv[1][0];

switch (mode) {
case 'u':
demo_uid();
break;
case 'e':
demo_euid();
break;
case 'd':
demo_dash();
break;
case 'o':
demo_other();
break;
default:
printf("Unknown mode %c.\n", mode);
}
return 0;
}

0 comments on commit 14f774e

Please sign in to comment.