Sat May 2 16:19:36 2009 UTC ()
easier done with a goto instead of closing in each error.


(christos)
diff -r1.10 -r1.11 src/usr.sbin/paxctl/paxctl.c

cvs diff -r1.10 -r1.11 src/usr.sbin/paxctl/paxctl.c (expand / switch to unified diff)

--- src/usr.sbin/paxctl/paxctl.c 2009/05/02 06:01:30 1.10
+++ src/usr.sbin/paxctl/paxctl.c 2009/05/02 16:19:36 1.11
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: paxctl.c,v 1.10 2009/05/02 06:01:30 elad Exp $ */ 1/* $NetBSD: paxctl.c,v 1.11 2009/05/02 16:19:36 christos Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2006 Elad Efrat <elad@NetBSD.org> 4 * Copyright (c) 2006 Elad Efrat <elad@NetBSD.org>
5 * Copyright (c) 2008 Christos Zoulas <christos@NetBSD.org> 5 * Copyright (c) 2008 Christos Zoulas <christos@NetBSD.org>
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 9 * modification, are permitted provided that the following conditions
10 * are met: 10 * are met:
11 * 1. Redistributions of source code must retain the above copyright 11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer. 12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
@@ -24,27 +24,27 @@ @@ -24,27 +24,27 @@
24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */ 29 */
30#if HAVE_NBTOOL_CONFIG_H 30#if HAVE_NBTOOL_CONFIG_H
31#include "nbtool_config.h" 31#include "nbtool_config.h"
32#endif 32#endif
33 33
34#include <sys/cdefs.h> 34#include <sys/cdefs.h>
35#ifndef lint 35#ifndef lint
36#ifdef __RCSID 36#ifdef __RCSID
37__RCSID("$NetBSD: paxctl.c,v 1.10 2009/05/02 06:01:30 elad Exp $"); 37__RCSID("$NetBSD: paxctl.c,v 1.11 2009/05/02 16:19:36 christos Exp $");
38#endif 38#endif
39#endif /* not lint */ 39#endif /* not lint */
40 40
41#include <sys/types.h> 41#include <sys/types.h>
42#ifdef HAVE_NBTOOL_CONFIG_H 42#ifdef HAVE_NBTOOL_CONFIG_H
43#include "../../sys/sys/exec_elf.h" 43#include "../../sys/sys/exec_elf.h"
44#else 44#else
45#include <elf.h> 45#include <elf.h>
46#endif 46#endif
47#include <stdio.h> 47#include <stdio.h>
48#include <err.h> 48#include <err.h>
49#include <fcntl.h> 49#include <fcntl.h>
50#include <unistd.h> 50#include <unistd.h>
@@ -183,151 +183,142 @@ process_one(const char *name, uint32_t a @@ -183,151 +183,142 @@ process_one(const char *name, uint32_t a
183 /*LINTED*/(sizeof(a) == 1 ? (a) : \ 183 /*LINTED*/(sizeof(a) == 1 ? (a) : \
184 /*LINTED*/(sizeof(a) == 2 ? bswap16(a) : \ 184 /*LINTED*/(sizeof(a) == 2 ? bswap16(a) : \
185 /*LINTED*/(sizeof(a) == 4 ? bswap32(a) : \ 185 /*LINTED*/(sizeof(a) == 4 ? bswap32(a) : \
186 /*LINTED*/(sizeof(a) == 8 ? bswap64(a) : (abort(), (a))))))) 186 /*LINTED*/(sizeof(a) == 8 ? bswap64(a) : (abort(), (a)))))))
187#define EH(field) (size == 32 ? SWAP(e.h32.field) : SWAP(e.h64.field)) 187#define EH(field) (size == 32 ? SWAP(e.h32.field) : SWAP(e.h64.field))
188#define PH(field) (size == 32 ? SWAP(p.h32.field) : SWAP(p.h64.field)) 188#define PH(field) (size == 32 ? SWAP(p.h32.field) : SWAP(p.h64.field))
189#define NH(field) (size == 32 ? SWAP(n.h32.field) : SWAP(n.h64.field)) 189#define NH(field) (size == 32 ? SWAP(n.h32.field) : SWAP(n.h64.field))
190#define PHSIZE (size == 32 ? sizeof(p.h32) : sizeof(p.h64)) 190#define PHSIZE (size == 32 ? sizeof(p.h32) : sizeof(p.h64))
191#define NHSIZE (size == 32 ? sizeof(n.h32) : sizeof(n.h64)) 191#define NHSIZE (size == 32 ? sizeof(n.h32) : sizeof(n.h64))
192 struct { 192 struct {
193 char name[ELF_NOTE_PAX_NAMESZ]; 193 char name[ELF_NOTE_PAX_NAMESZ];
194 uint32_t flags; 194 uint32_t flags;
195 } pax_tag; 195 } pax_tag;
196 int fd, size, ok = 0, flagged = 0, swap; 196 int fd, size, ok = 0, flagged = 0, swap, error = 1;
197 size_t i; 197 size_t i;
198 198
199 fd = open(name, list ? O_RDONLY: O_RDWR, 0); 199 fd = open(name, list ? O_RDONLY: O_RDWR, 0);
200 if (fd == -1) { 200 if (fd == -1) {
201 warn("Can't open `%s'", name); 201 warn("Can't open `%s'", name);
202 return 1; 202 return error;
203 } 203 }
204 204
205 if (read(fd, &e, sizeof(e)) != sizeof(e)) { 205 if (read(fd, &e, sizeof(e)) != sizeof(e)) {
206 warn("Can't read ELF header from `%s'", name); 206 warn("Can't read ELF header from `%s'", name);
207 (void)close(fd); 207 goto out;
208 return 1; 
209 } 208 }
210 209
211 if (memcmp(e.h32.e_ident, ELFMAG, SELFMAG) != 0) { 210 if (memcmp(e.h32.e_ident, ELFMAG, SELFMAG) != 0) {
212 warnx("Bad ELF magic from `%s' (maybe it's not an ELF?)", name); 211 warnx("Bad ELF magic from `%s' (maybe it's not an ELF?)", name);
213 (void)close(fd); 212 goto out;
214 return 1; 
215 } 213 }
216 214
217 if (e.h32.e_ehsize == sizeof(e.h32)) { 215 if (e.h32.e_ehsize == sizeof(e.h32)) {
218 size = 32; 216 size = 32;
219 swap = 0; 217 swap = 0;
220 } else if (e.h64.e_ehsize == sizeof(e.h64)) { 218 } else if (e.h64.e_ehsize == sizeof(e.h64)) {
221 size = 64; 219 size = 64;
222 swap = 0; 220 swap = 0;
223 } else if (bswap16(e.h32.e_ehsize) == sizeof(e.h32)) { 221 } else if (bswap16(e.h32.e_ehsize) == sizeof(e.h32)) {
224 size = 32; 222 size = 32;
225 swap = 1; 223 swap = 1;
226 } else if (bswap16(e.h64.e_ehsize) == sizeof(e.h64)) { 224 } else if (bswap16(e.h64.e_ehsize) == sizeof(e.h64)) {
227 size = 64; 225 size = 64;
228 swap = 1; 226 swap = 1;
229 } else { 227 } else {
230 warnx("Bad ELF size %d from `%s' (maybe it's not an ELF?)", 228 warnx("Bad ELF size %d from `%s' (maybe it's not an ELF?)",
231 (int)e.h32.e_ehsize, name); 229 (int)e.h32.e_ehsize, name);
232 (void)close(fd); 230 goto out;
233 return 1; 
234 } 231 }
235 232
236 for (i = 0; i < EH(e_phnum); i++) { 233 for (i = 0; i < EH(e_phnum); i++) {
237 if ((size_t)pread(fd, &p, PHSIZE, (off_t)EH(e_phoff) + i * PHSIZE) != 234 if ((size_t)pread(fd, &p, PHSIZE,
238 PHSIZE) { 235 (off_t)EH(e_phoff) + i * PHSIZE) != PHSIZE) {
239 warn("Can't read program header data from `%s'", name); 236 warn("Can't read program header data from `%s'", name);
240 (void)close(fd); 237 goto out;
241 return 1; 
242 } 238 }
243 239
244 if (PH(p_type) != PT_NOTE) 240 if (PH(p_type) != PT_NOTE)
245 continue; 241 continue;
246 242
247 if (pread(fd, &n, NHSIZE, (off_t)PH(p_offset)) != NHSIZE) { 243 if (pread(fd, &n, NHSIZE, (off_t)PH(p_offset)) != NHSIZE) {
248 warn("Can't read note header from `%s'", name); 244 warn("Can't read note header from `%s'", name);
249 (void)close(fd); 245 goto out;
250 return 1; 
251 } 246 }
252 if (NH(n_type) != ELF_NOTE_TYPE_PAX_TAG || 247 if (NH(n_type) != ELF_NOTE_TYPE_PAX_TAG ||
253 NH(n_descsz) != ELF_NOTE_PAX_DESCSZ || 248 NH(n_descsz) != ELF_NOTE_PAX_DESCSZ ||
254 NH(n_namesz) != ELF_NOTE_PAX_NAMESZ) 249 NH(n_namesz) != ELF_NOTE_PAX_NAMESZ)
255 continue; 250 continue;
256 if (pread(fd, &pax_tag, sizeof(pax_tag), PH(p_offset) + NHSIZE) 251 if (pread(fd, &pax_tag, sizeof(pax_tag), PH(p_offset) + NHSIZE)
257 != sizeof(pax_tag)) { 252 != sizeof(pax_tag)) {
258 warn("Can't read pax_tag from `%s'", name); 253 warn("Can't read pax_tag from `%s'", name);
259 (void)close(fd); 254 goto out;
260 return 1; 
261 } 255 }
262 if (memcmp(pax_tag.name, ELF_NOTE_PAX_NAME, 256 if (memcmp(pax_tag.name, ELF_NOTE_PAX_NAME,
263 sizeof(pax_tag.name)) != 0) { 257 sizeof(pax_tag.name)) != 0) {
264 warn("Unknown pax_tag name `%*.*s' from `%s'", 258 warn("Unknown pax_tag name `%*.*s' from `%s'",
265 ELF_NOTE_PAX_NAMESZ, ELF_NOTE_PAX_NAMESZ, 259 ELF_NOTE_PAX_NAMESZ, ELF_NOTE_PAX_NAMESZ,
266 pax_tag.name, name); 260 pax_tag.name, name);
267 (void)close(fd); 261 goto out;
268 return 1; 
269 } 262 }
270 ok = 1; 263 ok = 1;
271 264
272 if (list) { 265 if (list) {
273 if (!pax_haveflags(SWAP(pax_tag.flags))) 266 if (!pax_haveflags(SWAP(pax_tag.flags)))
274 break; 267 break;
275 268
276 if (!pax_flags_sane(SWAP(pax_tag.flags))) 269 if (!pax_flags_sane(SWAP(pax_tag.flags)))
277 warnx("Current flags 0x%x don't make sense", 270 warnx("Current flags 0x%x don't make sense",
278 (uint32_t)SWAP(pax_tag.flags)); 271 (uint32_t)SWAP(pax_tag.flags));
279 272
280 if (many) 273 if (many)
281 (void)printf("%s: ", name); 274 (void)printf("%s: ", name);
282 (void)printf("PaX flags:\n"); 275 (void)printf("PaX flags:\n");
283 276
284 pax_printflags(name, many, SWAP(pax_tag.flags)); 277 pax_printflags(name, many, SWAP(pax_tag.flags));
285 
286 flagged = 1; 278 flagged = 1;
287 
288 break; 279 break;
289 } 280 }
290 281
291 pax_tag.flags |= SWAP(add_flags); 282 pax_tag.flags |= SWAP(add_flags);
292 pax_tag.flags &= SWAP(~del_flags); 283 pax_tag.flags &= SWAP(~del_flags);
293 284
294 if (!pax_flags_sane(SWAP(pax_tag.flags))) { 285 if (!pax_flags_sane(SWAP(pax_tag.flags))) {
295 warnx("New flags 0x%x don't make sense", 286 warnx("New flags 0x%x don't make sense",
296 (uint32_t)SWAP(pax_tag.flags)); 287 (uint32_t)SWAP(pax_tag.flags));
297 (void)close(fd); 288 goto out;
298 return 1; 
299 } 289 }
300 290
301 if (pwrite(fd, &pax_tag, sizeof(pax_tag), 291 if (pwrite(fd, &pax_tag, sizeof(pax_tag),
302 (off_t)PH(p_offset) + NHSIZE) != sizeof(pax_tag)) 292 (off_t)PH(p_offset) + NHSIZE) != sizeof(pax_tag))
303 warn("Can't modify flags on `%s'", name); 293 warn("Can't modify flags on `%s'", name);
304 break; 294 break;
305 } 295 }
306 296
307 (void)close(fd); 
308 
309 if (!ok) { 297 if (!ok) {
310 warnx("Could not find an ELF PaX PT_NOTE section in `%s'", 298 warnx("Could not find an ELF PaX PT_NOTE section in `%s'",
311 name); 299 name);
312 return 1; 300 goto out;
313 } 301 }
314 302
 303 error = 0;
315 if (list && !flagged) { 304 if (list && !flagged) {
316 if (many) 305 if (many)
317 (void)printf("%s: ", name); 306 (void)printf("%s: ", name);
318 (void)printf("No PaX flags.\n"); 307 (void)printf("No PaX flags.\n");
319 } 308 }
320 return 0; 309out:
 310 (void)close(fd);
 311 return error;
321} 312}
322 313
323int 314int
324main(int argc, char **argv) 315main(int argc, char **argv)
325{ 316{
326 char *opt; 317 char *opt;
327 int i, list = 0, bad = 0, many, minus; 318 int i, list = 0, bad = 0, many, minus;
328 uint32_t add_flags = 0, del_flags = 0; 319 uint32_t add_flags = 0, del_flags = 0;
329 320
330 setprogname(argv[0]); 321 setprogname(argv[0]);
331 322
332 if (argc < 2) 323 if (argc < 2)
333 usage(); 324 usage();