summaryrefslogtreecommitdiff
blob: c5ee207f45720e54ad946a714e4ecc6d2b54b86b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
  When calling man for instance with:

    $ man -k "foo bar"

  will result in the following crash:

    $ man -k "foo bar"
    sh: line 1: unsafe: command not found
    Error executing formatting or display command.
    System command unsafe exited with status 127.
    Segmentation fault

  The reason for this is that my_xsprintf() in util.c passes
  NOT_SAFE as the result if the string is not shell safe.
  When do_appros() (or whatever) then calls 'free(command)',
  free() tries to free a constant, and segfault.

  The attached solution are not eligant, but works without
  breaking the API.  Basically we redefine NOT_SAFE as a
  message that we want to display, prepended with 'echo'.
  When the command is then executed, our message are displayed,
  and not the the line containing:
  
    sh: line 1: unsafe: command not found

  Further more, we do not return NOT_SAFE, but rather a string
  that we malloc, and then fill with the contents of NOT_SAFE,
  which will solve us trying to free a constant.

  More info can be found at:

    http://bugs.gentoo.org/show_bug.cgi?id=9761

  Alternatively it is possible to redefine what is "shell safe",
  but that will me a much more comprehensive fix ...
 
 
  Martin Schlemmer <azarah@gentoo.org> (26 Dec 2002).

--- man-1.5k/src/util.c.orig	2002-12-26 07:41:03.000000000 +0200
+++ man-1.5k/src/util.c	2002-12-26 07:51:48.000000000 +0200
@@ -261,7 +261,7 @@
  * The %S parameters are checked for being shell safe.
  * The %Q parameters are checked for being shell safe inside single quotes.
  */
-#define NOT_SAFE "unsafe"
+#define NOT_SAFE "echo Cannot run command, as it is not shell safe!\necho Check that you do not quote search strings, etc."
 
 static int
 is_shell_safe(const char *ss, int quoted) {
@@ -295,8 +295,14 @@
 			case 'Q':
 			case 'S': /* check and turn into 's' */
 				ss = va_arg(p, char *);
-				if (!is_shell_safe(ss, (s[1] == 'Q')))
-					return NOT_SAFE;
+				if (!is_shell_safe(ss, (s[1] == 'Q'))) {
+					/* we cannot return NOT_SAFE, as it will cause
+					 * free to segfault in trying to free a constant
+					 */
+					s = my_malloc(sizeof(NOT_SAFE) + 1);
+					s = strncpy(s, NOT_SAFE, sizeof(NOT_SAFE));
+					return s;
+				}
 				len += strlen(ss);
 				s[1] = 's';
 				break;