Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE
rpm.8248
safeugid.diff
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File safeugid.diff of Package rpm.8248
--- ./lib/rpmchroot.c.orig 2012-11-07 12:55:24.000000000 +0000 +++ ./lib/rpmchroot.c 2014-02-20 12:50:05.360815211 +0000 @@ -66,6 +66,7 @@ int rpmChrootIn(void) } else if (rootState.chrootDone == 0) { if (chdir("/") == 0 && chroot(rootState.rootDir) == 0) { rootState.chrootDone = 1; + rpmugChroot(1); } else { rpmlog(RPMLOG_ERR, _("Unable to change root directory: %m\n")); rc = -1; @@ -91,6 +92,7 @@ int rpmChrootOut(void) } else if (rootState.chrootDone == 1) { if (chroot(".") == 0 && fchdir(rootState.cwd) == 0) { rootState.chrootDone = 0; + rpmugChroot(0); } else { rpmlog(RPMLOG_ERR, _("Unable to restore root directory: %m\n")); rc = -1; --- ./lib/rpmug.c.orig 2014-02-05 13:04:37.000000000 +0000 +++ ./lib/rpmug.c 2014-02-20 12:50:05.361815211 +0000 @@ -10,6 +10,47 @@ #include "lib/rpmug.h" #include "debug.h" +#if defined(__GLIBC__) + +static int inchroot; + +/* + * Unfortunatelly glibc caches nss/nscd data and there is no + * good way to flush those caches when we did a chroot(). Thus + * we need to parse /etc/passwd and /etc/group ourselfs. + */ +static int safe_lookup(const char * file, const char * name) +{ + FILE *fp; + int l; + char buf[4096], *p; + + if (!name || !*name) + return -1; + l = strlen(name); + if ((fp = fopen(file, "r")) == 0) + return -1; + while ((p = fgets(buf, sizeof(buf), fp)) != 0) { + if (*p == '#') + continue; + while (*p && (*p == ' ' || *p == '\t')) + p++; + if (strncmp(p, name, l) != 0 || p[l] != ':') + continue; + p = strchr(p + l + 1, ':'); + if (!p) + continue; + fclose(fp); + p++; + while (*p && (*p == ' ' || *p == '\t')) + p++; + return atoi(p); + } + fclose(fp); + return -1; +} +#endif + /* * These really ought to use hash tables. I just made the * guess that most files would be owned by root or the same person/group @@ -43,17 +84,28 @@ int rpmugUid(const char * thisUname, uid lastUnameAlloced = thisUnameLen + 10; lastUname = xrealloc(lastUname, lastUnameAlloced); /* XXX memory leak */ } - strcpy(lastUname, thisUname); - pwent = getpwnam(thisUname); - if (pwent == NULL) { - /* FIX: shrug */ - endpwent(); +#if defined(__GLIBC__) + if (inchroot) { + int uid = safe_lookup("/etc/passwd", thisUname); + if (uid < 0) + return -1; + lastUid = uid; + } else +#endif + { pwent = getpwnam(thisUname); - if (pwent == NULL) return -1; + if (pwent == NULL) { + /* FIX: shrug */ + endpwent(); + pwent = getpwnam(thisUname); + if (pwent == NULL) return -1; + } + lastUid = pwent->pw_uid; } - lastUid = pwent->pw_uid; + strcpy(lastUname, thisUname); + lastUnameLen = thisUnameLen; } *uid = lastUid; @@ -86,18 +138,29 @@ int rpmugGid(const char * thisGname, gid lastGnameAlloced = thisGnameLen + 10; lastGname = xrealloc(lastGname, lastGnameAlloced); /* XXX memory leak */ } - strcpy(lastGname, thisGname); - grent = getgrnam(thisGname); - if (grent == NULL) { - /* FIX: shrug */ - endgrent(); +#if defined(__GLIBC__) + if (inchroot) { + int gid = safe_lookup("/etc/group", thisGname); + if (gid < 0) + return -1; + lastGid = gid; + } else +#endif + { grent = getgrnam(thisGname); if (grent == NULL) { - return -1; + /* FIX: shrug */ + endgrent(); + grent = getgrnam(thisGname); + if (grent == NULL) { + return -1; + } } + lastGid = grent->gr_gid; } - lastGid = grent->gr_gid; + strcpy(lastGname, thisGname); + lastGnameLen = thisGnameLen; } *gid = lastGid; @@ -109,7 +172,7 @@ const char * rpmugUname(uid_t uid) { static uid_t lastUid = (uid_t) -1; static char * lastUname = NULL; - static size_t lastUnameLen = 0; + static size_t lastUnameAlloced = 0; if (uid == (uid_t) -1) { lastUid = (uid_t) -1; @@ -126,9 +189,9 @@ const char * rpmugUname(uid_t uid) lastUid = uid; len = strlen(pwent->pw_name); - if (lastUnameLen < len + 1) { - lastUnameLen = len + 20; - lastUname = xrealloc(lastUname, lastUnameLen); + if (lastUnameAlloced < len + 1) { + lastUnameAlloced = len + 20; + lastUname = xrealloc(lastUname, lastUnameAlloced); } strcpy(lastUname, pwent->pw_name); @@ -140,7 +203,7 @@ const char * rpmugGname(gid_t gid) { static gid_t lastGid = (gid_t) -1; static char * lastGname = NULL; - static size_t lastGnameLen = 0; + static size_t lastGnameAlloced = 0; if (gid == (gid_t) -1) { lastGid = (gid_t) -1; @@ -157,9 +220,9 @@ const char * rpmugGname(gid_t gid) lastGid = gid; len = strlen(grent->gr_name); - if (lastGnameLen < len + 1) { - lastGnameLen = len + 20; - lastGname = xrealloc(lastGname, lastGnameLen); + if (lastGnameAlloced < len + 1) { + lastGnameAlloced = len + 20; + lastGname = xrealloc(lastGname, lastGnameAlloced); } strcpy(lastGname, grent->gr_name); @@ -189,3 +252,16 @@ void rpmugFree(void) rpmugUname(-1); rpmugGname(-1); } + +void rpmugChroot(int in) +{ + /* tell libc to drop caches / file descriptors */ + endpwent(); + endgrent(); + /* drop our own caches */ + rpmugUid(NULL, NULL); + rpmugGid(NULL, NULL); +#if defined(__GLIBC__) + inchroot = in; +#endif +} --- ./lib/rpmug.h.orig 2014-02-05 13:04:02.000000000 +0000 +++ ./lib/rpmug.h 2014-02-20 12:50:05.362815211 +0000 @@ -15,4 +15,6 @@ int rpmugInit(void); void rpmugFree(void); +void rpmugChroot(int in); + #endif /* _RPMUG_H */
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor