You are viewing a plain text version of this content. The canonical link for it is here.
Posted to common-issues@hadoop.apache.org by "cnauroth (via GitHub)" <gi...@apache.org> on 2026/02/28 07:33:43 UTC

Re: [PR] YARN-11919 segfault with get_user_info [hadoop]

cnauroth commented on code in PR #8177:
URL: https://github.com/apache/hadoop/pull/8177#discussion_r2867182367


##########
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/container-executor.c:
##########
@@ -915,26 +934,47 @@ static int create_container_directories(const char* user, const char *app_id,
 
 /**
  * Load the user information for a given user name.
+ * See <a href="https://linux.die.net/man/3/getpwnam_r">getpwname_r</a>
+ * Note: for user not found and some error conditions NULL is returned
  */
-static struct passwd* get_user_info(const char* user) {
-  size_t string_size = sysconf(_SC_GETPW_R_SIZE_MAX);
+static struct serialized_passwd* get_user_info(const char* user) {
+  struct passwd pwd;
   struct passwd *result = NULL;
-  if(string_size < 1024) {
-    string_size = 1024;
-  }
-  struct passwd* buffer = malloc(sizeof(struct passwd) + string_size);
-  if (NULL == buffer) {
-    fprintf(LOGFILE, "Failed malloc in get_user_info\n");
-    return NULL;
-  }
-  if (getpwnam_r(user, buffer, ((char*)buffer) + sizeof(struct passwd),
-        string_size, &result) != 0) {
-    free(buffer);
-    fprintf(LOGFILE, "Can't get user information %s - %s\n", user,
-           strerror(errno));
+  struct serialized_passwd *serialized_result;
+  char *buf;
+  size_t bufsize;
+  int s;
+  bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
+  if (bufsize == -1){
+    bufsize = 1024;
+  }
+  buf = malloc(bufsize);
+  if (buf == NULL) {
+    exit(EXIT_FAILURE);
+  }
+  while ((s = getpwnam_r(user, &pwd, buf, bufsize, &result)) == ERANGE){
+    bufsize = 2 * bufsize;
+    char *newbuffer = realloc(buf, bufsize);
+    if (newbuffer == NULL){

Review Comment:
   Nitpick: space before curly brace please.



##########
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/container-executor.c:
##########
@@ -915,26 +934,47 @@ static int create_container_directories(const char* user, const char *app_id,
 
 /**
  * Load the user information for a given user name.
+ * See <a href="https://linux.die.net/man/3/getpwnam_r">getpwname_r</a>
+ * Note: for user not found and some error conditions NULL is returned
  */
-static struct passwd* get_user_info(const char* user) {
-  size_t string_size = sysconf(_SC_GETPW_R_SIZE_MAX);
+static struct serialized_passwd* get_user_info(const char* user) {
+  struct passwd pwd;
   struct passwd *result = NULL;
-  if(string_size < 1024) {
-    string_size = 1024;
-  }
-  struct passwd* buffer = malloc(sizeof(struct passwd) + string_size);
-  if (NULL == buffer) {
-    fprintf(LOGFILE, "Failed malloc in get_user_info\n");
-    return NULL;
-  }
-  if (getpwnam_r(user, buffer, ((char*)buffer) + sizeof(struct passwd),
-        string_size, &result) != 0) {
-    free(buffer);
-    fprintf(LOGFILE, "Can't get user information %s - %s\n", user,
-           strerror(errno));
+  struct serialized_passwd *serialized_result;
+  char *buf;
+  size_t bufsize;
+  int s;
+  bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
+  if (bufsize == -1){
+    bufsize = 1024;
+  }
+  buf = malloc(bufsize);
+  if (buf == NULL) {
+    exit(EXIT_FAILURE);
+  }
+  while ((s = getpwnam_r(user, &pwd, buf, bufsize, &result)) == ERANGE){
+    bufsize = 2 * bufsize;
+    char *newbuffer = realloc(buf, bufsize);
+    if (newbuffer == NULL){
+      exit(EXIT_FAILURE);
+    }
+    buf = newbuffer;
+  }
+  if (result == NULL) {
+    if (s == 0){

Review Comment:
   Nitpick: space before curly brace please.



##########
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/container-executor.c:
##########
@@ -915,26 +934,47 @@ static int create_container_directories(const char* user, const char *app_id,
 
 /**
  * Load the user information for a given user name.
+ * See <a href="https://linux.die.net/man/3/getpwnam_r">getpwname_r</a>
+ * Note: for user not found and some error conditions NULL is returned
  */
-static struct passwd* get_user_info(const char* user) {
-  size_t string_size = sysconf(_SC_GETPW_R_SIZE_MAX);
+static struct serialized_passwd* get_user_info(const char* user) {
+  struct passwd pwd;
   struct passwd *result = NULL;
-  if(string_size < 1024) {
-    string_size = 1024;
-  }
-  struct passwd* buffer = malloc(sizeof(struct passwd) + string_size);
-  if (NULL == buffer) {
-    fprintf(LOGFILE, "Failed malloc in get_user_info\n");
-    return NULL;
-  }
-  if (getpwnam_r(user, buffer, ((char*)buffer) + sizeof(struct passwd),
-        string_size, &result) != 0) {
-    free(buffer);
-    fprintf(LOGFILE, "Can't get user information %s - %s\n", user,
-           strerror(errno));
+  struct serialized_passwd *serialized_result;
+  char *buf;
+  size_t bufsize;
+  int s;
+  bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
+  if (bufsize == -1){
+    bufsize = 1024;
+  }
+  buf = malloc(bufsize);
+  if (buf == NULL) {
+    exit(EXIT_FAILURE);
+  }
+  while ((s = getpwnam_r(user, &pwd, buf, bufsize, &result)) == ERANGE){
+    bufsize = 2 * bufsize;
+    char *newbuffer = realloc(buf, bufsize);

Review Comment:
   If a [`realloc`](https://linux.die.net/man/3/realloc) fails, it returns `NULL`. If there is a failure, the original buffer remains in place. This implies we need to `free` the original if the `realloc` fails.



##########
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/container-executor.c:
##########
@@ -915,26 +934,47 @@ static int create_container_directories(const char* user, const char *app_id,
 
 /**
  * Load the user information for a given user name.
+ * See <a href="https://linux.die.net/man/3/getpwnam_r">getpwname_r</a>
+ * Note: for user not found and some error conditions NULL is returned
  */
-static struct passwd* get_user_info(const char* user) {
-  size_t string_size = sysconf(_SC_GETPW_R_SIZE_MAX);
+static struct serialized_passwd* get_user_info(const char* user) {
+  struct passwd pwd;
   struct passwd *result = NULL;
-  if(string_size < 1024) {
-    string_size = 1024;
-  }
-  struct passwd* buffer = malloc(sizeof(struct passwd) + string_size);
-  if (NULL == buffer) {
-    fprintf(LOGFILE, "Failed malloc in get_user_info\n");
-    return NULL;
-  }
-  if (getpwnam_r(user, buffer, ((char*)buffer) + sizeof(struct passwd),
-        string_size, &result) != 0) {
-    free(buffer);
-    fprintf(LOGFILE, "Can't get user information %s - %s\n", user,
-           strerror(errno));
+  struct serialized_passwd *serialized_result;
+  char *buf;
+  size_t bufsize;
+  int s;
+  bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
+  if (bufsize == -1){
+    bufsize = 1024;
+  }
+  buf = malloc(bufsize);
+  if (buf == NULL) {
+    exit(EXIT_FAILURE);
+  }
+  while ((s = getpwnam_r(user, &pwd, buf, bufsize, &result)) == ERANGE){
+    bufsize = 2 * bufsize;
+    char *newbuffer = realloc(buf, bufsize);
+    if (newbuffer == NULL){

Review Comment:
   Nitpick: space before the curly brace please.



##########
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/container-executor.c:
##########
@@ -120,6 +120,25 @@ void set_nm_uid(uid_t user, gid_t group) {
   nm_gid = group;
 }
 
+//function to make a deep clone of passwd to serialized_passwd
+void deep_copy_passwd(const struct passwd *src, struct serialized_passwd *dest){
+  dest->pw_name = strdup(src->pw_name);

Review Comment:
   [`strdup`](https://man7.org/linux/man-pages/man3/strdup.3.html) can return `NULL` if there is insufficient memory. (There are pre-existing calls to `strdup` that don't have the error checking. No expectation that you need to do a mass update of all error handling in scope of this patch.)



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: common-issues-unsubscribe@hadoop.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: common-issues-unsubscribe@hadoop.apache.org
For additional commands, e-mail: common-issues-help@hadoop.apache.org