update to rpm-4.9.0
OBS-URL: https://build.opensuse.org/package/show/Base:System/rpm?expand=0&rev=93
This commit is contained in:
279
safeugid.diff
279
safeugid.diff
@@ -1,50 +1,33 @@
|
||||
--- lib/fsm.c.orig 2010-03-26 15:06:20.000000000 +0000
|
||||
+++ lib/fsm.c 2010-03-26 15:16:31.000000000 +0000
|
||||
@@ -736,22 +736,26 @@ static int fsmMapAttrs(FSM_t fsm)
|
||||
|
||||
/* this check is pretty moot, rpmfi accessors check array bounds etc */
|
||||
if (fi && i >= 0 && i < rpmfiFC(fi)) {
|
||||
+ rpmts ts = fsmGetTs(fsm);
|
||||
mode_t finalMode = rpmfiFModeIndex(fi, i);
|
||||
dev_t finalRdev = rpmfiFRdevIndex(fi, i);
|
||||
time_t finalMtime = rpmfiFMtimeIndex(fi, i);
|
||||
const char *user = rpmfiFUserIndex(fi, i);
|
||||
const char *group = rpmfiFGroupIndex(fi, i);
|
||||
+ int safe = rpmtsChrootDone(ts);
|
||||
+ extern int unameToUid_safe(const char *, gid_t *, int);
|
||||
+ extern int gnameToGid_safe(const char *, gid_t *, int);
|
||||
uid_t uid = 0;
|
||||
gid_t gid = 0;
|
||||
|
||||
- if (user && unameToUid(user, &uid)) {
|
||||
+ if (user && unameToUid_safe(user, &uid, safe)) {
|
||||
if (fsm->goal == FSM_PKGINSTALL)
|
||||
rpmlog(RPMLOG_WARNING,
|
||||
_("user %s does not exist - using root\n"), user);
|
||||
finalMode &= ~S_ISUID; /* turn off suid bit */
|
||||
}
|
||||
|
||||
- if (group && gnameToGid(group, &gid)) {
|
||||
+ if (group && gnameToGid_safe(group, &gid, safe)) {
|
||||
if (fsm->goal == FSM_PKGINSTALL)
|
||||
rpmlog(RPMLOG_WARNING,
|
||||
_("group %s does not exist - using root\n"), group);
|
||||
@@ -773,8 +777,7 @@ static int fsmMapAttrs(FSM_t fsm)
|
||||
if (fsm->mapFlags & CPIO_MAP_GID)
|
||||
st->st_gid = gid;
|
||||
|
||||
- { rpmts ts = fsmGetTs(fsm);
|
||||
-
|
||||
+ {
|
||||
/*
|
||||
* Set file digest (if not disabled).
|
||||
*/
|
||||
--- lib/misc.c.orig 2009-12-07 14:36:49.000000000 +0000
|
||||
+++ lib/misc.c 2010-03-26 15:26:05.000000000 +0000
|
||||
@@ -14,6 +14,42 @@ const char * const RPMVERSION = VERSION;
|
||||
|
||||
#include "debug.h"
|
||||
Work around glibc/nscd caching problems when doing 'rpm --root'.
|
||||
|
||||
--- ./lib/rpmchroot.c.orig 2011-05-12 08:26:10.000000000 +0000
|
||||
+++ ./lib/rpmchroot.c 2011-05-12 08:28:32.000000000 +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 2011-05-12 08:13:52.000000000 +0000
|
||||
+++ ./lib/rpmug.c 2011-05-12 08:33:28.000000000 +0000
|
||||
@@ -35,6 +35,47 @@ const char * rpmugStashStr(const char *s
|
||||
return ret;
|
||||
}
|
||||
|
||||
+#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
|
||||
@@ -80,50 +63,30 @@
|
||||
+ fclose(fp);
|
||||
+ return -1;
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
/* unameToUid(), uidTouname() and the group variants are really poorly
|
||||
implemented. They really ought to use hash tables. I just made the
|
||||
guess that most files would be owned by root or the same person/group
|
||||
@@ -21,11 +57,12 @@ const char * const RPMVERSION = VERSION;
|
||||
is looked up via getpw() and getgr() functions. If this performs
|
||||
too poorly I'll have to implement it properly :-( */
|
||||
|
||||
-int unameToUid(const char * thisUname, uid_t * uid)
|
||||
+int unameToUid_safe(const char * thisUname, uid_t * uid, int safe)
|
||||
{
|
||||
static char * lastUname = NULL;
|
||||
static size_t lastUnameLen = 0;
|
||||
static size_t lastUnameAlloced;
|
||||
+ static int lastUnameSafe;
|
||||
static uid_t lastUid;
|
||||
struct passwd * pwent;
|
||||
size_t thisUnameLen;
|
||||
@@ -38,6 +75,11 @@ static char * lastUname = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
+ if (safe != lastUnameSafe) {
|
||||
+ lastUnameLen = 0;
|
||||
+ lastUnameSafe = safe;
|
||||
+ }
|
||||
+
|
||||
thisUnameLen = strlen(thisUname);
|
||||
if (lastUname == NULL || thisUnameLen != lastUnameLen ||
|
||||
!rstreq(thisUname, lastUname))
|
||||
@@ -48,15 +90,21 @@ static char * lastUname = NULL;
|
||||
/*
|
||||
* 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
|
||||
@@ -68,17 +109,28 @@ int rpmugUid(const char * thisUname, uid
|
||||
lastUnameAlloced = thisUnameLen + 10;
|
||||
lastUname = xrealloc(lastUname, lastUnameAlloced); /* XXX memory leak */
|
||||
}
|
||||
strcpy(lastUname, thisUname);
|
||||
- strcpy(lastUname, thisUname);
|
||||
|
||||
- pwent = getpwnam(thisUname);
|
||||
- if (pwent == NULL) {
|
||||
- /* FIX: shrug */
|
||||
- endpwent();
|
||||
+ if (safe) {
|
||||
+ int uid = safe_lookup("/etc/passwd", thisUname);
|
||||
+#if defined(__GLIBC__)
|
||||
+ if (inchroot) {
|
||||
+ int uid = safe_lookup("/etc/passwd", thisUname);
|
||||
+ if (uid < 0)
|
||||
+ return -1;
|
||||
+ lastUid = (uid_t)uid;
|
||||
+ } else {
|
||||
+ lastUid = uid;
|
||||
+ } else
|
||||
+#endif
|
||||
+ {
|
||||
pwent = getpwnam(thisUname);
|
||||
- if (pwent == NULL) return -1;
|
||||
+ if (pwent == NULL) {
|
||||
@@ -134,103 +97,117 @@
|
||||
+ }
|
||||
+ lastUid = pwent->pw_uid;
|
||||
}
|
||||
-
|
||||
|
||||
- lastUid = pwent->pw_uid;
|
||||
+ strcpy(lastUname, thisUname);
|
||||
+ lastUnameLen = thisUnameLen;
|
||||
}
|
||||
|
||||
*uid = lastUid;
|
||||
@@ -64,11 +112,18 @@ static char * lastUname = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
-int gnameToGid(const char * thisGname, gid_t * gid)
|
||||
+int unameToUid(const char * thisUname, uid_t * uid)
|
||||
+{
|
||||
+ return unameToUid_safe(thisUname, uid, 0);
|
||||
+}
|
||||
+
|
||||
+
|
||||
+int gnameToGid_safe(const char * thisGname, gid_t * gid, int safe)
|
||||
{
|
||||
static char * lastGname = NULL;
|
||||
static size_t lastGnameLen = 0;
|
||||
static size_t lastGnameAlloced;
|
||||
+ static int lastGnameSafe;
|
||||
static gid_t lastGid;
|
||||
size_t thisGnameLen;
|
||||
struct group * grent;
|
||||
@@ -81,6 +136,11 @@ static char * lastGname = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
+ if (safe != lastGnameSafe) {
|
||||
+ lastGnameLen = 0;
|
||||
+ lastGnameSafe = safe;
|
||||
+ }
|
||||
+
|
||||
thisGnameLen = strlen(thisGname);
|
||||
if (lastGname == NULL || thisGnameLen != lastGnameLen ||
|
||||
!rstreq(thisGname, lastGname))
|
||||
@@ -91,25 +151,34 @@ static char * lastGname = NULL;
|
||||
@@ -111,18 +163,29 @@ int rpmugGid(const char * thisGname, gid
|
||||
lastGnameAlloced = thisGnameLen + 10;
|
||||
lastGname = xrealloc(lastGname, lastGnameAlloced); /* XXX memory leak */
|
||||
}
|
||||
strcpy(lastGname, thisGname);
|
||||
- strcpy(lastGname, thisGname);
|
||||
|
||||
- grent = getgrnam(thisGname);
|
||||
- if (grent == NULL) {
|
||||
- /* FIX: shrug */
|
||||
- endgrent();
|
||||
+ if (safe) {
|
||||
+ int gid = safe_lookup("/etc/group", thisGname);
|
||||
+#if defined(__GLIBC__)
|
||||
+ if (inchroot) {
|
||||
+ int gid = safe_lookup("/etc/group", thisGname);
|
||||
+ if (gid < 0)
|
||||
+ return -1;
|
||||
+ lastGid = (gid_t)gid;
|
||||
+ } else {
|
||||
+ lastGid = gid;
|
||||
+ } else
|
||||
+#endif
|
||||
+ {
|
||||
grent = getgrnam(thisGname);
|
||||
if (grent == NULL) {
|
||||
- /* XXX The filesystem package needs group/lock w/o getgrnam. */
|
||||
- if (rstreq(thisGname, "lock")) {
|
||||
- *gid = lastGid = 54;
|
||||
- return 0;
|
||||
- } else
|
||||
- if (rstreq(thisGname, "mail")) {
|
||||
- *gid = lastGid = 12;
|
||||
- return 0;
|
||||
- } else
|
||||
- return -1;
|
||||
+ /* FIX: shrug */
|
||||
+ endgrent();
|
||||
+ grent = getgrnam(thisGname);
|
||||
+ if (grent == NULL) {
|
||||
+#ifdef STRANGE_FEDORA_HACKS
|
||||
+ /* XXX The filesystem package needs group/lock w/o getgrnam. */
|
||||
+ if (rstreq(thisGname, "lock")) {
|
||||
+ *gid = lastGid = 54;
|
||||
+ return 0;
|
||||
+ } else
|
||||
+ if (rstreq(thisGname, "mail")) {
|
||||
+ *gid = lastGid = 12;
|
||||
+ return 0;
|
||||
+ } else
|
||||
+#endif
|
||||
+ return -1;
|
||||
+ }
|
||||
}
|
||||
+ lastGid = grent->gr_gid;
|
||||
}
|
||||
- lastGid = grent->gr_gid;
|
||||
+ strcpy(lastGname, thisGname);
|
||||
+ lastGnameLen = thisGnameLen;
|
||||
}
|
||||
|
||||
*gid = lastGid;
|
||||
@@ -117,6 +186,12 @@ static char * lastGname = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
+int gnameToGid(const char * thisGname, gid_t * gid)
|
||||
+{
|
||||
+ return gnameToGid_safe(thisGname, gid, 0);
|
||||
+}
|
||||
+
|
||||
+
|
||||
const char * uidToUname(uid_t uid)
|
||||
@@ -134,7 +197,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;
|
||||
@@ -151,9 +214,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);
|
||||
|
||||
@@ -165,7 +228,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;
|
||||
@@ -182,9 +245,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);
|
||||
|
||||
@@ -200,3 +263,16 @@ void rpmugFree(void)
|
||||
rpmugGname(-1);
|
||||
strStash = strCacheFree(strStash);
|
||||
}
|
||||
+
|
||||
+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 2011-05-12 08:13:52.000000000 +0000
|
||||
+++ ./lib/rpmug.h 2011-05-12 08:26:56.000000000 +0000
|
||||
@@ -15,4 +15,6 @@ const char * rpmugGname(gid_t gid);
|
||||
|
||||
void rpmugFree(void);
|
||||
|
||||
+void rpmugChroot(int in);
|
||||
+
|
||||
#endif /* _RPMUG_H */
|
||||
|
Reference in New Issue
Block a user