]> code.ossystems Code Review - openembedded-core.git/blob
e911a7c1f24ca53beb8b5194358952d927da8d57
[openembedded-core.git] /
1 From 90881d24d3f6d5fb207e97df3b91bbea8598e84e Mon Sep 17 00:00:00 2001
2 From: Martin Matuska <martin@matuska.org>
3 Date: Tue, 29 Nov 2016 16:47:37 +0100
4 Subject: [PATCH 1/2] archive_write_disk_posix.c: make *_fsobj functions more
5  readable
6
7 Upstream-Status: Backported
8
9 Signed-off-by: Amarnath Valluri <amarnath.valluri@intel.com>
10 ---
11  libarchive/archive_write_disk_posix.c | 121 +++++++++++++++++-----------------
12  1 file changed, 61 insertions(+), 60 deletions(-)
13
14 diff --git a/libarchive/archive_write_disk_posix.c b/libarchive/archive_write_disk_posix.c
15 index 17c23b0..d786bc2 100644
16 --- a/libarchive/archive_write_disk_posix.c
17 +++ b/libarchive/archive_write_disk_posix.c
18 @@ -336,6 +336,8 @@ struct archive_write_disk {
19  
20  #define HFS_BLOCKS(s)  ((s) >> 12)
21  
22 +static void    fsobj_error(int *, struct archive_string *, int, const char *,
23 +                   const char *);
24  static int     check_symlinks_fsobj(char *path, int *error_number, struct archive_string *error_string, int flags);
25  static int     check_symlinks(struct archive_write_disk *);
26  static int     create_filesystem_object(struct archive_write_disk *);
27 @@ -2005,8 +2007,9 @@ restore_entry(struct archive_write_disk *a)
28  
29         if (en) {
30                 /* Everything failed; give up here. */
31 -               archive_set_error(&a->archive, en, "Can't create '%s'",
32 -                   a->name);
33 +               if ((&a->archive)->error == NULL)
34 +                       archive_set_error(&a->archive, en, "Can't create '%s'",
35 +                           a->name);
36                 return (ARCHIVE_FAILED);
37         }
38  
39 @@ -2388,6 +2391,17 @@ current_fixup(struct archive_write_disk *a, const char *pathname)
40         return (a->current_fixup);
41  }
42  
43 +/* Error helper for new *_fsobj functions */
44 +static void
45 +fsobj_error(int *a_eno, struct archive_string *a_estr,
46 +    int err, const char *errstr, const char *path)
47 +{
48 +       if (a_eno)
49 +               *a_eno = err;
50 +       if (a_estr)
51 +               archive_string_sprintf(a_estr, errstr, path);
52 +}
53 +
54  /*
55   * TODO: Someday, integrate this with the deep dir support; they both
56   * scan the path and both can be optimized by comparing against other
57 @@ -2400,7 +2414,7 @@ current_fixup(struct archive_write_disk *a, const char *pathname)
58   * ARCHIVE_OK if there are none, otherwise puts an error in errmsg.
59   */
60  static int
61 -check_symlinks_fsobj(char *path, int *error_number, struct archive_string *error_string, int flags)
62 +check_symlinks_fsobj(char *path, int *a_eno, struct archive_string *a_estr, int flags)
63  {
64  #if !defined(HAVE_LSTAT)
65         /* Platform doesn't have lstat, so we can't look for symlinks. */
66 @@ -2474,19 +2488,20 @@ check_symlinks_fsobj(char *path, int *error_number, struct archive_string *error
67                         if (errno == ENOENT) {
68                                 break;
69                         } else {
70 -                               /* Treat any other error as fatal - best to be paranoid here
71 -                                * Note: This effectively disables deep directory
72 -                                * support when security checks are enabled.
73 -                                * Otherwise, very long pathnames that trigger
74 -                                * an error here could evade the sandbox.
75 -                                * TODO: We could do better, but it would probably
76 -                                * require merging the symlink checks with the
77 -                                * deep-directory editing. */
78 -                               if (error_number) *error_number = errno;
79 -                               if (error_string)
80 -                                       archive_string_sprintf(error_string,
81 -                                                       "Could not stat %s",
82 -                                                       path);
83 +                               /*
84 +                                * Treat any other error as fatal - best to be
85 +                                * paranoid here.
86 +                                * Note: This effectively disables deep
87 +                                * directory support when security checks are
88 +                                * enabled. Otherwise, very long pathnames that
89 +                                * trigger an error here could evade the
90 +                                * sandbox.
91 +                                * TODO: We could do better, but it would
92 +                                * probably require merging the symlink checks
93 +                                * with the deep-directory editing.
94 +                                */
95 +                               fsobj_error(a_eno, a_estr, errno,
96 +                                   "Could not stat %s", path);
97                                 res = ARCHIVE_FAILED;
98                                 break;
99                         }
100 @@ -2494,11 +2509,8 @@ check_symlinks_fsobj(char *path, int *error_number, struct archive_string *error
101                         if (!last) {
102                                 if (chdir(head) != 0) {
103                                         tail[0] = c;
104 -                                       if (error_number) *error_number = errno;
105 -                                       if (error_string)
106 -                                               archive_string_sprintf(error_string,
107 -                                                               "Could not chdir %s",
108 -                                                               path);
109 +                                       fsobj_error(a_eno, a_estr, errno,
110 +                                           "Could not chdir %s", path);
111                                         res = (ARCHIVE_FATAL);
112                                         break;
113                                 }
114 @@ -2514,11 +2526,9 @@ check_symlinks_fsobj(char *path, int *error_number, struct archive_string *error
115                                  */
116                                 if (unlink(head)) {
117                                         tail[0] = c;
118 -                                       if (error_number) *error_number = errno;
119 -                                       if (error_string)
120 -                                               archive_string_sprintf(error_string,
121 -                                                               "Could not remove symlink %s",
122 -                                                               path);
123 +                                       fsobj_error(a_eno, a_estr, errno,
124 +                                           "Could not remove symlink %s",
125 +                                           path);
126                                         res = ARCHIVE_FAILED;
127                                         break;
128                                 }
129 @@ -2529,13 +2539,14 @@ check_symlinks_fsobj(char *path, int *error_number, struct archive_string *error
130                                  * symlink with another symlink.
131                                  */
132                                 tail[0] = c;
133 -                               /* FIXME:  not sure how important this is to restore
134 +                               /*
135 +                                * FIXME:  not sure how important this is to
136 +                                * restore
137 +                                */
138 +                               /*
139                                 if (!S_ISLNK(path)) {
140 -                                       if (error_number) *error_number = 0;
141 -                                       if (error_string)
142 -                                               archive_string_sprintf(error_string,
143 -                                                               "Removing symlink %s",
144 -                                                               path);
145 +                                       fsobj_error(a_eno, a_estr, 0,
146 +                                           "Removing symlink %s", path);
147                                 }
148                                 */
149                                 /* Symlink gone.  No more problem! */
150 @@ -2545,22 +2556,17 @@ check_symlinks_fsobj(char *path, int *error_number, struct archive_string *error
151                                 /* User asked us to remove problems. */
152                                 if (unlink(head) != 0) {
153                                         tail[0] = c;
154 -                                       if (error_number) *error_number = 0;
155 -                                       if (error_string)
156 -                                               archive_string_sprintf(error_string,
157 -                                                               "Cannot remove intervening symlink %s",
158 -                                                               path);
159 +                                       fsobj_error(a_eno, a_estr, 0,
160 +                                           "Cannot remove intervening "
161 +                                           "symlink %s", path);
162                                         res = ARCHIVE_FAILED;
163                                         break;
164                                 }
165                                 tail[0] = c;
166                         } else {
167                                 tail[0] = c;
168 -                               if (error_number) *error_number = 0;
169 -                               if (error_string)
170 -                                       archive_string_sprintf(error_string,
171 -                                                       "Cannot extract through symlink %s",
172 -                                                       path);
173 +                               fsobj_error(a_eno, a_estr, 0,
174 +                                   "Cannot extract through symlink %s", path);
175                                 res = ARCHIVE_FAILED;
176                                 break;
177                         }
178 @@ -2577,10 +2583,8 @@ check_symlinks_fsobj(char *path, int *error_number, struct archive_string *error
179         if (restore_pwd >= 0) {
180                 r = fchdir(restore_pwd);
181                 if (r != 0) {
182 -                       if(error_number) *error_number = errno;
183 -                       if(error_string)
184 -                               archive_string_sprintf(error_string,
185 -                                               "chdir() failure");
186 +                       fsobj_error(a_eno, a_estr, errno,
187 +                           "chdir() failure", "");
188                 }
189                 close(restore_pwd);
190                 restore_pwd = -1;
191 @@ -2688,17 +2692,16 @@ cleanup_pathname_win(struct archive_write_disk *a)
192   * is set) if the path is absolute.
193   */
194  static int
195 -cleanup_pathname_fsobj(char *path, int *error_number, struct archive_string *error_string, int flags)
196 +cleanup_pathname_fsobj(char *path, int *a_eno, struct archive_string *a_estr,
197 +    int flags)
198  {
199         char *dest, *src;
200         char separator = '\0';
201  
202         dest = src = path;
203         if (*src == '\0') {
204 -               if (error_number) *error_number = ARCHIVE_ERRNO_MISC;
205 -               if (error_string)
206 -                   archive_string_sprintf(error_string,
207 -                           "Invalid empty pathname");
208 +               fsobj_error(a_eno, a_estr, ARCHIVE_ERRNO_MISC,
209 +                   "Invalid empty ", "pathname");
210                 return (ARCHIVE_FAILED);
211         }
212  
213 @@ -2708,10 +2711,8 @@ cleanup_pathname_fsobj(char *path, int *error_number, struct archive_string *err
214         /* Skip leading '/'. */
215         if (*src == '/') {
216                 if (flags & ARCHIVE_EXTRACT_SECURE_NOABSOLUTEPATHS) {
217 -                       if (error_number) *error_number = ARCHIVE_ERRNO_MISC;
218 -                       if (error_string)
219 -                           archive_string_sprintf(error_string,
220 -                                   "Path is absolute");
221 +                       fsobj_error(a_eno, a_estr, ARCHIVE_ERRNO_MISC,
222 +                           "Path is ", "absolute");
223                         return (ARCHIVE_FAILED);
224                 }
225  
226 @@ -2738,11 +2739,11 @@ cleanup_pathname_fsobj(char *path, int *error_number, struct archive_string *err
227                         } else if (src[1] == '.') {
228                                 if (src[2] == '/' || src[2] == '\0') {
229                                         /* Conditionally warn about '..' */
230 -                                       if (flags & ARCHIVE_EXTRACT_SECURE_NODOTDOT) {
231 -                                               if (error_number) *error_number = ARCHIVE_ERRNO_MISC;
232 -                                               if (error_string)
233 -                                                   archive_string_sprintf(error_string,
234 -                                                           "Path contains '..'");
235 +                                       if (flags
236 +                                           & ARCHIVE_EXTRACT_SECURE_NODOTDOT) {
237 +                                               fsobj_error(a_eno, a_estr,
238 +                                                   ARCHIVE_ERRNO_MISC,
239 +                                                   "Path contains ", "'..'");
240                                                 return (ARCHIVE_FAILED);
241                                         }
242                                 }
243 -- 
244 2.7.4
245