fix HOME env of container unset error
Signed-off-by: haozi007 <liuhao27@huawei.com> (cherry picked from commit d97043c9d07b01f0d12e3bdaa5daff150bffe5b5)
This commit is contained in:
parent
adb6a1a369
commit
aedeb84ae5
321
0044-fix-HOME-env-unset-error.patch
Normal file
321
0044-fix-HOME-env-unset-error.patch
Normal file
@ -0,0 +1,321 @@
|
||||
From d86ad6bf0acaa98b11344627a8118a2945b8da1e Mon Sep 17 00:00:00 2001
|
||||
From: haozi007 <liuhao27@huawei.com>
|
||||
Date: Mon, 25 Jul 2022 11:08:29 +0800
|
||||
Subject: [PATCH] fix HOME env unset error
|
||||
|
||||
Signed-off-by: haozi007 <liuhao27@huawei.com>
|
||||
---
|
||||
src/lxc/isulad_utils.c | 190 +++++++++++++++++++++++++++++++++++++++++
|
||||
src/lxc/isulad_utils.h | 3 +
|
||||
src/lxc/start.c | 14 +--
|
||||
src/lxc/utils.c | 22 ++++-
|
||||
4 files changed, 218 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/src/lxc/isulad_utils.c b/src/lxc/isulad_utils.c
|
||||
index b282404..f72b5fe 100644
|
||||
--- a/src/lxc/isulad_utils.c
|
||||
+++ b/src/lxc/isulad_utils.c
|
||||
@@ -6,11 +6,21 @@
|
||||
* Create: 2020-04-11
|
||||
******************************************************************************/
|
||||
|
||||
+#ifndef _GNU_SOURCE
|
||||
+#define _GNU_SOURCE 1
|
||||
+#endif
|
||||
+
|
||||
+#include <stdio.h>
|
||||
+#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
+#include <unistd.h>
|
||||
+#include <errno.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <stdio_ext.h>
|
||||
|
||||
#include "isulad_utils.h"
|
||||
#include "log.h"
|
||||
@@ -97,3 +107,183 @@ FILE *lxc_fopen(const char *filename, const char *mode)
|
||||
|
||||
return fopen_cloexec(rpath, mode);
|
||||
}
|
||||
+
|
||||
+static int hold_int(const char delim, bool required, char **src, unsigned int *dst)
|
||||
+{
|
||||
+ unsigned long long int res = 0;
|
||||
+ char *err_str = NULL;
|
||||
+
|
||||
+ // ensure *src not a empty string
|
||||
+ if (**src == '\0') {
|
||||
+ ERROR("Empty subject on given entrie is not allowed.");
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ errno = 0;
|
||||
+ // covert string to long long
|
||||
+ res = strtoull(*src, &err_str, 0);
|
||||
+ if (errno != 0 && errno != ERANGE) {
|
||||
+ ERROR("Parse int from string failed.");
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ // **src is not a digit
|
||||
+ if (err_str == *src) {
|
||||
+ if (!required) {
|
||||
+ ERROR("Integer part is missing.");
|
||||
+ return -1;
|
||||
+ }
|
||||
+ // if required, just set 0
|
||||
+ *dst = 0;
|
||||
+ } else {
|
||||
+ if (sizeof(void *) > 4 && res > UINT_MAX) { // make sure 64-bit platform behave same as 32-bit
|
||||
+ res = UINT_MAX;
|
||||
+ }
|
||||
+ res = res & UINT_MAX;
|
||||
+ *dst = (uint32_t)res;
|
||||
+ }
|
||||
+
|
||||
+ // normal case
|
||||
+ if (*err_str == delim) {
|
||||
+ err_str++;
|
||||
+ } else if (*err_str != '\0') {
|
||||
+ ERROR("Invalid digit string.");
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ *src = err_str; // update src to next valid context in line.
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void hold_string(const char delim, char **src, char **dst)
|
||||
+{
|
||||
+ for (*dst = *src; **src != delim; ++(*src)) {
|
||||
+ if (**src == '\0') {
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (**src == delim) {
|
||||
+ **src = '\0';
|
||||
+ ++(*src);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static int parse_line_pw(const char delim, char *line, struct passwd *result)
|
||||
+{
|
||||
+ int ret = 0;
|
||||
+ bool required = false;
|
||||
+ char *walker = NULL;
|
||||
+
|
||||
+ walker = strpbrk(line, "\n");
|
||||
+ if (walker != NULL) {
|
||||
+ // clear newline char
|
||||
+ *walker = '\0';
|
||||
+ }
|
||||
+
|
||||
+ hold_string(delim, &line, &result->pw_name);
|
||||
+
|
||||
+ required = (result->pw_name[0] == '+' || result->pw_name[0] == '-') ? true : false;
|
||||
+
|
||||
+ hold_string(delim, &line, &result->pw_passwd);
|
||||
+
|
||||
+ ret = hold_int(delim, required, &line, &result->pw_uid);
|
||||
+ if (ret != 0) {
|
||||
+ // a legitimate line must have uid
|
||||
+ ERROR("Parse uid error.");
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ ret = hold_int(delim, required, &line, &result->pw_gid);
|
||||
+ if (ret != 0) {
|
||||
+ // it's ok to not provide gid
|
||||
+ ERROR("Parse gid error.");
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ hold_string(delim, &line, &result->pw_gecos);
|
||||
+
|
||||
+ hold_string(delim, &line, &result->pw_dir);
|
||||
+
|
||||
+ result->pw_shell = line;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+char *util_left_trim_space(char *str)
|
||||
+{
|
||||
+ char *begin = str;
|
||||
+ char *tmp = str;
|
||||
+ while (isspace(*begin)) {
|
||||
+ begin++;
|
||||
+ }
|
||||
+ while ((*tmp++ = *begin++)) {
|
||||
+ }
|
||||
+ return str;
|
||||
+}
|
||||
+
|
||||
+int util_getpwent_r(FILE *stream, struct passwd *resbuf, char *buffer, size_t buflen, struct passwd **result)
|
||||
+{
|
||||
+ const char delim = ':';
|
||||
+ char *buff_end = NULL;
|
||||
+ char *walker = NULL;
|
||||
+ bool got = false;
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ if (stream == NULL || resbuf == NULL || buffer == NULL || result == NULL) {
|
||||
+ ERROR("Password obj, params is NULL.");
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ if (buflen <= 1) {
|
||||
+ ERROR("Inadequate buffer length was given.");
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ buff_end = buffer + buflen - 1;
|
||||
+ flockfile(stream);
|
||||
+
|
||||
+ while (1) {
|
||||
+ *buff_end = '\xff';
|
||||
+ walker = fgets_unlocked(buffer, buflen, stream);
|
||||
+ // if get NULL string
|
||||
+ if (walker == NULL) {
|
||||
+ *result = NULL;
|
||||
+ // reach end of file, return error
|
||||
+ if (feof(stream)) {
|
||||
+ ret = ENOENT;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ // overflow buffer
|
||||
+ ret = ERANGE;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ // just overflow last char in buffer
|
||||
+ if (*buff_end != '\xff') {
|
||||
+ *result = NULL;
|
||||
+ ret = ERANGE;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ (void)util_left_trim_space(buffer);
|
||||
+ // skip comment line and empty line
|
||||
+ if (walker[0] == '#' || walker[0] == '\0') {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ if (parse_line_pw(delim, walker, resbuf) == 0) {
|
||||
+ got = true;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ if (!got) {
|
||||
+ *result = NULL;
|
||||
+ ret = ERANGE;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ *result = resbuf;
|
||||
+ ret = 0;
|
||||
+out:
|
||||
+ funlockfile(stream);
|
||||
+ return ret;
|
||||
+}
|
||||
\ No newline at end of file
|
||||
diff --git a/src/lxc/isulad_utils.h b/src/lxc/isulad_utils.h
|
||||
index 7a6ab00..1368c83 100644
|
||||
--- a/src/lxc/isulad_utils.h
|
||||
+++ b/src/lxc/isulad_utils.h
|
||||
@@ -9,6 +9,7 @@
|
||||
#define __iSULAD_UTILS_H
|
||||
|
||||
#include <stdio.h>
|
||||
+#include <pwd.h>
|
||||
|
||||
extern int lxc_mem_realloc(void **newptr, size_t newsize, void *oldptr, size_t oldsize);
|
||||
extern void *lxc_common_calloc_s(size_t size);
|
||||
@@ -17,4 +18,6 @@ extern char *safe_strdup(const char *src);
|
||||
extern int lxc_open(const char *filename, int flags, mode_t mode);
|
||||
extern FILE *lxc_fopen(const char *filename, const char *mode);
|
||||
|
||||
+int util_getpwent_r(FILE *stream, struct passwd *resbuf, char *buffer, size_t buflen, struct passwd **result);
|
||||
+
|
||||
#endif
|
||||
diff --git a/src/lxc/start.c b/src/lxc/start.c
|
||||
index c1563e0..aeafd47 100644
|
||||
--- a/src/lxc/start.c
|
||||
+++ b/src/lxc/start.c
|
||||
@@ -1716,6 +1716,13 @@ static int do_start(void *data)
|
||||
new_uid = handler->conf->init_uid;
|
||||
new_gid = handler->conf->init_gid;
|
||||
|
||||
+#ifdef HAVE_ISULAD
|
||||
+ // isulad: set env home in container, must before "Avoid unnecessary syscalls."
|
||||
+ if (lxc_setup_env_home(new_uid) < 0) {
|
||||
+ goto out_warn_father;
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
/* Avoid unnecessary syscalls. */
|
||||
if (new_uid == nsuid)
|
||||
new_uid = LXC_INVALID_UID;
|
||||
@@ -1723,13 +1730,6 @@ static int do_start(void *data)
|
||||
if (new_gid == nsgid)
|
||||
new_gid = LXC_INVALID_GID;
|
||||
|
||||
-#ifdef HAVE_ISULAD
|
||||
- // isulad: set env home in container
|
||||
- if (lxc_setup_env_home(new_uid) < 0) {
|
||||
- goto out_warn_father;
|
||||
- }
|
||||
-#endif
|
||||
-
|
||||
/* Make sure that the processes STDIO is correctly owned by the user that we are switching to */
|
||||
ret = fix_stdio_permissions(new_uid);
|
||||
if (ret)
|
||||
diff --git a/src/lxc/utils.c b/src/lxc/utils.c
|
||||
index b39b6a8..20ca181 100644
|
||||
--- a/src/lxc/utils.c
|
||||
+++ b/src/lxc/utils.c
|
||||
@@ -2213,20 +2213,34 @@ out:
|
||||
// isulad: set env home in container
|
||||
int lxc_setup_env_home(uid_t uid)
|
||||
{
|
||||
+#define __PASSWD_FILE__ "/etc/passwd"
|
||||
char *homedir = "/"; // default home dir is /
|
||||
+ FILE *stream = NULL;
|
||||
struct passwd pw, *pwbufp = NULL;
|
||||
char buf[BUFSIZ];
|
||||
- int ret;
|
||||
|
||||
- ret = getpwuid_r(uid, &pw, buf, sizeof(buf), &pwbufp);
|
||||
- if ((ret == 0) && (pwbufp != NULL) && (pwbufp->pw_uid == uid)) {
|
||||
- homedir = pwbufp->pw_dir;
|
||||
+ stream = fopen_cloexec(__PASSWD_FILE__, "r");
|
||||
+ if (stream == NULL) {
|
||||
+ SYSWARN("Failed to open %s", __PASSWD_FILE__);
|
||||
goto set_env;
|
||||
}
|
||||
|
||||
+#if IS_BIONIC
|
||||
+ while (util_getpwent_r(stream, &pw, buf, sizeof(buf), &pwbufp) == 0 && pwbufp != NULL) {
|
||||
+#else
|
||||
+ while (fgetpwent_r(stream, &pw, buf, sizeof(buf), &pwbufp) == 0 && pwbufp != NULL) {
|
||||
+#endif
|
||||
+ if (pwbufp->pw_uid == uid) {
|
||||
+ homedir = pwbufp->pw_dir;
|
||||
+ goto set_env;
|
||||
+ }
|
||||
+ }
|
||||
WARN("User invalid, can not find user '%u'", uid);
|
||||
|
||||
set_env:
|
||||
+ if (stream)
|
||||
+ fclose(stream);
|
||||
+
|
||||
// if we didn't configure HOME, set it based on uid
|
||||
if (setenv("HOME", homedir, 0) < 0) {
|
||||
SYSERROR("Unable to set env 'HOME'");
|
||||
--
|
||||
2.25.1
|
||||
|
||||
9
lxc.spec
9
lxc.spec
@ -1,4 +1,4 @@
|
||||
%global _release 2022052501
|
||||
%global _release 2022072501
|
||||
|
||||
Name: lxc
|
||||
Version: 4.0.3
|
||||
@ -51,6 +51,7 @@ Patch0040: 0040-refactor-the-way-to-convert-selinux-label-to-shared.path
|
||||
Patch0041: 0041-do-not-free-the-pointer-returned-by-dirname.patch
|
||||
Patch0042: 0042-add-x-permission-when-create-directory.patch
|
||||
Patch0043: 0043-do-not-operate-playload-and-attach-cgroup-if-no-cont.patch
|
||||
Patch0044: 0044-fix-HOME-env-unset-error.patch
|
||||
|
||||
BuildRequires: systemd-units git libtool graphviz docbook2X doxygen chrpath
|
||||
BuildRequires: pkgconfig(libseccomp)
|
||||
@ -222,6 +223,12 @@ make check
|
||||
%{_mandir}/*/man7/%{name}*
|
||||
|
||||
%changelog
|
||||
* Mon Jul 25 2022 haozi007<liuhao27@huawei.com> - 4.0.3-2022072501
|
||||
- Type:bugfix
|
||||
- ID:NA
|
||||
- SUG:NA
|
||||
- DESC: fix HOME env unset error
|
||||
|
||||
* Wed May 25 2022 hejunjie<hejunjie10@huawei.com> - 4.0.3-2022052501
|
||||
- Type:bugfix
|
||||
- ID:NA
|
||||
|
||||
@ -41,3 +41,4 @@
|
||||
0041-do-not-free-the-pointer-returned-by-dirname.patch
|
||||
0042-add-x-permission-when-create-directory.patch
|
||||
0043-do-not-operate-playload-and-attach-cgroup-if-no-cont.patch
|
||||
0044-fix-HOME-env-unset-error.patch
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user