Blame safeugid.diff

Bernhard M. Wiedemann eb41fd
--- ../safeugid.diff	2019-10-02 13:37:13.191868203 +0200
Bernhard M. Wiedemann eb41fd
+++ P	2019-10-02 13:36:09.036002978 +0200
Bernhard M. Wiedemann eb41fd
@@ -0,0 +1,211 @@
ef651c
+--- lib/rpmchroot.c.orig	2019-06-26 14:17:31.411985696 +0000
ef651c
++++ lib/rpmchroot.c	2019-10-02 11:35:58.788024507 +0000
Bernhard M. Wiedemann eb41fd
+@@ -126,6 +126,7 @@ int rpmChrootIn(void)
Bernhard M. Wiedemann eb41fd
+ 
Bernhard M. Wiedemann eb41fd
+ 	if (chdir("/") == 0 && chroot(rootState.rootDir) == 0) {
Bernhard M. Wiedemann eb41fd
+ 	    rootState.chrootDone = 1;
Bernhard M. Wiedemann eb41fd
++	    rpmugChroot(1);
Bernhard M. Wiedemann eb41fd
+ 	} else {
Bernhard M. Wiedemann eb41fd
+ 	    rpmlog(RPMLOG_ERR, _("Unable to change root directory: %m\n"));
Bernhard M. Wiedemann eb41fd
+ 	    rc = -1;
Bernhard M. Wiedemann eb41fd
+@@ -151,6 +152,7 @@ int rpmChrootOut(void)
Bernhard M. Wiedemann eb41fd
+     } else if (rootState.chrootDone == 1) {
Bernhard M. Wiedemann eb41fd
+ 	if (chroot(".") == 0 && fchdir(rootState.cwd) == 0) {
Bernhard M. Wiedemann eb41fd
+ 	    rootState.chrootDone = 0;
Bernhard M. Wiedemann eb41fd
++	    rpmugChroot(0);
Bernhard M. Wiedemann eb41fd
+ 	} else {
Bernhard M. Wiedemann eb41fd
+ 	    rpmlog(RPMLOG_ERR, _("Unable to restore root directory: %m\n"));
Bernhard M. Wiedemann eb41fd
+ 	    rc = -1;
ef651c
+--- lib/rpmug.c.orig	2019-06-26 14:17:31.418985685 +0000
ef651c
++++ lib/rpmug.c	2019-10-02 11:35:58.788024507 +0000
Bernhard M. Wiedemann eb41fd
+@@ -11,6 +11,47 @@
Bernhard M. Wiedemann eb41fd
+ #include "lib/rpmug.h"
Bernhard M. Wiedemann eb41fd
+ #include "debug.h"
Bernhard M. Wiedemann eb41fd
+ 
Bernhard M. Wiedemann eb41fd
++#if defined(__GLIBC__)
Bernhard M. Wiedemann eb41fd
++
Bernhard M. Wiedemann eb41fd
++static int inchroot;
Bernhard M. Wiedemann eb41fd
++
Bernhard M. Wiedemann eb41fd
++/*
Bernhard M. Wiedemann eb41fd
++ * Unfortunatelly glibc caches nss/nscd data and there is no
Bernhard M. Wiedemann eb41fd
++ * good way to flush those caches when we did a chroot(). Thus
Bernhard M. Wiedemann eb41fd
++ * we need to parse /etc/passwd and /etc/group ourselfs.
Bernhard M. Wiedemann eb41fd
++ */
Bernhard M. Wiedemann eb41fd
++static int safe_lookup(const char * file, const char * name)
Bernhard M. Wiedemann eb41fd
++{
Bernhard M. Wiedemann eb41fd
++    FILE *fp;
Bernhard M. Wiedemann eb41fd
++    int l;
Bernhard M. Wiedemann eb41fd
++    char buf[4096], *p;
Bernhard M. Wiedemann eb41fd
++
Bernhard M. Wiedemann eb41fd
++    if (!name || !*name)
Bernhard M. Wiedemann eb41fd
++	return -1;
Bernhard M. Wiedemann eb41fd
++    l = strlen(name);
Bernhard M. Wiedemann eb41fd
++    if ((fp = fopen(file, "r")) == 0)
Bernhard M. Wiedemann eb41fd
++	return -1;
Bernhard M. Wiedemann eb41fd
++    while ((p = fgets(buf, sizeof(buf), fp)) != 0) {
Bernhard M. Wiedemann eb41fd
++	if (*p == '#')
Bernhard M. Wiedemann eb41fd
++	    continue;
Bernhard M. Wiedemann eb41fd
++	while (*p && (*p == ' ' || *p == '\t'))
Bernhard M. Wiedemann eb41fd
++	    p++;
Bernhard M. Wiedemann eb41fd
++	if (strncmp(p, name, l) != 0 || p[l] != ':')
Bernhard M. Wiedemann eb41fd
++	    continue;
Bernhard M. Wiedemann eb41fd
++	p = strchr(p + l + 1, ':');
Bernhard M. Wiedemann eb41fd
++	if (!p)
Bernhard M. Wiedemann eb41fd
++	    continue;
Bernhard M. Wiedemann eb41fd
++	fclose(fp);
Bernhard M. Wiedemann eb41fd
++	p++;
Bernhard M. Wiedemann eb41fd
++	while (*p && (*p == ' ' || *p == '\t'))
Bernhard M. Wiedemann eb41fd
++	    p++;
Bernhard M. Wiedemann eb41fd
++	return atoi(p);
Bernhard M. Wiedemann eb41fd
++    }
Bernhard M. Wiedemann eb41fd
++    fclose(fp);
Bernhard M. Wiedemann eb41fd
++    return -1;
Bernhard M. Wiedemann eb41fd
++}
Bernhard M. Wiedemann eb41fd
++#endif
Bernhard M. Wiedemann eb41fd
++
Bernhard M. Wiedemann eb41fd
+ /* 
Bernhard M. Wiedemann eb41fd
+  * These really ought to use hash tables. I just made the
Bernhard M. Wiedemann eb41fd
+  * guess that most files would be owned by root or the same person/group
Bernhard M. Wiedemann eb41fd
+@@ -44,17 +85,28 @@ int rpmugUid(const char * thisUname, uid
Bernhard M. Wiedemann eb41fd
+ 	    lastUnameAlloced = thisUnameLen + 10;
Bernhard M. Wiedemann eb41fd
+ 	    lastUname = xrealloc(lastUname, lastUnameAlloced);	/* XXX memory leak */
Bernhard M. Wiedemann eb41fd
+ 	}
Bernhard M. Wiedemann eb41fd
+-	strcpy(lastUname, thisUname);
Bernhard M. Wiedemann eb41fd
+ 
Bernhard M. Wiedemann eb41fd
+-	pwent = getpwnam(thisUname);
Bernhard M. Wiedemann eb41fd
+-	if (pwent == NULL) {
Bernhard M. Wiedemann eb41fd
+-	    /* FIX: shrug */
Bernhard M. Wiedemann eb41fd
+-	    endpwent();
Bernhard M. Wiedemann eb41fd
++#if defined(__GLIBC__)
Bernhard M. Wiedemann eb41fd
++	if (inchroot) {
Bernhard M. Wiedemann eb41fd
++	    int uid =  safe_lookup("/etc/passwd", thisUname);
Bernhard M. Wiedemann eb41fd
++	    if (uid < 0)
Bernhard M. Wiedemann eb41fd
++		return -1;
Bernhard M. Wiedemann eb41fd
++	    lastUid = uid;
Bernhard M. Wiedemann eb41fd
++	} else
Bernhard M. Wiedemann eb41fd
++#endif
Bernhard M. Wiedemann eb41fd
++	{
Bernhard M. Wiedemann eb41fd
+ 	    pwent = getpwnam(thisUname);
Bernhard M. Wiedemann eb41fd
+-	    if (pwent == NULL) return -1;
Bernhard M. Wiedemann eb41fd
++	    if (pwent == NULL) {
Bernhard M. Wiedemann eb41fd
++		/* FIX: shrug */
Bernhard M. Wiedemann eb41fd
++		endpwent();
Bernhard M. Wiedemann eb41fd
++		pwent = getpwnam(thisUname);
Bernhard M. Wiedemann eb41fd
++		if (pwent == NULL) return -1;
Bernhard M. Wiedemann eb41fd
++	    }
Bernhard M. Wiedemann eb41fd
++	    lastUid = pwent->pw_uid;
Bernhard M. Wiedemann eb41fd
+ 	}
Bernhard M. Wiedemann eb41fd
+ 
Bernhard M. Wiedemann eb41fd
+-	lastUid = pwent->pw_uid;
Bernhard M. Wiedemann eb41fd
++	strcpy(lastUname, thisUname);
Bernhard M. Wiedemann eb41fd
++	lastUnameLen = thisUnameLen;
Bernhard M. Wiedemann eb41fd
+     }
Bernhard M. Wiedemann eb41fd
+ 
Bernhard M. Wiedemann eb41fd
+     *uid = lastUid;
Bernhard M. Wiedemann eb41fd
+@@ -87,18 +139,29 @@ int rpmugGid(const char * thisGname, gid
Bernhard M. Wiedemann eb41fd
+ 	    lastGnameAlloced = thisGnameLen + 10;
Bernhard M. Wiedemann eb41fd
+ 	    lastGname = xrealloc(lastGname, lastGnameAlloced);	/* XXX memory leak */
Bernhard M. Wiedemann eb41fd
+ 	}
Bernhard M. Wiedemann eb41fd
+-	strcpy(lastGname, thisGname);
Bernhard M. Wiedemann eb41fd
+ 
Bernhard M. Wiedemann eb41fd
+-	grent = getgrnam(thisGname);
Bernhard M. Wiedemann eb41fd
+-	if (grent == NULL) {
Bernhard M. Wiedemann eb41fd
+-	    /* FIX: shrug */
Bernhard M. Wiedemann eb41fd
+-	    endgrent();
Bernhard M. Wiedemann eb41fd
++#if defined(__GLIBC__)
Bernhard M. Wiedemann eb41fd
++	if (inchroot) {
Bernhard M. Wiedemann eb41fd
++	    int gid =  safe_lookup("/etc/group", thisGname);
Bernhard M. Wiedemann eb41fd
++	    if (gid < 0)
Bernhard M. Wiedemann eb41fd
++		return -1;
Bernhard M. Wiedemann eb41fd
++	    lastGid = gid;
Bernhard M. Wiedemann eb41fd
++	} else
Bernhard M. Wiedemann eb41fd
++#endif
Bernhard M. Wiedemann eb41fd
++	{
Bernhard M. Wiedemann eb41fd
+ 	    grent = getgrnam(thisGname);
Bernhard M. Wiedemann eb41fd
+ 	    if (grent == NULL) {
Bernhard M. Wiedemann eb41fd
+-		return -1;
Bernhard M. Wiedemann eb41fd
++		/* FIX: shrug */
Bernhard M. Wiedemann eb41fd
++		endgrent();
Bernhard M. Wiedemann eb41fd
++		grent = getgrnam(thisGname);
Bernhard M. Wiedemann eb41fd
++		if (grent == NULL) {
Bernhard M. Wiedemann eb41fd
++		    return -1;
Bernhard M. Wiedemann eb41fd
++		}
Bernhard M. Wiedemann eb41fd
+ 	    }
Bernhard M. Wiedemann eb41fd
++	    lastGid = grent->gr_gid;
Bernhard M. Wiedemann eb41fd
+ 	}
Bernhard M. Wiedemann eb41fd
+-	lastGid = grent->gr_gid;
Bernhard M. Wiedemann eb41fd
++	strcpy(lastGname, thisGname);
Bernhard M. Wiedemann eb41fd
++	lastGnameLen = thisGnameLen;
Bernhard M. Wiedemann eb41fd
+     }
Bernhard M. Wiedemann eb41fd
+ 
Bernhard M. Wiedemann eb41fd
+     *gid = lastGid;
Bernhard M. Wiedemann eb41fd
+@@ -110,7 +173,7 @@ const char * rpmugUname(uid_t uid)
Bernhard M. Wiedemann eb41fd
+ {
Bernhard M. Wiedemann eb41fd
+     static uid_t lastUid = (uid_t) -1;
Bernhard M. Wiedemann eb41fd
+     static char * lastUname = NULL;
Bernhard M. Wiedemann eb41fd
+-    static size_t lastUnameLen = 0;
Bernhard M. Wiedemann eb41fd
++    static size_t lastUnameAlloced = 0;
Bernhard M. Wiedemann eb41fd
+ 
Bernhard M. Wiedemann eb41fd
+     if (uid == (uid_t) -1) {
Bernhard M. Wiedemann eb41fd
+ 	lastUid = (uid_t) -1;
Bernhard M. Wiedemann eb41fd
+@@ -127,9 +190,9 @@ const char * rpmugUname(uid_t uid)
Bernhard M. Wiedemann eb41fd
+ 
Bernhard M. Wiedemann eb41fd
+ 	lastUid = uid;
Bernhard M. Wiedemann eb41fd
+ 	len = strlen(pwent->pw_name);
Bernhard M. Wiedemann eb41fd
+-	if (lastUnameLen < len + 1) {
Bernhard M. Wiedemann eb41fd
+-	    lastUnameLen = len + 20;
Bernhard M. Wiedemann eb41fd
+-	    lastUname = xrealloc(lastUname, lastUnameLen);
Bernhard M. Wiedemann eb41fd
++	if (lastUnameAlloced < len + 1) {
Bernhard M. Wiedemann eb41fd
++	    lastUnameAlloced = len + 20;
Bernhard M. Wiedemann eb41fd
++	    lastUname = xrealloc(lastUname, lastUnameAlloced);
Bernhard M. Wiedemann eb41fd
+ 	}
Bernhard M. Wiedemann eb41fd
+ 	strcpy(lastUname, pwent->pw_name);
Bernhard M. Wiedemann eb41fd
+ 
Bernhard M. Wiedemann eb41fd
+@@ -141,7 +204,7 @@ const char * rpmugGname(gid_t gid)
Bernhard M. Wiedemann eb41fd
+ {
Bernhard M. Wiedemann eb41fd
+     static gid_t lastGid = (gid_t) -1;
Bernhard M. Wiedemann eb41fd
+     static char * lastGname = NULL;
Bernhard M. Wiedemann eb41fd
+-    static size_t lastGnameLen = 0;
Bernhard M. Wiedemann eb41fd
++    static size_t lastGnameAlloced = 0;
Bernhard M. Wiedemann eb41fd
+ 
Bernhard M. Wiedemann eb41fd
+     if (gid == (gid_t) -1) {
Bernhard M. Wiedemann eb41fd
+ 	lastGid = (gid_t) -1;
Bernhard M. Wiedemann eb41fd
+@@ -158,9 +221,9 @@ const char * rpmugGname(gid_t gid)
Bernhard M. Wiedemann eb41fd
+ 
Bernhard M. Wiedemann eb41fd
+ 	lastGid = gid;
Bernhard M. Wiedemann eb41fd
+ 	len = strlen(grent->gr_name);
Bernhard M. Wiedemann eb41fd
+-	if (lastGnameLen < len + 1) {
Bernhard M. Wiedemann eb41fd
+-	    lastGnameLen = len + 20;
Bernhard M. Wiedemann eb41fd
+-	    lastGname = xrealloc(lastGname, lastGnameLen);
Bernhard M. Wiedemann eb41fd
++	if (lastGnameAlloced < len + 1) {
Bernhard M. Wiedemann eb41fd
++	    lastGnameAlloced = len + 20;
Bernhard M. Wiedemann eb41fd
++	    lastGname = xrealloc(lastGname, lastGnameAlloced);
Bernhard M. Wiedemann eb41fd
+ 	}
Bernhard M. Wiedemann eb41fd
+ 	strcpy(lastGname, grent->gr_name);
Bernhard M. Wiedemann eb41fd
+ 
Bernhard M. Wiedemann eb41fd
+@@ -192,3 +255,16 @@ void rpmugFree(void)
Bernhard M. Wiedemann eb41fd
+     rpmugUname(-1);
Bernhard M. Wiedemann eb41fd
+     rpmugGname(-1);
Bernhard M. Wiedemann eb41fd
+ }
Bernhard M. Wiedemann eb41fd
++
Bernhard M. Wiedemann eb41fd
++void rpmugChroot(int in)
Bernhard M. Wiedemann eb41fd
++{
Bernhard M. Wiedemann eb41fd
++    /* tell libc to drop caches / file descriptors */
Bernhard M. Wiedemann eb41fd
++    endpwent();
Bernhard M. Wiedemann eb41fd
++    endgrent();
Bernhard M. Wiedemann eb41fd
++    /* drop our own caches */
Bernhard M. Wiedemann eb41fd
++    rpmugUid(NULL, NULL);
Bernhard M. Wiedemann eb41fd
++    rpmugGid(NULL, NULL);
Bernhard M. Wiedemann eb41fd
++#if defined(__GLIBC__)
Bernhard M. Wiedemann eb41fd
++    inchroot = in;
Bernhard M. Wiedemann eb41fd
++#endif
Bernhard M. Wiedemann eb41fd
++}
ef651c
+--- lib/rpmug.h.orig	2019-06-26 14:17:31.418985685 +0000
ef651c
++++ lib/rpmug.h	2019-10-02 11:35:58.788024507 +0000
Bernhard M. Wiedemann eb41fd
+@@ -15,4 +15,6 @@ int rpmugInit(void);
Bernhard M. Wiedemann eb41fd
+ 
Bernhard M. Wiedemann eb41fd
+ void rpmugFree(void);
Bernhard M. Wiedemann eb41fd
+ 
Bernhard M. Wiedemann eb41fd
++void rpmugChroot(int in);
Bernhard M. Wiedemann eb41fd
++
Bernhard M. Wiedemann eb41fd
+ #endif /* _RPMUG_H */