diff options
author | Natanael Copa <ncopa@alpinelinux.org> | 2017-07-11 19:08:15 +0200 |
---|---|---|
committer | Natanael Copa <ncopa@alpinelinux.org> | 2017-07-11 19:11:01 +0200 |
commit | 9e0f3ef79e2abc5e7ef29250820e99ff5246b78d (patch) | |
tree | 79b9f0d73e0930c7c608c9d574c95fadd1a2f6ec /main/alsa-lib/0001-snd_user_file-avoid-use-wordexp.patch | |
parent | d99210497704ebac146e48e2f93c8bee906a0b35 (diff) |
main/alsa-lib: avoid using wordexp
wordexp implementation will execute /bin/sh (as suggested in posix).
This breaks firefox sandbox. We also need to expand ~/ so that alsa uses
~/.asoundrc so we cannot just trick the configurescript to think that we
dont have wordexp since the fallback code would not expand anything at
all.
ref #7454
Diffstat (limited to 'main/alsa-lib/0001-snd_user_file-avoid-use-wordexp.patch')
-rw-r--r-- | main/alsa-lib/0001-snd_user_file-avoid-use-wordexp.patch | 129 |
1 files changed, 129 insertions, 0 deletions
diff --git a/main/alsa-lib/0001-snd_user_file-avoid-use-wordexp.patch b/main/alsa-lib/0001-snd_user_file-avoid-use-wordexp.patch new file mode 100644 index 00000000000..9205aa215de --- /dev/null +++ b/main/alsa-lib/0001-snd_user_file-avoid-use-wordexp.patch @@ -0,0 +1,129 @@ +From 1f9113336e8eb4bd89ca040e90c5fdc79b0c567f Mon Sep 17 00:00:00 2001 +From: Natanael Copa <ncopa@alpinelinux.org> +Date: Tue, 11 Jul 2017 18:25:13 +0200 +Subject: [PATCH] snd_user_file: avoid use wordexp + +As suggested in POSIX[1], wordexp might execute the shell. If the libc +implementation does so, it will break the firefox sandbox which does +not allow exec. This happened on Alpine Linux with musl libc[2]. + +Since we cannot guarantee that the system wordexp implementation does +not execute shell, we cannot really use it, and need to implement the +~/ expansion ourselves. + +[1]: http://pubs.opengroup.org/onlinepubs/9699919799/functions/wordexp.html#tag_16_684_08 +[2]: http://bugs.alpinelinux.org/issues/7454#note-2 + +Signed-off-by: Natanael Copa <ncopa@alpinelinux.org> +--- + src/userfile.c | 77 +++++++++++++++++++++++++++++++++++----------------------- + 1 file changed, 47 insertions(+), 30 deletions(-) + +diff --git a/src/userfile.c b/src/userfile.c +index 72779da4..0e3f5fae 100644 +--- a/src/userfile.c ++++ b/src/userfile.c +@@ -21,6 +21,11 @@ + #include <config.h> + #include <string.h> + #include <errno.h> ++#include <sys/types.h> ++#include <unistd.h> ++#include <pwd.h> ++#include <stdio.h> ++#include <stdlib.h> + + /** + * \brief Get the full file name +@@ -28,46 +33,58 @@ + * \param result The pointer to store the resultant file name + * \return 0 if successful, or a negative error code + * +- * Parses the given file name with POSIX-Shell-like expansion and +- * stores the first matchine one. The returned string is strdup'ed. ++ * Parses the given file name with POSIX-Shell-like expansion for ~/. ++ * The returned string is strdup'ed. + */ + +-#ifdef HAVE_WORDEXP_H +-#include <wordexp.h> + #include <assert.h> + int snd_user_file(const char *file, char **result) + { +- wordexp_t we; + int err; +- ++ size_t len; ++ char *buf = NULL; ++ + assert(file && result); +- err = wordexp(file, &we, WRDE_NOCMD); +- switch (err) { +- case WRDE_NOSPACE: +- wordfree(&we); +- return -ENOMEM; +- case 0: +- if (we.we_wordc == 1) +- break; +- wordfree(&we); +- /* fall thru */ +- default: +- return -EINVAL; ++ *result = NULL; ++ ++ /* expand ~/ if needed */ ++ if (file[0] == '~' && file[1] == '/') { ++ const char *home = getenv("HOME"); ++ if (home == NULL) { ++ struct passwd pwent, *p = NULL; ++ uid_t id = getuid(); ++ size_t bufsize = 1024; ++ ++ buf = malloc(bufsize); ++ if (buf == NULL) ++ goto out; ++ ++ while ((err = getpwuid_r(id, &pwent, buf, bufsize, &p)) == ERANGE) { ++ char *newbuf; ++ bufsize += 1024; ++ if (bufsize < 1024) ++ break; ++ newbuf = realloc(buf, bufsize); ++ if (newbuf == NULL) ++ goto out; ++ buf = newbuf; ++ } ++ home = err ? "" : pwent.pw_dir; ++ } ++ len = strlen(home) + strlen(&file[2]) + 2; ++ *result = malloc(len); ++ if (*result) ++ snprintf(*result, len, "%s/%s", home, &file[2]); ++ } else { ++ *result = strdup(file); + } +- *result = strdup(we.we_wordv[0]); +- wordfree(&we); ++ ++out: ++ if (buf) ++ free(buf); ++ + if (*result == NULL) + return -ENOMEM; + return 0; + } + +-#else /* !HAVE_WORDEXP_H */ +-/* just copy the string - would be nicer to expand by ourselves, though... */ +-int snd_user_file(const char *file, char **result) +-{ +- *result = strdup(file); +- if (! *result) +- return -ENOMEM; +- return 0; +-} +-#endif /* HAVE_WORDEXP_H */ +-- +2.13.2 + |