Configurable buffer size for getpwnam() and getgrnam() (fwd)

Ricard Wanderlof ricard.wanderlof at axis.com
Thu Feb 22 14:12:21 UTC 2007


The following patch adds a configurable buffer size for getpwnam() and 
getgrnam() and friends. The default buffer size is, as before, 256 (glibc seems 
to use 1024 by default).

I couldn't find a good existing place to put the config variable so I added a 
new menu to the configuration called Advanced Library Settings which would then 
be intended for esoteric stuff like this that most people won't want to change.

The patch was originally submitted a couple of months ago, but got a 
comment that the buffer size should have a range check. Good point, 
although it's not obvious what the range values should be. I tested a 
number of different values, and technically, any size down to 1 is ok, 
although that means that functions like getpwnam() etc don't really return 
any useful info at all. Values in the several kilobyte range also work, 
but compared to glibc default value of 1024, seem a bit excessive. So I 
settled on a range of 256 to 1024, i.e. from the default uClibc value of 
256 up to glibc's 1024.

Patch included in the mail for visual review, and also as an attachement. 
Patch done against 0.9.28.2 .

It would be nice to get this into 0.9.29. We have found the patch useful 
in our application (network cameras) which actually utilize users and 
groups for authentication purposes.

/Ricard
--
Ricard Wolf Wanderlöf                           ricardw(at)axis.com
Axis Communications AB, Lund, Sweden            www.axis.com
Phone +46 46 272 2016                           Fax +46 46 13 61 30


diff -Naur uClibc-0.9.28.2/extra/Configs/Config.in uClibc-dev-new/extra/Configs/Config.in
--- uClibc-0.9.28.2/extra/Configs/Config.in	2007-01-26 01:01:55.000000000 +0100
+++ uClibc-dev-new/extra/Configs/Config.in	2007-02-22 14:51:37.951411192 +0100
@@ -523,6 +523,30 @@

  endmenu

+menu "Advanced Library Settings"
+
+config UCLIBC_PWD_BUFFER_SIZE
+	int "Buffer size for getpwnam() and friends"
+	default 256
+	range 256 1024
+	help
+	  This sets the value of the buffer size for getpwnam() and friends.
+	  By default, this is 256. (For reference, glibc uses 1024).
+	  The value can be found using sysconf() with the _SC_GETPW_R_SIZE_MAX
+	  parameter.
+
+config UCLIBC_GRP_BUFFER_SIZE
+	int "Buffer size for getgrnam() and friends"
+	default 256
+	range 256 1024
+	help
+	  This sets the value of the buffer size for getgrnam() and friends.
+	  By default, this is 256. (For reference, glibc uses 1024).
+	  The value can be found using sysconf() with the _SC_GETGR_R_SIZE_MAX
+	  parameter.
+
+endmenu
+
  menu "Networking Support"

  config UCLIBC_HAS_IPV6
diff -Naur uClibc-0.9.28.2/libc/pwd_grp/pwd_grp.c uClibc-dev-new/libc/pwd_grp/pwd_grp.c
--- uClibc-0.9.28.2/libc/pwd_grp/pwd_grp.c	2007-01-26 01:47:48.000000000 +0100
+++ uClibc-dev-new/libc/pwd_grp/pwd_grp.c	2007-02-22 14:40:11.000000000 +0100
@@ -46,14 +46,6 @@
  #include <bits/uClibc_mutex.h>

  /**********************************************************************/
-/* Sizes for staticly allocated buffers. */
-
-/* If you change these values, also change _SC_GETPW_R_SIZE_MAX and
- * _SC_GETGR_R_SIZE_MAX in libc/unistd/sysconf.c to match */
-#define PWD_BUFFER_SIZE 256
-#define GRP_BUFFER_SIZE 256
-
-/**********************************************************************/
  /* Prototypes for internal functions. */

  extern int __parsepwent(void *pw, char *line);
@@ -143,7 +135,7 @@

  struct passwd *fgetpwent(FILE *stream)
  {
-	static char buffer[PWD_BUFFER_SIZE];
+	static char buffer[__UCLIBC_PWD_BUFFER_SIZE__];
  	static struct passwd resultbuf;
  	struct passwd *result;

@@ -157,7 +149,7 @@

  struct group *fgetgrent(FILE *stream)
  {
-	static char buffer[GRP_BUFFER_SIZE];
+	static char buffer[__UCLIBC_GRP_BUFFER_SIZE__];
  	static struct group resultbuf;
  	struct group *result;

@@ -171,7 +163,7 @@

  struct spwd *fgetspent(FILE *stream)
  {
-	static char buffer[PWD_BUFFER_SIZE];
+	static char buffer[__UCLIBC_PWD_BUFFER_SIZE__];
  	static struct spwd resultbuf;
  	struct spwd *result;

@@ -190,7 +182,7 @@

  	*result = NULL;

-	if (buflen < PWD_BUFFER_SIZE) {
+	if (buflen < __UCLIBC_PWD_BUFFER_SIZE__) {
  	DO_ERANGE:
  		__set_errno(rv);
  		goto DONE;
@@ -307,7 +299,7 @@

  struct passwd *getpwuid(uid_t uid)
  {
-	static char buffer[PWD_BUFFER_SIZE];
+	static char buffer[__UCLIBC_PWD_BUFFER_SIZE__];
  	static struct passwd resultbuf;
  	struct passwd *result;

@@ -321,7 +313,7 @@

  struct group *getgrgid(gid_t gid)
  {
-	static char buffer[GRP_BUFFER_SIZE];
+	static char buffer[__UCLIBC_GRP_BUFFER_SIZE__];
  	static struct group resultbuf;
  	struct group *result;

@@ -344,7 +336,7 @@
  	int rv;
  	struct passwd *pp;
  	struct passwd password;
-	char pwd_buff[PWD_BUFFER_SIZE];
+	char pwd_buff[__UCLIBC_PWD_BUFFER_SIZE__];

  	*result = NULL;
  	if (!(rv = getpwuid_r(uid, &password, pwd_buff, sizeof(pwd_buff), &pp))) {
@@ -363,7 +355,7 @@

  struct spwd *getspuid(uid_t uid)
  {
-	static char buffer[PWD_BUFFER_SIZE];
+	static char buffer[__UCLIBC_PWD_BUFFER_SIZE__];
  	static struct spwd resultbuf;
  	struct spwd *result;

@@ -377,7 +369,7 @@

  struct passwd *getpwnam(const char *name)
  {
-	static char buffer[PWD_BUFFER_SIZE];
+	static char buffer[__UCLIBC_PWD_BUFFER_SIZE__];
  	static struct passwd resultbuf;
  	struct passwd *result;

@@ -391,7 +383,7 @@

  struct group *getgrnam(const char *name)
  {
-	static char buffer[GRP_BUFFER_SIZE];
+	static char buffer[__UCLIBC_GRP_BUFFER_SIZE__];
  	static struct group resultbuf;
  	struct group *result;

@@ -405,7 +397,7 @@

  struct spwd *getspnam(const char *name)
  {
-	static char buffer[PWD_BUFFER_SIZE];
+	static char buffer[__UCLIBC_PWD_BUFFER_SIZE__];
  	static struct spwd resultbuf;
  	struct spwd *result;

@@ -421,7 +413,7 @@
  {
  	struct passwd resultbuf;
  	struct passwd *result;
-	char buffer[PWD_BUFFER_SIZE];
+	char buffer[__UCLIBC_PWD_BUFFER_SIZE__];

  	if (!buf) {
  		__set_errno(EINVAL);
@@ -614,7 +606,7 @@

  struct passwd *getpwent(void)
  {
-	static char line_buff[PWD_BUFFER_SIZE];
+	static char line_buff[__UCLIBC_PWD_BUFFER_SIZE__];
  	static struct passwd pwd;
  	struct passwd *result;

@@ -628,7 +620,7 @@

  struct group *getgrent(void)
  {
-	static char line_buff[GRP_BUFFER_SIZE];
+	static char line_buff[__UCLIBC_GRP_BUFFER_SIZE__];
  	static struct group gr;
  	struct group *result;

@@ -642,7 +634,7 @@

  struct spwd *getspent(void)
  {
-	static char line_buff[PWD_BUFFER_SIZE];
+	static char line_buff[__UCLIBC_PWD_BUFFER_SIZE__];
  	static struct spwd spwd;
  	struct spwd *result;

@@ -656,7 +648,7 @@

  struct spwd *sgetspent(const char *string)
  {
-	static char line_buff[PWD_BUFFER_SIZE];
+	static char line_buff[__UCLIBC_PWD_BUFFER_SIZE__];
  	static struct spwd spwd;
  	struct spwd *result;

@@ -675,7 +667,7 @@
  	int num_groups, rv;
  	char **m;
  	struct group group;
-	char buff[PWD_BUFFER_SIZE];
+	char buff[__UCLIBC_PWD_BUFFER_SIZE__];

  	rv = -1;

@@ -1101,7 +1093,7 @@
  	int rv = ERANGE;
  	__STDIO_AUTO_THREADLOCK_VAR;

-	if (buflen < PWD_BUFFER_SIZE) {
+	if (buflen < __UCLIBC_PWD_BUFFER_SIZE__) {
  		__set_errno(rv);
  	} else {
  		__STDIO_AUTO_THREADLOCK(f);
diff -Naur uClibc-0.9.28.2/libc/unistd/sysconf.c uClibc-dev-new/libc/unistd/sysconf.c
--- uClibc-0.9.28.2/libc/unistd/sysconf.c	2004-07-15 11:09:24.000000000 +0200
+++ uClibc-dev-new/libc/unistd/sysconf.c	2007-02-22 14:41:05.000000000 +0100
@@ -564,13 +564,11 @@
  #endif

  /* If you change these, also change libc/pwd_grp/pwd_grp.c to match */
-#define PWD_BUFFER_SIZE 256
-#define GRP_BUFFER_SIZE 256
      case _SC_GETGR_R_SIZE_MAX:
-      return GRP_BUFFER_SIZE;
+      return __UCLIBC_GRP_BUFFER_SIZE__;

      case _SC_GETPW_R_SIZE_MAX:
-      return PWD_BUFFER_SIZE;
+      return __UCLIBC_PWD_BUFFER_SIZE__;

  /* getlogin() is a worthless interface.  In uClibc we let the user specify
   * whatever they want via the LOGNAME environment variable, or we return NULL
-------------- next part --------------
diff -Naur uClibc-0.9.28.2/extra/Configs/Config.in uClibc-dev-new/extra/Configs/Config.in
--- uClibc-0.9.28.2/extra/Configs/Config.in	2007-01-26 01:01:55.000000000 +0100
+++ uClibc-dev-new/extra/Configs/Config.in	2007-02-22 14:51:37.951411192 +0100
@@ -523,6 +523,30 @@
 
 endmenu
 
+menu "Advanced Library Settings"
+
+config UCLIBC_PWD_BUFFER_SIZE
+	int "Buffer size for getpwnam() and friends"
+	default 256
+	range 256 1024
+	help
+	  This sets the value of the buffer size for getpwnam() and friends.
+	  By default, this is 256. (For reference, glibc uses 1024).
+	  The value can be found using sysconf() with the _SC_GETPW_R_SIZE_MAX
+	  parameter.
+
+config UCLIBC_GRP_BUFFER_SIZE
+	int "Buffer size for getgrnam() and friends"
+	default 256
+	range 256 1024
+	help
+	  This sets the value of the buffer size for getgrnam() and friends.
+	  By default, this is 256. (For reference, glibc uses 1024).
+	  The value can be found using sysconf() with the _SC_GETGR_R_SIZE_MAX
+	  parameter.
+
+endmenu
+
 menu "Networking Support"
 
 config UCLIBC_HAS_IPV6
diff -Naur uClibc-0.9.28.2/libc/pwd_grp/pwd_grp.c uClibc-dev-new/libc/pwd_grp/pwd_grp.c
--- uClibc-0.9.28.2/libc/pwd_grp/pwd_grp.c	2007-01-26 01:47:48.000000000 +0100
+++ uClibc-dev-new/libc/pwd_grp/pwd_grp.c	2007-02-22 14:40:11.000000000 +0100
@@ -46,14 +46,6 @@
 #include <bits/uClibc_mutex.h>
 
 /**********************************************************************/
-/* Sizes for staticly allocated buffers. */
-
-/* If you change these values, also change _SC_GETPW_R_SIZE_MAX and
- * _SC_GETGR_R_SIZE_MAX in libc/unistd/sysconf.c to match */
-#define PWD_BUFFER_SIZE 256
-#define GRP_BUFFER_SIZE 256
-
-/**********************************************************************/
 /* Prototypes for internal functions. */
 
 extern int __parsepwent(void *pw, char *line);
@@ -143,7 +135,7 @@
 
 struct passwd *fgetpwent(FILE *stream)
 {
-	static char buffer[PWD_BUFFER_SIZE];
+	static char buffer[__UCLIBC_PWD_BUFFER_SIZE__];
 	static struct passwd resultbuf;
 	struct passwd *result;
 
@@ -157,7 +149,7 @@
 
 struct group *fgetgrent(FILE *stream)
 {
-	static char buffer[GRP_BUFFER_SIZE];
+	static char buffer[__UCLIBC_GRP_BUFFER_SIZE__];
 	static struct group resultbuf;
 	struct group *result;
 
@@ -171,7 +163,7 @@
 
 struct spwd *fgetspent(FILE *stream)
 {
-	static char buffer[PWD_BUFFER_SIZE];
+	static char buffer[__UCLIBC_PWD_BUFFER_SIZE__];
 	static struct spwd resultbuf;
 	struct spwd *result;
 
@@ -190,7 +182,7 @@
 
 	*result = NULL;
 
-	if (buflen < PWD_BUFFER_SIZE) {
+	if (buflen < __UCLIBC_PWD_BUFFER_SIZE__) {
 	DO_ERANGE:
 		__set_errno(rv);
 		goto DONE;
@@ -307,7 +299,7 @@
 
 struct passwd *getpwuid(uid_t uid)
 {
-	static char buffer[PWD_BUFFER_SIZE];
+	static char buffer[__UCLIBC_PWD_BUFFER_SIZE__];
 	static struct passwd resultbuf;
 	struct passwd *result;
 
@@ -321,7 +313,7 @@
 
 struct group *getgrgid(gid_t gid)
 {
-	static char buffer[GRP_BUFFER_SIZE];
+	static char buffer[__UCLIBC_GRP_BUFFER_SIZE__];
 	static struct group resultbuf;
 	struct group *result;
 
@@ -344,7 +336,7 @@
 	int rv;
 	struct passwd *pp;
 	struct passwd password;
-	char pwd_buff[PWD_BUFFER_SIZE];
+	char pwd_buff[__UCLIBC_PWD_BUFFER_SIZE__];
 
 	*result = NULL;
 	if (!(rv = getpwuid_r(uid, &password, pwd_buff, sizeof(pwd_buff), &pp))) {
@@ -363,7 +355,7 @@
 
 struct spwd *getspuid(uid_t uid)
 {
-	static char buffer[PWD_BUFFER_SIZE];
+	static char buffer[__UCLIBC_PWD_BUFFER_SIZE__];
 	static struct spwd resultbuf;
 	struct spwd *result;
 
@@ -377,7 +369,7 @@
 
 struct passwd *getpwnam(const char *name)
 {
-	static char buffer[PWD_BUFFER_SIZE];
+	static char buffer[__UCLIBC_PWD_BUFFER_SIZE__];
 	static struct passwd resultbuf;
 	struct passwd *result;
 
@@ -391,7 +383,7 @@
 
 struct group *getgrnam(const char *name)
 {
-	static char buffer[GRP_BUFFER_SIZE];
+	static char buffer[__UCLIBC_GRP_BUFFER_SIZE__];
 	static struct group resultbuf;
 	struct group *result;
 
@@ -405,7 +397,7 @@
 
 struct spwd *getspnam(const char *name)
 {
-	static char buffer[PWD_BUFFER_SIZE];
+	static char buffer[__UCLIBC_PWD_BUFFER_SIZE__];
 	static struct spwd resultbuf;
 	struct spwd *result;
 
@@ -421,7 +413,7 @@
 {
 	struct passwd resultbuf;
 	struct passwd *result;
-	char buffer[PWD_BUFFER_SIZE];
+	char buffer[__UCLIBC_PWD_BUFFER_SIZE__];
 
 	if (!buf) {
 		__set_errno(EINVAL);
@@ -614,7 +606,7 @@
 
 struct passwd *getpwent(void)
 {
-	static char line_buff[PWD_BUFFER_SIZE];
+	static char line_buff[__UCLIBC_PWD_BUFFER_SIZE__];
 	static struct passwd pwd;
 	struct passwd *result;
 
@@ -628,7 +620,7 @@
 
 struct group *getgrent(void)
 {
-	static char line_buff[GRP_BUFFER_SIZE];
+	static char line_buff[__UCLIBC_GRP_BUFFER_SIZE__];
 	static struct group gr;
 	struct group *result;
 
@@ -642,7 +634,7 @@
 
 struct spwd *getspent(void)
 {
-	static char line_buff[PWD_BUFFER_SIZE];
+	static char line_buff[__UCLIBC_PWD_BUFFER_SIZE__];
 	static struct spwd spwd;
 	struct spwd *result;
 
@@ -656,7 +648,7 @@
 
 struct spwd *sgetspent(const char *string)
 {
-	static char line_buff[PWD_BUFFER_SIZE];
+	static char line_buff[__UCLIBC_PWD_BUFFER_SIZE__];
 	static struct spwd spwd;
 	struct spwd *result;
 
@@ -675,7 +667,7 @@
 	int num_groups, rv;
 	char **m;
 	struct group group;
-	char buff[PWD_BUFFER_SIZE];
+	char buff[__UCLIBC_PWD_BUFFER_SIZE__];
 
 	rv = -1;
 
@@ -1101,7 +1093,7 @@
 	int rv = ERANGE;
 	__STDIO_AUTO_THREADLOCK_VAR;
 
-	if (buflen < PWD_BUFFER_SIZE) {
+	if (buflen < __UCLIBC_PWD_BUFFER_SIZE__) {
 		__set_errno(rv);
 	} else {
 		__STDIO_AUTO_THREADLOCK(f);
diff -Naur uClibc-0.9.28.2/libc/unistd/sysconf.c uClibc-dev-new/libc/unistd/sysconf.c
--- uClibc-0.9.28.2/libc/unistd/sysconf.c	2004-07-15 11:09:24.000000000 +0200
+++ uClibc-dev-new/libc/unistd/sysconf.c	2007-02-22 14:41:05.000000000 +0100
@@ -564,13 +564,11 @@
 #endif
 
 /* If you change these, also change libc/pwd_grp/pwd_grp.c to match */
-#define PWD_BUFFER_SIZE 256
-#define GRP_BUFFER_SIZE 256
     case _SC_GETGR_R_SIZE_MAX:
-      return GRP_BUFFER_SIZE;
+      return __UCLIBC_GRP_BUFFER_SIZE__;
 
     case _SC_GETPW_R_SIZE_MAX:
-      return PWD_BUFFER_SIZE;
+      return __UCLIBC_PWD_BUFFER_SIZE__;
 
 /* getlogin() is a worthless interface.  In uClibc we let the user specify
  * whatever they want via the LOGNAME environment variable, or we return NULL


More information about the uClibc mailing list