Subject: hashinit()
To: None <tech-kern@NetBSD.org>
From: Christian Biere <christianbiere@gmx.de>
List: tech-kern
Date: 02/01/2007 02:28:37
--3lcZGd9BuhuYXNfi
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Are there objections against the attached patch?
* hashinit(9):
* Change type of parameter elements from u_int to size_t.
* Prevent an infinite loop in hashinit() finding the next power of 2.
* Prevent integer overflow when calculating the memory size in hashinit().
* Always panic() on errors as no user checks the result.
* veriexec_table_add(9), fileassoc_table_add(9):
* Prevent integer overflows caused by implicit casts due to prototypes:
int64_t -> size_t -> uint_t
--
Christian
--3lcZGd9BuhuYXNfi
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="hashinit.udif"
Index: kern_subr.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_subr.c,v
retrieving revision 1.150
diff -u -p -r1.150 kern_subr.c
--- sys/kern/kern_subr.c.orig 1 Nov 2006 10:17:58 -0000 1.150
+++ sys/kern/kern_subr.c 1 Feb 2007 01:03:21 -0000
@@ -382,7 +382,7 @@ ioctl_copyout(int ioctlflags, const void
* suitable for masking a value to use as an index into the returned array.
*/
void *
-hashinit(u_int elements, enum hashtype htype, struct malloc_type *mtype,
+hashinit(size_t elements, enum hashtype htype, struct malloc_type *mtype,
int mflags, u_long *hashmask)
{
u_long hashsize, i;
@@ -390,29 +390,40 @@ hashinit(u_int elements, enum hashtype h
TAILQ_HEAD(, generic) *hashtbl_tailq;
size_t esize;
void *p;
+ const char *msg;
+
+ if (elements == 0 || elements > (size_t)LONG_MAX + 1) {
+ msg = "bad cnt";
+ goto error;
+ }
- if (elements == 0)
- panic("hashinit: bad cnt");
for (hashsize = 1; hashsize < elements; hashsize <<= 1)
continue;
switch (htype) {
case HASH_LIST:
+ if (hashsize > SIZE_MAX / sizeof(*hashtbl_list)) {
+ msg = "too many elements";
+ goto error;
+ }
esize = sizeof(*hashtbl_list);
break;
case HASH_TAILQ:
+ if (hashsize > SIZE_MAX / sizeof(*hashtbl_tailq)) {
+ msg = "too many elements";
+ goto error;
+ }
esize = sizeof(*hashtbl_tailq);
break;
default:
-#ifdef DIAGNOSTIC
- panic("hashinit: invalid table type");
-#else
+ panic("invalid table type");
return NULL;
-#endif
}
- if ((p = malloc(hashsize * esize, mtype, mflags)) == NULL)
- return (NULL);
+ if ((p = malloc(hashsize * esize, mtype, mflags)) == NULL) {
+ msg = "out of memory";
+ goto error;
+ }
switch (htype) {
case HASH_LIST:
@@ -428,6 +439,12 @@ hashinit(u_int elements, enum hashtype h
}
*hashmask = hashsize - 1;
return (p);
+
+error:
+ if (!(mflags & M_CANFAIL))
+ panic("hashinit: %s", msg);
+
+ return NULL;
}
/*
Index: hashinit.9
===================================================================
RCS file: /cvsroot/src/share/man/man9/hashinit.9,v
retrieving revision 1.3
diff -u -p -r1.3 hashinit.9
--- share/man/man9/hashinit.9.orig 23 Dec 2006 06:36:19 -0000 1.3
+++ share/man/man9/hashinit.9 1 Feb 2007 00:59:59 -0000
@@ -42,7 +42,7 @@
.In sys/systm.h
.Ft "void *"
.Fo hashinit
-.Fa "u_int chains"
+.Fa "size_t chains"
.Fa "enum hashtype htype"
.Fa "struct malloc_type *mtype"
.Fa "int mflags"
Index: systm.h
===================================================================
RCS file: /cvsroot/src/sys/sys/systm.h,v
retrieving revision 1.192
diff -u -p -r1.192 systm.h
--- sys/sys/systm.h.orig 10 Jan 2007 11:20:20 -0000 1.192
+++ sys/sys/systm.h 1 Feb 2007 01:02:10 -0000
@@ -152,7 +152,7 @@ enum hashtype {
};
struct malloc_type;
-void *hashinit(u_int, enum hashtype, struct malloc_type *, int, u_long *);
+void *hashinit(size_t, enum hashtype, struct malloc_type *, int, u_long *);
void hashdone(void *, struct malloc_type *);
int seltrue(dev_t, int, struct lwp *);
int sys_nosys(struct lwp *, void *, register_t *);
Index: kern_verifiedexec.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_verifiedexec.c,v
retrieving revision 1.94
diff -u -p -r1.94 kern_verifiedexec.c
--- sys/kern/kern_verifiedexec.c.orig 11 Jan 2007 16:24:48 -0000 1.94
+++ sys/kern/kern_verifiedexec.c 1 Feb 2007 01:25:22 -0000
@@ -1096,6 +1096,7 @@ veriexec_table_add(struct lwp *l, prop_d
u_char buf[16];
int error;
static ONCE_DECL(control);
+ uint64_t count;
error = RUN_ONCE(&control, veriexec_mountspecific_init);
if (error) {
@@ -1108,8 +1109,13 @@ veriexec_table_add(struct lwp *l, prop_d
if (error)
return (error);
- error = fileassoc_table_add(nid.ni_vp->v_mount,
- prop_number_integer_value(prop_dictionary_get(dict, "count")));
+ count = prop_number_integer_value(prop_dictionary_get(dict, "count"));
+ if (count > SIZE_MAX) {
+ error = ERANGE;
+ goto out;
+ }
+
+ error = fileassoc_table_add(nid.ni_vp->v_mount, (size_t)count);
if (error && (error != EEXIST))
goto out;
--3lcZGd9BuhuYXNfi--