Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

agetpass(): Allocate on the stack (alloca(3)) #1191

Open
wants to merge 13 commits into
base: master
Choose a base branch
from
Open
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
11 changes: 9 additions & 2 deletions lib/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@ libshadow_la_SOURCES = \
adds.c \
adds.h \
age.c \
agetpass.c \
agetpass.h \
alloc/calloc.c \
alloc/calloc.h \
alloc/malloc.c \
Expand Down Expand Up @@ -138,6 +136,15 @@ libshadow_la_SOURCES = \
pam_defs.h \
pam_pass.c \
pam_pass_non_interactive.c \
pass/limits.h \
pass/getpass2.c \
pass/getpass2.h \
pass/passalloca.c \
pass/passalloca.h \
pass/passzero.c \
pass/passzero.h \
pass/readpass.c \
pass/readpass.h \
port.c \
port.h \
prefix_flag.c \
Expand Down
145 changes: 0 additions & 145 deletions lib/agetpass.c

This file was deleted.

23 changes: 0 additions & 23 deletions lib/agetpass.h

This file was deleted.

2 changes: 2 additions & 0 deletions lib/alloc/malloc.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,13 @@

#include <config.h>

#include <alloca.h>
#include <stdlib.h>

#include "attr.h"


#define ALLOCA(n, type) ((type *) alloca(n * sizeof(type)))
#define MALLOC(n, type) \
( \
(type *) mallocarray(n, sizeof(type)) \
Expand Down
10 changes: 0 additions & 10 deletions lib/defines.h
Original file line number Diff line number Diff line change
Expand Up @@ -198,14 +198,4 @@
# define shadow_getenv(name) getenv(name)
#endif

/*
* Maximum password length
*
* Consider that there is also limit in PAM (PAM_MAX_RESP_SIZE)
* currently set to 512.
*/
#if !defined(PASS_MAX)
#define PASS_MAX BUFSIZ - 1
#endif

#endif /* _DEFINES_H_ */
7 changes: 7 additions & 0 deletions lib/pass/getpass2.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// SPDX-FileCopyrightText: 2022-2025, Alejandro Colomar <[email protected]>
// SPDX-License-Identifier: BSD-3-Clause


#include <config.h>

#include "pass/getpass2.h"
27 changes: 27 additions & 0 deletions lib/pass/getpass2.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// SPDX-FileCopyrightText: 2022-2025, Alejandro Colomar <[email protected]>
// SPDX-License-Identifier: BSD-3-Clause


#ifndef SHADOW_INCLUDE_LIB_PASS_GETPASS2_H_
#define SHADOW_INCLUDE_LIB_PASS_GETPASS2_H_


#include <config.h>

#include <readpassphrase.h>
#include <stddef.h>

#include "pass/passalloca.h"
#include "pass/readpass.h"


// Similar to getpass(3), but free of its problems, and get the buffer in $1.
#define getpass2(buf, prompt) readpass(buf, prompt, RPP_REQUIRE_TTY)
#define getpass2_stdin(buf) readpass(buf, NULL, RPP_STDIN)

// Similar to getpass(3), but free of its problems, and using alloca(3).
#define getpassa(prompt) getpass2(passalloca(), prompt)
#define getpassa_stdin() getpass2_stdin(passalloca())


#endif // include guard
21 changes: 21 additions & 0 deletions lib/pass/limits.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// SPDX-FileCopyrightText: 2022-2025, Alejandro Colomar <[email protected]>
// SPDX-License-Identifier: BSD-3-Clause


#ifndef SHADOW_INCLUDE_LIB_PASS_LIMITS_H_
#define SHADOW_INCLUDE_LIB_PASS_LIMITS_H_


#include <config.h>

#include <limits.h>
#include <stdio.h>


// There is also a limit in PAM (PAM_MAX_RESP_SIZE), currently set to 512.
#ifndef PASS_MAX
# define PASS_MAX (BUFSIZ - 1)
#endif


#endif // include guard
7 changes: 7 additions & 0 deletions lib/pass/passalloca.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// SPDX-FileCopyrightText: 2022-2025, Alejandro Colomar <[email protected]>
// SPDX-License-Identifier: BSD-3-Clause


#include <config.h>

#include "pass/passalloca.h"
18 changes: 18 additions & 0 deletions lib/pass/passalloca.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// SPDX-FileCopyrightText: 2022-2025, Alejandro Colomar <[email protected]>
// SPDX-License-Identifier: BSD-3-Clause


#ifndef SHADOW_INCLUDE_LIB_PASS_PASSALLOCA_H_
#define SHADOW_INCLUDE_LIB_PASS_PASSALLOCA_H_


#include <config.h>

#include "alloc/malloc.h"
#include "pass/limits.h"


#define passalloca() ALLOCA(PASS_MAX + 2, char)


#endif // include guard
22 changes: 22 additions & 0 deletions lib/pass/passzero.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// SPDX-FileCopyrightText: 2022-2025, Alejandro Colomar <[email protected]>
// SPDX-License-Identifier: BSD-3-Clause


#include <config.h>

#include "pass/passzero.h"

#include <stddef.h>

#include "pass/limits.h"
#include "string/memset/memzero.h"


char *
passzero(char pass[PASS_MAX + 2])
{
if (pass == NULL)
return NULL;

return memzero(pass, PASS_MAX + 2);
}
17 changes: 17 additions & 0 deletions lib/pass/passzero.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// SPDX-FileCopyrightText: 2022-2025, Alejandro Colomar <[email protected]>
// SPDX-License-Identifier: BSD-3-Clause


#ifndef SHADOW_INCLUDE_LIB_PASS_PASSZERO_H_
#define SHADOW_INCLUDE_LIB_PASS_PASSZERO_H_


#include <config.h>

#include "pass/limits.h"


char *passzero(char pass[PASS_MAX + 2]);


#endif // include guard
45 changes: 45 additions & 0 deletions lib/pass/readpass.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// SPDX-FileCopyrightText: 2022-2025, Alejandro Colomar <[email protected]>
// SPDX-License-Identifier: BSD-3-Clause


#include <config.h>

#include "pass/readpass.h"

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

#include "pass/limits.h"
#include "string/memset/memzero.h"


// readpassphrase(3), but detect truncation, and memzero() on error.
char *
readpass(char pass[restrict PASS_MAX + 2], const char *restrict prompt, int flags)
{
size_t len;

/*
* Since we want to support passwords upto PASS_MAX, we need
* PASS_MAX bytes for the password itself, and one more byte for
* the terminating '\0'. We also want to detect truncation, and
* readpassphrase(3) doesn't detect it, so we need some trick.
* Let's add one more byte, and if the password uses it, it
* means the introduced password was longer than PASS_MAX.
*/
if (readpassphrase(prompt, pass, PASS_MAX + 2, flags) == NULL)
goto fail;

len = strlen(pass);
if (len == PASS_MAX + 1) {
errno = ENOBUFS;
goto fail;
}

return pass;
fail:
memzero(pass, PASS_MAX + 2);
return NULL;
}
Loading
Loading