|
From: Jeremy F. <je...@go...> - 2004-09-08 20:05:36
|
CVS commit by fitzhardinge:
Pull permissions checking out into a separate function to clean
things up a bit.
M +57 -35 ume.c 1.26 [POSSIBLY UNSAFE: printf]
--- valgrind/coregrind/ume.c #1.25:1.26
@@ -612,43 +612,28 @@ static int load_script(char *hdr, int le
}
-static int do_exec_inner(const char *exe, struct exeinfo *info)
+/*
+ Emulate the normal Unix permissions checking algorithm.
+
+ If owner matches, then use the owner permissions, else
+ if group matches, then use the group permissions, else
+ use other permissions.
+
+ Note that we can't deal with SUID/SGID, so we refuse to run them
+ (otherwise the executable may misbehave if it doesn't have the
+ permissions it thinks it does).
+*/
+static int check_perms(int fd)
{
- int fd;
- char buf[VKI_BYTES_PER_PAGE];
- int bufsz;
- int i;
- int ret;
struct stat st;
- static const struct {
- int (*match)(const char *hdr, int len);
- int (*load) ( char *hdr, int len, int fd2, const char *name,
- struct exeinfo *);
- } formats[] = {
- { match_ELF, load_ELF },
- { match_script, load_script },
- };
-
- fd = open(exe, O_RDONLY);
- if (fd == -1) {
- if (0)
- fprintf(stderr, "Can't open executable %s: %s\n",
- exe, strerror(errno));
- return errno;
- }
if (fstat(fd, &st) == -1)
return errno;
- else {
- uid_t uid = geteuid();
- gid_t gid = getegid();
- gid_t groups[32];
- int ngrp = getgroups(32, groups);
if (st.st_mode & (S_ISUID | S_ISGID)) {
- fprintf(stderr, "Can't execute suid/sgid executable %s\n", exe);
+ //fprintf(stderr, "Can't execute suid/sgid executable %s\n", exe);
return EACCES;
}
- if (uid == st.st_uid) {
+ if (geteuid() == st.st_uid) {
if (!(st.st_mode & S_IXUSR))
return EACCES;
@@ -656,7 +641,11 @@ static int do_exec_inner(const char *exe
int grpmatch = 0;
- if (gid == st.st_gid)
+ if (getegid() == st.st_gid)
grpmatch = 1;
- else
+ else {
+ gid_t groups[32];
+ int ngrp = getgroups(32, groups);
+ int i;
+
for(i = 0; i < ngrp; i++)
if (groups[i] == st.st_gid) {
@@ -664,4 +653,5 @@ static int do_exec_inner(const char *exe
break;
}
+ }
if (grpmatch) {
@@ -671,4 +661,36 @@ static int do_exec_inner(const char *exe
return EACCES;
}
+
+ return 0;
+}
+
+static int do_exec_inner(const char *exe, struct exeinfo *info)
+{
+ int fd;
+ char buf[VKI_BYTES_PER_PAGE];
+ int bufsz;
+ int i;
+ int ret;
+ static const struct {
+ int (*match)(const char *hdr, int len);
+ int (*load) ( char *hdr, int len, int fd2, const char *name,
+ struct exeinfo *);
+ } formats[] = {
+ { match_ELF, load_ELF },
+ { match_script, load_script },
+ };
+
+ fd = open(exe, O_RDONLY);
+ if (fd == -1) {
+ if (0)
+ fprintf(stderr, "Can't open executable %s: %s\n",
+ exe, strerror(errno));
+ return errno;
+ }
+
+ int err = check_perms(fd);
+ if (err != 0) {
+ close(fd);
+ return err;
}
|