Hi,
I guess thanks for fixing Hurd portability bugs. Ideally these fixes
would go upstream instead of just into Debian.
* Federico Bonino <[email protected]> [260729 22:35]:
netkit-ntalk fails to build from source on hurd-amd64 because two macros
the source relies on are not defined by the Hurd libc headers:
Buildd log (hurd-amd64, 0.17-20):
https://buildd.debian.org/status/fetch.php?pkg=netkit-ntalk&arch=hurd-amd64&ver=0.17-20&stamp=1783711377&raw=1
talk/get_names.c:55:23: error: 'MAXHOSTNAMELEN' undeclared (first use in
this function)
55 | char hostname[MAXHOSTNAMELEN];
The build stops there. One file later, talkd/process.c:122 declares
find_user()'s scratch buffer as "char besttty[PATH_MAX]", which does not
compile on Hurd either.
Root cause: GNU/Hurd has no fixed path limit, so PATH_MAX is not defined.
MAXHOSTNAMELEN is a BSD constant that is also absent on Hurd.
The patch below replaces the PATH_MAX-sized temporary buffer in
talkd/process.c with dynamic allocation. It also supplies MAXHOSTNAMELEN
from HOST_NAME_MAX, or from _POSIX_HOST_NAME_MAX when HOST_NAME_MAX is
unavailable. No feature or test is disabled.
I verified the patch on native GNU/Hurd amd64 running Debian unstable. The
unmodified 0.17-20 source reproduced the MAXHOSTNAMELEN build failure. The
patch then applied with zero fuzz and zero offset, and dpkg-buildpackage
completed successfully, producing talk and talkd. The package defines no
autopkgtest or upstream test suite.
One thing to flag rather than let you find it in your own build log: on GCC
15 the new strdup(uptr->ut_line) call raises
warning: 'strdup' argument 1 declared attribute 'nonstring'
[-Wstringop-overread]
because ut_line is a fixed-size utmp field with no guaranteed NUL
terminator.
The strcpy() it replaces read ut_line exactly the same way, so this is a
new diagnostic rather than a new unbounded read — but it is new, and it
appears on every architecture. If you would prefer the variant without it,
sizing besttty
as sizeof(uptr->ut_line) + 1 and copying with an explicit terminator
removes the PATH_MAX dependency just as well and is a smaller diff. I am
happy to send that instead; I went with the allocation because it makes no
assumption about the utmp field width.
Toolchain stamp:
- hurd 1:0.9.git20260527-3+b1
- libc0.3 2.42-17
- gcc-15 15.3.0-1
- binutils 2.46.90.20260712-1
netkit-ntalk is maintained by the Debian QA Group and the netkit collection
has no active upstream, so there is nowhere to forward this fix — hence
"Forwarded: no" in the DEP-3 header below, and this report rather than an
upstream submission.
Assisted-by: hurd-collab agent (automated portability triage and fix)
Could you take some time to explain what "hurd-collab agent" is
exactly? I could not find anything in a quick web search.
Best,
Chris
Signed-off-by: Federico Bonino <[email protected]>
--- netkit-ntalk-hurd.patch ---
Description: Replace PATH_MAX buffer with dynamic allocation and add
MAXHOSTNAMELEN fallback for GNU/Hurd
Source-Version: 0.17-20
Author: Federico Bonino <[email protected]>
Forwarded: no
Last-Update: 2026-07-28
GNU/Hurd does not define PATH_MAX because it has no fixed path limit. The
besttty buffer in talkd/process.c was only used as a temporary scratch area
to hold a utmp tty line before copying it to the caller's output buffer; it
is now dynamically allocated with strdup, removing the fixed-size PATH_MAX
dependency.
The MAXHOSTNAMELEN buffer in talk/get_names.c is used for gethostname and
the legacy talk wire protocol uses fixed-size fields, so a bounded hostname
buffer remains appropriate. Since Hurd does not provide MAXHOSTNAMELEN,
provide a conditional fallback to HOST_NAME_MAX (or _POSIX_HOST_NAME_MAX)
from
<limits.h>, preserving the existing behaviour on BSD/Linux platforms.
--- a/talkd/process.c
+++ b/talkd/process.c
@@ -55,6 +55,7 @@ char rcsid[] =
#include <syslog.h>
#include <stdio.h>
#include <string.h>
+#include <stdlib.h>
/* #include <paths.h> <---- unused? */
#include <utmp.h>
#include "prot_talkd.h"
@@ -119,9 +120,12 @@ find_user(const char *name, char *tty)
struct utmp *uptr;
int found=0, ok=0, ret;
time_t best_time = 0, this_time;
- char besttty[PATH_MAX];
+ char *besttty;
- *besttty = 0;
+ besttty = strdup("");
+ if (besttty == NULL) {
+ return FAILED;
+ }
setutent();
while ((uptr = getutent())!=NULL) {
#ifdef USER_PROCESS
@@ -135,6 +139,7 @@ find_user(const char *name, char *tty)
if (*tty && !strcmp(tty, uptr->ut_line)) {
/* asked for a tty, found it */
endutent();
+ free(besttty);
return SUCCESS;
}
ret = check_tty_perms(uptr->ut_line, &this_time);
@@ -145,11 +150,17 @@ find_user(const char *name, char *tty)
found = ok = 1;
if (this_time > best_time) {
best_time = this_time;
- strcpy(besttty, uptr->ut_line);
+ free(besttty);
+ besttty = strdup(uptr->ut_line);
+ if (besttty == NULL) {
+ endutent();
+ return FAILED;
+ }
}
}
endutent();
strcpy(tty, besttty);
+ free(besttty);
return !found ? NOT_HERE : (!ok ? PERMISSION_DENIED : SUCCESS);
}
--- a/talk/get_names.c
+++ b/talk/get_names.c
@@ -39,6 +39,14 @@ char gn_rcsid[] =
#include <stdio.h>
#include <sys/param.h>
+#include <limits.h>
+#ifndef MAXHOSTNAMELEN
+#ifdef HOST_NAME_MAX
+#define MAXHOSTNAMELEN HOST_NAME_MAX
+#else
+#define MAXHOSTNAMELEN _POSIX_HOST_NAME_MAX
+#endif
+#endif
#include <sys/socket.h>
#include <pwd.h>
#include <unistd.h>