This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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);
  }

}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]