tech@mandoc.bsd.lv
 help / color / mirror / Atom feed
* Do not cast void pointers to pointers requiring alignment.
@ 2011-12-20  1:17 Ingo Schwarze
  2011-12-20 10:58 ` Kristaps Dzonsons
  0 siblings, 1 reply; 4+ messages in thread
From: Ingo Schwarze @ 2011-12-20  1:17 UTC (permalink / raw)
  To: tech

You want this, too?
  Ingo

----- Forwarded message from Ingo Schwarze <schwarze@cvs.openbsd.org> -----

From: Ingo Schwarze <schwarze@cvs.openbsd.org>
Date: Mon, 19 Dec 2011 17:41:24 -0700 (MST)
To: source-changes@cvs.openbsd.org
Subject: CVS: cvs.openbsd.org: src

CVSROOT:	/cvs
Module name:	src
Changes by:	schwarze@cvs.openbsd.org	2011/12/19 17:41:24

Modified files:
	usr.bin/mandoc : apropos_db.c mandocdb.c 

Log message:
Do not cast void pointers to pointers requiring alignment.
This makes mandocdb(8)/apropos(1) work on strict alignment architectures.
Basic way to fix this confirmed by deraadt@ and kettenis@, thanks.

This now works on both sparc64 and i386, but note that the binary
database format is still machine-dependent.

----- End forwarded message -----

Index: apropos_db.c
===================================================================
RCS file: /cvs/src/usr.bin/mandoc/apropos_db.c,v
retrieving revision 1.15
diff -u -p -r1.15 apropos_db.c
--- apropos_db.c	19 Dec 2011 02:26:33 -0000	1.15
+++ apropos_db.c	20 Dec 2011 00:18:56 -0000
@@ -160,7 +160,7 @@ btree_read(const DBT *k, const DBT *v, 
 		const struct mchars *mc, 
 		struct db_val *dbv, char **buf)
 {
-	const struct db_val *vp;
+	struct db_val	 raw_dbv;
 
 	/* Are our sizes sane? */
 	if (k->size < 2 || sizeof(struct db_val) != v->size)
@@ -170,10 +170,10 @@ btree_read(const DBT *k, const DBT *v, 
 	if ('\0' != ((const char *)k->data)[(int)k->size - 1])
 		return(0);
 
-	vp = v->data;
 	norm_string((const char *)k->data, mc, buf);
-	dbv->rec = betoh32(vp->rec);
-	dbv->mask = betoh64(vp->mask);
+	memcpy(&raw_dbv, v->data, v->size);
+	dbv->rec = betoh32(raw_dbv.rec);
+	dbv->mask = betoh64(raw_dbv.mask);
 	return(1);
 }
 
@@ -369,7 +369,8 @@ index_read(const DBT *key, const DBT *va
 		return(0);
 
 	cp = val->data;
-	rec->res.rec = *(recno_t *)key->data;
+	assert(sizeof(recno_t) == key->size);
+	memcpy(&rec->res.rec, key->data, key->size);
 	rec->res.volume = index;
 
 	if ('d' == (type = *cp++))
Index: mandocdb.c
===================================================================
RCS file: /cvs/src/usr.bin/mandoc/mandocdb.c,v
retrieving revision 1.26
diff -u -p -r1.26 mandocdb.c
--- mandocdb.c	19 Dec 2011 02:26:33 -0000	1.26
+++ mandocdb.c	20 Dec 2011 00:18:58 -0000
@@ -518,6 +518,7 @@ index_merge(const struct of *of, struct 
 	struct mdoc	*mdoc;
 	struct man	*man;
 	const char	*fn, *msec, *mtitle, *arch;
+	uint64_t	 mask;
 	size_t		 sv;
 	unsigned	 seq;
 	struct db_val	 vbuf;
@@ -648,7 +649,9 @@ index_merge(const struct of *of, struct 
 		seq = R_FIRST;
 		while (0 == (ch = (*hash->seq)(hash, &key, &val, seq))) {
 			seq = R_NEXT;
-			vbuf.mask = htobe64(*(uint64_t *)val.data);
+			assert(sizeof(uint64_t) == val.size);
+			memcpy(&mask, val.data, val.size);
+			vbuf.mask = htobe64(mask);
 			val.size = sizeof(struct db_val);
 			val.data = &vbuf;
 			dbt_put(db, dbf, &key, &val);
@@ -701,7 +704,8 @@ index_prune(const struct of *ofile, DB *
 	seq = R_FIRST;
 	while (0 == (ch = (*idx->seq)(idx, &key, &val, seq))) {
 		seq = R_NEXT;
-		*maxrec = *(recno_t *)key.data;
+		assert(sizeof(recno_t) == key.size);
+		memcpy(maxrec, key.data, key.size);
 
 		/* Deleted records are zero-sized.  Skip them. */
 
@@ -1061,6 +1065,7 @@ pmdoc_Sh(MDOC_ARGS)
 static void
 hash_put(DB *db, const struct buf *buf, uint64_t mask)
 {
+	uint64_t	 oldmask;
 	DBT		 key, val;
 	int		 rc;
 
@@ -1073,8 +1078,11 @@ hash_put(DB *db, const struct buf *buf, 
 	if ((rc = (*db->get)(db, &key, &val, 0)) < 0) {
 		perror("hash");
 		exit((int)MANDOCLEVEL_SYSERR);
-	} else if (0 == rc)
-		mask |= *(uint64_t *)val.data;
+	} else if (0 == rc) {
+		assert(sizeof(uint64_t) == val.size);
+		memcpy(&oldmask, val.data, val.size);
+		mask |= oldmask;
+	}
 
 	val.data = &mask;
 	val.size = sizeof(uint64_t); 
--
 To unsubscribe send an email to tech+unsubscribe@mdocml.bsd.lv

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Do not cast void pointers to pointers requiring alignment.
  2011-12-20  1:17 Do not cast void pointers to pointers requiring alignment Ingo Schwarze
@ 2011-12-20 10:58 ` Kristaps Dzonsons
  2011-12-20 16:47   ` Ingo Schwarze
  0 siblings, 1 reply; 4+ messages in thread
From: Kristaps Dzonsons @ 2011-12-20 10:58 UTC (permalink / raw)
  To: tech

> You want this, too?

Is it easier to apply this or wait for the patch being reviewed by 
millert@?  Whichever's more convenient for you.

However, I don't like the assertions in this code.  A bad database 
shouldn't result in assertions (except the internal hashtable, as it's a 
programmatic matter).

All of these areas (index_prune(), index_read(), etc.), are built with 
failure handlers when break;ing or return badly.  Can you modify the 
patch to use these instead?

But of course, I'm following these conversations and want these also!

Thanks,

Kristaps

>    Ingo
>
> ----- Forwarded message from Ingo Schwarze<schwarze@cvs.openbsd.org>  -----
>
> From: Ingo Schwarze<schwarze@cvs.openbsd.org>
> Date: Mon, 19 Dec 2011 17:41:24 -0700 (MST)
> To: source-changes@cvs.openbsd.org
> Subject: CVS: cvs.openbsd.org: src
>
> CVSROOT:	/cvs
> Module name:	src
> Changes by:	schwarze@cvs.openbsd.org	2011/12/19 17:41:24
>
> Modified files:
> 	usr.bin/mandoc : apropos_db.c mandocdb.c
>
> Log message:
> Do not cast void pointers to pointers requiring alignment.
> This makes mandocdb(8)/apropos(1) work on strict alignment architectures.
> Basic way to fix this confirmed by deraadt@ and kettenis@, thanks.
>
> This now works on both sparc64 and i386, but note that the binary
> database format is still machine-dependent.
>
> ----- End forwarded message -----
>
> Index: apropos_db.c
> ===================================================================
> RCS file: /cvs/src/usr.bin/mandoc/apropos_db.c,v
> retrieving revision 1.15
> diff -u -p -r1.15 apropos_db.c
> --- apropos_db.c	19 Dec 2011 02:26:33 -0000	1.15
> +++ apropos_db.c	20 Dec 2011 00:18:56 -0000
> @@ -160,7 +160,7 @@ btree_read(const DBT *k, const DBT *v,
>   		const struct mchars *mc,
>   		struct db_val *dbv, char **buf)
>   {
> -	const struct db_val *vp;
> +	struct db_val	 raw_dbv;
>
>   	/* Are our sizes sane? */
>   	if (k->size<  2 || sizeof(struct db_val) != v->size)
> @@ -170,10 +170,10 @@ btree_read(const DBT *k, const DBT *v,
>   	if ('\0' != ((const char *)k->data)[(int)k->size - 1])
>   		return(0);
>
> -	vp = v->data;
>   	norm_string((const char *)k->data, mc, buf);
> -	dbv->rec = betoh32(vp->rec);
> -	dbv->mask = betoh64(vp->mask);
> +	memcpy(&raw_dbv, v->data, v->size);
> +	dbv->rec = betoh32(raw_dbv.rec);
> +	dbv->mask = betoh64(raw_dbv.mask);
>   	return(1);
>   }
>
> @@ -369,7 +369,8 @@ index_read(const DBT *key, const DBT *va
>   		return(0);
>
>   	cp = val->data;
> -	rec->res.rec = *(recno_t *)key->data;
> +	assert(sizeof(recno_t) == key->size);
> +	memcpy(&rec->res.rec, key->data, key->size);
>   	rec->res.volume = index;
>
>   	if ('d' == (type = *cp++))
> Index: mandocdb.c
> ===================================================================
> RCS file: /cvs/src/usr.bin/mandoc/mandocdb.c,v
> retrieving revision 1.26
> diff -u -p -r1.26 mandocdb.c
> --- mandocdb.c	19 Dec 2011 02:26:33 -0000	1.26
> +++ mandocdb.c	20 Dec 2011 00:18:58 -0000
> @@ -518,6 +518,7 @@ index_merge(const struct of *of, struct
>   	struct mdoc	*mdoc;
>   	struct man	*man;
>   	const char	*fn, *msec, *mtitle, *arch;
> +	uint64_t	 mask;
>   	size_t		 sv;
>   	unsigned	 seq;
>   	struct db_val	 vbuf;
> @@ -648,7 +649,9 @@ index_merge(const struct of *of, struct
>   		seq = R_FIRST;
>   		while (0 == (ch = (*hash->seq)(hash,&key,&val, seq))) {
>   			seq = R_NEXT;
> -			vbuf.mask = htobe64(*(uint64_t *)val.data);
> +			assert(sizeof(uint64_t) == val.size);
> +			memcpy(&mask, val.data, val.size);
> +			vbuf.mask = htobe64(mask);
>   			val.size = sizeof(struct db_val);
>   			val.data =&vbuf;
>   			dbt_put(db, dbf,&key,&val);
> @@ -701,7 +704,8 @@ index_prune(const struct of *ofile, DB *
>   	seq = R_FIRST;
>   	while (0 == (ch = (*idx->seq)(idx,&key,&val, seq))) {
>   		seq = R_NEXT;
> -		*maxrec = *(recno_t *)key.data;
> +		assert(sizeof(recno_t) == key.size);
> +		memcpy(maxrec, key.data, key.size);
>
>   		/* Deleted records are zero-sized.  Skip them. */
>
> @@ -1061,6 +1065,7 @@ pmdoc_Sh(MDOC_ARGS)
>   static void
>   hash_put(DB *db, const struct buf *buf, uint64_t mask)
>   {
> +	uint64_t	 oldmask;
>   	DBT		 key, val;
>   	int		 rc;
>
> @@ -1073,8 +1078,11 @@ hash_put(DB *db, const struct buf *buf,
>   	if ((rc = (*db->get)(db,&key,&val, 0))<  0) {
>   		perror("hash");
>   		exit((int)MANDOCLEVEL_SYSERR);
> -	} else if (0 == rc)
> -		mask |= *(uint64_t *)val.data;
> +	} else if (0 == rc) {
> +		assert(sizeof(uint64_t) == val.size);
> +		memcpy(&oldmask, val.data, val.size);
> +		mask |= oldmask;
> +	}
>
>   	val.data =&mask;
>   	val.size = sizeof(uint64_t);
> --
>   To unsubscribe send an email to tech+unsubscribe@mdocml.bsd.lv
>

--
 To unsubscribe send an email to tech+unsubscribe@mdocml.bsd.lv

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Do not cast void pointers to pointers requiring alignment.
  2011-12-20 10:58 ` Kristaps Dzonsons
@ 2011-12-20 16:47   ` Ingo Schwarze
  2011-12-20 16:54     ` Kristaps Dzonsons
  0 siblings, 1 reply; 4+ messages in thread
From: Ingo Schwarze @ 2011-12-20 16:47 UTC (permalink / raw)
  To: tech

Hi Kristaps,

Kristaps Dzonsons wrote on Tue, Dec 20, 2011 at 11:58:07AM +0100:

> Is it easier to apply this or wait for the patch being reviewed by
> millert@?  Whichever's more convenient for you.

I guess i'll apply it unless millert@ provides feedback before
we agree on it.

> However, I don't like the assertions in this code.  A bad database
> shouldn't result in assertions (except the internal hashtable, as
> it's a programmatic matter).

I fully agree with that, but there are no assertions of the kind you
seem to suspect.

> All of these areas (index_prune(), index_read(), etc.), are built
> with failure handlers when break;ing or return badly.  Can you
> modify the patch to use these instead?

That's already the case.

Yours,
  Ingo


>>@@ -170,10 +170,10 @@ btree_read(const DBT *k, const DBT *v,
>>  	if ('\0' != ((const char *)k->data)[(int)k->size - 1])
>>  		return(0);
>>
>>-	vp = v->data;
>>  	norm_string((const char *)k->data, mc, buf);
>>-	dbv->rec = betoh32(vp->rec);
>>-	dbv->mask = betoh64(vp->mask);
>>+	memcpy(&raw_dbv, v->data, v->size);
>>+	dbv->rec = betoh32(raw_dbv.rec);
>>+	dbv->mask = betoh64(raw_dbv.mask);
>>  	return(1);
>>  }
>>

No assertion here, checks are above (unchanged).

>>@@ -369,7 +369,8 @@ index_read(const DBT *key, const DBT *va
>>  		return(0);
>>
>>  	cp = val->data;
>>-	rec->res.rec = *(recno_t *)key->data;
>>+	assert(sizeof(recno_t) == key->size);
>>+	memcpy(&rec->res.rec, key->data, key->size);
>>  	rec->res.volume = index;
>>
>>  	if ('d' == (type = *cp++))

The key is not stored in the database but is just the record number in
the file, so this asserts against internal malfunctioning of recno(3).

>>@@ -648,7 +649,9 @@ index_merge(const struct of *of, struct
>>  		seq = R_FIRST;
>>  		while (0 == (ch = (*hash->seq)(hash,&key,&val, seq))) {
>>  			seq = R_NEXT;
>>-			vbuf.mask = htobe64(*(uint64_t *)val.data);
>>+			assert(sizeof(uint64_t) == val.size);
>>+			memcpy(&mask, val.data, val.size);
>>+			vbuf.mask = htobe64(mask);
>>  			val.size = sizeof(struct db_val);
>>  			val.data =&vbuf;
>>  			dbt_put(db, dbf,&key,&val);

Assert against hash mishandling.

>>@@ -701,7 +704,8 @@ index_prune(const struct of *ofile, DB *
>>  	seq = R_FIRST;
>>  	while (0 == (ch = (*idx->seq)(idx,&key,&val, seq))) {
>>  		seq = R_NEXT;
>>-		*maxrec = *(recno_t *)key.data;
>>+		assert(sizeof(recno_t) == key.size);
>>+		memcpy(maxrec, key.data, key.size);
>>
>>  		/* Deleted records are zero-sized.  Skip them. */
>>

Assert against internal recno(3) errors, see above.

>>@@ -1073,8 +1078,11 @@ hash_put(DB *db, const struct buf *buf,
>>  	if ((rc = (*db->get)(db,&key,&val, 0))<  0) {
>>  		perror("hash");
>>  		exit((int)MANDOCLEVEL_SYSERR);
>>-	} else if (0 == rc)
>>-		mask |= *(uint64_t *)val.data;
>>+	} else if (0 == rc) {
>>+		assert(sizeof(uint64_t) == val.size);
>>+		memcpy(&oldmask, val.data, val.size);
>>+		mask |= oldmask;
>>+	}

Against hash mishandling, see above.
--
 To unsubscribe send an email to tech+unsubscribe@mdocml.bsd.lv

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Do not cast void pointers to pointers requiring alignment.
  2011-12-20 16:47   ` Ingo Schwarze
@ 2011-12-20 16:54     ` Kristaps Dzonsons
  0 siblings, 0 replies; 4+ messages in thread
From: Kristaps Dzonsons @ 2011-12-20 16:54 UTC (permalink / raw)
  To: tech

On 12/20/11 17:47, Ingo Schwarze wrote:
> Hi Kristaps,
>
> Kristaps Dzonsons wrote on Tue, Dec 20, 2011 at 11:58:07AM +0100:
>
>> Is it easier to apply this or wait for the patch being reviewed by
>> millert@?  Whichever's more convenient for you.
>
> I guess i'll apply it unless millert@ provides feedback before
> we agree on it.
>
>> However, I don't like the assertions in this code.  A bad database
>> shouldn't result in assertions (except the internal hashtable, as
>> it's a programmatic matter).
>
> I fully agree with that, but there are no assertions of the kind you
> seem to suspect.
>
>> All of these areas (index_prune(), index_read(), etc.), are built
>> with failure handlers when break;ing or return badly.  Can you
>> modify the patch to use these instead?
>
> That's already the case.

Gah, you're absolutely right -- I didn't look closely enough.  Thanks again!

--
 To unsubscribe send an email to tech+unsubscribe@mdocml.bsd.lv

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2011-12-20 16:55 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-12-20  1:17 Do not cast void pointers to pointers requiring alignment Ingo Schwarze
2011-12-20 10:58 ` Kristaps Dzonsons
2011-12-20 16:47   ` Ingo Schwarze
2011-12-20 16:54     ` Kristaps Dzonsons

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).