RPM Package Manager, CVS Repository
http://rpm5.org/cvs/
____________________________________________________________________________
Server: rpm5.org Name: Anders F. Björklund
Root: /v/rpm/cvs Email: afb@rpm5.org
Module: xar Date: 29-Sep-2007 14:29:44
Branch: HEAD Handle: 2007092913294301
Modified files:
xar ChangeLog
xar/include xar.h.in
xar/lib io.c stat.c
xar/src xar.1 xar.c
Log:
inode/device and setuid/setgid fixes (from upstream)
Summary:
Revision Changes Path
1.3 +6 -0 xar/ChangeLog
1.4 +4 -0 xar/include/xar.h.in
1.4 +43 -73 xar/lib/io.c
1.5 +17 -2 xar/lib/stat.c
1.5 +13 -3 xar/src/xar.1
1.9 +9 -0 xar/src/xar.c
____________________________________________________________________________
patch -p0 <<'@@ .'
Index: xar/ChangeLog
============================================================================
$ cvs diff -u -r1.2 -r1.3 ChangeLog
--- xar/ChangeLog 21 Sep 2007 12:00:58 -0000 1.2
+++ xar/ChangeLog 29 Sep 2007 12:29:43 -0000 1.3
@@ -1,4 +1,10 @@
devel
+ 2007-09-26 Rob Braun bbraun@synack.net
+ * lib/io.c: Consolidate the lseek handling code into one function.
+ Contributed by Charles Srstka as part of Issue 2.
+ 2007-09-21 Rob Braun bbraun@synack.net
+ * include/xar.h.in src/xar.c src/xar.1 lib/stat.c: Only extract setuid/setgid bits if the user/group are the same as the archived file (if -p/-P are specified on the command line) OR if the newly added --keep-setuid flag is specified.
+ * configure.ac lib/stat.c: Fix the autoconf test for ino_t size, and switch the inode and device number printf's to use the autogenerated INO_STRING and DEV_STRING to get the correct formatting parameter.
2007-09-20 Rob Braun bbraun@synack.net
* src/xar.c src/xar.1: Add -k as a synonym for --keep-existing for tar compatibility.
2007-09-20 Rob Braun bbraun@synack.net
@@ .
patch -p0 <<'@@ .'
Index: xar/include/xar.h.in
============================================================================
$ cvs diff -u -r1.3 -r1.4 xar.h.in
--- xar/include/xar.h.in 21 Sep 2007 11:55:42 -0000 1.3
+++ xar/include/xar.h.in 29 Sep 2007 12:29:43 -0000 1.4
@@ -101,6 +101,10 @@
#define XAR_OPT_PROPINCLUDE "prop-include" /* File property to include */
#define XAR_OPT_PROPEXCLUDE "prop-exclude" /* File property to exclude */
+#define XAR_OPT_SAVESUID "savesuid" /* Preserve setuid/setgid bits */
+#define XAR_OPT_VAL_TRUE "true"
+#define XAR_OPT_VAL_FALSE "false"
+
/* xar signing algorithms */
#define XAR_SIG_SHA1RSA 1
@@ .
patch -p0 <<'@@ .'
Index: xar/lib/io.c
============================================================================
$ cvs diff -u -r1.3 -r1.4 io.c
--- xar/lib/io.c 19 Sep 2007 22:14:01 -0000 1.3
+++ xar/lib/io.c 29 Sep 2007 12:29:43 -0000 1.4
@@ -108,6 +108,47 @@
}
};
+static void xar_io_seek(xar_t x, xar_file_t f, off_t seekoff) {
+ int r;
+
+ if( XAR(x)->fd > 1 ) {
+ r = lseek(XAR(x)->fd, seekoff, SEEK_SET);
+ if( r == -1 ) {
+ if( errno == ESPIPE ) {
+ ssize_t rr;
+ char *buf;
+ unsigned int len;
+
+ len = seekoff - XAR(x)->toc_count;
+ len -= sizeof(xar_header_t);
+ if( XAR(x)->heap_offset > len ) {
+ xar_err_new(x);
+ xar_err_set_file(x, f);
+ xar_err_set_string(x, "Unable to seek");
+ xar_err_callback(x, XAR_SEVERITY_NONFATAL, XAR_ERR_ARCHIVE_EXTRACTION);
+ } else {
+ len -= XAR(x)->heap_offset;
+ buf = malloc(len);
+ assert(buf);
+ rr = read(XAR(x)->fd, buf, len);
+ if( rr < len ) {
+ xar_err_new(x);
+ xar_err_set_file(x, f);
+ xar_err_set_string(x, "Unable to seek");
+ xar_err_callback(x, XAR_SEVERITY_NONFATAL, XAR_ERR_ARCHIVE_EXTRACTION);
+ }
+ free(buf);
+ }
+ } else {
+ xar_err_new(x);
+ xar_err_set_file(x, f);
+ xar_err_set_string(x, "Unable to seek");
+ xar_err_callback(x, XAR_SEVERITY_NONFATAL, XAR_ERR_ARCHIVE_EXTRACTION);
+ }
+ }
+ }
+}
+
int32_t xar_attrcopy_to_heap(xar_t x, xar_file_t f, xar_prop_t p, read_callback rcb, void *context) {
int modulecount = (sizeof(xar_datamods)/sizeof(struct datamod));
void *modulecontext[modulecount];
@@ -320,42 +361,7 @@
}
seekoff += XAR(x)->toc_count + sizeof(xar_header_t);
- if( XAR(x)->fd > 1 ) {
- r = lseek(XAR(x)->fd, seekoff, SEEK_SET);
- if( r == -1 ) {
- if( errno == ESPIPE ) {
- ssize_t rr;
- char *buf;
- unsigned int len;
-
- len = seekoff - XAR(x)->toc_count;
- len -= sizeof(xar_header_t);
- if( XAR(x)->heap_offset > len ) {
- xar_err_new(x);
- xar_err_set_file(x, f);
- xar_err_set_string(x, "Unable to seek");
- xar_err_callback(x, XAR_SEVERITY_NONFATAL, XAR_ERR_ARCHIVE_EXTRACTION);
- } else {
- len -= XAR(x)->heap_offset;
- buf = malloc(len);
- assert(buf);
- rr = read(XAR(x)->fd, buf, len);
- if( rr < len ) {
- xar_err_new(x);
- xar_err_set_file(x, f);
- xar_err_set_string(x, "Unable to seek");
- xar_err_callback(x, XAR_SEVERITY_NONFATAL, XAR_ERR_ARCHIVE_EXTRACTION);
- }
- free(buf);
- }
- } else {
- xar_err_new(x);
- xar_err_set_file(x, f);
- xar_err_set_string(x, "Unable to seek");
- xar_err_callback(x, XAR_SEVERITY_NONFATAL, XAR_ERR_ARCHIVE_EXTRACTION);
- }
- }
- }
+ xar_io_seek(x, f, seekoff);
opt = NULL;
tmpp = xar_prop_pget(p, "length");
@@ -475,43 +481,7 @@
}
seekoff += XAR(xsource)->toc_count + sizeof(xar_header_t);
-
- if( XAR(xsource)->fd > 1 ) {
- r = lseek(XAR(xsource)->fd, seekoff, SEEK_SET);
- if( r == -1 ) {
- if( errno == ESPIPE ) {
- ssize_t rr;
- char *buf;
- unsigned int len;
-
- len = seekoff - XAR(xsource)->toc_count;
- len -= sizeof(xar_header_t);
- if( XAR(xsource)->heap_offset > len ) {
- xar_err_new(xsource);
- xar_err_set_file(xsource, fsource);
- xar_err_set_string(xsource, "Unable to seek");
- xar_err_callback(xsource, XAR_SEVERITY_NONFATAL, XAR_ERR_ARCHIVE_EXTRACTION);
- } else {
- len -= XAR(xsource)->heap_offset;
- buf = malloc(len);
- assert(buf);
- rr = read(XAR(xsource)->fd, buf, len);
- if( rr < len ) {
- xar_err_new(xsource);
- xar_err_set_file(xsource, fsource);
- xar_err_set_string(xsource, "Unable to seek");
- xar_err_callback(xsource, XAR_SEVERITY_NONFATAL, XAR_ERR_ARCHIVE_EXTRACTION);
- }
- free(buf);
- }
- } else {
- xar_err_new(xsource);
- xar_err_set_file(xsource, fsource);
- xar_err_set_string(xsource, "Unable to seek");
- xar_err_callback(xsource, XAR_SEVERITY_NONFATAL, XAR_ERR_ARCHIVE_EXTRACTION);
- }
- }
- }
+ xar_io_seek(xsource, fsource, seekoff);
opt = NULL;
tmpp = xar_prop_pget(p, "length");
@@ .
patch -p0 <<'@@ .'
Index: xar/lib/stat.c
============================================================================
$ cvs diff -u -r1.4 -r1.5 stat.c
--- xar/lib/stat.c 21 Sep 2007 12:00:58 -0000 1.4
+++ xar/lib/stat.c 29 Sep 2007 12:29:43 -0000 1.5
@@ -460,13 +460,13 @@
}
if( xar_check_prop(x, "inode") ) {
- asprintf(&tmpstr, "%d", XAR(x)->sbcache.st_ino);
+ asprintf(&tmpstr, "%"INO_STRING, XAR(x)->sbcache.st_ino);
xar_prop_set(f, "inode", tmpstr);
free(tmpstr);
}
if( xar_check_prop(x, "deviceno") ) {
- asprintf(&tmpstr, "%d", XAR(x)->sbcache.st_dev);
+ asprintf(&tmpstr, "%"DEV_STRING, XAR(x)->sbcache.st_dev);
xar_prop_set(f, "deviceno", tmpstr);
free(tmpstr);
}
@@ -541,6 +541,7 @@
struct tm t;
enum {ATIME=0, MTIME};
struct timeval tv[2];
+ char savesuid = 0;
/* when writing to a buffer, there are no permissions to set */
if ( len )
@@ -569,6 +570,7 @@
g = gr->gr_gid;
}
}
+ savesuid = 1;
}
if( opt && (strcmp(opt, XAR_OPT_VAL_NUMERIC) == 0) ) {
xar_prop_get(f, "uid", &opt);
@@ -590,8 +592,13 @@
}
g = (gid_t)tmp;
}
+ savesuid = 1;
}
+ opt = xar_opt_get(x, XAR_OPT_SAVESUID);
+ if( opt && (strcmp(opt, XAR_OPT_VAL_TRUE) == 0) ) {
+ savesuid = 1;
+ }
xar_prop_get(f, "mode", &opt);
if( opt ) {
@@ -601,6 +608,10 @@
return -1;
}
m = (mode_t)tmp;
+ if( !savesuid ) {
+ m &= ~S_ISUID;
+ m &= ~S_ISGID;
+ }
mset = 1;
}
@@ -622,6 +633,8 @@
xar_err_set_file(x, f);
xar_err_set_string(x, "perm: could not lchown symlink");
xar_err_callback(x, XAR_SEVERITY_NONFATAL, XAR_ERR_ARCHIVE_EXTRACTION);
+ m &= ~S_ISUID;
+ m &= ~S_ISGID;
}
#ifdef HAVE_LCHMOD
if( mset )
@@ -640,6 +653,8 @@
xar_err_set_string(x, "perm: could not chown file");
xar_err_set_errno(x, errno);
xar_err_callback(x, XAR_SEVERITY_NONFATAL, XAR_ERR_ARCHIVE_EXTRACTION);
+ m &= ~S_ISUID;
+ m &= ~S_ISGID;
}
if( mset )
if( chmod(file, m) ) {
@@ .
patch -p0 <<'@@ .'
Index: xar/src/xar.1
============================================================================
$ cvs diff -u -r1.4 -r1.5 xar.1
--- xar/src/xar.1 21 Sep 2007 12:00:59 -0000 1.4
+++ xar/src/xar.1 29 Sep 2007 12:29:44 -0000 1.5
@@ -59,10 +59,13 @@
On archival, stay on the local device.
.TP
\-P
-On extract, set ownership based on uid/gid.
+On extract, set ownership based on uid/gid. If the uid/gid can be set
+on the extracted file, setuid/setgid bits will also be preserved.
.TP
\-p
-On extract, set ownership based on symbolic names, if possible.
+On extract, set ownership based on symbolic names, if possible.
+If the uid/gid can be set on the extracted file, setuid/setgid bits
+will also be preserved.
.TP
\-s <filename>
On extract, specifies the file to extract subdocuments to.
@@ -94,7 +97,7 @@
\-\-prop-exclude
Specifies a file property to be excluded from the archive. When this option is specified, all file properties will be included except the specified properties. This option can be used multiple times.
.TP
-\-\-distribution
+\\-\-distribution
Creates an archive to only contain file properties safe for file distribution. Currently, only name, type, mode, and data are preserved with this option.
.TP
\-\-keep-existing
@@ -102,6 +105,13 @@
.TP
\-k
Synonym for \-\-keep-existing.
+.TP
+\-\-keep-setuid
+When extracting without -p or -P options, xar will extract files as the
+uid/gid of the extracting process. In this situation, xar will strip
+setuid/setgid bits from the extracted files for security reasons.
+\-\-keep-setuid will preserve the setuid/setgid bits even though the
+uid/gid of the extracted file is not the same as the archived file.
.SH EXAMPLES
.TP
xar -cf sample.xar /home/uid
@@ .
patch -p0 <<'@@ .'
Index: xar/src/xar.c
============================================================================
$ cvs diff -u -r1.8 -r1.9 xar.c
--- xar/src/xar.c 21 Sep 2007 12:00:59 -0000 1.8
+++ xar/src/xar.c 29 Sep 2007 12:29:44 -0000 1.9
@@ -68,6 +68,7 @@
static int Coalesce = 0;
static int LinkSame = 0;
static int NoOverwrite = 0;
+static int SaveSuid = 0;
struct lnode {
char *str;
@@ -356,6 +357,9 @@
if ( Rsize != NULL ) {
xar_opt_set(x, XAR_OPT_RSIZE, Rsize);
}
+ if( SaveSuid ) {
+ xar_opt_set(x, XAR_OPT_SAVESUID, XAR_OPT_VAL_TRUE);
+ }
i = xar_iter_new();
if( !i ) {
@@ -684,6 +688,7 @@
fprintf(stderr, "\t appropriate for archive distribution\n");
fprintf(stderr, "\t--keep-existing Do not overwrite existing files while extracting\n");
fprintf(stderr, "\t-k Synonym for --keep-existing\n");
+ fprintf(stderr, "\t--keep-setuid Preserve the suid/sgid bits when extracting\n");
fprintf(stderr, "\t--version Print xar's version number\n");
return;
@@ -723,6 +728,7 @@
{"prop-exclude", 1, 0, 13},
{"distribution", 0, 0, 14},
{"keep-existing", 0, 0, 15},
+ {"keep-setuid", 0, 0, 16},
{ 0, 0, 0, 0}
};
@@ -880,6 +886,9 @@
case 15 :
NoOverwrite++;
break;
+ case 16 :
+ SaveSuid++;
+ break;
case 'c':
case 'x':
case 't':
@@ .
Received on Sat Sep 29 14:29:44 2007