diff --git a/games/hack/hack.o_init.c b/games/hack/hack.o_init.c index 9ca796e2f23c..18333338b297 100644 --- a/games/hack/hack.o_init.c +++ b/games/hack/hack.o_init.c @@ -1,4 +1,4 @@ -/* $NetBSD: hack.o_init.c,v 1.14 2011/08/06 20:42:43 dholland Exp $ */ +/* $NetBSD: hack.o_init.c,v 1.15 2023/07/30 09:23:21 pho Exp $ */ /* * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica, @@ -63,7 +63,7 @@ #include #ifndef lint -__RCSID("$NetBSD: hack.o_init.c,v 1.14 2011/08/06 20:42:43 dholland Exp $"); +__RCSID("$NetBSD: hack.o_init.c,v 1.15 2023/07/30 09:23:21 pho Exp $"); #endif /* not lint */ #include @@ -184,15 +184,21 @@ savenames(int fd) bwrite(fd, bases, sizeof bases); bwrite(fd, objects, sizeof objects); /* - * as long as we use only one version of Hack/Quest we need not save - * oc_name and oc_descr, but we must save oc_uname for all objects + * We must save not only oc_uname but also oc_name and oc_descr, + * because they are string constants whose pointer values aren't + * peristent when ASLR is enabled. */ for (i = 0; i < SIZE(objects); i++) { - if (objects[i].oc_uname) { - len = strlen(objects[i].oc_uname) + 1; - bwrite(fd, &len, sizeof len); - bwrite(fd, objects[i].oc_uname, len); +#define SAVE_NAME_FIELD(FIELD) \ + if (objects[i].FIELD) { \ + len = strlen(objects[i].FIELD) + 1; \ + bwrite(fd, &len, sizeof len); \ + bwrite(fd, objects[i].FIELD, len); \ } + SAVE_NAME_FIELD(oc_name); + SAVE_NAME_FIELD(oc_descr); + SAVE_NAME_FIELD(oc_uname); +#undef SAVE_NAME_FIELD } } @@ -200,15 +206,25 @@ void restnames(int fd) { int i; - unsigned len; + size_t len; mread(fd, bases, sizeof bases); mread(fd, objects, sizeof objects); - for (i = 0; i < SIZE(objects); i++) - if (objects[i].oc_uname) { - mread(fd, &len, sizeof len); - objects[i].oc_uname = alloc(len); - mread(fd, objects[i].oc_uname, len); + for (i = 0; i < SIZE(objects); i++) { +#define RESTORE_NAME_FIELD(FIELD) \ + if (objects[i].FIELD) { \ + mread(fd, &len, sizeof len); \ + objects[i].FIELD = alloc(len); \ + mread(fd, __UNCONST(objects[i].FIELD), len); \ } + /* + * This leaks memory but who cares? Restoration only + * happens on the process startup. + */ + RESTORE_NAME_FIELD(oc_name); + RESTORE_NAME_FIELD(oc_descr); + RESTORE_NAME_FIELD(oc_uname); +#undef RESTORE_NAME_FIELD + } } int