1
Description: fix use-after-free via posix_spawn_file_actions_addopen
2
failing to copy the path argument
3
Origin: backport, https://sourceware.org/git/?p=glibc.git;h=89e435f3559c53084498e9baad22172b64429362
4
Origin: backport, https://sourceware.org/git/?p=glibc.git;h=35a5e3e338ae17f3d42c60a708763c5d498fb840
5
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=17048
6
Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=751774
8
Index: eglibc-2.15/posix/spawn_faction_addopen.c
9
===================================================================
10
--- eglibc-2.15.orig/posix/spawn_faction_addopen.c 2006-08-16 21:18:26.000000000 -0400
11
+++ eglibc-2.15/posix/spawn_faction_addopen.c 2014-07-25 13:31:56.634828694 -0400
18
#include "spawn_int.h"
21
if (fd < 0 || fd >= maxfd)
24
+ char *path_copy = strdup (path);
25
+ if (path_copy == NULL)
28
/* Allocate more memory if needed. */
29
if (file_actions->__used == file_actions->__allocated
30
&& __posix_spawn_file_actions_realloc (file_actions) != 0)
31
- /* This can only mean we ran out of memory. */
34
+ /* This can only mean we ran out of memory. */
39
/* Add the new value. */
40
rec = &file_actions->__actions[file_actions->__used];
41
rec->tag = spawn_do_open;
42
rec->action.open_action.fd = fd;
43
- rec->action.open_action.path = path;
44
+ rec->action.open_action.path = path_copy;
45
rec->action.open_action.oflag = oflag;
46
rec->action.open_action.mode = mode;
48
Index: eglibc-2.15/posix/spawn_faction_destroy.c
49
===================================================================
50
--- eglibc-2.15.orig/posix/spawn_faction_destroy.c 2006-08-16 21:18:26.000000000 -0400
51
+++ eglibc-2.15/posix/spawn_faction_destroy.c 2014-07-25 13:31:56.638828694 -0400
56
-/* Initialize data structure for file attribute for `spawn' call. */
57
+#include "spawn_int.h"
59
+/* Deallocate the file actions. */
61
posix_spawn_file_actions_destroy (posix_spawn_file_actions_t *file_actions)
63
- /* Free the memory allocated. */
64
+ /* Free the paths in the open actions. */
65
+ for (int i = 0; i < file_actions->__used; ++i)
67
+ struct __spawn_action *sa = &file_actions->__actions[i];
71
+ free (sa->action.open_action.path);
73
+ case spawn_do_close:
75
+ /* No cleanup required. */
80
+ /* Free the array of actions. */
81
free (file_actions->__actions);
84
Index: eglibc-2.15/posix/spawn_int.h
85
===================================================================
86
--- eglibc-2.15.orig/posix/spawn_int.h 2011-09-06 11:08:18.000000000 -0400
87
+++ eglibc-2.15/posix/spawn_int.h 2014-07-25 13:31:56.638828694 -0400
97
Index: eglibc-2.15/posix/tst-spawn.c
98
===================================================================
99
--- eglibc-2.15.orig/posix/tst-spawn.c 2006-08-26 17:52:38.000000000 -0400
100
+++ eglibc-2.15/posix/tst-spawn.c 2014-07-25 13:31:56.638828694 -0400
110
if (posix_spawn_file_actions_addclose (&actions, fd1) != 0)
111
error (EXIT_FAILURE, errno, "posix_spawn_file_actions_addclose");
112
/* We want to open the third file. */
113
- if (posix_spawn_file_actions_addopen (&actions, fd3, name3,
114
+ name3_copy = strdup (name3);
115
+ if (name3_copy == NULL)
116
+ error (EXIT_FAILURE, errno, "strdup");
117
+ if (posix_spawn_file_actions_addopen (&actions, fd3, name3_copy,
118
O_RDONLY, 0666) != 0)
119
error (EXIT_FAILURE, errno, "posix_spawn_file_actions_addopen");
120
+ /* Overwrite the name to check that a copy has been made. */
121
+ memset (name3_copy, 'X', strlen (name3_copy));
123
/* We dup the second descriptor. */
124
fd4 = MAX (2, MAX (fd1, MAX (fd2, fd3))) + 1;
125
if (posix_spawn_file_actions_adddup2 (&actions, fd2, fd4) != 0)
128
if (posix_spawn_file_actions_destroy (&actions) != 0)
129
error (EXIT_FAILURE, errno, "posix_spawn_file_actions_destroy");
132
/* Wait for the child. */
133
if (waitpid (pid, &status, 0) != pid)