Browse Source

Avoid a potential overflow should a pool specify a large nonce2 length with stratum.

Con Kolivas 12 years ago
parent
commit
46b6b07afa
3 changed files with 23 additions and 7 deletions
  1. 13 4
      cgminer.c
  2. 9 3
      util.c
  3. 1 0
      util.h

+ 13 - 4
cgminer.c

@@ -5587,16 +5587,17 @@ void set_target(unsigned char *dest_target, double diff)
 static void gen_stratum_work(struct pool *pool, struct work *work)
 static void gen_stratum_work(struct pool *pool, struct work *work)
 {
 {
 	unsigned char merkle_root[32], merkle_sha[64];
 	unsigned char merkle_root[32], merkle_sha[64];
+	uint32_t *data32, *swap32, nonce2;
 	char *header, *merkle_hash;
 	char *header, *merkle_hash;
-	uint32_t *data32, *swap32;
+	size_t nonce2_len;
 	int i;
 	int i;
 
 
 	cg_wlock(&pool->data_lock);
 	cg_wlock(&pool->data_lock);
 
 
 	/* Update coinbase */
 	/* Update coinbase */
-	memcpy(pool->coinbase + pool->nonce2_offset, &pool->nonce2, pool->n2size);
-	work->nonce2 = bin2hex((const unsigned char *)&pool->nonce2, pool->n2size);
-	pool->nonce2++;
+	memcpy(pool->coinbase + pool->nonce2_offset, &pool->nonce2, sizeof(uint32_t));
+	nonce2 = pool->nonce2++;
+	nonce2_len = pool->n2size;
 
 
 	/* Downgrade to a read lock to read off the pool variables */
 	/* Downgrade to a read lock to read off the pool variables */
 	cg_dwlock(&pool->data_lock);
 	cg_dwlock(&pool->data_lock);
@@ -5637,6 +5638,14 @@ static void gen_stratum_work(struct pool *pool, struct work *work)
 	work->ntime = strdup(pool->swork.ntime);
 	work->ntime = strdup(pool->swork.ntime);
 	cg_runlock(&pool->data_lock);
 	cg_runlock(&pool->data_lock);
 
 
+	/* nonce2 length can be bigger than uint32_t but we only use the 4
+	 * bytes so avoid potential overflow if a pool has set a large length */
+	align_len(&nonce2_len);
+	work->nonce2 = calloc(nonce2_len, 1);
+	if (unlikely(!work->nonce2))
+		quit(1, "Failed to calloc work nonce2 in gen_stratum_work");
+	__bin2hex(work->nonce2, (const unsigned char *)&nonce2, sizeof(uint32_t));
+
 	applog(LOG_DEBUG, "Generated stratum merkle %s", merkle_hash);
 	applog(LOG_DEBUG, "Generated stratum merkle %s", merkle_hash);
 	applog(LOG_DEBUG, "Generated stratum header %s", header);
 	applog(LOG_DEBUG, "Generated stratum header %s", header);
 	applog(LOG_DEBUG, "Work job_id %s nonce2 %s ntime %s", work->job_id, work->nonce2, work->ntime);
 	applog(LOG_DEBUG, "Work job_id %s nonce2 %s ntime %s", work->job_id, work->nonce2, work->ntime);

+ 9 - 3
util.c

@@ -576,12 +576,19 @@ char *get_proxy(char *url, struct pool *pool)
 	return url;
 	return url;
 }
 }
 
 
+void __bin2hex(char *s, const unsigned char *p, size_t len)
+{
+	int i;
+
+	for (i = 0; i < (int)len; i++)
+		sprintf(s + (i * 2), "%02x", (unsigned int)p[i]);
+}
+
 /* Returns a malloced array string of a binary value of arbitrary length. The
 /* Returns a malloced array string of a binary value of arbitrary length. The
  * array is rounded up to a 4 byte size to appease architectures that need
  * array is rounded up to a 4 byte size to appease architectures that need
  * aligned array  sizes */
  * aligned array  sizes */
 char *bin2hex(const unsigned char *p, size_t len)
 char *bin2hex(const unsigned char *p, size_t len)
 {
 {
-	unsigned int i;
 	ssize_t slen;
 	ssize_t slen;
 	char *s;
 	char *s;
 
 
@@ -592,8 +599,7 @@ char *bin2hex(const unsigned char *p, size_t len)
 	if (unlikely(!s))
 	if (unlikely(!s))
 		quithere(1, "Failed to calloc");
 		quithere(1, "Failed to calloc");
 
 
-	for (i = 0; i < len; i++)
-		sprintf(s + (i * 2), "%02x", (unsigned int) p[i]);
+	__bin2hex(s, p, len);
 
 
 	return s;
 	return s;
 }
 }

+ 1 - 0
util.h

@@ -70,6 +70,7 @@ enum dev_reason;
 struct cgpu_info;
 struct cgpu_info;
 int thr_info_create(struct thr_info *thr, pthread_attr_t *attr, void *(*start) (void *), void *arg);
 int thr_info_create(struct thr_info *thr, pthread_attr_t *attr, void *(*start) (void *), void *arg);
 void thr_info_cancel(struct thr_info *thr);
 void thr_info_cancel(struct thr_info *thr);
+void __bin2hex(char *s, const unsigned char *p, size_t len);
 void nmsleep(unsigned int msecs);
 void nmsleep(unsigned int msecs);
 void nusleep(unsigned int usecs);
 void nusleep(unsigned int usecs);
 void cgtime(struct timeval *tv);
 void cgtime(struct timeval *tv);