[BusyBox] my_getpw(u/g)id.....and call for helping to test new id

Felipe Kellermann stdfk at terra.com.br
Sun Aug 29 12:15:20 UTC 2004


On Sun, 29 Aug 2004 1:45pm  -0000, Tito wrote:

> Take a look at it , it is attached as drop in replacement.
> Comments, improvements , optimizations , testing (specially  about the 
> SELINUX stuff)  and flames are welcome.

I wrote a jumbo patch do make ``my_getpw{u,g}id'' and busybox manipulate 
usernames and groupnames of any length.  Yes, now there is a memleak.  We 
should use an additional buffer for the cases we are now using xasprintf.

The ``xstrdup'' would then only be used when we _need_ more instances of 
the username/groupname (we are actually only using it in top right now).

Tested `ps', `top', `id' and `ls'.  Didn't test `tar' (as I have other 
ideas here).  Sorry for sending such a big diff.

-- 
Felipe Kellermann
-------------- next part --------------
? fk-jumbopatch1-busybox.patch
? coreutils/cscope.out
? libbb/stBo9bWZ
Index: archival/tar.c
===================================================================
RCS file: /var/cvs/busybox/archival/tar.c,v
retrieving revision 1.195
diff -u -3 -p -u -r1.195 tar.c
--- archival/tar.c	26 Aug 2004 22:18:56 -0000	1.195
+++ archival/tar.c	29 Aug 2004 11:44:07 -0000
@@ -46,8 +46,11 @@
 #include <fnmatch.h>
 #include <string.h>
 #include <errno.h>
+#include <pwd.h>
+#include <grp.h>
 #include <signal.h>
 #include <sys/wait.h>
+#include <sys/types.h>
 #include <sys/socket.h>
 #include <sys/sysmacros.h>     /* major() and minor() */
 #include "unarchive.h"
@@ -220,6 +223,8 @@ static inline int writeTarHeader(struct 
 	struct TarHeader header;
 	const unsigned char *cp = (const unsigned char *) &header;
 	ssize_t size = sizeof(struct TarHeader);
+	struct passwd *pw;
+	struct group *gr;
 
 	memset(&header, 0, size);
 
@@ -234,10 +239,18 @@ static inline int writeTarHeader(struct 
 			TAR_MAGIC_LEN + TAR_VERSION_LEN);
 
 	/* Enter the user and group names (default to root if it fails) */
-	if (my_getpwuid(header.uname, statbuf->st_uid, sizeof(header.uname)) == NULL)
+	/* XXX:  This will be changed!  -- felipek */
+	if ((pw = getpwuid(statbuf->st_uid)) == NULL) {
 		strcpy(header.uname, "root");
-	if (my_getgrgid(header.gname, statbuf->st_gid, sizeof(header.gname)) == NULL)
+	} else {
+		safe_strncpy(header.uname, pw->pw_name, sizeof(header.uname));
+	}
+
+	if ((gr = getgrgid(statbuf->st_gid)) == NULL) {
 		strcpy(header.gname, "root");
+	} else {
+		safe_strncpy(header.uname, gr->gr_name, sizeof(header.gname));
+	}
 
 	if (tbInfo->hlInfo) {
 		/* This is a hard link */
Index: coreutils/id.c
===================================================================
RCS file: /var/cvs/busybox/coreutils/id.c,v
retrieving revision 1.25
diff -u -3 -p -u -r1.25 id.c
--- coreutils/id.c	26 Aug 2004 22:18:57 -0000	1.25
+++ coreutils/id.c	29 Aug 2004 11:44:08 -0000
@@ -40,9 +40,10 @@
 
 extern int id_main(int argc, char **argv)
 {
-	char user[32], group[32];
+	char *user = NULL;
+	char *group = NULL;
 	long pwnam, grnam;
-	int uid, gid;
+	long uid, gid;
 	int flags;
 #ifdef CONFIG_SELINUX
 	int is_flask_enabled_flag = is_flask_enabled();
@@ -64,12 +65,12 @@ extern int id_main(int argc, char **argv
 			uid = geteuid();
 			gid = getegid();
 		}
-		my_getpwuid(user, uid, sizeof(user));
+		user = my_getpwuid(uid);
 	} else {
-		safe_strncpy(user, argv[optind], sizeof(user));
+		user = argv[optind];
 	    gid = my_getpwnamegid(user);
 	}
-	my_getgrgid(group, gid, sizeof(group));
+	group = my_getgrgid(gid);
 
 	pwnam=my_getpwnam(user);
 	grnam=my_getgrnam(group);
Index: coreutils/ls.c
===================================================================
RCS file: /var/cvs/busybox/coreutils/ls.c,v
retrieving revision 1.111
diff -u -3 -p -u -r1.111 ls.c
--- coreutils/ls.c	26 Aug 2004 22:18:57 -0000	1.111
+++ coreutils/ls.c	29 Aug 2004 11:44:14 -0000
@@ -637,7 +637,7 @@ static int list_single(struct dnode *dn)
 	int i, column = 0;
 
 #ifdef CONFIG_FEATURE_LS_USERNAME
-	char scratch[16];
+	char *scratch;
 #endif
 #ifdef CONFIG_FEATURE_LS_TIMESTAMPS
 	char *filetime;
@@ -683,9 +683,9 @@ static int list_single(struct dnode *dn)
 			break;
 		case LIST_ID_NAME:
 #ifdef CONFIG_FEATURE_LS_USERNAME
-			my_getpwuid(scratch, dn->dstat.st_uid, sizeof(scratch));
+			scratch = my_getpwuid(dn->dstat.st_uid);
 			printf("%-8.8s ", scratch);
-			my_getgrgid(scratch, dn->dstat.st_gid, sizeof(scratch));
+			scratch = my_getgrgid(dn->dstat.st_gid);
 			printf("%-8.8s", scratch);
 			column += 17;
 			break;
Index: include/libbb.h
===================================================================
RCS file: /var/cvs/busybox/include/libbb.h,v
retrieving revision 1.134
diff -u -3 -p -u -r1.134 libbb.h
--- include/libbb.h	26 Aug 2004 22:18:58 -0000	1.134
+++ include/libbb.h	29 Aug 2004 11:44:19 -0000
@@ -230,8 +230,8 @@ extern unsigned long bb_xparse_number(co
  * increases target size and is often not needed embedded systems.  */
 extern long my_getpwnam(const char *name);
 extern long my_getgrnam(const char *name);
-extern char * my_getpwuid(char *name, long uid, int bufsize);
-extern char * my_getgrgid(char *group, long gid, int bufsize);
+extern char * my_getpwuid(long uid);
+extern char * my_getgrgid(long gid);
 extern long my_getpwnamegid(const char *name);
 extern char *bb_askpass(int timeout, const char * prompt);
 
@@ -441,7 +441,7 @@ extern unsigned char bb_xread_char(int f
 
 typedef struct {
 	int pid;
-	char user[9];
+	char *user;
 	char state[4];
 	unsigned long rss;
 	int ppid;
@@ -456,10 +456,11 @@ typedef struct {
 	char short_cmd[16];
 } procps_status_t;
 
-extern procps_status_t * procps_scan(int save_user_arg0
+extern procps_status_t * procps_scan(int save_user_arg0,
 #ifdef CONFIG_SELINUX
-	, int use_selinux, security_id_t *sid
+	, int use_selinux, security_id_t *sid,
 #endif
+	procps_status_t *curstatus
 );
 extern unsigned short compare_string_array(const char *string_array[], const char *key);
 
Index: libbb/find_pid_by_name.c
===================================================================
RCS file: /var/cvs/busybox/libbb/find_pid_by_name.c,v
retrieving revision 1.14
diff -u -3 -p -u -r1.14 find_pid_by_name.c
--- libbb/find_pid_by_name.c	15 Mar 2004 08:28:42 -0000	1.14
+++ libbb/find_pid_by_name.c	29 Aug 2004 11:44:19 -0000
@@ -38,25 +38,25 @@
  *
  *  Returns a list of all matching PIDs
  */
-extern long* find_pid_by_name( const char* pidName)
+extern long *find_pid_by_name(const char* pidName)
 {
-	long* pidList;
-	int i=0;
-	procps_status_t * p;
+	long *pidList;
+	int i = 0;
+	procps_status_t p;
 
 	pidList = xmalloc(sizeof(long));
 #ifdef CONFIG_SELINUX
-	while ((p = procps_scan(0, 0, NULL)) != 0) {
+	while ((procps_scan(0, 0, NULL, &p)) != 0) {
 #else
-	while ((p = procps_scan(0)) != 0) {
+	while ((procps_scan(0, &p)) != 0) {
 #endif
-		if (strncmp(p->short_cmd, pidName, COMM_LEN-1) == 0) {
-			pidList=xrealloc( pidList, sizeof(long) * (i+2));
-			pidList[i++]=p->pid;
+		if (strncmp(p.short_cmd, pidName, COMM_LEN - 1) == 0) {
+			pidList=xrealloc(pidList, sizeof(long) * (i+2));
+			pidList[i++] = p.pid;
 		}
 	}
 
-	pidList[i] = i==0 ? -1 : 0;
+	pidList[i] = i == 0 ? -1 : 0;
 	return pidList;
 }
 
Index: libbb/my_getgrgid.c
===================================================================
RCS file: /var/cvs/busybox/libbb/my_getgrgid.c,v
retrieving revision 1.8
diff -u -3 -p -u -r1.8 my_getgrgid.c
--- libbb/my_getgrgid.c	26 Aug 2004 22:18:58 -0000	1.8
+++ libbb/my_getgrgid.c	29 Aug 2004 11:44:20 -0000
@@ -27,17 +27,20 @@
 
 
 /* gets a groupname given a gid */
-char * my_getgrgid(char *group, long gid, int bufsize)
+char * my_getgrgid(long gid)
 {
 	struct group *mygroup;
+	char *ret;
 
-	mygroup  = getgrgid(gid);
-	if (mygroup==NULL) {
-		snprintf(group, bufsize, "%ld", gid);
-		return NULL;
+	mygroup = getgrgid(gid);
+	if (mygroup == NULL) {
+		/* XXX:  Not needed.  Will be changed.  -- felipek */
+		bb_xasprintf(&ret, "%ld", (long)gid);
 	} else {
-		return safe_strncpy(group, mygroup->gr_name, bufsize);
+		ret = mygroup->gr_name;
 	}
+
+	return ret;
 }
 
 
Index: libbb/my_getpwuid.c
===================================================================
RCS file: /var/cvs/busybox/libbb/my_getpwuid.c,v
retrieving revision 1.8
diff -u -3 -p -u -r1.8 my_getpwuid.c
--- libbb/my_getpwuid.c	26 Aug 2004 22:18:58 -0000	1.8
+++ libbb/my_getpwuid.c	29 Aug 2004 11:44:20 -0000
@@ -28,17 +28,20 @@
 
 
 /* gets a username given a uid */
-char * my_getpwuid(char *name, long uid, int bufsize)
+char *my_getpwuid(long uid)
 {
 	struct passwd *myuser;
+	char *ret;
 
-	myuser  = getpwuid(uid);
-	if (myuser==NULL) {
-		snprintf(name, bufsize, "%ld", (long)uid);
-		return NULL;
+	myuser = getpwuid(uid);
+	if (myuser == NULL) {
+		/* XXX:  Not needed.  Will be changed.  -- felipek */
+		bb_xasprintf(&ret, "%ld", (long)uid);
 	} else {
-		return safe_strncpy(name, myuser->pw_name, bufsize);
+		ret = myuser->pw_name;
 	}
+
+	return ret;
 }
 
 /* END CODE */
Index: libbb/procps.c
===================================================================
RCS file: /var/cvs/busybox/libbb/procps.c,v
retrieving revision 1.14
diff -u -3 -p -u -r1.14 procps.c
--- libbb/procps.c	26 Aug 2004 22:18:58 -0000	1.14
+++ libbb/procps.c	29 Aug 2004 11:44:21 -0000
@@ -16,21 +16,19 @@
 
 #include "libbb.h"
 
-extern procps_status_t * procps_scan(int save_user_arg0
+extern procps_status_t * procps_scan(int save_user_arg0,
 #ifdef CONFIG_SELINUX
-	, int use_selinux , security_id_t *sid
+	int use_selinux, security_id_t *sid,
 #endif
-	)
+	procps_status_t *curstatus)
 {
 	static DIR *dir;
 	struct dirent *entry;
-	static procps_status_t ret_status;
 	char *name;
 	int n;
 	char status[32];
 	char buf[1024];
 	FILE *fp;
-	procps_status_t curstatus;
 	int pid;
 	long tasknice;
 	struct stat sb;
@@ -50,14 +48,14 @@ extern procps_status_t * procps_scan(int
 		if (!(*name >= '0' && *name <= '9'))
 			continue;
 
-		memset(&curstatus, 0, sizeof(procps_status_t));
 		pid = atoi(name);
-		curstatus.pid = pid;
+		bzero(curstatus, sizeof(procps_status_t));
+		curstatus->pid = pid;
 
 		sprintf(status, "/proc/%d", pid);
 		if(stat(status, &sb))
 			continue;
-		my_getpwuid(curstatus.user, sb.st_uid, sizeof(curstatus.user));
+		curstatus->user = bb_xstrdup(my_getpwuid(sb.st_uid));
 
 		sprintf(status, "/proc/%d/stat", pid);
 		if((fp = fopen(status, "r")) == NULL)
@@ -78,7 +76,7 @@ extern procps_status_t * procps_scan(int
 		if(name == 0 || name[1] != ' ')
 			continue;
 		*name = 0;
-		sscanf(buf, "%*s (%15c", curstatus.short_cmd);
+		sscanf(buf, "%*s (%15c", curstatus->short_cmd);
 		n = sscanf(name+2,
 		"%c %d "
 		"%*s %*s %*s %*s "     /* pgrp, session, tty, tpgid */
@@ -93,12 +91,12 @@ extern procps_status_t * procps_scan(int
 		"%*s %*s %*s "         /* timeout, it_real_value, start_time */
 		"%*s "                 /* vsize */
 		"%ld",
-		curstatus.state, &curstatus.ppid,
+		curstatus->state, &curstatus->ppid,
 #ifdef FEATURE_CPU_USAGE_PERCENTAGE
-		&curstatus.utime, &curstatus.stime,
+		&curstatus->utime, &curstatus->stime,
 #endif
 		&tasknice,
-		&curstatus.rss);
+		&curstatus->rss);
 #ifdef FEATURE_CPU_USAGE_PERCENTAGE
 		if(n != 6)
 #else
@@ -106,21 +104,21 @@ extern procps_status_t * procps_scan(int
 #endif
 			continue;
 
-		if (curstatus.rss == 0 && curstatus.state[0] != 'Z')
-			curstatus.state[1] = 'W';
+		if (curstatus->rss == 0 && curstatus->state[0] != 'Z')
+			curstatus->state[1] = 'W';
 		else
-			curstatus.state[1] = ' ';
+			curstatus->state[1] = ' ';
 		if (tasknice < 0)
-			curstatus.state[2] = '<';
+			curstatus->state[2] = '<';
 		else if (tasknice > 0)
-			curstatus.state[2] = 'N';
+			curstatus->state[2] = 'N';
 		else
-			curstatus.state[2] = ' ';
+			curstatus->state[2] = ' ';
 
 #ifdef PAGE_SHIFT
-		curstatus.rss <<= (PAGE_SHIFT - 10);     /* 2**10 = 1kb */
+		curstatus->rss <<= (PAGE_SHIFT - 10);     /* 2**10 = 1kb */
 #else
-		curstatus.rss *= (getpagesize() >> 10);     /* 2**10 = 1kb */
+		curstatus->rss *= (getpagesize() >> 10);     /* 2**10 = 1kb */
 #endif
 
 		if(save_user_arg0) {
@@ -139,12 +137,12 @@ extern procps_status_t * procps_scan(int
 				}
 				*name = 0;
 				if(buf[0])
-					curstatus.cmd = strdup(buf);
+					curstatus->cmd = strdup(buf);
 				/* if NULL it work true also */
 			}
 			fclose(fp);
 		}
-		return memcpy(&ret_status, &curstatus, sizeof(procps_status_t));
+		return 1;
 	}
 }
 
Index: procps/ps.c
===================================================================
RCS file: /var/cvs/busybox/procps/ps.c,v
retrieving revision 1.52
diff -u -3 -p -u -r1.52 ps.c
--- procps/ps.c	15 Mar 2004 08:29:03 -0000	1.52
+++ procps/ps.c	29 Aug 2004 11:44:22 -0000
@@ -42,7 +42,7 @@ static const int TERMINAL_WIDTH = 79;   
 
 extern int ps_main(int argc, char **argv)
 {
-	procps_status_t * p;
+	procps_status_t p;
 	int i, len;
 	int terminal_width = TERMINAL_WIDTH;
 
@@ -64,11 +64,11 @@ extern int ps_main(int argc, char **argv
 #endif
 	printf("  PID  Uid     VmSize Stat Command\n");
 #ifdef CONFIG_SELINUX
-	while ((p = procps_scan(1, use_selinux, &sid)) != 0) {
+	while ((procps_scan(1, use_selinux, &sid, &p)) != 0) {
 #else
-	while ((p = procps_scan(1)) != 0) {
+	while ((procps_scan(1, &p)) != 0) {
 #endif
-		char *namecmd = p->cmd;
+		char *namecmd = p.cmd;
 
 #ifdef CONFIG_SELINUX
 		if(use_selinux)
@@ -78,14 +78,14 @@ extern int ps_main(int argc, char **argv
 			if(security_sid_to_context(sid, (security_context_t)&sbuf, &len))
 				strcpy(sbuf, "unknown");
 
-			len = printf("%5d %-32s %s ", p->pid, sbuf, p->state);
+			len = printf("%5d %-32s %s ", p.pid, sbuf, p.state);
 		}
 		else
 #endif
-		if(p->rss == 0)
-			len = printf("%5d %-8s        %s ", p->pid, p->user, p->state);
+		if(p.rss == 0)
+			len = printf("%5d %-8s        %s ", p.pid, p.user, p.state);
 		else
-			len = printf("%5d %-8s %6ld %s ", p->pid, p->user, p->rss, p->state);
+			len = printf("%5d %-8s %6ld %s ", p.pid, p.user, p.rss, p.state);
 		i = terminal_width-len;
 
 		if(namecmd != 0 && namecmd[0] != 0) {
@@ -95,14 +95,15 @@ extern int ps_main(int argc, char **argv
 				namecmd[i] = 0;
 			printf("%s\n", namecmd);
 		} else {
-			namecmd = p->short_cmd;
+			namecmd = p.short_cmd;
 			if(i < 2)
 				i = 2;
 			if(strlen(namecmd) > (i-2))
 				namecmd[i-2] = 0;
 			printf("[%s]\n", namecmd);
 		}
-		free(p->cmd);
+		free(p.user);
+		free(p.cmd);
 	}
 	return EXIT_SUCCESS;
 }
Index: procps/top.c
===================================================================
RCS file: /var/cvs/busybox/procps/top.c,v
retrieving revision 1.12
diff -u -3 -p -u -r1.12 top.c
--- procps/top.c	14 Apr 2004 17:51:28 -0000	1.12
+++ procps/top.c	29 Aug 2004 11:44:26 -0000
@@ -53,24 +53,14 @@ static procps_status_t *top;   /* Hehe *
 static int ntop;
 
 
-static int pid_sort (procps_status_t *P, procps_status_t *Q)
+static int pid_sort(procps_status_t *P, procps_status_t *Q)
 {
-    int p = P->pid;
-    int q = Q->pid;
-
-    if( p < q ) return -1;
-    if( p > q ) return  1;
-    return 0;
+    return (P->pid - Q->pid);
 }
 
-static int mem_sort (procps_status_t *P, procps_status_t *Q)
+static int mem_sort(procps_status_t *P, procps_status_t *Q)
 {
-    long p = P->rss;
-    long q = Q->rss;
-
-    if( p > q ) return -1;
-    if( p < q ) return  1;
-    return 0;
+    return (P->rss - Q->rss);
 }
 
 #ifdef FEATURE_CPU_USAGE_PERCENTAGE
@@ -80,12 +70,7 @@ static cmp_t sort_function[sort_depth];
 
 static int pcpu_sort (procps_status_t *P, procps_status_t *Q)
 {
-    int p = P->pcpu;
-    int q = Q->pcpu;
-
-    if( p > q ) return -1;
-    if( p < q ) return  1;
-    return 0;
+    return (P->pcpu - Q->pcpu);
 }
 
 static int time_sort (procps_status_t *P, procps_status_t *Q)
@@ -461,6 +446,7 @@ static void sig_catcher (int sig)
 int top_main(int argc, char **argv)
 {
 	int opt, interval, lines, col;
+	procps_status_t p;
 #if defined CONFIG_FEATURE_USE_TERMIOS
 	struct termios new_settings;
 	struct timeval tv;
@@ -528,23 +514,22 @@ int top_main(int argc, char **argv)
 #else
 	sort_function = mem_sort;
 #endif
+	/* read process IDs & status for all the processes */
 	while (1) {
-		/* read process IDs & status for all the processes */
-		procps_status_t * p;
-
 #ifdef CONFIG_SELINUX
-		while ((p = procps_scan(0, 0, NULL) ) != 0) {
+		while ((procps_scan(0, 0, NULL, &p)) != 0) {
 #else
-		while ((p = procps_scan(0)) != 0) {
+		while ((procps_scan(0, &p)) != 0) {
 #endif
 			int n = ntop;
 
-			top = xrealloc(top, (++ntop)*sizeof(procps_status_t));
-			memcpy(top + n, p, sizeof(procps_status_t));
+			top = xrealloc(top, (++ntop) * sizeof(procps_status_t));
+			memcpy(top + n, &p, sizeof(procps_status_t));
 		}
+
 		if (ntop == 0) {
-		bb_perror_msg_and_die("scandir('/proc')");
-	}
+			bb_perror_msg_and_die("scandir('/proc')");
+		}
 #ifdef FEATURE_CPU_USAGE_PERCENTAGE
 		if(!Hertz) {
 			init_Hertz_value();
@@ -552,7 +537,7 @@ int top_main(int argc, char **argv)
 			sleep(1);
 			clearmems();
 			continue;
-	}
+		}
 		do_stats();
 #else
 		qsort(top, ntop, sizeof(procps_status_t), (void*)sort_function);
@@ -571,8 +556,9 @@ int top_main(int argc, char **argv)
 		select (1, &readfds, NULL, NULL, &tv);
 		if (FD_ISSET (0, &readfds)) {
 			if (read (0, &c, 1) <= 0) {   /* signal */
-		return EXIT_FAILURE;
-	}
+				return EXIT_FAILURE;
+			}
+
 			if(c == 'q' || c == initial_settings.c_cc[VINTR])
 				return EXIT_SUCCESS;
 			if(c == 'M') {
@@ -590,6 +576,7 @@ int top_main(int argc, char **argv)
 				sort_function[1] = mem_sort;
 				sort_function[2] = time_sort;
 			}
+
 			if(c == 'T') {
 				sort_function[0] = time_sort;
 				sort_function[1] = mem_sort;
Index: sysklogd/logger.c
===================================================================
RCS file: /var/cvs/busybox/sysklogd/logger.c,v
retrieving revision 1.40
diff -u -3 -p -u -r1.40 logger.c
--- sysklogd/logger.c	26 Aug 2004 22:18:59 -0000	1.40
+++ sysklogd/logger.c	29 Aug 2004 11:44:28 -0000
@@ -105,10 +105,10 @@ extern int logger_main(int argc, char **
 	int pri = LOG_USER | LOG_NOTICE;
 	int option = 0;
 	int c, i, opt;
-	char buf[1024], name[128];
+	char buf[1024], *name;
 
 	/* Fill out the name string early (may be overwritten later) */
-	my_getpwuid(name, geteuid(), sizeof(name));
+	name = my_getpwuid(geteuid());
 
 	/* Parse any options */
 	while ((opt = getopt(argc, argv, "p:st:")) > 0) {


More information about the busybox mailing list