This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
eaccess question
- From: David Lutterkort <dlutter at redhat dot com>
- To: libc-alpha at sourceware dot org
- Date: Mon, 08 Jan 2007 14:54:37 -0800
- Subject: eaccess question
Hi,
I am trying to track down a change in behavior in Fedora's ruby
interpreter from version 1.8.4 to 1.8.5. The issue is caused by
ruby-1.8.5 using eaccess for file access checks where it used to use its
own code before. The intent of the checks is to see if the effective
user can read/write/exec etc. a file.
The attached little test program simulates what happens, and what leads
to problems using eaccess. What this program would expect is that after
changing euid/egid, eaccess denies write access to a mode 0700 directory
owned by root - but surprisingly, eaccess returns 0 on a number of RH
distros I tried, e.g. glibc-2.5-3 on FC6
Is my understanding of eaccess ('do the same check as access but against
euid/egid') wrong ? What is the exact intent of eaccess ? Jim Meyering
pointed out that the eaccess implementation falls back to access if the
process is run as root when _LIBC is defined (in
libc/sysdeps/posix/euidaccess.c) which clearly does not mesh with my use
of it.
David
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define TMP_PAT "/tmp/eaccessXXXXXX"
static char* dir;
/* Print error message and exit */
void bail(const char* msg) {
if (msg != 0) {
perror(msg);
}
if (dir != 0 && rmdir(dir) == -1) {
perror("rmdir");
exit(1);
}
if (msg !=0) {
exit(1);
}
}
/* Bail out if COND is not true */
void assert(int cond, const char* msg) {
if (!cond) {
bail(msg);
}
}
int main() {
if (getuid() != 0) {
fprintf(stderr, "Please run as root\n");
exit(1);
}
dir = mkdtemp(strdup(TMP_PAT));
assert(setegid(1) != -1, "egid");
assert(seteuid(1) != -1, "euid");
printf("euid %d egid %d\n", geteuid(), getegid());
if ( euidaccess(dir, W_OK|X_OK) == 0 ) {
printf("Writable %s\n", dir);
char fname[100];
assert( snprintf(fname, 100, "%s/xxx", dir) >= 0, "format filename");
FILE* out = fopen(fname, "w");
assert( out != NULL, "fopen");
assert( fprintf(out, "yo") >= 0, "fprintf");
assert( fclose(out) == EOF, "fclose");
} else {
printf("Not writable %s\n", dir);
}
}