From 8e64faef03af02a8d4635d199a5b8e55ec68111e Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Sat, 3 Dec 2005 22:15:54 +0000 Subject: [PATCH] * nis/nis_error.c (nis_sperror_r): Let snprintf determine whether there is an overflow. * nis/nss_nisplus/nisplus-netgrp.c (_nss_nisplus_setnetgrent): Rewrite to use snprintf. * nis/nss_nisplus/nisplus-publickey.c (_nss_nisplus_netname2user): Likewise. --- ChangeLog | 6 +++ nis/nis_error.c | 15 +++---- nis/nss_nisplus/nisplus-ethers.c | 88 ++++++++++++++++--------------------- nis/nss_nisplus/nisplus-netgrp.c | 7 ++- nis/nss_nisplus/nisplus-publickey.c | 21 ++++----- nis/nss_nisplus/nisplus-pwd.c | 15 +++---- nis/nss_nisplus/nisplus-spwd.c | 4 -- 7 files changed, 68 insertions(+), 88 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4e8ee89335..4601a7a513 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ 2005-12-03 Ulrich Drepper + * nis/nis_error.c (nis_sperror_r): Let snprintf determine whether + there is an overflow. * nis/nss_nisplus/nisplus-service.c: Fix locking to use _nss_create_tablename. Avoid unnecessary copying, remove unnecessary variables, general cleanup. @@ -17,6 +19,10 @@ general cleanup. * nis/nss_nisplus/nisplus-alias.c: Fix locking to use _nss_create_tablename. Avoid unnecessary copying, general cleanup. + * nis/nss_nisplus/nisplus-netgrp.c (_nss_nisplus_setnetgrent): + Rewrite to use snprintf. + * nis/nss_nisplus/nisplus-publickey.c (_nss_nisplus_netname2user): + Likewise. 2005-12-02 Ulrich Drepper diff --git a/nis/nis_error.c b/nis/nis_error.c index 147f88ce15..7db885ef93 100644 --- a/nis/nis_error.c +++ b/nis/nis_error.c @@ -1,4 +1,4 @@ -/* Copyright (c) 1997, 1998, 1999, 2004 Free Software Foundation, Inc. +/* Copyright (c) 1997, 1998, 1999, 2004, 2005 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Thorsten Kukuk , 1997. @@ -102,26 +102,21 @@ char * nis_sperror_r (const nis_error status, const char *label, char *buffer, size_t buflen) { - const char *cptr; - - cptr = nis_sperrno (status); - - if ((strlen (cptr) + strlen (label) + 3) > buflen) + if (snprintf (buffer, buflen, "%s: %s", label, nis_sperrno (status)) + >= buflen) { errno = ERANGE; return NULL; } - sprintf (buffer, "%s: %s", label, cptr); - - return buffer; + return buffer; } libnsl_hidden_def (nis_sperror_r) char * nis_sperror (const nis_error status, const char *label) { - static char buffer[NIS_MAXNAMELEN +1]; + static char buffer[NIS_MAXNAMELEN + 1]; return nis_sperror_r (status, label, buffer, sizeof (buffer)); } diff --git a/nis/nss_nisplus/nisplus-ethers.c b/nis/nss_nisplus/nisplus-ethers.c index 528ae88a0c..fcc550e743 100644 --- a/nis/nss_nisplus/nisplus-ethers.c +++ b/nis/nss_nisplus/nisplus-ethers.c @@ -156,8 +156,6 @@ static enum nss_status internal_nisplus_getetherent_r (struct etherent *ether, char *buffer, size_t buflen, int *errnop) { - int parse_res; - if (tablename_val == NULL) { enum nss_status status = _nss_create_tablename (errnop); @@ -167,6 +165,7 @@ internal_nisplus_getetherent_r (struct etherent *ether, char *buffer, } /* Get the next entry until we found a correct one. */ + int parse_res; do { nis_result *saved_result; @@ -180,11 +179,8 @@ internal_nisplus_getetherent_r (struct etherent *ether, char *buffer, } else { - nis_result *res2; - - res2 = nis_next_entry(tablename_val, &result->cookie); saved_result = result; - result = res2; + result = nis_next_entry (tablename_val, &result->cookie); if (niserr2nss (result->status) != NSS_STATUS_SUCCESS) { nis_freeresult (saved_result); @@ -200,13 +196,12 @@ internal_nisplus_getetherent_r (struct etherent *ether, char *buffer, result = saved_result; return NSS_STATUS_TRYAGAIN; } - else - { - if (saved_result != NULL) - nis_freeresult (saved_result); - } - } while (!parse_res); + if (saved_result != NULL) + nis_freeresult (saved_result); + + } + while (!parse_res); return NSS_STATUS_SUCCESS; } @@ -230,8 +225,6 @@ enum nss_status _nss_nisplus_gethostton_r (const char *name, struct etherent *eth, char *buffer, size_t buflen, int *errnop) { - int parse_res; - if (tablename_val == NULL) { enum nss_status status = _nss_create_tablename (errnop); @@ -245,49 +238,47 @@ _nss_nisplus_gethostton_r (const char *name, struct etherent *eth, *errnop = EINVAL; return NSS_STATUS_UNAVAIL; } - else - { - nis_result *result; - char buf[strlen (name) + 40 + tablename_len]; - int olderr = errno; - sprintf (buf, "[name=%s],%s", name, tablename_val); + char buf[strlen (name) + 9 + tablename_len]; + int olderr = errno; - result = nis_list (buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL); + snprintf (buf, sizeof (buf), "[name=%s],%s", name, tablename_val); - if (result == NULL) - { - *errnop = ENOMEM; - return NSS_STATUS_TRYAGAIN; - } - if (niserr2nss (result->status) != NSS_STATUS_SUCCESS) - { - enum nss_status status = niserr2nss (result->status); - nis_freeresult (result); - return status; - } + nis_result *result = nis_list (buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL); - parse_res = _nss_nisplus_parse_etherent (result, eth, buffer, + if (result == NULL) + { + *errnop = ENOMEM; + return NSS_STATUS_TRYAGAIN; + } + + if (__builtin_expect (niserr2nss (result->status) != NSS_STATUS_SUCCESS, 0)) + { + enum nss_status status = niserr2nss (result->status); + nis_freeresult (result); + return status; + } + + int parse_res = _nss_nisplus_parse_etherent (result, eth, buffer, buflen, errnop); - if (parse_res < 1) - { - __set_errno (olderr); + if (__builtin_expect (parse_res < 1, 0)) + { + __set_errno (olderr); - if (parse_res == -1) - { - nis_freeresult (result); - return NSS_STATUS_TRYAGAIN; - } - else - return NSS_STATUS_NOTFOUND; + if (parse_res == -1) + { + nis_freeresult (result); + return NSS_STATUS_TRYAGAIN; } - return NSS_STATUS_SUCCESS; + else + return NSS_STATUS_NOTFOUND; } + + return NSS_STATUS_SUCCESS; } enum nss_status -_nss_nisplus_getntohost_r (const struct ether_addr *addr, - struct etherent *eth, +_nss_nisplus_getntohost_r (const struct ether_addr *addr, struct etherent *eth, char *buffer, size_t buflen, int *errnop) { if (tablename_val == NULL) @@ -308,7 +299,6 @@ _nss_nisplus_getntohost_r (const struct ether_addr *addr, return NSS_STATUS_UNAVAIL; } - int parse_res; char buf[26 + tablename_len]; snprintf (buf, sizeof (buf), @@ -334,8 +324,8 @@ _nss_nisplus_getntohost_r (const struct ether_addr *addr, return status; } - parse_res = _nss_nisplus_parse_etherent (result, eth, buffer, - buflen, errnop); + int parse_res = _nss_nisplus_parse_etherent (result, eth, buffer, + buflen, errnop); if (__builtin_expect (parse_res < 1, 0)) { if (parse_res == -1) diff --git a/nis/nss_nisplus/nisplus-netgrp.c b/nis/nss_nisplus/nisplus-netgrp.c index 344d65f4c4..31a8cdf097 100644 --- a/nis/nss_nisplus/nisplus-netgrp.c +++ b/nis/nss_nisplus/nisplus-netgrp.c @@ -150,15 +150,14 @@ internal_endnetgrent (struct __netgrent *netgrp) enum nss_status _nss_nisplus_setnetgrent (const char *group, struct __netgrent *netgrp) { - enum nss_status status; - char buf[strlen (group) + 30]; + char buf[strlen (group) + 25]; if (group == NULL || group[0] == '\0') return NSS_STATUS_UNAVAIL; - status = NSS_STATUS_SUCCESS; + enum nss_status status = NSS_STATUS_SUCCESS; - sprintf (buf, "[name=%s],netgroup.org_dir", group); + snprintf (buf, sizeof (buf), "[name=%s],netgroup.org_dir", group); netgrp->data = (char *) nis_list (buf, EXPAND_NAME, NULL, NULL); diff --git a/nis/nss_nisplus/nisplus-publickey.c b/nis/nss_nisplus/nisplus-publickey.c index 58ae7012af..c24e898137 100644 --- a/nis/nss_nisplus/nisplus-publickey.c +++ b/nis/nss_nisplus/nisplus-publickey.c @@ -1,4 +1,4 @@ -/* Copyright (c) 1997, 1999, 2001, 2003 Free Software Foundation, Inc. +/* Copyright (c) 1997, 1999, 2001, 2003, 2005 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Thorsten Kukuk , 1997. @@ -37,7 +37,7 @@ _nss_nisplus_getpublickey (const char *netname, char *pkey, int *errnop) { nis_result *res; enum nss_status retval; - char buf[NIS_MAXNAMELEN+2]; + char buf[NIS_MAXNAMELEN + 2]; size_t slen; char *domain, *cptr; int len; @@ -120,7 +120,7 @@ _nss_nisplus_getsecretkey (const char *netname, char *skey, char *passwd, { nis_result *res; enum nss_status retval; - char buf[NIS_MAXNAMELEN+2]; + char buf[NIS_MAXNAMELEN + 2]; size_t slen; char *domain, *cptr; int len; @@ -154,7 +154,7 @@ _nss_nisplus_getsecretkey (const char *netname, char *skey, char *passwd, buf[slen] = '\0'; } - res = nis_list (buf, USE_DGRAM+NO_AUTHINFO+FOLLOW_LINKS+FOLLOW_PATH, + res = nis_list (buf, USE_DGRAM | NO_AUTHINFO | FOLLOW_LINKS | FOLLOW_PATH, NULL, NULL); if (res == NULL) @@ -242,9 +242,9 @@ _nss_nisplus_netname2user (char netname[MAXNETNAMELEN + 1], uid_t *uidp, { char *domain; nis_result *res; - char sname[NIS_MAXNAMELEN+2]; /* search criteria + table name */ + char sname[NIS_MAXNAMELEN + 2]; /* search criteria + table name */ size_t slen; - char principal[NIS_MAXNAMELEN+1]; + char principal[NIS_MAXNAMELEN + 1]; int len; /* 1. Get home domain of user. */ @@ -255,10 +255,6 @@ _nss_nisplus_netname2user (char netname[MAXNETNAMELEN + 1], uid_t *uidp, ++domain; /* skip '@' */ /* 2. Get user's nisplus principal name. */ - if ((strlen (netname) + strlen (domain)+45) > - (size_t) NIS_MAXNAMELEN) - return NSS_STATUS_UNAVAIL; - slen = snprintf (sname, NIS_MAXNAMELEN, "[auth_name=%s,auth_type=DES],cred.org_dir.%s", netname, domain); @@ -339,8 +335,9 @@ _nss_nisplus_netname2user (char netname[MAXNETNAMELEN + 1], uid_t *uidp, return NSS_STATUS_UNAVAIL; } - slen = sprintf (sname, "[cname=%s,auth_type=LOCAL],cred.org_dir.%s", - principal, domain); + slen = snprintf (sname, sizeof (sname), + "[cname=%s,auth_type=LOCAL],cred.org_dir.%s", + principal, domain); if (sname[slen - 1] != '.') { diff --git a/nis/nss_nisplus/nisplus-pwd.c b/nis/nss_nisplus/nisplus-pwd.c index a1c53f74a6..97679dd349 100644 --- a/nis/nss_nisplus/nisplus-pwd.c +++ b/nis/nss_nisplus/nisplus-pwd.c @@ -56,7 +56,12 @@ _nss_pwd_create_tablename (int *errnop) atomic_write_barrier (); - pwd_tablename_val = p; + if (atomic_compare_and_exchange_bool_acq (&pwd_tablename_val, p, NULL)) + { + /* Another thread already installed the value. */ + free (p); + pwd_tablename_len = strlen (pwd_tablename_val); + } } return NSS_STATUS_SUCCESS; @@ -181,12 +186,8 @@ _nss_nisplus_getpwnam_r (const char *name, struct passwd *pw, if (pwd_tablename_val == NULL) { - __libc_lock_lock (lock); - enum nss_status status = _nss_pwd_create_tablename (errnop); - __libc_lock_unlock (lock); - if (status != NSS_STATUS_SUCCESS) return status; } @@ -248,12 +249,8 @@ _nss_nisplus_getpwuid_r (const uid_t uid, struct passwd *pw, { if (pwd_tablename_val == NULL) { - __libc_lock_lock (lock); - enum nss_status status = _nss_pwd_create_tablename (errnop); - __libc_lock_unlock (lock); - if (status != NSS_STATUS_SUCCESS) return status; } diff --git a/nis/nss_nisplus/nisplus-spwd.c b/nis/nss_nisplus/nisplus-spwd.c index dd213c1ca9..8584300698 100644 --- a/nis/nss_nisplus/nisplus-spwd.c +++ b/nis/nss_nisplus/nisplus-spwd.c @@ -154,12 +154,8 @@ _nss_nisplus_getspnam_r (const char *name, struct spwd *sp, if (pwd_tablename_val == NULL) { - __libc_lock_lock (lock); - enum nss_status status = _nss_pwd_create_tablename (errnop); - __libc_lock_unlock (lock); - if (status != NSS_STATUS_SUCCESS) return status; } -- 2.11.4.GIT