diff mbox series

[v2] misc: add a new test for gethostname

Message ID 20240731104605.1329319-1-mcoufal@redhat.com
State New
Headers show
Series [v2] misc: add a new test for gethostname | expand

Commit Message

Martin Coufal July 31, 2024, 10:42 a.m. UTC
---
v1: https://sourceware.org/pipermail/libc-alpha/2024-July/158745.html
Changes since v1: delete check for default_hostname, do sanity only
---
 misc/Makefile          |   1 +
 misc/tst-gethostname.c | 101 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 102 insertions(+)
 create mode 100644 misc/tst-gethostname.c

Comments

Andreas Schwab July 31, 2024, 11:16 a.m. UTC | #1
Please follow the GNU coding standard.

On Jul 31 2024, Martin Coufal wrote:

> +void set_hostname (const char* name){
> +  char hostnamectl_cmd[] = "hostnamectl set-hostname ";
> +  char cmd[strlen(hostnamectl_cmd) + strlen(name)];
> +  strcpy(cmd, hostnamectl_cmd);
> +  strcat(cmd, name);
> +  system(cmd);

Doesn't that require special privileges?
Florian Weimer July 31, 2024, 11:54 a.m. UTC | #2
* Andreas Schwab:

> Please follow the GNU coding standard.
>
> On Jul 31 2024, Martin Coufal wrote:
>
>> +void set_hostname (const char* name){
>> +  char hostnamectl_cmd[] = "hostnamectl set-hostname ";
>> +  char cmd[strlen(hostnamectl_cmd) + strlen(name)];
>> +  strcpy(cmd, hostnamectl_cmd);
>> +  strcat(cmd, name);
>> +  system(cmd);
>
> Doesn't that require special privileges?

Right.

Martin, please enter an UTS namespace using unshare (CLONE_NEWUTS),
after calling support_become_root.  The test can only proceed if the
unshare call suceeds.  With this setup, you can safely call sethostname
to change the host name for this particular process.  It is not
necessary to invoke systemd commands.

Thanks,
Florian
Carlos O'Donell Aug. 2, 2024, 8:50 p.m. UTC | #3
On 7/31/24 7:54 AM, Florian Weimer wrote:
> * Andreas Schwab:
> 
>> Please follow the GNU coding standard.
>>
>> On Jul 31 2024, Martin Coufal wrote:
>>
>>> +void set_hostname (const char* name){
>>> +  char hostnamectl_cmd[] = "hostnamectl set-hostname ";
>>> +  char cmd[strlen(hostnamectl_cmd) + strlen(name)];
>>> +  strcpy(cmd, hostnamectl_cmd);
>>> +  strcat(cmd, name);
>>> +  system(cmd);
>>
>> Doesn't that require special privileges?
> 
> Right.
> 
> Martin, please enter an UTS namespace using unshare (CLONE_NEWUTS),
> after calling support_become_root.  The test can only proceed if the
> unshare call suceeds.  With this setup, you can safely call sethostname
> to change the host name for this particular process.  It is not
> necessary to invoke systemd commands.

I'll note that v1 failed pre-commit CI:
https://patchwork.sourceware.org/project/glibc/patch/20240730080525.15196-1-mcoufal@redhat.com/
Adhemerval Zanella Netto Aug. 6, 2024, 1:12 p.m. UTC | #4
On 02/08/24 17:50, Carlos O'Donell wrote:
> On 7/31/24 7:54 AM, Florian Weimer wrote:
>> * Andreas Schwab:
>>
>>> Please follow the GNU coding standard.
>>>
>>> On Jul 31 2024, Martin Coufal wrote:
>>>
>>>> +void set_hostname (const char* name){
>>>> +  char hostnamectl_cmd[] = "hostnamectl set-hostname ";
>>>> +  char cmd[strlen(hostnamectl_cmd) + strlen(name)];
>>>> +  strcpy(cmd, hostnamectl_cmd);
>>>> +  strcat(cmd, name);
>>>> +  system(cmd);
>>>
>>> Doesn't that require special privileges?
>>
>> Right.
>>
>> Martin, please enter an UTS namespace using unshare (CLONE_NEWUTS),
>> after calling support_become_root.  The test can only proceed if the
>> unshare call suceeds.  With this setup, you can safely call sethostname
>> to change the host name for this particular process.  It is not
>> necessary to invoke systemd commands.
> 
> I'll note that v1 failed pre-commit CI:
> https://patchwork.sourceware.org/project/glibc/patch/20240730080525.15196-1-mcoufal@redhat.com/
> 

The v2 also failed aarch64/arm CI [1]:

FAIL: misc/tst-gethostname
original exit status 127

It seems a test issue due the exit result.

[1] https://ci.linaro.org/job/tcwg_glibc_check--master-aarch64-precommit/2145/artifact/artifacts/artifacts.precommit/00-sumfiles/
diff mbox series

Patch

diff --git a/misc/Makefile b/misc/Makefile
index 5d17c562fe..ff45b2887d 100644
--- a/misc/Makefile
+++ b/misc/Makefile
@@ -243,6 +243,7 @@  tests := \
   tst-empty \
   tst-error1 \
   tst-fdset \
+  tst-gethostname \
   tst-hsearch \
   tst-insremque \
   tst-ioctl \
diff --git a/misc/tst-gethostname.c b/misc/tst-gethostname.c
new file mode 100644
index 0000000000..7c94283e61
--- /dev/null
+++ b/misc/tst-gethostname.c
@@ -0,0 +1,101 @@ 
+/* Basic test for gethostname.
+   Copyright (C) 2024 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <support/check.h>
+#include <unistd.h>
+
+#ifndef HOST_NAME_MAX
+#define HOST_NAME_MAX 64
+#endif
+
+#define MAX_LEN_INCREASE 10
+
+void set_hostname (const char* name){
+  char hostnamectl_cmd[] = "hostnamectl set-hostname ";
+  char cmd[strlen(hostnamectl_cmd) + strlen(name)];
+  strcpy(cmd, hostnamectl_cmd);
+  strcat(cmd, name);
+  system(cmd);
+}
+
+static int
+do_test (void)
+{
+  char default_hostname[HOST_NAME_MAX + 1] = "\0";
+  char hostname[HOST_NAME_MAX + 1] = "\0";
+  char generated_hostname[HOST_NAME_MAX + MAX_LEN_INCREASE + 1] = "\0";
+
+  // check default hostname is not empty string
+  TEST_VERIFY_EXIT(gethostname(default_hostname, HOST_NAME_MAX) == 0);
+  TEST_VERIFY(strlen(default_hostname) > 0);
+
+  // input: empty string
+  // expected output: system's default hostname
+  set_hostname("\"\"");
+  TEST_VERIFY(gethostname(hostname, HOST_NAME_MAX) == 0);
+  TEST_VERIFY(strlen(hostname) > 0); // sanity check only, we don't know system's default hostname
+
+  // input: 'a'
+  // expected output: 'a'
+  set_hostname("a");
+  TEST_VERIFY(gethostname(hostname, HOST_NAME_MAX) == 0);
+  TEST_COMPARE(strlen(hostname), 1);
+  TEST_VERIFY(strcmp(hostname, "a") == 0);
+
+  // input: abc.def.ghi
+  // expected output: abc.def.ghi
+  set_hostname("abc.def.ghi");
+  TEST_VERIFY(gethostname(hostname, HOST_NAME_MAX) == 0);
+  TEST_COMPARE(strlen(hostname), 11);
+  TEST_VERIFY(strcmp(hostname, "abc.def.ghi") == 0);
+
+  // input: exactly HOST_NAME_MAX
+  // expected output: exactly HOST_NAME_MAX, return -1, errno set
+  // generate hostname of length == HOST_NAME_MAX
+  for (int i = 0; i < HOST_NAME_MAX; i++){
+    generated_hostname[i] = 'a' + i % 26;
+  }
+  set_hostname(generated_hostname);
+  TEST_VERIFY(gethostname(hostname, HOST_NAME_MAX) == -1);
+  TEST_COMPARE(errno, ENAMETOOLONG);
+  TEST_COMPARE(strlen(hostname), HOST_NAME_MAX);
+  TEST_VERIFY(strcmp(hostname, generated_hostname) == 0);
+
+  // input: longer than HOST_NAME_MAX
+  // expected output: cropped to HOST_NAME_MAX, return -1, errno set
+  // generate hostname LONGER that HOST_NAME_MAX
+  for (int i = 0; i < HOST_NAME_MAX + MAX_LEN_INCREASE; i++){
+    generated_hostname[i] = 'a' + i % 26;
+  }
+  set_hostname(generated_hostname);
+  TEST_VERIFY(gethostname(hostname, HOST_NAME_MAX) == -1);
+  TEST_COMPARE(errno, ENAMETOOLONG);
+  generated_hostname[HOST_NAME_MAX] = '\0'; // crop at HOST_NAME_MAX
+  TEST_COMPARE(strlen(hostname), HOST_NAME_MAX);
+  TEST_VERIFY(strcmp(hostname, generated_hostname) == 0);
+
+  // restore default hostname
+  set_hostname(default_hostname);
+  return 0;
+}
+
+#include <support/test-driver.c>