summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--trunk/ChangeLog16
-rw-r--r--trunk/src/dso.c68
-rw-r--r--trunk/src/execstack.c8
-rw-r--r--trunk/src/prelink.h3
-rw-r--r--trunk/src/undo.c8
-rw-r--r--trunk/src/verify.c10
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;
}