Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
* crypt/crypt-private.h: Include stdbool.h.
(_ufc_setup_salt_r): Return bool.
* crypt/crypt-entry.c: Include errno.h.
(__crypt_r): Return NULL with EINVAL for bad salt.
* crypt/crypt_util.c (bad_for_salt): New.
(_ufc_setup_salt_r): Check that salt is long enough and within
the specified alphabet.
* crypt/badsalttest.c: New file.
* crypt/Makefile (tests): Add it.
($(objpfx)badsalttest): New.
  • Loading branch information
Alexandre Oliva committed Oct 10, 2012
1 parent 0e3b5d6 commit 4ba74a3
Show file tree
Hide file tree
Showing 6 changed files with 146 additions and 7 deletions.
13 changes: 13 additions & 0 deletions ChangeLog
@@ -1,3 +1,16 @@
2012-10-10 Alexandre Oliva <aoliva@redhat.com>

* crypt/crypt-private.h: Include stdbool.h.
(_ufc_setup_salt_r): Return bool.
* crypt/crypt-entry.c: Include errno.h.
(__crypt_r): Return NULL with EINVAL for bad salt.
* crypt/crypt_util.c (bad_for_salt): New.
(_ufc_setup_salt_r): Check that salt is long enough and within
the specified alphabet.
* crypt/badsalttest.c: New file.
* crypt/Makefile (tests): Add it.
($(objpfx)badsalttest): New.

2012-10-09 Maxim Kuvyrkov <maxim@codesourcery.com>

* NEWS: Add entry for BZ #14602.
Expand Down
2 changes: 1 addition & 1 deletion crypt/Makefile
Expand Up @@ -28,7 +28,7 @@ extra-libs-others := $(extra-libs)
libcrypt-routines := crypt-entry md5-crypt sha256-crypt sha512-crypt crypt \
crypt_util

tests := cert md5c-test sha256c-test sha512c-test
tests := cert md5c-test sha256c-test sha512c-test badsalttest

include ../Makeconfig

Expand Down
86 changes: 86 additions & 0 deletions crypt/badsalttest.c
@@ -0,0 +1,86 @@
/* Test program for bad DES salt detection in crypt.
Copyright (C) 2012 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
<http://www.gnu.org/licenses/>. */

#include <stdio.h>
#include <unistd.h>
#include <sys/mman.h>
#include <crypt.h>

static const char *tests[][2] =
{
{ "no salt", "" },
{ "single char", "/" },
{ "first char bad", "!x" },
{ "second char bad", "Z%" },
{ "both chars bad", ":@" },
{ "un$upported algorithm", "$2$" },
{ "unsupported_algorithm", "_1" },
{ "end of page", NULL }
};

static int
do_test (void)
{
int result = 0;
struct crypt_data cd;
size_t n = sizeof (tests) / sizeof (*tests);
size_t pagesize = (size_t) sysconf (_SC_PAGESIZE);
char *page;

/* Check that crypt won't look at the second character if the first
one is invalid. */
page = mmap (NULL, pagesize * 2, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANON, -1, 0);
if (page == MAP_FAILED)
{
perror ("mmap");
n--;
}
else
{
if (mmap (page + pagesize, pagesize, 0,
MAP_PRIVATE | MAP_ANON | MAP_FIXED,
-1, 0) != page + pagesize)
perror ("mmap 2");
page[pagesize - 1] = '*';
tests[n - 1][1] = &page[pagesize - 1];
}

for (size_t i = 0; i < n; i++)
{
if (crypt (tests[i][0], tests[i][1]))
{
result++;
printf ("%s: crypt returned non-NULL with salt \"%s\"\n",
tests[i][0], tests[i][1]);
}

if (crypt_r (tests[i][0], tests[i][1], &cd))
{
result++;
printf ("%s: crypt_r returned non-NULL with salt \"%s\"\n",
tests[i][0], tests[i][1]);
}
}

return result;
}

#define TIMEOUT 5
#define TEST_FUNCTION do_test ()
#include "../test-skeleton.c"
7 changes: 6 additions & 1 deletion crypt/crypt-entry.c
Expand Up @@ -27,6 +27,7 @@
#include <stdio.h>
#endif
#include <string.h>
#include <errno.h>

#ifndef STATIC
#define STATIC static
Expand Down Expand Up @@ -108,7 +109,11 @@ __crypt_r (key, salt, data)
/*
* Hack DES tables according to salt
*/
_ufc_setup_salt_r (salt, data);
if (!_ufc_setup_salt_r (salt, data))
{
__set_errno (EINVAL);
return NULL;
}

/*
* Setup key schedule
Expand Down
3 changes: 2 additions & 1 deletion crypt/crypt-private.h
Expand Up @@ -26,6 +26,7 @@
#define CRYPT_PRIVATE_H 1

#include <features.h>
#include <stdbool.h>

/* crypt.c */
extern void _ufc_doit_r (ufc_long itr, struct crypt_data * __restrict __data,
Expand All @@ -36,7 +37,7 @@ extern void _ufc_doit_r (ufc_long itr, struct crypt_data * __restrict __data,
extern void __init_des_r (struct crypt_data * __restrict __data);
extern void __init_des (void);

extern void _ufc_setup_salt_r (const char *s,
extern bool _ufc_setup_salt_r (const char *s,
struct crypt_data * __restrict __data);
extern void _ufc_mk_keytab_r (const char *key,
struct crypt_data * __restrict __data);
Expand Down
42 changes: 38 additions & 4 deletions crypt/crypt_util.c
Expand Up @@ -595,24 +595,56 @@ shuffle_sb(k, saltbits)
}
#endif

/*
* Return false iff C is in the specified alphabet for crypt salt.
*/

static bool
bad_for_salt (char c)
{
switch (c)
{
case '0' ... '9':
case 'A' ... 'Z':
case 'a' ... 'z':
case '.': case '/':
return false;

default:
return true;
}
}

/*
* Setup the unit for a new salt
* Hopefully we'll not see a new salt in each crypt call.
* Return false if an unexpected character was found in s[0] or s[1].
*/

void
bool
_ufc_setup_salt_r(s, __data)
const char *s;
struct crypt_data * __restrict __data;
{
ufc_long i, j, saltbits;
char s0, s1;

if(__data->initialized == 0)
__init_des_r(__data);

if(s[0] == __data->current_salt[0] && s[1] == __data->current_salt[1])
return;
__data->current_salt[0] = s[0]; __data->current_salt[1] = s[1];
s0 = s[0];
if(bad_for_salt (s0))
return false;

s1 = s[1];
if(bad_for_salt (s1))
return false;

if(s0 == __data->current_salt[0] && s1 == __data->current_salt[1])
return true;

__data->current_salt[0] = s0;
__data->current_salt[1] = s1;

/*
* This is the only crypt change to DES:
Expand Down Expand Up @@ -646,6 +678,8 @@ _ufc_setup_salt_r(s, __data)
shuffle_sb((LONGG)__data->sb3, __data->current_saltbits ^ saltbits);

__data->current_saltbits = saltbits;

return true;
}

void
Expand Down

0 comments on commit 4ba74a3

Please sign in to comment.