diff options
-rw-r--r-- | trunk/ChangeLog | 16 | ||||
-rw-r--r-- | trunk/src/dso.c | 68 | ||||
-rw-r--r-- | trunk/src/execstack.c | 8 | ||||
-rw-r--r-- | trunk/src/prelink.h | 3 | ||||
-rw-r--r-- | trunk/src/undo.c | 8 | ||||
-rw-r--r-- | trunk/src/verify.c | 10 |
6 files changed, 95 insertions, 18 deletions
diff --git a/trunk/ChangeLog b/trunk/ChangeLog index cf7a444..cc0ef4d 100644 --- a/trunk/ChangeLog +++ b/trunk/ChangeLog @@ -1,3 +1,19 @@ +2010-04-13 Jakub Jelinek <jakub@redhat.com> + + * src/prelink.h (send_file): New prototype. + * src/execstack.c (send_file): New dummy function. + * src/verify.c (send_file): No longer static. Don't loop forever + if write or read return 0. + * src/undo.c (prelink_undo): If undo_output is -, use /tmp/undo + instead of - as temp file prefix. + * src/dso.c (set_security_context): Drop unused dso argument, add + ignore_errors argument. If it is non-zero, don't error if + setfilecon failed. + (update_dso): If orig_name is non-NULL, don't error if fchown or + fchmod fails. If rename fails or name1 is - and orig_name is + non-NULL, copy the temporary file to name1 (or to stdout if + name1 is -) instead of failing. + 2010-01-06 Jakub Jelinek <jakub@redhat.com> * src/arch-s390.c (s390_prelink_conflict_rela) <case R_390_PC32DBL>: diff --git a/trunk/src/dso.c b/trunk/src/dso.c index c12997b..afafe64 100644 --- a/trunk/src/dso.c +++ b/trunk/src/dso.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 Red Hat, Inc. +/* Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2010 Red Hat, Inc. Written by Jakub Jelinek <jakub@redhat.com>, 2001. This program is free software; you can redistribute it and/or modify @@ -1694,8 +1694,9 @@ write_dso (DSO *dso) return 0; } -int -set_security_context (DSO *dso, const char *temp_name, const char *name) +static int +set_security_context (const char *temp_name, const char *name, + int ignore_errors) { #ifdef USE_SELINUX static int selinux_enabled = -1; @@ -1716,7 +1717,7 @@ set_security_context (DSO *dso, const char *temp_name, const char *name) name); return 1; } - if (setfilecon (temp_name, scontext) < 0) + if (setfilecon (temp_name, scontext) < 0 && !ignore_errors) { error (0, errno, "Could not set security context for %s", name); @@ -1739,6 +1740,7 @@ update_dso (DSO *dso, const char *orig_name) char *name1, *name2; struct utimbuf u; struct stat64 st; + int fdin, fdout; switch (write_dso (dso)) { @@ -1761,30 +1763,80 @@ update_dso (DSO *dso, const char *orig_name) close_dso (dso); return 1; } - if (fchown (dso->fd, st.st_uid, st.st_gid) < 0 - || fchmod (dso->fd, st.st_mode & 07777) < 0) + if ((fchown (dso->fd, st.st_uid, st.st_gid) < 0 + || fchmod (dso->fd, st.st_mode & 07777) < 0) + && orig_name == NULL) { error (0, errno, "Could not set %s owner or mode", dso->filename); close_dso (dso); return 1; } + if (orig_name != NULL) + fdin = dup (dso->fd); + else + fdin = -1; close_dso_1 (dso); u.actime = time (NULL); u.modtime = st.st_mtime; utime (name2, &u); - if (set_security_context (dso, name2, orig_name ? orig_name : name1)) + if (set_security_context (name2, orig_name ? orig_name : name1, + orig_name != NULL)) { + if (fdin != -1) + close (fdin); unlink (name2); return 1; } - if (rename (name2, name1)) + if ((orig_name != NULL && strcmp (name1, "-") == 0) + || rename (name2, name1)) { + if (fdin != -1) + { + struct stat64 stt; + off_t off = 0; + int err; + if (strcmp (name1, "-") == 0) + fdout = 1; + else + fdout = open (name1, O_WRONLY | O_CREAT, 0600); + if (fdout != -1 + && fstat64 (fdin, &stt) >= 0 + && send_file (fdout, fdin, &off, stt.st_size) == stt.st_size) + { + close (fdin); + if (fchown (fdout, st.st_uid, st.st_gid) >= 0) + fchmod (fdout, st.st_mode & 07777); + if (strcmp (name1, "-") != 0) + { + set_security_context (name1, name1, 1); + utime (name1, &u); + close (fdout); + } + unlink (name2); + return 0; + } + else if (fdout != -1) + { + err = errno; + if (strcmp (name1, "-") == 0) + close (fdout); + } + else + err = errno; + close (fdin); + unlink (name2); + error (0, err, "Could not rename nor copy temporary to %s", + name1); + return 1; + } unlink (name2); error (0, errno, "Could not rename temporary to %s", name1); return 1; } + if (fdin != -1) + close (fdin); } else close_dso_1 (dso); diff --git a/trunk/src/execstack.c b/trunk/src/execstack.c index 1e50aad..2f503ba 100644 --- a/trunk/src/execstack.c +++ b/trunk/src/execstack.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2003, 2005 Red Hat, Inc. +/* Copyright (C) 2003, 2005, 2010 Red Hat, Inc. Written by Jakub Jelinek <jakub@redhat.com>, 2003. This program is free software; you can redistribute it and/or modify @@ -454,6 +454,12 @@ prelink_conflict_add_rela (struct prelink_info *info) abort (); } +ssize_t +send_file (int outfd, int infd, off_t *poff, size_t count) +{ + abort (); +} + GElf_Addr mmap_reg_start; GElf_Addr mmap_reg_end; int exec_shield; diff --git a/trunk/src/prelink.h b/trunk/src/prelink.h index 8fcb599..8849539 100644 --- a/trunk/src/prelink.h +++ b/trunk/src/prelink.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009 +/* Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009, 2010 Red Hat, Inc. Written by Jakub Jelinek <jakub@redhat.com>, 2001. @@ -494,6 +494,7 @@ int is_ldso_soname (const char *soname); int prelink_undo (DSO *dso); int prelink_verify (const char *filename); +ssize_t send_file (int outfd, int infd, off_t *poff, size_t count); int gather_object (const char *dir, int deref, int onefs); int read_config (const char *config); diff --git a/trunk/src/undo.c b/trunk/src/undo.c index accbbfb..4d1332c 100644 --- a/trunk/src/undo.c +++ b/trunk/src/undo.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001, 2002, 2003, 2005 Red Hat, Inc. +/* Copyright (C) 2001, 2002, 2003, 2005, 2010 Red Hat, Inc. Written by Jakub Jelinek <jakub@redhat.com>, 2001. This program is free software; you can redistribute it and/or modify @@ -500,7 +500,8 @@ prelink_undo (DSO *dso) if (undo == dso->ehdr.e_shnum) { if (undo_output) - return reopen_dso (dso, NULL, undo_output); + return reopen_dso (dso, NULL, strcmp (undo_output, "-") == 0 + ? "/tmp/undo" : undo_output); error (0, 0, "%s does not have .gnu.prelink_undo section", dso->filename); return 1; } @@ -516,7 +517,8 @@ prelink_undo (DSO *dso) if (undo_sections (dso, undo, move, &rinfo, &ehdr, phdr, shdr)) goto error_out; - if (reopen_dso (dso, move, undo_output)) + if (reopen_dso (dso, move, (undo_output && strcmp (undo_output, "-") == 0) + ? "/tmp/undo" : undo_output)) goto error_out; if (find_reloc_sections (dso, &rinfo)) diff --git a/trunk/src/verify.c b/trunk/src/verify.c index 7abc945..15cbd0e 100644 --- a/trunk/src/verify.c +++ b/trunk/src/verify.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002, 2003, 2006, 2007 Red Hat, Inc. +/* Copyright (C) 2002, 2003, 2006, 2007, 2010 Red Hat, Inc. Written by Jakub Jelinek <jakub@redhat.com>, 2002. This program is free software; you can redistribute it and/or modify @@ -30,7 +30,7 @@ #include "md5.h" #include "sha.h" -static ssize_t +ssize_t send_file (int outfd, int infd, off_t *poff, size_t count) { char buf[65536], *b, *p, *q; @@ -45,7 +45,7 @@ send_file (int outfd, int infd, off_t *poff, size_t count) while (p != q) { n = TEMP_FAILURE_RETRY (write (outfd, p, q - p)); - if (n < 0) + if (n <= 0) { munmap (b, count); return -1; @@ -66,7 +66,7 @@ send_file (int outfd, int infd, off_t *poff, size_t count) while (p != q) { n = TEMP_FAILURE_RETRY (read (infd, p, q - p)); - if (n < 0) + if (n <= 0) return -1; p += n; } @@ -74,7 +74,7 @@ send_file (int outfd, int infd, off_t *poff, size_t count) while (p != q) { n = TEMP_FAILURE_RETRY (write (outfd, p, q - p)); - if (n < 0) + if (n <= 0) return -1; p += n; } |