What is the purpose of the call to access() in localtime.c?

In localtime.c, there is the following stanza of code that opens a time zone file to file descriptor fid: { register int doaccess; /* ** Section 4.9.1 of the C standard says that ** "FILENAME_MAX expands to an integral constant expression ** that is the size needed for an array of char large enough ** to hold the longest file name string that the implementation ** guarantees can be opened." */ char fullname[FILENAME_MAX + 1]; if (name[0] == ':') ++name; doaccess = name[0] == '/'; if (!doaccess) { if ((p = TZDIR) == NULL) return -1; if ((strlen(p) + strlen(name) + 1) >= sizeof fullname) return -1; (void) strcpy(fullname, p); (void) strcat(fullname, "/"); (void) strcat(fullname, name); /* ** Set doaccess if '.' (as in "../") shows up in name. */ if (strchr(name, '.') != NULL) doaccess = TRUE; name = fullname; } if (doaccess && access(name, R_OK) != 0) return -1; if ((fid = open(name, OPEN_MODE)) == -1) return -1; } I'm puzzled about the benefit of calling access(). Won't the open() call work, or not, pretty much the same? The only reason I've thought of for why access() would fail where open() might succeed is in a programming running with setuid (or setgid) privileges, where access() would check the permissions using the real UID (and GID) but open would be controlled by the effective UID (and GID). However, it seems incorrect to prevent a setuid or setgid program from working like that -- maybe the reason the program is setuid or setgid is to permit it to access the time zone files. In terms of performance, a call to access() is only slightly less expensive than a call to open(). My concern is more about correctness than performance, though. Is there a system where using access makes a difference? -- Jonathan Leffler <jonathan.leffler@gmail.com> #include <disclaimer.h> Guardian of DBD::Informix - v2007.0914 - http://dbi.perl.org "Blessed are we who can laugh at ourselves, for we shall never cease to be amused."

Date: Sun, 2 Dec 2007 20:40:15 -0800 From: "Jonathan Leffler" <jonathan.leffler@gmail.com> Message-ID: <844b8e1c0712022040v687119f2i4a2dc32f8fcb19d5@mail.gmail.com> | The only reason I've thought of for why access() would fail where open() | might succeed is in a programming running with setuid (or setgid) | privileges, where access() would check the permissions using the real UID | (and GID) but open would be controlled by the effective UID (and GID). | However, it seems incorrect to prevent a setuid or setgid program from | working like that -- maybe the reason the program is setuid or setgid is to | permit it to access the time zone files. No, that's exactly why it is like that - remember the time zone files can be located from a user controlled environment variable, which can end up aimed at any file at all - including files that the user should not have permission to read. Many suid programs use localtime() functions, any of them could be made to read any file if that verification of permission were not present. As for the last part - anyone stupid enough to install the timezone data in such a way that it needs enhanced privileges to read deserves to have the programs all fail - there's no rationale whatever for protecting public information from access by everyone. kre
participants (2)
-
Jonathan Leffler
-
Robert Elz