Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions lib/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -221,8 +221,12 @@ libshadow_la_SOURCES = \
string/strcmp/strneq.h \
string/strcmp/strprefix.c \
string/strcmp/strprefix.h \
string/strcpy/memmove.c \
string/strcpy/memmove.h \
string/strcpy/stpecpy.c \
string/strcpy/stpecpy.h \
string/strcpy/strmove.c \
string/strcpy/strmove.h \
string/strcpy/strncat.c \
string/strcpy/strncat.h \
string/strcpy/strncpy.c \
Expand Down
95 changes: 19 additions & 76 deletions lib/list.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,16 @@

#include "config.h"

#include <stddef.h>
#include <string.h>

#include "alloc/malloc.h"
#include "alloc/realloc.h"
#include "prototypes.h"
#include "defines.h"
#include "string/strchr/strchrcnt.h"
#include "string/strcmp/streq.h"
#include "string/strcpy/memmove.h"
#include "string/strdup/strdup.h"
#include "string/strtok/strsep2ls.h"

Expand All @@ -22,16 +27,11 @@

/*
* add_list - add a member to a list of group members
*
* the array of member names is searched for the new member
* name, and if not present it is added to a freshly allocated
* list of users.
*/
/*@only@*/char **
add_list(/*@returned@*/ /*@only@*/char **list, const char *member)
{
int i;
char **tmp;

assert (NULL != member);
assert (NULL != list);
Expand All @@ -40,97 +40,40 @@ add_list(/*@returned@*/ /*@only@*/char **list, const char *member)
* Scan the list for the new name. Return the original list
* pointer if it is present.
*/

for (i = 0; list[i] != NULL; i++) {
if (streq(list[i], member)) {
return list;
}
}

/*
* Allocate a new list pointer large enough to hold all the
* old entries, and the new entries as well.
*/

tmp = xmalloc_T(i + 2, char *);

/*
* Copy the original list to the new list, then append the
* new member and NULL terminate the result. This new list
* is returned to the invoker.
*/

for (i = 0; list[i] != NULL; i++) {
tmp[i] = list[i];
}

tmp[i] = xstrdup (member);
tmp[i+1] = NULL;

free (list);
list = xrealloc_T(list, i + 2, char *);
list[i] = xstrdup(member);
list[i+1] = NULL;

return tmp;
return list;
}

/*
* del_list - delete a member from a list of group members
*
* the array of member names is searched for the old member
* name, and if present it is deleted from a freshly allocated
* list of users.
*/

/*@only@*/char **
del_list(/*@returned@*/ /*@only@*/char **list, const char *member)
{
int i, j;
char **tmp;
int n, m;

assert (NULL != member);
assert (NULL != list);

/*
* Scan the list for the old name. Return the original list
* pointer if it is not present.
*/

for (i = j = 0; list[i] != NULL; i++) {
if (!streq(list[i], member)) {
j++;
}
}

if (j == i) {
return list;
}

/*
* Allocate a new list pointer large enough to hold all the
* old entries.
*/

tmp = xmalloc_T(j + 1, char *);
do {
for (n = 0; list[n] != NULL; n++)
continue;
for (m = 0; list[m] != NULL && !streq(list[m], member); m++)
continue;
free(list[m]);
memmove_T(&list[m], &list[m+1], n-m, char *);
} while (m != n);

/*
* Copy the original list except the deleted members to the
* new list, then NULL terminate the result. This new list
* is returned to the invoker.
*/

for (i = j = 0; list[i] != NULL; i++) {
if (!streq(list[i], member)) {
tmp[j] = list[i];
j++;
} else {
free (list[i]);
}
}

tmp[j] = NULL;

free (list);

return tmp;
return xrealloc_T(list, n+1, char *);
}

/*
Expand Down
7 changes: 7 additions & 0 deletions lib/string/README
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,10 @@ strcpy/ - String copying
Do NOT use. I'll remove it soon.

s/
strmove()
Like memmove(3), for strings. It takes the length of the string
internally with strlen(3).

strtcpy()
Copy from a string into another string with truncation.
This is what the Linux kernel calls strscpy().
Expand All @@ -208,6 +212,9 @@ strcpy/ - String copying
MEMCPY()
Like memcpy(3), but takes two arrays.

memmove_T()
Like memmove(3), but type safe.

sprintf/ - Formatted string creation

aprintf(3)
Expand Down
7 changes: 7 additions & 0 deletions lib/string/strcpy/memmove.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// SPDX-FileCopyrightText: 2025, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause


#include "config.h"

#include "string/strcpy/memmove.h"
26 changes: 26 additions & 0 deletions lib/string/strcpy/memmove.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// SPDX-FileCopyrightText: 2025, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause


#ifndef SHADOW_INCLUDE_LIB_STRING_STRCPY_MEMMOVE_H_
#define SHADOW_INCLUDE_LIB_STRING_STRCPY_MEMMOVE_H_


#include "config.h"

#include <memory.h>

#include "sizeof.h"


// memmove_T - memory move type-safe
#define memmove_T(dst, src, n, T) memmove_T_(dst, src, n, typeas(T))
#define memmove_T_(dst, src, n, T) do \
{ \
_Generic(dst, T *: (void)0); \
_Generic(src, T *: (void)0); \
memmove(dst, src, (n) * sizeof(T)); \
} while (0)


#endif // include guard
10 changes: 10 additions & 0 deletions lib/string/strcpy/strmove.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// SPDX-FileCopyrightText: 2025-2026, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause


#include "config.h"

#include "string/strcpy/strmove.h"


extern inline void strmove(char *dst, char *src);
29 changes: 29 additions & 0 deletions lib/string/strcpy/strmove.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// SPDX-FileCopyrightText: 2025-2026, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause


#ifndef SHADOW_INCLUDE_LIB_STRING_STRCPY_STRMOVE_H_
#define SHADOW_INCLUDE_LIB_STRING_STRCPY_STRMOVE_H_


#include "config.h"

#include <string.h>

#include "attr.h"
#include "string/strcpy/memmove.h"


ATTR_STRING(2)
inline void strmove(char *dst, char *src);


// strmove - string move
inline void
strmove(char *dst, char *src)
{
memmove_T(dst, src, strlen(src) + 1, char);
}


#endif // include guard
3 changes: 2 additions & 1 deletion src/usermod.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
#include "string/sprintf/aprintf.h"
#include "string/strcmp/streq.h"
#include "string/strcmp/strprefix.h"
#include "string/strcpy/strmove.h"
#include "string/strdup/strdup.h"
#include "string/strspn/stprspn.h"
#include "sysconf.h"
Expand Down Expand Up @@ -489,7 +490,7 @@ new_pw_passwd(char *pw_pass, bool process_selinux)
"updating-password", user_newname, user_newid, 1);
#endif
SYSLOG(LOG_INFO, "unlock user '%s' password", user_newname);
memmove(pw_pass, pw_pass + 1, strlen(pw_pass));
strmove(pw_pass, pw_pass + 1);
} else if (pflg) {
#ifdef WITH_AUDIT
audit_logger (AUDIT_USER_CHAUTHTOK,
Expand Down
Loading