[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

opensc: FTBFS on hurd-i386: patch for review



Source: opensc
Version: 0.12.2-2
Severity: important
Tags: patch
User: debian-hurd@lists.debian.org
Usertags: hurd

opensc FTBFS on GNU/Hurd due to usage of PATH_MAX in several places.
The attached patch use dynamic allocation of strings instead of fixed
length ones. The number of changes are maybe on the order to check with
upstream if they are OK. Since I don't have a smartcard I cannot test
the functionality (is that even possible with kvm?).

Note: Not yet submitted as a Debian bug. Comments welcome!

Thanks!

diff -ur opensc-0.12.2/src/libopensc/card-piv.c opensc-0.12.2.modified/src/libopensc/card-piv.c
--- opensc-0.12.2/src/libopensc/card-piv.c	2011-07-05 13:28:53.000000000 +0200
+++ opensc-0.12.2.modified/src/libopensc/card-piv.c	2011-12-28 18:12:21.000000000 +0100
@@ -2355,7 +2355,7 @@
 	r = 0;
 	if (priv->offCardCertURL) {
 		char * fp;
-		char filename[PATH_MAX]; 
+		char *filename = NULL; 
 
 		if (strncmp("http://";, priv->offCardCertURL, 7)) {
 				r = SC_ERROR_INVALID_DATA;
@@ -2370,10 +2370,10 @@
 		fp++;
 
 		/* Use the same directory as used for other OpenSC cached items */
-		r = sc_get_cache_dir(card->ctx, filename, 
-				sizeof(filename) - strlen(fp) - 2);
-		if (r != SC_SUCCESS) 
-			goto err; 
+		r = sc_get_cache_dir(card->ctx, &filename);
+		if (r != SC_SUCCESS) {
+			goto err;
+		}
 #ifdef _WIN32
 		strcat(filename,"\\");
 #else
@@ -2383,6 +2383,7 @@
 
 		r = piv_read_obj_from_file(card, filename,
 			 &ocfhfbuf, &ocfhflen);
+		free (filename);
 		if (r == SC_ERROR_FILE_NOT_FOUND) {
 			r = 0;
 			goto err;
diff -ur opensc-0.12.2/src/libopensc/ctx.c opensc-0.12.2.modified/src/libopensc/ctx.c
--- opensc-0.12.2/src/libopensc/ctx.c	2011-07-05 13:28:53.000000000 +0200
+++ opensc-0.12.2.modified/src/libopensc/ctx.c	2011-12-28 18:18:09.000000000 +0100
@@ -796,10 +796,11 @@
 	return SC_SUCCESS;
 }
 
-int sc_get_cache_dir(sc_context_t *ctx, char *buf, size_t bufsize)
+int sc_get_cache_dir(sc_context_t *ctx, char *buf)
 {
 	char *homedir;
 	const char *cache_dir;
+	int len, n;
 #ifdef _WIN32
 	char temp_path[PATH_MAX];
 #endif
@@ -819,18 +820,25 @@
 #endif
 	if (homedir == NULL)
 		return SC_ERROR_INTERNAL;
-	if (snprintf(buf, bufsize, "%s/%s", homedir, cache_dir) < 0)
+	len = strlen(homedir) + 1 + strlen(cache_dir) + 1;
+	if ((buf = malloc(len)) == NULL)
+		return SC_ERROR_OUT_OF_MEMORY;
+	n = snprintf(buf, len, "%s/%s", homedir, cache_dir);
+	/* On error buf is freed so no need to free in calling functions */
+	if (n < 0 || n > len) {
+		free(buf);
 		return SC_ERROR_BUFFER_TOO_SMALL;
+	}
 	return SC_SUCCESS;
 }
 
 int sc_make_cache_dir(sc_context_t *ctx)
 {
-	char dirname[PATH_MAX], *sp;
+	char *dirname = NULL, *sp;
 	int    r;
 	size_t j, namelen;
 
-	if ((r = sc_get_cache_dir(ctx, dirname, sizeof(dirname))) < 0)
+	if ((r = sc_get_cache_dir(ctx, &dirname)) < 0)
 		return r;
 	namelen = strlen(dirname);
 
@@ -862,6 +870,7 @@
 #endif
 			goto failed;
 	}
+	free(dirname);
 	return SC_SUCCESS;
 
 	/* for lack of a better return code */
diff -ur opensc-0.12.2/src/libopensc/opensc.h opensc-0.12.2.modified/src/libopensc/opensc.h
--- opensc-0.12.2/src/libopensc/opensc.h	2011-07-05 13:28:53.000000000 +0200
+++ opensc-0.12.2.modified/src/libopensc/opensc.h	2011-12-28 13:51:03.000000000 +0100
@@ -1150,7 +1150,7 @@
 void *sc_mem_alloc_secure(size_t len);
 int sc_mem_reverse(unsigned char *buf, size_t len);
 
-int sc_get_cache_dir(sc_context_t *ctx, char *buf, size_t bufsize);
+int sc_get_cache_dir(sc_context_t *ctx, char *buf);
 int sc_make_cache_dir(sc_context_t *ctx);
 
 int sc_enum_apps(sc_card_t *card);
diff -ur opensc-0.12.2/src/libopensc/pkcs15-cache.c opensc-0.12.2.modified/src/libopensc/pkcs15-cache.c
--- opensc-0.12.2/src/libopensc/pkcs15-cache.c	2011-07-05 13:28:53.000000000 +0200
+++ opensc-0.12.2.modified/src/libopensc/pkcs15-cache.c	2011-12-28 18:24:45.000000000 +0100
@@ -36,18 +36,18 @@
 
 static int generate_cache_filename(struct sc_pkcs15_card *p15card,
 				   const sc_path_t *path,
-				   char *buf, size_t bufsize)
+				   char *buf)
 {
-	char dir[PATH_MAX];
+	char *dir = NULL;
         char pathname[SC_MAX_PATH_SIZE*2+1];
-	int  r;
+	int  r, len;
         const u8 *pathptr;
         size_t i, pathlen;
 
 	if (path->type != SC_PATH_TYPE_PATH)
                 return SC_ERROR_INVALID_ARGUMENTS;
 	assert(path->len <= SC_MAX_PATH_SIZE);
-	r = sc_get_cache_dir(p15card->card->ctx, dir, sizeof(dir));
+	r = sc_get_cache_dir(p15card->card->ctx, &dir);
 	if (r)
 		return r;
 	pathptr = path->value;
@@ -59,17 +59,27 @@
 	for (i = 0; i < pathlen; i++)
 		sprintf(pathname + 2*i, "%02X", pathptr[i]);
 	if (p15card->tokeninfo->serial_number != NULL) {
-		if (p15card->tokeninfo->last_update != NULL)
-			r = snprintf(buf, bufsize, "%s/%s_%s_%s", dir,
+		if (p15card->tokeninfo->last_update != NULL)  {
+			len = strlen(dir) + 1 + strlen(p15card->tokeninfo->serial_number) + 1 + strlen(p15card->tokeninfo->last_update) + 1 + strlen(pathname) + 1;
+			if ((buf = malloc(buf)) == NULL)
+				return SC_ERROR_OUT_OF_MEMORY;
+			r = snprintf(buf, len, "%s/%s_%s_%s", dir,
 			     p15card->tokeninfo->serial_number, p15card->tokeninfo->last_update,
 			     pathname);
-		else
-			r = snprintf(buf, bufsize, "%s/%s_DATE_%s", dir,
+	  }
+	  else  {
+			len = strlen(dir) + 1 + strlen(p15card->tokeninfo->serial_number) + 6 + strlen(pathname) + 1;
+			if ((buf = malloc(buf)) == NULL)
+				return SC_ERROR_OUT_OF_MEMORY;
+ 			r = snprintf(buf, len, "%s/%s_DATE_%s", dir,
 			     p15card->tokeninfo->serial_number, pathname);
-		if (r < 0)
+	  }
+	  if (r < 0) {
 			return SC_ERROR_BUFFER_TOO_SMALL;
+	  }
 	} else
 		return SC_ERROR_INVALID_ARGUMENTS;
+	free(buf);
         return SC_SUCCESS;
 }
 
@@ -77,14 +87,14 @@
 			       const sc_path_t *path,
 			       u8 **buf, size_t *bufsize)
 {
-	char fname[PATH_MAX];
+	char *fname = NULL;
 	int r;
 	FILE *f;
 	size_t count, offset, got;
 	struct stat stbuf;
 	u8 *data = NULL;
 
-	r = generate_cache_filename(p15card, path, fname, sizeof(fname));
+	r = generate_cache_filename(p15card, path, &fname);
 	if (r != 0)
 		return r;
 	r = stat(fname, &stbuf);
@@ -96,20 +106,27 @@
 	} else {
 		count = path->count;
 		offset = path->index;
-		if (offset + count > (size_t)stbuf.st_size)
+		if (offset + count > (size_t)stbuf.st_size) {
+			free(fname);
 			return SC_ERROR_FILE_NOT_FOUND; /* cache file bad? */
+		}
 	}
 	if (*buf == NULL) {
 		data = malloc((size_t)stbuf.st_size);
-		if (data == NULL)
+		if (data == NULL) {
+			free(fname);
 			return SC_ERROR_OUT_OF_MEMORY;
+		}
 	} else
-		if (count > *bufsize)
+		if (count > *bufsize) {
+			free(fname);
 			return SC_ERROR_BUFFER_TOO_SMALL;
+		}
 	f = fopen(fname, "rb");
 	if (f == NULL) {
 		if (data)
 			free(data);
+		free(fname);
 		return SC_ERROR_FILE_NOT_FOUND;
 	}
 	if (offset)
@@ -121,11 +138,13 @@
 	if (got != count) {
 		if (data)
 			free(data);
+		free(fname);
 		return SC_ERROR_BUFFER_TOO_SMALL;
 	}
 	*bufsize = count;
 	if (data)
 		*buf = data;
+	free(fname);
 	return 0;
 }
 
@@ -133,12 +152,12 @@
 			 const sc_path_t *path,
 			 const u8 *buf, size_t bufsize)
 {
-	char fname[PATH_MAX];
+	char *fname = NULL;
 	int r;
         FILE *f;
         size_t c;
 
-	r = generate_cache_filename(p15card, path, fname, sizeof(fname));
+	r = generate_cache_filename(p15card, path, &fname);
 	if (r != 0)
 		return r;
 
@@ -147,19 +166,25 @@
 	 * not exist, create it and a re-try the fopen() call.
 	 */
 	if (f == NULL && errno == ENOENT) {
-		if ((r = sc_make_cache_dir(p15card->card->ctx)) < 0)
+		if ((r = sc_make_cache_dir(p15card->card->ctx)) < 0) {
+			free(fname);
 			return r;
+	  }
 		f = fopen(fname, "wb");
 	}
-	if (f == NULL)
+	if (f == NULL) {
+		free(fname);
 		return 0;
+	}
 
 	c = fwrite(buf, 1, bufsize, f);
         fclose(f);
 	if (c != bufsize) {
 		sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, "fwrite() wrote only %d bytes", c);
 		unlink(fname);
+		free(fname);
 		return SC_ERROR_INTERNAL;
 	}
+	free(fname);
         return 0;
 }
diff -ur opensc-0.12.2/src/pkcs15init/pkcs15-lib.c opensc-0.12.2.modified/src/pkcs15init/pkcs15-lib.c
--- opensc-0.12.2/src/pkcs15init/pkcs15-lib.c	2011-07-05 13:28:53.000000000 +0200
+++ opensc-0.12.2.modified/src/pkcs15init/pkcs15-lib.c	2011-12-28 18:31:45.000000000 +0100
@@ -183,7 +183,7 @@
  * in the config file, or 0 otherwise.
  */
 static int
-get_profile_from_config(struct sc_card *card, char *buffer, size_t size)
+get_profile_from_config(struct sc_card *card, char *buffer)
 {
 	struct sc_context *ctx = card->ctx;
 	const char *tmp;
@@ -201,7 +201,7 @@
 
 		tmp = scconf_get_str(blk, "profile", NULL);
 		if (tmp != NULL) {
-			strlcpy(buffer, tmp, size);
+			buffer = strdup(tmp);
 			return 1;
 		}
 	}
@@ -290,7 +290,7 @@
 	struct sc_profile *profile;
 	struct sc_pkcs15init_operations * (* func)(void) = NULL;
 	const char	*driver = card->driver->short_name;
-	char		card_profile[PATH_MAX];
+	char		*card_profile = NULL;
 	int		r, i;
 
 	LOG_FUNC_CALLED(ctx);
@@ -345,10 +345,13 @@
 	/* Check the config file for a profile name. 
 	 * If none is defined, use the default profile name.
 	 */
-	if (!get_profile_from_config(card, card_profile, sizeof(card_profile)))
+	if (!get_profile_from_config(card, &card_profile)) {
+		if ((card_profile = malloc(strlen(driver) + 1)) == NULL)
+			return SC_ERROR_OUT_OF_MEMORY;
 		strcpy(card_profile, driver);
+	}
 	if (profile_option != NULL) {
-		strlcpy(card_profile, profile_option, sizeof(card_profile));
+		card_profile = strdup(profile_option);
 	}
 
 	do   {
@@ -370,11 +373,13 @@
 	}  while (0);
 
 	if (r < 0)   {
+		free(card_profile);
 		sc_profile_free(profile);
 		LOG_TEST_RET(ctx, r, "Load profile error");
 	}
 
 	*result = profile;
+	free(card_profile);
 	LOG_FUNC_RETURN(ctx, r);
 }
 
diff -ur opensc-0.12.2/src/pkcs15init/profile.c opensc-0.12.2.modified/src/pkcs15init/profile.c
--- opensc-0.12.2/src/pkcs15init/profile.c	2011-07-05 13:28:53.000000000 +0200
+++ opensc-0.12.2.modified/src/pkcs15init/profile.c	2011-12-28 18:39:24.000000000 +0100
@@ -315,8 +315,8 @@
 	struct sc_context *ctx = profile->card->ctx;
 	scconf_context	*conf;
 	const char *profile_dir = NULL;
-	char path[PATH_MAX];
-	int             res = 0, i;
+	char *path = NULL;
+	int  res = 0, i, len, n;
 #ifdef _WIN32
 	char temp_path[PATH_MAX];
 	DWORD temp_len;
@@ -359,7 +359,12 @@
 #ifdef _WIN32
 	snprintf(path, sizeof(path), "%s\\%s.%s", profile_dir, filename, SC_PKCS15_PROFILE_SUFFIX);
 #else /* _WIN32 */
-	snprintf(path, sizeof(path), "%s/%s.%s", profile_dir, filename, SC_PKCS15_PROFILE_SUFFIX);
+	len = strlen(profile_dir) + strlen(filename) + strlen(SC_PKCS15_PROFILE_SUFFIX) + 2 + 1;
+	n = snprintf(path, len, "%s/%s.%s", profile_dir, filename, SC_PKCS15_PROFILE_SUFFIX);
+	if ( n < 0 || n > len) {
+	  free(path);
+	  return SC_ERROR_BUFFER_TOO_SMALL;
+	}
 #endif /* _WIN32 */
 
 	sc_log(ctx, "Trying profile file %s", path);
diff -ur opensc-0.12.2/src/tools/pkcs15-tool.c opensc-0.12.2.modified/src/tools/pkcs15-tool.c
--- opensc-0.12.2/src/tools/pkcs15-tool.c	2011-07-05 13:28:53.000000000 +0200
+++ opensc-0.12.2.modified/src/tools/pkcs15-tool.c	2011-12-28 18:33:03.000000000 +0100
@@ -1386,18 +1386,19 @@
 
 static int learn_card(void)
 {
-	char dir[PATH_MAX];
+	char *dir = NULL;
 	int r, i, cert_count;
 	struct sc_pkcs15_object *certs[32];
 	struct sc_pkcs15_df *df;
 
-	r = sc_get_cache_dir(ctx, dir, sizeof(dir)); 
+	r = sc_get_cache_dir(ctx, &dir); 
 	if (r) {
 		fprintf(stderr, "Unable to find cache directory: %s\n", sc_strerror(r));
 		return 1;
 	}
 
 	printf("Using cache directory '%s'.\n", dir);
+	free(dir);
 	r = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_CERT_X509, certs, 32);
 	if (r < 0) {
 		fprintf(stderr, "Certificate enumeration failed: %s\n", sc_strerror(r));

Reply to: