Patchwork chg: verify XDG_RUNTIME_DIR

login
register
mail settings
Submitter Jun Wu
Date Feb. 7, 2017, 1:03 a.m.
Message ID <8081cb8c346f1ccfa8c9.1486429438@x1c>
Download mbox | patch
Permalink /patch/18337/
State Accepted
Headers show

Comments

Jun Wu - Feb. 7, 2017, 1:03 a.m.
# HG changeset patch
# User Jun Wu <quark@fb.com>
# Date 1486429266 28800
#      Mon Feb 06 17:01:06 2017 -0800
# Node ID 8081cb8c346f1ccfa8c98e94d7e25cdfccafeb06
# Parent  b6c051cd1231910b0981edb01b173cd53a3338d0
# Available At https://bitbucket.org/quark-zju/hg-draft
#              hg pull https://bitbucket.org/quark-zju/hg-draft -r 8081cb8c346f
chg: verify XDG_RUNTIME_DIR

According to the specification [1], $XDG_RUNTIME_DIR should be ignored
unless:

  The directory MUST be owned by the user, and he MUST be the only one
  having read and write access to it. Its Unix access mode MUST be 0700.

This patch adds a check and ignores it if it does not meet part of the
criteria.

[1]: https://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
Augie Fackler - Feb. 7, 2017, 5:24 a.m.
> On Feb 6, 2017, at 20:03, Jun Wu <quark@fb.com> wrote:
> 
> # HG changeset patch
> # User Jun Wu <quark@fb.com>
> # Date 1486429266 28800
> #      Mon Feb 06 17:01:06 2017 -0800
> # Node ID 8081cb8c346f1ccfa8c98e94d7e25cdfccafeb06
> # Parent  b6c051cd1231910b0981edb01b173cd53a3338d0
> # Available At https://bitbucket.org/quark-zju/hg-draft
> #              hg pull https://bitbucket.org/quark-zju/hg-draft -r 8081cb8c346f
> chg: verify XDG_RUNTIME_DIR

queued, thanks

> 
> According to the specification [1], $XDG_RUNTIME_DIR should be ignored
> unless:
> 
>  The directory MUST be owned by the user, and he MUST be the only one
>  having read and write access to it. Its Unix access mode MUST be 0700.
> 
> This patch adds a check and ignores it if it does not meet part of the
> criteria.
> 
> [1]: https://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
> 
> diff --git a/contrib/chg/chg.c b/contrib/chg/chg.c
> --- a/contrib/chg/chg.c
> +++ b/contrib/chg/chg.c
> @@ -129,4 +129,22 @@ static void preparesockdir(const char *s
> }
> 
> +/*
> + * Check if a socket directory exists and is only owned by the current user.
> + * Return 1 if so, 0 if not. This is used to check if XDG_RUNTIME_DIR can be
> + * used or not. According to the specification [1], XDG_RUNTIME_DIR should be
> + * ignored if the directory is not owned by the user with mode 0700.
> + * [1]: https://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
> + */
> +static int checkruntimedir(const char *sockdir)
> +{
> +	struct stat st;
> +	int r = lstat(sockdir, &st);
> +	if (r < 0) /* ex. does not exist */
> +		return 0;
> +	if (!S_ISDIR(st.st_mode)) /* ex. is a file, not a directory */
> +		return 0;
> +	return st.st_uid == geteuid() && (st.st_mode & 0777) == 0700;
> +}
> +
> static void getdefaultsockdir(char sockdir[], size_t size)
> {
> @@ -136,5 +154,5 @@ static void getdefaultsockdir(char sockd
> 	const char *runtimedir = getenv("XDG_RUNTIME_DIR");
> 	int r;
> -	if (runtimedir) {
> +	if (runtimedir && checkruntimedir(runtimedir)) {
> 		r = snprintf(sockdir, size, "%s/chg", runtimedir);
> 	} else {
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel@mercurial-scm.org
> https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel

Patch

diff --git a/contrib/chg/chg.c b/contrib/chg/chg.c
--- a/contrib/chg/chg.c
+++ b/contrib/chg/chg.c
@@ -129,4 +129,22 @@  static void preparesockdir(const char *s
 }
 
+/*
+ * Check if a socket directory exists and is only owned by the current user.
+ * Return 1 if so, 0 if not. This is used to check if XDG_RUNTIME_DIR can be
+ * used or not. According to the specification [1], XDG_RUNTIME_DIR should be
+ * ignored if the directory is not owned by the user with mode 0700.
+ * [1]: https://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
+ */
+static int checkruntimedir(const char *sockdir)
+{
+	struct stat st;
+	int r = lstat(sockdir, &st);
+	if (r < 0) /* ex. does not exist */
+		return 0;
+	if (!S_ISDIR(st.st_mode)) /* ex. is a file, not a directory */
+		return 0;
+	return st.st_uid == geteuid() && (st.st_mode & 0777) == 0700;
+}
+
 static void getdefaultsockdir(char sockdir[], size_t size)
 {
@@ -136,5 +154,5 @@  static void getdefaultsockdir(char sockd
 	const char *runtimedir = getenv("XDG_RUNTIME_DIR");
 	int r;
-	if (runtimedir) {
+	if (runtimedir && checkruntimedir(runtimedir)) {
 		r = snprintf(sockdir, size, "%s/chg", runtimedir);
 	} else {