aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorandersen <andersen@69ca8d6d-28ef-0310-b511-8ec308f3f277>2004-08-26 22:18:59 +0000
committerandersen <andersen@69ca8d6d-28ef-0310-b511-8ec308f3f277>2004-08-26 22:18:59 +0000
commitdba2d5102b5841853c25721682d3b0d295365963 (patch)
treecf0f347d2c4a0cd48c6d5b4cc83aead35726434e
parent74693c0d771cc5e0b80d091b3bba4625956ff309 (diff)
downloadbusybox-w32-dba2d5102b5841853c25721682d3b0d295365963.tar.gz
busybox-w32-dba2d5102b5841853c25721682d3b0d295365963.tar.bz2
busybox-w32-dba2d5102b5841853c25721682d3b0d295365963.zip
Tito writes:
Hi, I've spent the half night staring at the devilish my_getpwuid and my_getgrgid functions trying to find out a way to avoid actual and future potential buffer overflow problems without breaking existing code. Finally I've found a not intrusive way to do this that surely doesn't break existing code and fixes a couple of problems too. The attached patch: 1) changes the behaviour of my_getpwuid and my_getgrgid to avoid potetntial buffer overflows 2) fixes all occurences of this function calls in tar.c , id.c , ls.c, whoami.c, logger.c, libbb.h. 3) The behaviour of tar, ls and logger is unchanged. 4) The behavior of ps with somewhat longer usernames messing up output is fixed. 5) The only bigger change was the increasing of size of the buffers in id.c to avoid false negatives (unknown user: xxxxxx) with usernames longer than 8 chars. The value i used ( 32 chars ) was taken from the tar header ( see gname and uname). Maybe this buffers can be reduced a bit ( to 16 or whatever ), this is up to you. 6) The increase of size of the binary is not so dramatic: size busybox text data bss dec hex filename 239568 2300 36816 278684 4409c busybox size busybox_fixed text data bss dec hex filename 239616 2300 36816 278732 440cc busybox 7) The behaviour of whoami changed: actually it prints out an username cut down to the size of the buffer. This could be fixed by increasing the size of the buffer as in id.c or avoid the use of my_getpwuid and use getpwuid directly instead. Maybe this colud be also remain unchanged...... Please apply if you think it is ok to do so. The diff applies on today's cvs tarball (2004-08-25). Thanks in advance, Ciao, Tito git-svn-id: svn://busybox.net/trunk/busybox@9165 69ca8d6d-28ef-0310-b511-8ec308f3f277
-rw-r--r--archival/tar.c4
-rw-r--r--coreutils/id.c6
-rw-r--r--coreutils/ls.c4
-rw-r--r--coreutils/whoami.c2
-rw-r--r--include/libbb.h4
-rw-r--r--libbb/my_getgrgid.c6
-rw-r--r--libbb/my_getpwuid.c6
-rw-r--r--libbb/procps.c2
-rw-r--r--sysklogd/logger.c2
9 files changed, 18 insertions, 18 deletions
diff --git a/archival/tar.c b/archival/tar.c
index 689dd1424..950e21dd3 100644
--- a/archival/tar.c
+++ b/archival/tar.c
@@ -234,9 +234,9 @@ static inline int writeTarHeader(struct TarBallInfo *tbInfo,
234 TAR_MAGIC_LEN + TAR_VERSION_LEN); 234 TAR_MAGIC_LEN + TAR_VERSION_LEN);
235 235
236 /* Enter the user and group names (default to root if it fails) */ 236 /* Enter the user and group names (default to root if it fails) */
237 if (my_getpwuid(header.uname, statbuf->st_uid) == NULL) 237 if (my_getpwuid(header.uname, statbuf->st_uid, sizeof(header.uname)) == NULL)
238 strcpy(header.uname, "root"); 238 strcpy(header.uname, "root");
239 if (my_getgrgid(header.gname, statbuf->st_gid) == NULL) 239 if (my_getgrgid(header.gname, statbuf->st_gid, sizeof(header.gname)) == NULL)
240 strcpy(header.gname, "root"); 240 strcpy(header.gname, "root");
241 241
242 if (tbInfo->hlInfo) { 242 if (tbInfo->hlInfo) {
diff --git a/coreutils/id.c b/coreutils/id.c
index 602b26ec3..db8afc585 100644
--- a/coreutils/id.c
+++ b/coreutils/id.c
@@ -40,7 +40,7 @@
40 40
41extern int id_main(int argc, char **argv) 41extern int id_main(int argc, char **argv)
42{ 42{
43 char user[9], group[9]; 43 char user[32], group[32];
44 long pwnam, grnam; 44 long pwnam, grnam;
45 int uid, gid; 45 int uid, gid;
46 int flags; 46 int flags;
@@ -64,12 +64,12 @@ extern int id_main(int argc, char **argv)
64 uid = geteuid(); 64 uid = geteuid();
65 gid = getegid(); 65 gid = getegid();
66 } 66 }
67 my_getpwuid(user, uid); 67 my_getpwuid(user, uid, sizeof(user));
68 } else { 68 } else {
69 safe_strncpy(user, argv[optind], sizeof(user)); 69 safe_strncpy(user, argv[optind], sizeof(user));
70 gid = my_getpwnamegid(user); 70 gid = my_getpwnamegid(user);
71 } 71 }
72 my_getgrgid(group, gid); 72 my_getgrgid(group, gid, sizeof(group));
73 73
74 pwnam=my_getpwnam(user); 74 pwnam=my_getpwnam(user);
75 grnam=my_getgrnam(group); 75 grnam=my_getgrnam(group);
diff --git a/coreutils/ls.c b/coreutils/ls.c
index a87f0ec2d..22685bcd9 100644
--- a/coreutils/ls.c
+++ b/coreutils/ls.c
@@ -683,9 +683,9 @@ static int list_single(struct dnode *dn)
683 break; 683 break;
684 case LIST_ID_NAME: 684 case LIST_ID_NAME:
685#ifdef CONFIG_FEATURE_LS_USERNAME 685#ifdef CONFIG_FEATURE_LS_USERNAME
686 my_getpwuid(scratch, dn->dstat.st_uid); 686 my_getpwuid(scratch, dn->dstat.st_uid, sizeof(scratch));
687 printf("%-8.8s ", scratch); 687 printf("%-8.8s ", scratch);
688 my_getgrgid(scratch, dn->dstat.st_gid); 688 my_getgrgid(scratch, dn->dstat.st_gid, sizeof(scratch));
689 printf("%-8.8s", scratch); 689 printf("%-8.8s", scratch);
690 column += 17; 690 column += 17;
691 break; 691 break;
diff --git a/coreutils/whoami.c b/coreutils/whoami.c
index f93034d3a..e2a03b1e9 100644
--- a/coreutils/whoami.c
+++ b/coreutils/whoami.c
@@ -36,7 +36,7 @@ extern int whoami_main(int argc, char **argv)
36 bb_show_usage(); 36 bb_show_usage();
37 37
38 uid = geteuid(); 38 uid = geteuid();
39 if (my_getpwuid(user, uid)) { 39 if (my_getpwuid(user, uid, sizeof(user))) {
40 puts(user); 40 puts(user);
41 bb_fflush_stdout_and_exit(EXIT_SUCCESS); 41 bb_fflush_stdout_and_exit(EXIT_SUCCESS);
42 } 42 }
diff --git a/include/libbb.h b/include/libbb.h
index afbd0203e..78b9711e8 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -230,8 +230,8 @@ extern unsigned long bb_xparse_number(const char *numstr,
230 * increases target size and is often not needed embedded systems. */ 230 * increases target size and is often not needed embedded systems. */
231extern long my_getpwnam(const char *name); 231extern long my_getpwnam(const char *name);
232extern long my_getgrnam(const char *name); 232extern long my_getgrnam(const char *name);
233extern char * my_getpwuid(char *name, long uid); 233extern char * my_getpwuid(char *name, long uid, int bufsize);
234extern char * my_getgrgid(char *group, long gid); 234extern char * my_getgrgid(char *group, long gid, int bufsize);
235extern long my_getpwnamegid(const char *name); 235extern long my_getpwnamegid(const char *name);
236extern char *bb_askpass(int timeout, const char * prompt); 236extern char *bb_askpass(int timeout, const char * prompt);
237 237
diff --git a/libbb/my_getgrgid.c b/libbb/my_getgrgid.c
index 907a47486..e6b877687 100644
--- a/libbb/my_getgrgid.c
+++ b/libbb/my_getgrgid.c
@@ -27,16 +27,16 @@
27 27
28 28
29/* gets a groupname given a gid */ 29/* gets a groupname given a gid */
30char * my_getgrgid(char *group, long gid) 30char * my_getgrgid(char *group, long gid, int bufsize)
31{ 31{
32 struct group *mygroup; 32 struct group *mygroup;
33 33
34 mygroup = getgrgid(gid); 34 mygroup = getgrgid(gid);
35 if (mygroup==NULL) { 35 if (mygroup==NULL) {
36 sprintf(group, "%ld", gid); 36 snprintf(group, bufsize, "%ld", gid);
37 return NULL; 37 return NULL;
38 } else { 38 } else {
39 return strcpy(group, mygroup->gr_name); 39 return safe_strncpy(group, mygroup->gr_name, bufsize);
40 } 40 }
41} 41}
42 42
diff --git a/libbb/my_getpwuid.c b/libbb/my_getpwuid.c
index 21a037f75..53f6c77ee 100644
--- a/libbb/my_getpwuid.c
+++ b/libbb/my_getpwuid.c
@@ -28,16 +28,16 @@
28 28
29 29
30/* gets a username given a uid */ 30/* gets a username given a uid */
31char * my_getpwuid(char *name, long uid) 31char * my_getpwuid(char *name, long uid, int bufsize)
32{ 32{
33 struct passwd *myuser; 33 struct passwd *myuser;
34 34
35 myuser = getpwuid(uid); 35 myuser = getpwuid(uid);
36 if (myuser==NULL) { 36 if (myuser==NULL) {
37 sprintf(name, "%ld", (long)uid); 37 snprintf(name, bufsize, "%ld", (long)uid);
38 return NULL; 38 return NULL;
39 } else { 39 } else {
40 return strcpy(name, myuser->pw_name); 40 return safe_strncpy(name, myuser->pw_name, bufsize);
41 } 41 }
42} 42}
43 43
diff --git a/libbb/procps.c b/libbb/procps.c
index 46e982766..e405fb7ef 100644
--- a/libbb/procps.c
+++ b/libbb/procps.c
@@ -57,7 +57,7 @@ extern procps_status_t * procps_scan(int save_user_arg0
57 sprintf(status, "/proc/%d", pid); 57 sprintf(status, "/proc/%d", pid);
58 if(stat(status, &sb)) 58 if(stat(status, &sb))
59 continue; 59 continue;
60 my_getpwuid(curstatus.user, sb.st_uid); 60 my_getpwuid(curstatus.user, sb.st_uid, sizeof(curstatus.user));
61 61
62 sprintf(status, "/proc/%d/stat", pid); 62 sprintf(status, "/proc/%d/stat", pid);
63 if((fp = fopen(status, "r")) == NULL) 63 if((fp = fopen(status, "r")) == NULL)
diff --git a/sysklogd/logger.c b/sysklogd/logger.c
index 981cef322..16155316f 100644
--- a/sysklogd/logger.c
+++ b/sysklogd/logger.c
@@ -108,7 +108,7 @@ extern int logger_main(int argc, char **argv)
108 char buf[1024], name[128]; 108 char buf[1024], name[128];
109 109
110 /* Fill out the name string early (may be overwritten later) */ 110 /* Fill out the name string early (may be overwritten later) */
111 my_getpwuid(name, geteuid()); 111 my_getpwuid(name, geteuid(), sizeof(name));
112 112
113 /* Parse any options */ 113 /* Parse any options */
114 while ((opt = getopt(argc, argv, "p:st:")) > 0) { 114 while ((opt = getopt(argc, argv, "p:st:")) > 0) {