From c297701987a5261749bcd801696368e9e149f025 Mon Sep 17 00:00:00 2001 From: Ben Gras Date: Mon, 26 Jul 2010 12:44:48 +0000 Subject: [PATCH] libarchive: sanitize out-of-range uids/gids --- lib/libarchive/archive_entry.c | 42 ++++++++++++++++++++++++++++++++-- lib/libarchive/archive_entry.h | 4 ++-- 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/lib/libarchive/archive_entry.c b/lib/libarchive/archive_entry.c index a2364c05a..c7ddaf67f 100644 --- a/lib/libarchive/archive_entry.c +++ b/lib/libarchive/archive_entry.c @@ -82,6 +82,9 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_entry.c 201096 2009-12-28 02:41: #define makedev(maj,min) ((0xff00 & ((maj)<<8)) | (0xffff00ff & (min))) #endif +#include +#include + /* Play games to come up with a suitable makedev() definition. */ #ifdef __QNXNTO__ /* QNX. */ @@ -804,10 +807,27 @@ archive_entry_copy_fflags_text_w(struct archive_entry *entry, } void -archive_entry_set_gid(struct archive_entry *entry, gid_t g) +archive_entry_set_gid(struct archive_entry *entry, int g) { entry->stat_valid = 0; entry->ae_stat.aest_gid = g; + if(entry->ae_stat.aest_gid != g) { + static int warned = 0; + static struct group *nobodygroup; + gid_t truncgroup; + if(!nobodygroup) + nobodygroup = getgrnam("nobody"); + if(nobodygroup) + truncgroup = nobodygroup->gr_gid; + else + truncgroup = 99; + if(!warned) { + fprintf(stderr, "libarchive: gid %d out of range; will be extracted as %d\n", + g, truncgroup); + warned = 1; + } + entry->ae_stat.aest_gid = truncgroup; + } } void @@ -1159,10 +1179,28 @@ archive_entry_update_symlink_utf8(struct archive_entry *entry, const char *linkn } void -archive_entry_set_uid(struct archive_entry *entry, uid_t u) +archive_entry_set_uid(struct archive_entry *entry, int u) { entry->stat_valid = 0; entry->ae_stat.aest_uid = u; + + if(entry->ae_stat.aest_uid != u) { + static int warned = 0; + static struct passwd *nobodyuser; + uid_t truncuser; + if(!nobodyuser) + nobodyuser = getpwnam("nobody"); + if(nobodyuser) + truncuser = nobodyuser->pw_uid; + else + truncuser = 99; + if(!warned) { + fprintf(stderr, "libarchive: uid %d out of range; will be extracted as %d\n", + u, truncuser); + warned = 1; + } + entry->ae_stat.aest_uid = truncuser; + } } void diff --git a/lib/libarchive/archive_entry.h b/lib/libarchive/archive_entry.h index 12b224416..16b1189a1 100644 --- a/lib/libarchive/archive_entry.h +++ b/lib/libarchive/archive_entry.h @@ -270,7 +270,7 @@ __LA_DECL const char *archive_entry_copy_fflags_text(struct archive_entry *, const char *); __LA_DECL const wchar_t *archive_entry_copy_fflags_text_w(struct archive_entry *, const wchar_t *); -__LA_DECL void archive_entry_set_gid(struct archive_entry *, __LA_GID_T); +__LA_DECL void archive_entry_set_gid(struct archive_entry *, int); __LA_DECL void archive_entry_set_gname(struct archive_entry *, const char *); __LA_DECL void archive_entry_copy_gname(struct archive_entry *, const char *); __LA_DECL void archive_entry_copy_gname_w(struct archive_entry *, const wchar_t *); @@ -315,7 +315,7 @@ __LA_DECL void archive_entry_set_symlink(struct archive_entry *, const char *); __LA_DECL void archive_entry_copy_symlink(struct archive_entry *, const char *); __LA_DECL void archive_entry_copy_symlink_w(struct archive_entry *, const wchar_t *); __LA_DECL int archive_entry_update_symlink_utf8(struct archive_entry *, const char *); -__LA_DECL void archive_entry_set_uid(struct archive_entry *, __LA_UID_T); +__LA_DECL void archive_entry_set_uid(struct archive_entry *, int); __LA_DECL void archive_entry_set_uname(struct archive_entry *, const char *); __LA_DECL void archive_entry_copy_uname(struct archive_entry *, const char *); __LA_DECL void archive_entry_copy_uname_w(struct archive_entry *, const wchar_t *); -- 2.44.0