summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Bogatov <KAction@gnu.org>2016-05-29 11:56:51 +0200
committerChristoph Lohmann <20h@r-36.net>2016-06-03 15:09:08 +0200
commit1308872b8bd7a2516d0626955abe391af076e711 (patch)
tree7a2d999c1aadb811e22fc2150d4033cb6ae3aa09
parentf5e8baad06eafef22df12ab2649139260127d4e4 (diff)
downloadsurf-1308872b8bd7a2516d0626955abe391af076e711.tar.gz
surf-1308872b8bd7a2516d0626955abe391af076e711.tar.bz2
surf-1308872b8bd7a2516d0626955abe391af076e711.zip
Check $HOME and home dir of $USER before getpwuid()->pw_dir
getpwnam(3) recommends to use $HOME instead of getpwuid()->pw_dir, as it allows users to point programs to a different path. Using getpwuid() also breaks namespaces-related use cases, like `unshare -r`. Patch was submitted by Dmitry Bogatov on the Debian bug tracker: https://bugs.debian.org/825397 Signed-off-by: Christoph Lohmann <20h@r-36.net>
-rw-r--r--surf.c43
1 files changed, 36 insertions, 7 deletions
diff --git a/surf.c b/surf.c
index 23c49bd..46b0ce8 100644
--- a/surf.c
+++ b/surf.c
@@ -287,29 +287,58 @@ buildfile(const char *path)
return fpath;
}
+static const char*
+get_user_homedir(const char *user) {
+ struct passwd *pw = getpwnam(user);
+ if (!pw) {
+ die("Can't get user `%s' home directory.\n", user);
+ }
+ return pw->pw_dir;
+}
+
+static const char*
+get_current_user_homedir() {
+ const char *homedir;
+ const char *user;
+ struct passwd *pw;
+
+ homedir = getenv("HOME");
+ if (homedir) {
+ return homedir;
+ }
+
+ user = getenv("USER");
+ if (user) {
+ return get_user_homedir(user);
+ }
+
+ pw = getpwuid(getuid());
+ if (!pw) {
+ die("Can't get current user home directory\n");
+ }
+ return pw->pw_dir;
+}
+
char *
buildpath(const char *path)
{
- struct passwd *pw;
char *apath, *name, *p, *fpath;
if (path[0] == '~') {
+ const char *homedir;
if (path[1] == '/' || path[1] == '\0') {
p = (char *)&path[1];
- pw = getpwuid(getuid());
+ homedir = get_current_user_homedir();
} else {
if ((p = strchr(path, '/')))
name = g_strndup(&path[1], --p - path);
else
name = g_strdup(&path[1]);
- if (!(pw = getpwnam(name))) {
- die("Can't get user %s home directory: %s.\n",
- name, path);
- }
+ homedir = get_user_homedir(name);
g_free(name);
}
- apath = g_build_filename(pw->pw_dir, p, NULL);
+ apath = g_build_filename(homedir, p, NULL);
} else {
apath = g_strdup(path);
}