aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog1
-rw-r--r--README5
-rw-r--r--src/package.c59
-rw-r--r--src/package.h15
4 files changed, 64 insertions, 16 deletions
diff --git a/ChangeLog b/ChangeLog
index 2df69f4..03a73ae 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,6 +2,7 @@
0.9.6d Oct 18, 2003
* updated docs
* reworked parse_packages_txt function
+ * fixed possible buffer overflows in parse_packages_txt
0.9.6c Oct 15, 2003
* patch data is now fetched from patches/PACKAGES.TXT instead of
diff --git a/README b/README
index 61a0f15..c8e62a3 100644
--- a/README
+++ b/README
@@ -31,12 +31,11 @@ Table of Contents:
slapt-get tries to emulate Debian's apt-get as closely as possible.
* cache package data and update data from mirror site
- * multiple sources (linuxpackage.net support)
+ * multiple sources (including linuxpackage.net support)
* show packages that are available (from cached data)
* allow packages to be retrieved and installed by name
* remove packages
* allow updates to be retrieved and applied
- * install and remove multiple packages at once
* uses native Slackware tools (installpkg, upgradepkg, and removepkg)
* show description of packages
* list installed packages
@@ -45,7 +44,7 @@ Table of Contents:
* easy to script with
* extremely fast
* transaction engine
- * compare package version algorithm to prevent downgrades
+ * "compare package version" algorithm to prevent downgrades
diff --git a/src/package.c b/src/package.c
index f5df515..43b3185 100644
--- a/src/package.c
+++ b/src/package.c
@@ -41,7 +41,7 @@ struct pkg_list *parse_packages_txt(FILE *pkg_list_fh){
char *getline_buffer = NULL;
char *size_c = NULL;
char *size_u = NULL;
- pkg_info_t *tmp_pkg = NULL;
+ pkg_info_t *tmp_pkg;
list = malloc( sizeof *list );
@@ -85,7 +85,6 @@ struct pkg_list *parse_packages_txt(FILE *pkg_list_fh){
/* skip this line if we didn't find a package name */
if( name_regex.reg_return != 0 ){
fprintf(stderr,"regex failed on [%s]\n",getline_buffer);
- free(tmp_pkg);
continue;
}
/* otherwise keep going and parse out the rest of the pkg data */
@@ -97,6 +96,15 @@ struct pkg_list *parse_packages_txt(FILE *pkg_list_fh){
}
/* pkg name base */
+ /* don't overflow the buffer */
+ if( (name_regex.pmatch[1].rm_eo - name_regex.pmatch[1].rm_so) > NAME_LEN ){
+ fprintf( stderr, "pkg name too long [%s:%d]\n",
+ getline_buffer + name_regex.pmatch[1].rm_so,
+ name_regex.pmatch[1].rm_eo - name_regex.pmatch[1].rm_so
+ );
+ free(tmp_pkg);
+ continue;
+ }
strncpy(tmp_pkg->name,
getline_buffer + name_regex.pmatch[1].rm_so,
name_regex.pmatch[1].rm_eo - name_regex.pmatch[1].rm_so
@@ -106,6 +114,15 @@ struct pkg_list *parse_packages_txt(FILE *pkg_list_fh){
] = '\0';
/* pkg version */
+ /* don't overflow the buffer */
+ if( (name_regex.pmatch[2].rm_eo - name_regex.pmatch[2].rm_so) > VERSION_LEN ){
+ fprintf( stderr, "pkg version too long [%s:%d]\n",
+ getline_buffer + name_regex.pmatch[2].rm_so,
+ name_regex.pmatch[2].rm_eo - name_regex.pmatch[2].rm_so
+ );
+ free(tmp_pkg);
+ continue;
+ }
strncpy(tmp_pkg->version,
getline_buffer + name_regex.pmatch[2].rm_so,
name_regex.pmatch[2].rm_eo - name_regex.pmatch[2].rm_so
@@ -127,6 +144,16 @@ struct pkg_list *parse_packages_txt(FILE *pkg_list_fh){
);
if( mirror_regex.reg_return == 0 ){
+ /* don't overflow the buffer */
+ if( (mirror_regex.pmatch[1].rm_eo - mirror_regex.pmatch[1].rm_so) > MIRROR_LEN ){
+ fprintf( stderr, "pkg mirror too long [%s:%d]\n",
+ getline_buffer + mirror_regex.pmatch[1].rm_so,
+ mirror_regex.pmatch[1].rm_eo - mirror_regex.pmatch[1].rm_so
+ );
+ free(tmp_pkg);
+ continue;
+ }
+
strncpy( tmp_pkg->mirror,
getline_buffer + mirror_regex.pmatch[1].rm_so,
mirror_regex.pmatch[1].rm_eo - mirror_regex.pmatch[1].rm_so
@@ -152,6 +179,17 @@ struct pkg_list *parse_packages_txt(FILE *pkg_list_fh){
0
);
if( location_regex.reg_return == 0){
+
+ /* don't overflow the buffer */
+ if( (location_regex.pmatch[1].rm_eo - location_regex.pmatch[1].rm_so) > LOCATION_LEN ){
+ fprintf( stderr, "pkg location too long [%s:%d]\n",
+ getline_buffer + location_regex.pmatch[1].rm_so,
+ location_regex.pmatch[1].rm_eo - location_regex.pmatch[1].rm_so
+ );
+ free(tmp_pkg);
+ continue;
+ }
+
strncpy(tmp_pkg->location,
getline_buffer + location_regex.pmatch[1].rm_so,
location_regex.pmatch[1].rm_eo - location_regex.pmatch[1].rm_so
@@ -261,7 +299,11 @@ struct pkg_list *parse_packages_txt(FILE *pkg_list_fh){
while( 1 ){
if( (bytes_read = getline(&getline_buffer,&getline_len,pkg_list_fh)) != EOF ){
- if( strcmp(getline_buffer,"\n") != 0 ){
+
+ if( strcmp(getline_buffer,"\n") != 0
+ /* don't overflow the buffer */
+ && (strlen(tmp_pkg->description) + bytes_read) < DESCRIPTION_LEN
+ ){
strncat(tmp_pkg->description,getline_buffer,bytes_read);
tmp_pkg->description[
strlen(tmp_pkg->description)
@@ -269,6 +311,7 @@ struct pkg_list *parse_packages_txt(FILE *pkg_list_fh){
}else{
break;
}
+
}else{
break;
}
@@ -279,18 +322,18 @@ struct pkg_list *parse_packages_txt(FILE *pkg_list_fh){
continue;
}
- list->pkgs[list->pkg_count] = tmp_pkg;
- tmp_pkg = NULL;
- list->pkg_count += 1;
/* grow our struct array */
realloc_tmp = realloc(list->pkgs , sizeof *list->pkgs * (list->pkg_count + 1) );
if( realloc_tmp == NULL ){
fprintf(stderr,"Failed to realloc pkgs\n");
exit(1);
- }else{
- list->pkgs = realloc_tmp;
}
+ list->pkgs = realloc_tmp;
+ list->pkgs[list->pkg_count] = tmp_pkg;
+ list->pkg_count += 1;
+ tmp_pkg = NULL;
+
/* printf("%c\b",spinner()); this interferes with --list scripting */
continue;
}
diff --git a/src/package.h b/src/package.h
index e054ec2..4003532 100644
--- a/src/package.h
+++ b/src/package.h
@@ -26,18 +26,23 @@
#define PKG_LOG_DIR "/var/log/packages"
#define PKG_LOG_PATTERN "^([a-zA-Z0-9\\+_\\-]+)-([a-zA-Z0-9._\\-]+)$"
#define MD5SUM_REGEX "([a-zA-Z0-9]+)[ ]+([a-zA-Z0-9._\\-\\/]+/)([a-zA-Z0-9\\+_\\-]+)-([a-zA-Z0-9._\\-]+).tgz$"
+#define NAME_LEN 50
+#define VERSION_LEN 50
+#define MIRROR_LEN 200
+#define LOCATION_LEN 50
+#define DESCRIPTION_LEN 1024
/*
* VARIABLE DEFINITIONS
*/
struct _pkg_info {
- char name[50];
- char version[50];
- char mirror[200];
- char location[60];
+ char name[NAME_LEN];
+ char version[VERSION_LEN];
+ char mirror[MIRROR_LEN];
+ char location[LOCATION_LEN];
int size_c;
int size_u;
- char description[1024];
+ char description[DESCRIPTION_LEN];
};
typedef struct _pkg_info pkg_info_t;
struct pkg_list {