glibc: new RHEL6 patches / fix CVE-2015-7547 and more

Signed-off-by: Arne Fitzenreiter <arne_f@ipfire.org>
This commit is contained in:
Arne Fitzenreiter
2016-02-17 12:46:11 +01:00
parent a439a239bc
commit bb330e25e9
73 changed files with 11580 additions and 269 deletions

216
lfs/glibc
View File

@@ -1,7 +1,7 @@
###############################################################################
# #
# IPFire.org - A linux based firewall #
# Copyright (C) 2007-2011 IPFire Team <info@ipfire.org> #
# Copyright (C) 2007-2016 IPFire Team <info@ipfire.org> #
# #
# This program is free software: you can redistribute it and/or modify #
# it under the terms of the GNU General Public License as published by #
@@ -140,156 +140,218 @@ endif
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-getlogin-r.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-localedata.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-recvmmsg.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh580498.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh582738.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh587360.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh582738.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh593396.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh593686.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh601686.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh607010.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh607461.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh615090.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh615701.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh621959.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh623187.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh625893.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh607010.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh630801.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh631011.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh641128.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh642584.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh643822.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh645672.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh580498.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh615090.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh623187.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh646954.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh647448.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh615701.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh652661.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh656014.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh656530.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh657572.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh656014.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh661982.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh667974.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh601686.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh676076.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh676591.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh667974.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh625893.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh681054.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh688720.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh688980.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh689471.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh692177.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh692838.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh703480.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh705465.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh703481.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh694386.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh676591.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh711987.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh695595.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh695963.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh696472.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh697421.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh699724.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh700507.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh703480.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh703481.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh705465.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh711927.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh711987.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh712248.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh713134.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh714823.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh718057.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh726517.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh730379.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh688980.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh712248.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh731042.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh730379.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh700507.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh699724.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh736346.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh737778.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh738665.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh738763.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh739184.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh739971.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh740506.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh740506-2.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh749188.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh750531.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh751750.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh711927.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh688720.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh726517.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh752122.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh739971.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh751750.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh740506.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh757888.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh766513.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh767146.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh767693.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh767693-2.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh750531.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh749188.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh767746.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh767693.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh740506-2.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh696472.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh771342.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh657572.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh767693-2.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh782585.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh784402.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh697421.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh785984.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh788959.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh788959-2.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh789189.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh767146.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh766513.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh789209.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh788959.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh789189.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh789238.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh789238-2.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh794817.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh794817-2.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh795498.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh797094-1.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh797094-2.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh804686.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh789238-2.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh795498.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh794817-2.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh804689.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh806404.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh808337.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh808545.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh809602.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh809726.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh808337.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh788959-2.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh808545.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh833717.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh823909.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh826149.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh827362.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh830127.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh832516.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh832694.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh833717.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh837695.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh837918.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh841787.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh809726.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh806404.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh832516.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh830127.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh832694.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh843673.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh846342.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh847932.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh848082.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh837918.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh849203.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh849651.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh827362.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh837695.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh804686.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh848082.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh846342.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh852445.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh861167.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh863453.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh864322.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh929388.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh970992.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh989558.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh989558-2.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh919562.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh886968.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh905575.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh905874.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh916986.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh928318.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh947882.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh952422.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh966775.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh834386.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh834386-2.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh862094.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh851470.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh868808.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh552960.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh663641.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh663641-2.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh848748.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh952422.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh663641-3.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh916986.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh970776.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh966778.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh863384.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh629823.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh629823-2.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh947882.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh905874.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh929302.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh928318.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh905575.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh988931.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh970090.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh995972.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh1008310.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh1019916.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh1022022.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh1027101.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh1027261.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh1043557.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh1039988.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh995972.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh981942.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh1032628.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh1027101.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh1025933.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh845218.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh1044628.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh1085273.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh1074342.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh1085289.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh1082379.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh1074353.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh1019916.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh1028285.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh1099025.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh1087833.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh1027261.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh905941.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh1054846.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh1111460.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh1133809-1.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh1133809-2.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh1139571.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh1099025-2.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh1133810-1.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh1133810-2.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh1138769.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh1171296.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh1172044.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh1154563.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh1170121.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh1183533.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh1207995.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh1209375.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh1125307.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh1176907.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh1183534.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh1159167.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh1023306.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh1085312.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh1091915.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh859965.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh1124204.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh978098.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh1144019.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh1053178.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh1144132.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh1116050.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh1116050-1.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh867679.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh1088301.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh1195453-avx512.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh1066724.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh1209376.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh1207236.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh1217186.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh1256812.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh1256812-2.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh1256812-3.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh1256812-4.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh1256890.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh1256891.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh1291270.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh1296031.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh1296031-0.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh1299319-0.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh1299319-1.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc-resolv-stack_chk_fail.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc-remove-ctors-dtors-output-sections.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc-test-installation.pl-nss_test1.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc-test-installation.pl-libgcc_s.patch
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc-2.12-accept-make-versions-4.0-and-greater.patch

View File

@@ -1,13 +1,8 @@
From 6e236b92765cdafb46d19e4907471699accc8269 Mon Sep 17 00:00:00 2001
From: Siddhesh Poyarekar <siddhesh@redhat.com>
Date: Thu, 26 Apr 2012 09:18:48 +0530
Subject: [PATCH] move libgcc_s soname definition to shlib-versions
diff --git a/nptl/sysdeps/pthread/unwind-forcedunwind.c b/nptl/sysdeps/pthread/unwind-forcedunwind.c
index adce6e7..60dfbe6 100644
--- a/nptl/sysdeps/pthread/unwind-forcedunwind.c
+++ b/nptl/sysdeps/pthread/unwind-forcedunwind.c
@@ -21,7 +21,7 @@
diff -Naur glibc-2.12-2-gc4ccff1.org/nptl/sysdeps/pthread/unwind-forcedunwind.c glibc-2.12-2-gc4ccff1/nptl/sysdeps/pthread/unwind-forcedunwind.c
index db56428..495f4b7 100644
--- glibc-2.12-2-gc4ccff1.org/nptl/sysdeps/pthread/unwind-forcedunwind.c
+++ glibc-2.12-2-gc4ccff1/nptl/sysdeps/pthread/unwind-forcedunwind.c
@@ -22,7 +22,7 @@
#include <unwind.h>
#include <pthreadP.h>
#include <sysdep.h>
@@ -16,12 +11,11 @@ index adce6e7..60dfbe6 100644
static void *libgcc_s_handle;
static void (*libgcc_s_resume) (struct _Unwind_Exception *exc);
diff --git a/scripts/test-installation.pl b/scripts/test-installation.pl
index c4f3d6d..1b22086 100755
--- a/scripts/test-installation.pl
+++ b/scripts/test-installation.pl
@@ -105,9 +105,10 @@ while (<SOVERSIONS>) {
diff -Naur glibc-2.12-2-gc4ccff1.org/scripts/test-installation.pl glibc-2.12-2-gc4ccff1/scripts/test-installation.pl
index 25a919b..3f409ab 100755
--- glibc-2.12-2-gc4ccff1.org/scripts/test-installation.pl
+++ glibc-2.12-2-gc4ccff1/scripts/test-installation.pl
@@ -106,9 +106,10 @@ while (<SOVERSIONS>) {
# - libnss1_* from glibc-compat add-on
# - libthread_db since it contains unresolved references
# - it's just a test NSS module
@@ -33,11 +27,11 @@ index c4f3d6d..1b22086 100755
$link_libs .= " -l$name";
$versions{$name} = $version;
}
diff --git a/shlib-versions b/shlib-versions
index c530a44..840e08f 100644
--- a/shlib-versions
+++ b/shlib-versions
@@ -124,3 +124,7 @@ sparc64.*-.*-.* libBrokenLocale=1 GLIBC_2.2
diff -Naur glibc-2.12-2-gc4ccff1.org/shlib-versions glibc-2.12-2-gc4ccff1/shlib-versions
index d3e8407..ac98e49 100644
--- glibc-2.12-2-gc4ccff1.org/shlib-versions
+++ glibc-2.12-2-gc4ccff1/shlib-versions
@@ -138,3 +138,7 @@ sparc64.*-.*-.* libBrokenLocale=1 GLIBC_2.2
# The asynchronous name lookup library.
.*-.*-.* libanl=1
@@ -45,10 +39,10 @@ index c530a44..840e08f 100644
+# This defines the libgcc soname version this glibc is to load for
+# asynchronous cancellation to work correctly.
+.*-.*-.* libgcc_s=1
diff --git a/sysdeps/generic/framestate.c b/sysdeps/generic/framestate.c
index 3638bbe..3bad5b5 100644
--- a/sysdeps/generic/framestate.c
+++ b/sysdeps/generic/framestate.c
diff -Naur glibc-2.12-2-gc4ccff1.org/sysdeps/generic/framestate.c glibc-2.12-2-gc4ccff1/sysdeps/generic/framestate.c
index 80375bb..edc3539 100644
--- glibc-2.12-2-gc4ccff1.org/sysdeps/generic/framestate.c
+++ glibc-2.12-2-gc4ccff1/sysdeps/generic/framestate.c
@@ -1,5 +1,5 @@
/* __frame_state_for unwinder helper function wrapper.
- Copyright (C) 2001, 2003 Free Software Foundation, Inc.
@@ -56,7 +50,7 @@ index 3638bbe..3bad5b5 100644
This file is part of the GNU C Library.
Contributed by Jakub Jelinek <jakub@redhat.com>, 2001.
@@ -23,7 +23,7 @@
@@ -24,7 +24,7 @@
#define __frame_state_for fallback_frame_state_for
#include <unwind-dw2.c>
#undef __frame_state_for
@@ -65,33 +59,30 @@ index 3638bbe..3bad5b5 100644
typedef struct frame_state * (*framesf)(void *pc, struct frame_state *);
struct frame_state *__frame_state_for (void *pc,
diff --git a/sysdeps/generic/libgcc_s.h b/sysdeps/generic/libgcc_s.h
diff -Naur glibc-2.12-2-gc4ccff1.org/sysdeps/generic/libgcc_s.h glibc-2.12-2-gc4ccff1.org/sysdeps/generic/libgcc_s.h
deleted file mode 100644
index e74a103..0000000
--- a/sysdeps/generic/libgcc_s.h
--- glibc-2.12-2-gc4ccff1.org/sysdeps/generic/libgcc_s.h
+++ /dev/null
@@ -1,2 +0,0 @@
-/* Name of libgcc_s library provided by gcc. */
-#define LIBGCC_S_SO "libgcc_s.so.1"
diff --git a/sysdeps/gnu/unwind-resume.c b/sysdeps/gnu/unwind-resume.c
index 1d3e33f..6afaebd 100644
--- a/sysdeps/gnu/unwind-resume.c
+++ b/sysdeps/gnu/unwind-resume.c
diff -Naur glibc-2.12-2-gc4ccff1.org/sysdeps/gnu/unwind-resume.c glibc-2.12-2-gc4ccff1/sysdeps/gnu/unwind-resume.c
index f8ff0c4..dab4370 100644
--- glibc-2.12-2-gc4ccff1.org/sysdeps/gnu/unwind-resume.c
+++ glibc-2.12-2-gc4ccff1/sysdeps/gnu/unwind-resume.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003 Free Software Foundation, Inc.
+/* Copyright (C) 2003-2012 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Jakub Jelinek <jakub@redhat.com>.
@@ -19,7 +19,7 @@
#include <dlfcn.h>
#include <stdio.h>
@@ -22,7 +22,7 @@
#include <unwind.h>
#include <pthreadP.h>
#include <sysdep.h>
-#include <libgcc_s.h>
+#include <gnu/lib-names.h>
static void *libgcc_s_handle;
static void (*libgcc_s_resume) (struct _Unwind_Exception *exc);
static _Unwind_Reason_Code (*libgcc_s_personality)
--
1.7.3.4

View File

@@ -0,0 +1,64 @@
diff -pruN glibc-2.17-c758a686/nptl/Makefile glibc-2.17-c758a686.new/nptl/Makefile
--- glibc-2.17-c758a686/nptl/Makefile 2013-07-31 11:51:24.882747234 +0530
+++ glibc-2.17-c758a686.new/nptl/Makefile 2013-07-31 11:58:55.964731526 +0530
@@ -276,10 +276,7 @@ gen-as-const-headers = pthread-errnos.sy
LDFLAGS-tst-cond24 = -lrt
LDFLAGS-tst-cond25 = -lrt
-# The size is 1MB + 4KB. The extra 4KB has been added to prevent allocatestack
-# from resizing the input size to avoid the 64K aliasing conflict on Intel
-# processors.
-DEFAULT_STACKSIZE=1052672
+DEFAULT_STACKSIZE=1048576
CFLAGS-tst-default-attr.c = -DDEFAULT_STACKSIZE=$(DEFAULT_STACKSIZE)
tst-default-attr-ENV = GLIBC_PTHREAD_STACKSIZE=$(DEFAULT_STACKSIZE)
diff -pruN glibc-2.17-c758a686/nptl/tst-default-attr.c glibc-2.17-c758a686.new/nptl/tst-default-attr.c
--- glibc-2.17-c758a686/nptl/tst-default-attr.c 2013-07-31 11:51:24.885747234 +0530
+++ glibc-2.17-c758a686.new/nptl/tst-default-attr.c 2013-07-31 12:18:10.016691337 +0530
@@ -38,6 +38,7 @@
/* DEFAULT_STACKSIZE macro is defined in the Makefile. */
static size_t stacksize = DEFAULT_STACKSIZE;
+long int pagesize;
static int
verify_stacksize_result (pthread_attr_t *attr)
@@ -46,12 +47,20 @@ verify_stacksize_result (pthread_attr_t
RETURN_IF_FAIL (pthread_attr_getstacksize, attr, &stack);
- if (stacksize != stack)
+ /* pthread_create perturbs the stack size by a page if it aligns to 64K to
+ avoid the 64K aliasing conflict. We cannot simply add 4K to the size in
+ the Makefile because it breaks the test on powerpc since the page size
+ there is 64K, resulting in a resize in __pthread_initialize_minimal.
+ Hence, our check is to ensure that the stack size is not more than a page
+ more than the requested size. */
+ if (stack < stacksize || stack > stacksize + pagesize)
{
printf ("failed to set default stacksize (%zu, %zu)\n", stacksize, stack);
return 1;
}
+ printf ("Requested %zu and got %zu\n", stacksize, stack);
+
return 0;
}
@@ -101,6 +110,15 @@ run_threads (void)
static int
do_test (void)
{
+ pthread_attr_t attr;
+
+ pagesize = sysconf (_SC_PAGESIZE);
+ if (pagesize < 0)
+ {
+ printf ("sysconf failed: %s\n", strerror (errno));
+ return 1;
+ }
+
RETURN_IF_FAIL (run_threads);
return 0;
}

View File

@@ -0,0 +1,287 @@
commit 0699f766b10c86912b75f35bef697106b70c1cf6
Author: Carlos O'Donell <carlos@redhat.com>
Date: Thu Apr 10 18:31:53 2014 -0400
nscd: Make SELinux checks dynamic.
The SELinux team has indicated to me that glibc's SELinux checks
in nscd are not being carried out as they would expect the API
to be used today. They would like to move away from static header
defines for class and permissions and instead use dynamic checks
at runtime that provide an answer which is dependent on the runtime
status of SELinux i.e. more dynamic.
The following patch is a minimal change that moves us forward in
this direction.
It does the following:
* Stop checking for SELinux headers that define NSCD__SHMEMHOST.
Check only for the presence or absence of the library.
* Don't encode the specific SELinux permission constants into a
table at build time, and instead use the symbolic name for the
permission as expected.
* Lookup the "What do we do if we don't know this permission?"
policy and use that if we find SELinux's policy is older than
the glibc policy e.g. we make a request for a permission that
SELinux doesn't know about.
* Lastly, translate the class and permission and then make
the permission check. This is done every time we lookup
a permission, and this is the expected way to use the API.
SELinux will optimize this for us, and we expect the network
latencies to hide these extra library calls.
Tested on x86, x86-64, and via Fedora Rawhide since November 2013.
See:
https://sourceware.org/ml/libc-alpha/2014-04/msg00179.html
diff --git a/configure b/configure
index abefcdb..8b0b222 100755
--- a/configure
+++ b/configure
@@ -7774,64 +7774,10 @@ else
have_selinux=no
fi
- # See if we have the SELinux header with the NSCD permissions in it.
- if test x$have_selinux = xyes ; then
- { $as_echo "$as_me:$LINENO: checking for NSCD Flask permissions in selinux/av_permissions.h" >&5
-$as_echo_n "checking for NSCD Flask permissions in selinux/av_permissions.h... " >&6; }
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <selinux/av_permissions.h>
-int
-main ()
-{
-#ifdef NSCD__SHMEMHOST
- return 0;
- #else
- #error NSCD__SHMEMHOST not defined
- #endif
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
-$as_echo "$ac_try_echo") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- have_selinux=yes
-else
- $as_echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- have_selinux=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
- { $as_echo "$as_me:$LINENO: result: $have_selinux" >&5
-$as_echo "$have_selinux" >&6; }
- fi
-
if test x$with_selinux = xyes ; then
if test x$have_selinux = xno ; then
- { { $as_echo "$as_me:$LINENO: error: SELinux explicitly required, but sufficiently recent SELinux library not found" >&5
-$as_echo "$as_me: error: SELinux explicitly required, but sufficiently recent SELinux library not found" >&2;}
+ { { $as_echo "$as_me:$LINENO: error: SELinux explicitly required, but SELinux library not found" >&5
+$as_echo "$as_me: error: SELinux explicitly required, but SELinux library not found" >&2;}
{ (exit 1); exit 1; }; }
fi
fi
diff --git a/configure.in b/configure.in
index 6291872..97a9591 100644
--- a/configure.in
+++ b/configure.in
@@ -1945,22 +1945,9 @@ else
# See if we have the SELinux library
AC_CHECK_LIB(selinux, is_selinux_enabled,
have_selinux=yes, have_selinux=no)
- # See if we have the SELinux header with the NSCD permissions in it.
- if test x$have_selinux = xyes ; then
- AC_MSG_CHECKING([for NSCD Flask permissions in selinux/av_permissions.h])
- AC_TRY_COMPILE([#include <selinux/av_permissions.h>],
- [#ifdef NSCD__SHMEMHOST
- return 0;
- #else
- #error NSCD__SHMEMHOST not defined
- #endif],
- have_selinux=yes, have_selinux=no)
- AC_MSG_RESULT($have_selinux)
- fi
-
if test x$with_selinux = xyes ; then
if test x$have_selinux = xno ; then
- AC_MSG_ERROR([SELinux explicitly required, but sufficiently recent SELinux library not found])
+ AC_MSG_ERROR([SELinux explicitly required, but SELinux library not found])
fi
fi
fi
diff --git a/nscd/selinux.c b/nscd/selinux.c
index 46b0ea9..9a8a5a8 100644
--- a/nscd/selinux.c
+++ b/nscd/selinux.c
@@ -28,7 +28,6 @@
#include <syslog.h>
#include <unistd.h>
#include <sys/prctl.h>
-#include <selinux/av_permissions.h>
#include <selinux/avc.h>
#include <selinux/flask.h>
#include <selinux/selinux.h>
@@ -44,35 +43,31 @@
/* Global variable to tell if the kernel has SELinux support. */
int selinux_enabled;
-/* Define mappings of access vector permissions to request types. */
-static const access_vector_t perms[LASTREQ] =
+/* Define mappings of request type to AVC permission name. */
+static const char *perms[LASTREQ] =
{
- [GETPWBYNAME] = NSCD__GETPWD,
- [GETPWBYUID] = NSCD__GETPWD,
- [GETGRBYNAME] = NSCD__GETGRP,
- [GETGRBYGID] = NSCD__GETGRP,
- [GETHOSTBYNAME] = NSCD__GETHOST,
- [GETHOSTBYNAMEv6] = NSCD__GETHOST,
- [GETHOSTBYADDR] = NSCD__GETHOST,
- [GETHOSTBYADDRv6] = NSCD__GETHOST,
- [GETSTAT] = NSCD__GETSTAT,
- [SHUTDOWN] = NSCD__ADMIN,
- [INVALIDATE] = NSCD__ADMIN,
- [GETFDPW] = NSCD__SHMEMPWD,
- [GETFDGR] = NSCD__SHMEMGRP,
- [GETFDHST] = NSCD__SHMEMHOST,
- [GETAI] = NSCD__GETHOST,
- [INITGROUPS] = NSCD__GETGRP,
-#ifdef NSCD__GETSERV
- [GETSERVBYNAME] = NSCD__GETSERV,
- [GETSERVBYPORT] = NSCD__GETSERV,
- [GETFDSERV] = NSCD__SHMEMSERV,
-#endif
-#ifdef NSCD__GETNETGRP
- [GETNETGRENT] = NSCD__GETNETGRP,
- [INNETGR] = NSCD__GETNETGRP,
- [GETFDNETGR] = NSCD__SHMEMNETGRP,
-#endif
+ [GETPWBYNAME] = "getpwd",
+ [GETPWBYUID] = "getpwd",
+ [GETGRBYNAME] = "getgrp",
+ [GETGRBYGID] = "getgrp",
+ [GETHOSTBYNAME] = "gethost",
+ [GETHOSTBYNAMEv6] = "gethost",
+ [GETHOSTBYADDR] = "gethost",
+ [GETHOSTBYADDRv6] = "gethost",
+ [SHUTDOWN] = "admin",
+ [GETSTAT] = "getstat",
+ [INVALIDATE] = "admin",
+ [GETFDPW] = "shmempwd",
+ [GETFDGR] = "shmemgrp",
+ [GETFDHST] = "shmemhost",
+ [GETAI] = "gethost",
+ [INITGROUPS] = "getgrp",
+ [GETSERVBYNAME] = "getserv",
+ [GETSERVBYPORT] = "getserv",
+ [GETFDSERV] = "shmemserv",
+ [GETNETGRENT] = "getnetgrp",
+ [INNETGR] = "getnetgrp",
+ [GETFDNETGR] = "shmemnetgrp",
};
/* Store an entry ref to speed AVC decisions. */
@@ -344,7 +339,16 @@ nscd_avc_init (void)
/* Check the permission from the caller (via getpeercon) to nscd.
- Returns 0 if access is allowed, 1 if denied, and -1 on error. */
+ Returns 0 if access is allowed, 1 if denied, and -1 on error.
+
+ The SELinux policy, enablement, and permission bits are all dynamic and the
+ caching done by glibc is not entirely correct. This nscd support should be
+ rewritten to use selinux_check_permission. A rewrite is risky though and
+ requires some refactoring. Currently we use symbolic mappings instead of
+ compile time constants (which SELinux upstream says are going away), and we
+ use security_deny_unknown to determine what to do if selinux-policy* doesn't
+ have a definition for the the permission or object class we are looking
+ up. */
int
nscd_request_avc_has_perm (int fd, request_type req)
{
@@ -354,6 +358,33 @@ nscd_request_avc_has_perm (int fd, request_type req)
security_id_t ssid = NULL;
security_id_t tsid = NULL;
int rc = -1;
+ security_class_t sc_nscd;
+ access_vector_t perm;
+ int avc_deny_unknown;
+
+ /* Check if SELinux denys or allows unknown object classes
+ and permissions. It is 0 if they are allowed, 1 if they
+ are not allowed and -1 on error. */
+ if ((avc_deny_unknown = security_deny_unknown ()) == -1)
+ dbg_log (_("Error querying policy for undefined object classes "
+ "or permissions."));
+
+ /* Get the security class for nscd. If this fails we will likely be
+ unable to do anything unless avc_deny_unknown is 0. */
+ sc_nscd = string_to_security_class ("nscd");
+ if (perm == 0 && avc_deny_unknown == 1)
+ dbg_log (_("Error getting security class for nscd."));
+
+ /* Convert permission to AVC bits. */
+ perm = string_to_av_perm (sc_nscd, perms[req]);
+ if (perm == 0 && avc_deny_unknown == 1)
+ dbg_log (_("Error translating permission name "
+ "\"%s\" to access vector bit."), perms[req]);
+
+ /* If the nscd security class was not found or perms were not
+ found and AVC does not deny unknown values then allow it. */
+ if ((sc_nscd == 0 || perm == 0) && avc_deny_unknown == 0)
+ return 0;
if (getpeercon (fd, &scon) < 0)
{
@@ -372,15 +403,13 @@ nscd_request_avc_has_perm (int fd, request_type req)
goto out;
}
-#ifndef NSCD__GETSERV
- if (perms[req] == 0)
- {
- dbg_log (_("compile-time support for database policy missing"));
- goto out;
- }
-#endif
-
- rc = avc_has_perm (ssid, tsid, SECCLASS_NSCD, perms[req], &aeref, NULL) < 0;
+ /* The SELinux API for avc_has_perm conflates access denied and error into
+ the return code -1, while nscd_request_avs_has_perm has distinct error
+ (-1) and denied (1) return codes. We map the avc_has_perm access denied or
+ error into an access denied at the nscd interface level (we do accurately
+ report error for the getpeercon, getcon, and avc_context_to_sid interfaces
+ used above). */
+ rc = avc_has_perm (ssid, tsid, sc_nscd, perm, &aeref, NULL) < 0;
out:
if (scon)

View File

@@ -0,0 +1,149 @@
From a5675717e35a02a3eba7e13701c6f9c0d7222e13 Mon Sep 17 00:00:00 2001
From: Adhemerval Zanella <azanella@linux.vnet.ibm.com>
Date: Fri, 7 Jun 2013 14:50:23 -0500
Subject: [PATCH 2/2] PowerPC: gettimeofday optimization by using IFUNC
Backport of ef26eece6331a1f6d959818e37c438cc7ce68e53 from master.
---
sysdeps/unix/sysv/linux/powerpc/bits/libc-vdso.h | 10 ++++
sysdeps/unix/sysv/linux/powerpc/gettimeofday.c | 49 +++++++++++++++-------
2 files changed, 44 insertions(+), 15 deletions(-)
commit 76a9b9986141b1a7d9fd290c349d27fcee780c7a
Author: Adhemerval Zanella <azanella@linux.vnet.ibm.com>
Date: Thu Nov 7 05:34:22 2013 -0600
PowerPC: Fix vDSO missing ODP entries
This patch fixes the vDSO symbol used directed in IFUNC resolver where
they do not have an associated ODP entry leading to undefined behavior
in some cases. It adds an artificial OPD static entry to such cases
and set its TOC to non 0 to avoid triggering lazy resolutions.
commit d98720e07f67fbeec00f9e1347840404240d3c48
Author: Adhemerval Zanella <azanella@linux.vnet.ibm.com>
Date: Mon Jan 20 12:29:51 2014 -0600
PowerPC: Fix gettimeofday ifunc selection
The IFUNC selector for gettimeofday runs before _libc_vdso_platform_setup where
__vdso_gettimeofday is set. The selector then sets __gettimeofday (the internal
version used within GLIBC) to use the system call version instead of the vDSO one.
This patch changes the check if vDSO is available to get its value directly
instead of rely on __vdso_gettimeofday.
This patch changes it by getting the vDSO value directly.
It fixes BZ#16431.
diff -pruN a/sysdeps/unix/sysv/linux/powerpc/bits/libc-vdso.h b/sysdeps/unix/sysv/linux/powerpc/bits/libc-vdso.h
--- a/sysdeps/unix/sysv/linux/powerpc/bits/libc-vdso.h 2014-05-20 14:46:51.026871920 +0530
+++ b/sysdeps/unix/sysv/linux/powerpc/bits/libc-vdso.h 2014-05-20 14:44:39.294877321 +0530
@@ -33,6 +33,36 @@ extern void *__vdso_get_tbfreq;
extern void *__vdso_getcpu;
+#if defined(__PPC64__) || defined(__powerpc64__)
+/* The correct solution is for _dl_vdso_vsym to return the address of the OPD
+ for the kernel VDSO function. That address would then be stored in the
+ __vdso_* variables and returned as the result of the IFUNC resolver function.
+ Yet, the kernel does not contain any OPD entries for the VDSO functions
+ (incomplete implementation). However, PLT relocations for IFUNCs still expect
+ the address of an OPD to be returned from the IFUNC resolver function (since
+ PLT entries on PPC64 are just copies of OPDs). The solution for now is to
+ create an artificial static OPD for each VDSO function returned by a resolver
+ function. The TOC value is set to a non-zero value to avoid triggering lazy
+ symbol resolution via .glink0/.plt0 for a zero TOC (requires thread-safe PLT
+ sequences) when the dynamic linker isn't prepared for it e.g. RTLD_NOW. None
+ of the kernel VDSO routines use the TOC or AUX values so any non-zero value
+ will work. Note that function pointer comparisons will not use this artificial
+ static OPD since those are resolved via ADDR64 relocations and will point at
+ the non-IFUNC default OPD for the symbol. Lastly, because the IFUNC relocations
+ are processed immediately at startup the resolver functions and this code need
+ not be thread-safe, but if the caller writes to a PLT slot it must do so in a
+ thread-safe manner with all the required barriers. */
+#define VDSO_IFUNC_RET(value) \
+ ({ \
+ static Elf64_FuncDesc vdso_opd = { .fd_toc = ~0x0 }; \
+ vdso_opd.fd_func = (Elf64_Addr)value; \
+ &vdso_opd; \
+ })
+
+#else
+#define VDSO_IFUNC_RET(value) ((void *) (value))
+#endif
+
#endif
#endif /* _LIBC_VDSO_H */
diff -pruN a/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c b/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c
--- a/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c 2010-05-04 16:57:23.000000000 +0530
+++ b/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c 2014-05-20 14:44:39.298877321 +0530
@@ -16,27 +16,51 @@
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
-#include <sysdep.h>
-#include <bp-checks.h>
-#include <stddef.h>
#include <sys/time.h>
-#include <time.h>
-#include <hp-timing.h>
-#undef __gettimeofday
-#include <bits/libc-vdso.h>
+#ifdef SHARED
-/* Get the current time of day and timezone information,
- putting it into *TV and *TZ. If TZ is NULL, *TZ is not filled.
- Returns 0 on success, -1 on errors. */
-
-int
-__gettimeofday (tv, tz)
- struct timeval *tv;
- struct timezone *tz;
+# include <dl-vdso.h>
+# include <bits/libc-vdso.h>
+# include <dl-machine.h>
+
+void *gettimeofday_ifunc (void) __asm__ ("__gettimeofday");
+
+static int
+__gettimeofday_syscall (struct timeval *tv, struct timezone *tz)
+{
+ return INLINE_SYSCALL (gettimeofday, 2, tv, tz);
+}
+
+void *
+gettimeofday_ifunc (void)
+{
+ PREPARE_VERSION (linux2615, "LINUX_2.6.15", 123718565);
+
+ /* If the vDSO is not available we fall back syscall. */
+ void *vdso_gettimeofday = _dl_vdso_vsym ("__kernel_gettimeofday", &linux2615);
+ return (vdso_gettimeofday ? VDSO_IFUNC_RET (vdso_gettimeofday)
+ : (void*)__gettimeofday_syscall);
+}
+asm (".type __gettimeofday, %gnu_indirect_function");
+
+/* This is doing "libc_hidden_def (__gettimeofday)" but the compiler won't
+ let us do it in C because it doesn't know we're defining __gettimeofday
+ here in this file. */
+asm (".globl __GI___gettimeofday\n"
+ "__GI___gettimeofday = __gettimeofday");
+
+#else
+
+# include <sysdep.h>
+# include <errno.h>
+
+int
+__gettimeofday (struct timeval *tv, struct timezone *tz)
{
- return INLINE_VSYSCALL (gettimeofday, 2, CHECK_1 (tv), CHECK_1 (tz));
+ return INLINE_SYSCALL (gettimeofday, 2, tv, tz);
}
+#endif
INTDEF (__gettimeofday)
weak_alias (__gettimeofday, gettimeofday)

View File

@@ -0,0 +1,141 @@
commit 9a3c6a6ff602c88d7155139a7d7d0000b7b7e946
Author: Siddhesh Poyarekar <siddhesh@redhat.com>
Date: Thu Jan 2 10:05:27 2014 +0530
Fix return code from getent netgroup when the netgroup is not found (bz #16366)
nscd incorrectly returns a success even when the netgroup in question
is not found and adds a positive result in the cache. this patch
fixes this behaviour by adding a negative lookup entry to cache and
returning an error when the netgroup is not found.
diff --git a/nscd/netgroupcache.c b/nscd/netgroupcache.c
index 50936ee..9fc1664 100644
--- a/nscd/netgroupcache.c
+++ b/nscd/netgroupcache.c
@@ -65,6 +65,55 @@ struct dataset
char strdata[0];
};
+/* Sends a notfound message and prepares a notfound dataset to write to the
+ cache. Returns true if there was enough memory to allocate the dataset and
+ returns the dataset in DATASETP, total bytes to write in TOTALP and the
+ timeout in TIMEOUTP. KEY_COPY is set to point to the copy of the key in the
+ dataset. */
+static bool
+do_notfound (struct database_dyn *db, int fd, request_header *req,
+ const char *key, struct dataset **datasetp, ssize_t *totalp,
+ time_t *timeoutp, char **key_copy)
+{
+ struct dataset *dataset;
+ ssize_t total;
+ time_t timeout;
+ bool cacheable = false;
+
+ total = sizeof (notfound);
+ timeout = time (NULL) + db->negtimeout;
+
+ if (fd != -1)
+ TEMP_FAILURE_RETRY (send (fd, &notfound, total, MSG_NOSIGNAL));
+
+ dataset = mempool_alloc (db, sizeof (struct dataset) + req->key_len, 1);
+ /* If we cannot permanently store the result, so be it. */
+ if (dataset != NULL)
+ {
+ dataset->head.allocsize = sizeof (struct dataset) + req->key_len;
+ dataset->head.recsize = total;
+ dataset->head.notfound = true;
+ dataset->head.nreloads = 0;
+ dataset->head.usable = true;
+
+ /* Compute the timeout time. */
+ timeout = dataset->head.timeout = time (NULL) + db->negtimeout;
+ dataset->head.ttl = db->negtimeout;
+
+ /* This is the reply. */
+ memcpy (&dataset->resp, &notfound, total);
+
+ /* Copy the key data. */
+ memcpy (dataset->strdata, key, req->key_len);
+ *key_copy = dataset->strdata;
+
+ cacheable = true;
+ }
+ *timeoutp = timeout;
+ *totalp = total;
+ *datasetp = dataset;
+ return cacheable;
+}
static time_t
addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
@@ -84,6 +133,7 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
struct dataset *dataset;
bool cacheable = false;
ssize_t total;
+ bool found = false;
char *key_copy = NULL;
struct __netgrent data;
@@ -103,35 +153,8 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
&& __nss_database_lookup ("netgroup", NULL, NULL, &netgroup_database))
{
/* No such service. */
- total = sizeof (notfound);
- timeout = time (NULL) + db->negtimeout;
-
- if (fd != -1)
- TEMP_FAILURE_RETRY (send (fd, &notfound, total, MSG_NOSIGNAL));
-
- dataset = mempool_alloc (db, sizeof (struct dataset) + req->key_len, 1);
- /* If we cannot permanently store the result, so be it. */
- if (dataset != NULL)
- {
- dataset->head.allocsize = sizeof (struct dataset) + req->key_len;
- dataset->head.recsize = total;
- dataset->head.notfound = true;
- dataset->head.nreloads = 0;
- dataset->head.usable = true;
-
- /* Compute the timeout time. */
- timeout = dataset->head.timeout = time (NULL) + db->negtimeout;
- dataset->head.ttl = db->negtimeout;
-
- /* This is the reply. */
- memcpy (&dataset->resp, &notfound, total);
-
- /* Copy the key data. */
- memcpy (dataset->strdata, key, req->key_len);
-
- cacheable = true;
- }
-
+ cacheable = do_notfound (db, fd, req, key, &dataset, &total, &timeout,
+ &key_copy);
goto writeout;
}
@@ -167,6 +190,7 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
if (status == NSS_STATUS_SUCCESS)
{
+ found = true;
union
{
enum nss_status (*f) (struct __netgrent *, char *, size_t,
@@ -326,6 +350,15 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
}
}
+ /* No results. Return a failure and write out a notfound record in the
+ cache. */
+ if (!found)
+ {
+ cacheable = do_notfound (db, fd, req, key, &dataset, &total, &timeout,
+ &key_copy);
+ goto writeout;
+ }
+
total = buffilled;
/* Fill in the dataset. */

View File

@@ -0,0 +1,145 @@
commit af37a8a3496327a6e5617a2c76f17aa1e8db835e
Author: Siddhesh Poyarekar <siddhesh@redhat.com>
Date: Mon Jan 27 11:32:44 2014 +0530
Avoid undefined behaviour in netgroupcache
Using a buffer after it has been reallocated is undefined behaviour,
so get offsets of the triplets in the old buffer before reallocating
it.
commit 5d41dadf31bc8a2f9c34c40d52a442d3794e405c
Author: Siddhesh Poyarekar <siddhesh@redhat.com>
Date: Fri Jan 24 13:51:15 2014 +0530
Adjust pointers to triplets in netgroup query data (BZ #16474)
The _nss_*_getnetgrent_r query populates the netgroup results in the
allocated buffer and then sets the result triplet to point to strings
in the buffer. This is a problem when the buffer is reallocated since
the pointers to the triplet strings are no longer valid. The pointers
need to be adjusted so that they now point to strings in the
reallocated buffer.
commit 980cb5180e1b71224a57ca52b995c959b7148c09
Author: Siddhesh Poyarekar <siddhesh@redhat.com>
Date: Thu Jan 16 10:20:22 2014 +0530
Don't use alloca in addgetnetgrentX (BZ #16453)
addgetnetgrentX has a buffer which is grown as per the needs of the
requested size either by using alloca or by falling back to malloc if
the size is larger than 1K. There are two problems with the alloca
bits: firstly, it doesn't really extend the buffer since it does not
use the return value of the extend_alloca macro, which is the location
of the reallocated buffer. Due to this the buffer does not actually
extend itself and hence a subsequent write may overwrite stuff on the
stack.
The second problem is more subtle - the buffer growth on the stack is
discontinuous due to block scope local variables. Combine that with
the fact that unlike realloc, extend_alloca does not copy over old
content and you have a situation where the buffer just has garbage in
the space where it should have had data.
This could have been fixed by adding code to copy over old data
whenever we call extend_alloca, but it seems unnecessarily
complicated. This code is not exactly a performance hotspot (it's
called when there is a cache miss, so factors like network lookup or
file reads will dominate over memory allocation/reallocation), so this
premature optimization is unnecessary.
Thanks Brad Hubbard <bhubbard@redhat.com> for his help with debugging
the problem.
diff -pruN glibc-2.12-2-gc4ccff1/nscd/netgroupcache.c glibc-2.12-2-gc4ccff1.patched/nscd/netgroupcache.c
--- glibc-2.12-2-gc4ccff1/nscd/netgroupcache.c 2014-04-09 12:13:58.618582111 +0530
+++ glibc-2.12-2-gc4ccff1.patched/nscd/netgroupcache.c 2014-04-09 12:07:21.486598665 +0530
@@ -93,7 +93,6 @@ addgetnetgrentX (struct database_dyn *db
size_t buffilled = sizeof (*dataset);
char *buffer = NULL;
size_t nentries = 0;
- bool use_malloc = false;
size_t group_len = strlen (key) + 1;
union
{
@@ -138,7 +137,7 @@ addgetnetgrentX (struct database_dyn *db
}
memset (&data, '\0', sizeof (data));
- buffer = alloca (buflen);
+ buffer = xmalloc (buflen);
first_needed.elem.next = &first_needed.elem;
memcpy (first_needed.elem.name, key, group_len);
data.needed_groups = &first_needed.elem;
@@ -218,21 +217,24 @@ addgetnetgrentX (struct database_dyn *db
if (buflen - req->key_len - bufused < needed)
{
- size_t newsize = MAX (2 * buflen,
- buflen + 2 * needed);
- if (use_malloc || newsize > 1024 * 1024)
- {
- buflen = newsize;
- char *newbuf = xrealloc (use_malloc
- ? buffer
- : NULL,
- buflen);
-
- buffer = newbuf;
- use_malloc = true;
- }
- else
- extend_alloca (buffer, buflen, newsize);
+ buflen += MAX (buflen, 2 * needed);
+ /* Save offset in the old buffer. We don't
+ bother with the NULL check here since
+ we'll do that later anyway. */
+ size_t nhostdiff = nhost - buffer;
+ size_t nuserdiff = nuser - buffer;
+ size_t ndomaindiff = ndomain - buffer;
+
+ char *newbuf = xrealloc (buffer, buflen);
+ /* Fix up the triplet pointers into the new
+ buffer. */
+ nhost = (nhost ? newbuf + nhostdiff
+ : NULL);
+ nuser = (nuser ? newbuf + nuserdiff
+ : NULL);
+ ndomain = (ndomain ? newbuf + ndomaindiff
+ : NULL);
+ buffer = newbuf;
}
nhost = memcpy (buffer + bufused,
@@ -299,18 +301,8 @@ addgetnetgrentX (struct database_dyn *db
}
else if (status == NSS_STATUS_UNAVAIL && e == ERANGE)
{
- size_t newsize = 2 * buflen;
- if (use_malloc || newsize > 1024 * 1024)
- {
- buflen = newsize;
- char *newbuf = xrealloc (use_malloc
- ? buffer : NULL, buflen);
-
- buffer = newbuf;
- use_malloc = true;
- }
- else
- extend_alloca (buffer, buflen, newsize);
+ buflen *= 2;
+ buffer = xrealloc (buffer, buflen);
}
}
@@ -446,8 +438,7 @@ addgetnetgrentX (struct database_dyn *db
}
out:
- if (use_malloc)
- free (buffer);
+ free (buffer);
*resultp = dataset;

View File

@@ -0,0 +1,214 @@
#
# Based on the commit:
#
# commit 6c82a2f8d7c8e21e39237225c819f182ae438db3
# Author: Carlos O'Donell <carlos@redhat.com>
# Date: Fri Sep 6 01:02:30 2013 -0400
#
# Coordinate IPv6 definitions for Linux and glibc
#
# This change synchronizes the glibc headers with the Linux kernel
# headers and arranges to coordinate the definition of structures
# already defined the Linux kernel UAPI headers.
#
# It is now safe to include glibc's netinet/in.h or Linux's linux/in6.h
# in any order in a userspace application and you will get the same
# ABI. The ABI is guaranteed by UAPI and glibc.
#
# 2013-09-05 Carlos O'Donell <carlos@redhat.com>
# Cong Wang <amwang@redhat.com>
#
# * sysdeps/unix/sysv/linux/bits/in.h
# [_UAPI_LINUX_IN6_H]: Define __USE_KERNEL_IPV6_DEFS.
# * inet/netinet/in.h: Move in_addr definition and bits/in.h inclusion
# before __USE_KERNEL_IPV6_DEFS uses.
# * inet/netinet/in.h [!__USE_KERNEL_IPV6_DEFS]: Define IPPROTO_MH, and
# IPPROTO_BEETPH.
# [__USE_KERNEL_IPV6_DEFS]: Don't define any of IPPROTO_*, in6_addr,
# sockaddr_in6, or ipv6_mreq.
#
diff -urN glibc-2.12-2-gc4ccff1/inet/netinet/in.h glibc-2.12-2-gc4ccff1.mod/inet/netinet/in.h
--- glibc-2.12-2-gc4ccff1/inet/netinet/in.h 2010-05-04 07:27:23.000000000 -0400
+++ glibc-2.12-2-gc4ccff1.mod/inet/netinet/in.h 2015-02-18 13:06:56.436802873 -0500
@@ -28,13 +28,21 @@
__BEGIN_DECLS
+/* Internet address. */
+typedef uint32_t in_addr_t;
+struct in_addr
+ {
+ in_addr_t s_addr;
+ };
+
+/* Get system-specific definitions. */
+#include <bits/in.h>
+
/* Standard well-defined IP protocols. */
enum
{
IPPROTO_IP = 0, /* Dummy protocol for TCP. */
#define IPPROTO_IP IPPROTO_IP
- IPPROTO_HOPOPTS = 0, /* IPv6 Hop-by-Hop options. */
-#define IPPROTO_HOPOPTS IPPROTO_HOPOPTS
IPPROTO_ICMP = 1, /* Internet Control Message Protocol. */
#define IPPROTO_ICMP IPPROTO_ICMP
IPPROTO_IGMP = 2, /* Internet Group Management Protocol. */
@@ -57,10 +65,6 @@
#define IPPROTO_DCCP IPPROTO_DCCP
IPPROTO_IPV6 = 41, /* IPv6 header. */
#define IPPROTO_IPV6 IPPROTO_IPV6
- IPPROTO_ROUTING = 43, /* IPv6 routing header. */
-#define IPPROTO_ROUTING IPPROTO_ROUTING
- IPPROTO_FRAGMENT = 44, /* IPv6 fragmentation header. */
-#define IPPROTO_FRAGMENT IPPROTO_FRAGMENT
IPPROTO_RSVP = 46, /* Reservation Protocol. */
#define IPPROTO_RSVP IPPROTO_RSVP
IPPROTO_GRE = 47, /* General Routing Encapsulation. */
@@ -69,14 +73,10 @@
#define IPPROTO_ESP IPPROTO_ESP
IPPROTO_AH = 51, /* authentication header. */
#define IPPROTO_AH IPPROTO_AH
- IPPROTO_ICMPV6 = 58, /* ICMPv6. */
-#define IPPROTO_ICMPV6 IPPROTO_ICMPV6
- IPPROTO_NONE = 59, /* IPv6 no next header. */
-#define IPPROTO_NONE IPPROTO_NONE
- IPPROTO_DSTOPTS = 60, /* IPv6 destination options. */
-#define IPPROTO_DSTOPTS IPPROTO_DSTOPTS
IPPROTO_MTP = 92, /* Multicast Transport Protocol. */
#define IPPROTO_MTP IPPROTO_MTP
+ IPPROTO_BEETPH = 94, /* IP option pseudo header for BEET. */
+#define IPPROTO_BEETPH IPPROTO_BEETPH
IPPROTO_ENCAP = 98, /* Encapsulation Header. */
#define IPPROTO_ENCAP IPPROTO_ENCAP
IPPROTO_PIM = 103, /* Protocol Independent Multicast. */
@@ -92,6 +92,28 @@
IPPROTO_MAX
};
+/* If __USER_KERNEL_IPV6_DEFS is defined then the user has included the kernel
+ network headers first and we should use those ABI-identical definitions
+ instead of our own. */
+#ifndef __USE_KERNEL_IPV6_DEFS
+enum
+ {
+ IPPROTO_HOPOPTS = 0, /* IPv6 Hop-by-Hop options. */
+#define IPPROTO_HOPOPTS IPPROTO_HOPOPTS
+ IPPROTO_ROUTING = 43, /* IPv6 routing header. */
+#define IPPROTO_ROUTING IPPROTO_ROUTING
+ IPPROTO_FRAGMENT = 44, /* IPv6 fragmentation header. */
+#define IPPROTO_FRAGMENT IPPROTO_FRAGMENT
+ IPPROTO_ICMPV6 = 58, /* ICMPv6. */
+#define IPPROTO_ICMPV6 IPPROTO_ICMPV6
+ IPPROTO_NONE = 59, /* IPv6 no next header. */
+#define IPPROTO_NONE IPPROTO_NONE
+ IPPROTO_DSTOPTS = 60, /* IPv6 destination options. */
+#define IPPROTO_DSTOPTS IPPROTO_DSTOPTS
+ IPPROTO_MH = 135, /* IPv6 mobility header. */
+#define IPPROTO_MH IPPROTO_MH
+ };
+#endif /* !__USE_KERNEL_IPV6_DEFS */
/* Type to represent a port. */
typedef uint16_t in_port_t;
@@ -136,15 +158,6 @@
IPPORT_USERRESERVED = 5000
};
-
-/* Internet address. */
-typedef uint32_t in_addr_t;
-struct in_addr
- {
- in_addr_t s_addr;
- };
-
-
/* Definitions of the bits in an Internet address integer.
On subnets, host and network parts are found according to
@@ -193,7 +206,7 @@
#define INADDR_ALLRTRS_GROUP ((in_addr_t) 0xe0000002) /* 224.0.0.2 */
#define INADDR_MAX_LOCAL_GROUP ((in_addr_t) 0xe00000ff) /* 224.0.0.255 */
-
+#ifndef __USE_KERNEL_IPV6_DEFS
/* IPv6 address */
struct in6_addr
{
@@ -211,6 +224,7 @@
# define s6_addr32 __in6_u.__u6_addr32
#endif
};
+#endif /* !__USE_KERNEL_IPV6_DEFS */
extern const struct in6_addr in6addr_any; /* :: */
extern const struct in6_addr in6addr_loopback; /* ::1 */
@@ -235,6 +249,7 @@
sizeof (struct in_addr)];
};
+#ifndef __USE_KERNEL_IPV6_DEFS
/* Ditto, for IPv6. */
struct sockaddr_in6
{
@@ -244,7 +259,7 @@
struct in6_addr sin6_addr; /* IPv6 address */
uint32_t sin6_scope_id; /* IPv6 scope-id */
};
-
+#endif /* !__USE_KERNEL_IPV6_DEFS */
#if defined __USE_MISC || defined __USE_GNU
/* IPv4 multicast request. */
@@ -270,7 +285,7 @@
};
#endif
-
+#ifndef __USE_KERNEL_IPV6_DEFS
/* Likewise, for IPv6. */
struct ipv6_mreq
{
@@ -280,7 +295,7 @@
/* local interface */
unsigned int ipv6mr_interface;
};
-
+#endif /* !__USE_KERNEL_IPV6_DEFS */
#if defined __USE_MISC || defined __USE_GNU
/* Multicast group request. */
@@ -351,10 +366,6 @@
* sizeof (struct sockaddr_storage)))
#endif
-
-/* Get system-specific definitions. */
-#include <bits/in.h>
-
/* Functions to convert between host and network byte order.
Please note that these functions normally take `unsigned long int' or
diff -urN glibc-2.12-2-gc4ccff1/sysdeps/unix/sysv/linux/bits/in.h glibc-2.12-2-gc4ccff1.mod/sysdeps/unix/sysv/linux/bits/in.h
--- glibc-2.12-2-gc4ccff1/sysdeps/unix/sysv/linux/bits/in.h 2015-02-18 13:04:15.547734092 -0500
+++ glibc-2.12-2-gc4ccff1.mod/sysdeps/unix/sysv/linux/bits/in.h 2015-02-18 13:06:56.436802873 -0500
@@ -22,6 +22,18 @@
# error "Never use <bits/in.h> directly; include <netinet/in.h> instead."
#endif
+/* If the application has already included linux/in6.h from a linux-based
+ kernel then we will not define the IPv6 IPPROTO_* defines, in6_addr (nor the
+ defines), sockaddr_in6, or ipv6_mreq. The ABI used by the linux-kernel and
+ glibc match exactly. Neither the linux kernel nor glibc should break this
+ ABI without coordination. */
+#ifdef _UAPI_LINUX_IN6_H
+/* This is not quite the same API since the kernel always defines s6_addr16 and
+ s6_addr32. This is not a violation of POSIX since POSIX says "at least the
+ following member" and that holds true. */
+# define __USE_KERNEL_IPV6_DEFS
+#endif
+
/* Options for use with `getsockopt' and `setsockopt' at the IP level.
The first word in the comment at the right is the data type used;
"bool" means a boolean value stored in an `int'. */

View File

@@ -0,0 +1,57 @@
commit fbd6b5a4052316f7eb03c4617eebfaafc59dcc06
Author: Siddhesh Poyarekar <siddhesh@redhat.com>
Date: Thu Mar 27 07:15:22 2014 +0530
Fix nscd lookup for innetgr when netgroup has wildcards (BZ #16758)
nscd works correctly when the request in innetgr is a wildcard,
i.e. when one or more of host, user or domain parameters is NULL.
However, it does not work when the the triplet in the netgroup
definition has a wildcard. This is easy to reproduce for a triplet
defined as follows:
foonet (,foo,)
Here, an innetgr call that looks like this:
innetgr ("foonet", "foohost", "foo", NULL);
should succeed and so should:
innetgr ("foonet", NULL, "foo", "foodomain");
It does succeed with nscd disabled, but not with nscd enabled. This
fix adds this additional check for all three parts of the triplet so
that it gives the correct result.
[BZ #16758]
* nscd/netgroupcache.c (addinnetgrX): Succeed if triplet has
blank values.
diff --git a/nscd/netgroupcache.c b/nscd/netgroupcache.c
index 5ba1e1f..5d15aa4 100644
--- a/nscd/netgroupcache.c
+++ b/nscd/netgroupcache.c
@@ -560,15 +560,19 @@ addinnetgrX (struct database_dyn *db, int fd, request_header *req,
{
bool success = true;
- if (host != NULL)
+ /* For the host, user and domain in each triplet, we assume success
+ if the value is blank because that is how the wildcard entry to
+ match anything is stored in the netgroup cache. */
+ if (host != NULL && *triplets != '\0')
success = strcmp (host, triplets) == 0;
triplets = (const char *) rawmemchr (triplets, '\0') + 1;
- if (success && user != NULL)
+ if (success && user != NULL && *triplets != '\0')
success = strcmp (user, triplets) == 0;
triplets = (const char *) rawmemchr (triplets, '\0') + 1;
- if (success && (domain == NULL || strcmp (domain, triplets) == 0))
+ if (success && (domain == NULL || *triplets == '\0'
+ || strcmp (domain, triplets) == 0))
{
dataset->resp.result = 1;
break;

View File

@@ -0,0 +1,620 @@
diff --git a/malloc/Makefile b/malloc/Makefile
index e7ec1ab..5330a3b 100644
--- a/malloc/Makefile
+++ b/malloc/Makefile
@@ -27,7 +27,8 @@ all:
dist-headers := malloc.h
headers := $(dist-headers) obstack.h mcheck.h
tests := mallocbug tst-malloc tst-valloc tst-calloc tst-obstack \
- tst-mallocstate tst-mcheck tst-mallocfork tst-trim1
+ tst-mallocstate tst-mcheck tst-mallocfork tst-trim1 \
+ tst-malloc-backtrace
test-srcs = tst-mtrace
distribute = thread-m.h mtrace.pl mcheck-init.c stackinfo.h memusage.h \
@@ -49,6 +50,9 @@ extra-libs-others = $(extra-libs)
libmemusage-routines = memusage
libmemusage-inhibit-o = $(filter-out .os,$(object-suffixes))
+$(objpfx)tst-malloc-backtrace: $(common-objpfx)nptl/libpthread.so \
+ $(common-objpfx)nptl/libpthread_nonshared.a
+
# These should be removed by `make clean'.
extra-objs = mcheck-init.o libmcheck.a
diff --git a/malloc/arena.c b/malloc/arena.c
index 18bea2b..5180516 100644
--- a/malloc/arena.c
+++ b/malloc/arena.c
@@ -123,7 +123,7 @@ int __malloc_initialized = -1;
#ifdef PER_THREAD
#define arena_lock(ptr, size) do { \
- if(ptr) \
+ if(ptr && !arena_is_corrupt (ptr)) \
(void)mutex_lock(&ptr->mutex); \
else \
ptr = arena_get2(ptr, (size), false); \
@@ -1011,7 +1011,21 @@ reused_arena (bool retrying)
if (retrying && result == &main_arena)
result = result->next;
- /* No arena available. Wait for the next in line. */
+ /* Make sure that the arena we get is not corrupted. */
+ mstate begin = result;
+ while (arena_is_corrupt (result))
+ {
+ result = result->next;
+ if (result == begin)
+ break;
+ }
+
+ /* We could not find any arena that was either not corrupted or not the one
+ we wanted to avoid. */
+ if (result == begin)
+ return NULL;
+
+ /* No arena available without contention. Wait for the next in line. */
(void)mutex_lock(&result->mutex);
out:
diff --git a/malloc/hooks.c b/malloc/hooks.c
index cc83d21..38d2542 100644
--- a/malloc/hooks.c
+++ b/malloc/hooks.c
@@ -220,7 +220,8 @@ top_check()
return 0;
mutex_unlock(&main_arena);
- malloc_printerr (check_action, "malloc: top chunk is corrupt", t);
+ malloc_printerr (check_action, "malloc: top chunk is corrupt", t,
+ &main_arena);
mutex_lock(&main_arena);
/* Try to set up a new top chunk. */
@@ -283,7 +284,7 @@ free_check(mem, caller) Void_t* mem; const Void_t *caller;
if(!p) {
(void)mutex_unlock(&main_arena.mutex);
- malloc_printerr(check_action, "free(): invalid pointer", mem);
+ malloc_printerr(check_action, "free(): invalid pointer", mem, &main_arena);
return;
}
#if HAVE_MMAP
@@ -329,7 +330,8 @@ realloc_check(oldmem, bytes, caller)
const mchunkptr oldp = mem2chunk_check(oldmem, &magic_p);
(void)mutex_unlock(&main_arena.mutex);
if(!oldp) {
- malloc_printerr(check_action, "realloc(): invalid pointer", oldmem);
+ malloc_printerr(check_action, "realloc(): invalid pointer", oldmem,
+ &main_arena);
return malloc_check(bytes, NULL);
}
const INTERNAL_SIZE_T oldsize = chunksize(oldp);
diff --git a/malloc/malloc.c b/malloc/malloc.c
index 597c7b0..20ac534 100644
--- a/malloc/malloc.c
+++ b/malloc/malloc.c
@@ -1633,7 +1633,7 @@ static size_t mUSABLe(Void_t*);
static void mSTATs(void);
static int mALLOPt(int, int);
static struct mallinfo mALLINFo(mstate);
-static void malloc_printerr(int action, const char *str, void *ptr);
+static void malloc_printerr(int action, const char *str, void *ptr, mstate av);
static Void_t* internal_function mem2mem_check(Void_t *p, size_t sz);
static int internal_function top_check(void);
@@ -2114,7 +2114,8 @@ typedef struct malloc_chunk* mbinptr;
BK = P->bk; \
if (__builtin_expect (FD->bk != P || BK->fd != P, 0)) { \
mutex_unlock(&(AV)->mutex); \
- malloc_printerr (check_action, "corrupted double-linked list", P); \
+ malloc_printerr (check_action, "corrupted double-linked list", P, \
+ AV); \
mutex_lock(&(AV)->mutex); \
} else { \
FD->bk = BK; \
@@ -2344,6 +2345,15 @@ typedef struct malloc_chunk* mfastbinptr;
#define set_noncontiguous(M) ((M)->flags |= NONCONTIGUOUS_BIT)
#define set_contiguous(M) ((M)->flags &= ~NONCONTIGUOUS_BIT)
+/* ARENA_CORRUPTION_BIT is set if a memory corruption was detected on the
+ arena. Such an arena is no longer used to allocate chunks. Chunks
+ allocated in that arena before detecting corruption are not freed. */
+
+#define ARENA_CORRUPTION_BIT (4U)
+
+#define arena_is_corrupt(A) (((A)->flags & ARENA_CORRUPTION_BIT))
+#define set_arena_corrupt(A) ((A)->flags |= ARENA_CORRUPTION_BIT)
+
/*
Set value of max_fast.
Use impossibly small value if 0.
@@ -3002,8 +3012,9 @@ static Void_t* sYSMALLOc(nb, av) INTERNAL_SIZE_T nb; mstate av;
rather than expanding top.
*/
- if ((unsigned long)(nb) >= (unsigned long)(mp_.mmap_threshold) &&
- (mp_.n_mmaps < mp_.n_mmaps_max)) {
+ if (av == NULL
+ || ((unsigned long)(nb) >= (unsigned long)(mp_.mmap_threshold) &&
+ (mp_.n_mmaps < mp_.n_mmaps_max))) {
char* mm; /* return value from mmap call*/
@@ -3079,6 +3090,10 @@ static Void_t* sYSMALLOc(nb, av) INTERNAL_SIZE_T nb; mstate av;
}
#endif
+ /* There are no usable arenas and mmap also failed. */
+ if (av == NULL)
+ return 0;
+
/* Record incoming configuration of top */
old_top = av->top;
@@ -3260,7 +3275,7 @@ static Void_t* sYSMALLOc(nb, av) INTERNAL_SIZE_T nb; mstate av;
else if (contiguous(av) && old_size && brk < old_end) {
/* Oops! Someone else killed our space.. Can't touch anything. */
mutex_unlock(&av->mutex);
- malloc_printerr (3, "break adjusted to free malloc space", brk);
+ malloc_printerr (3, "break adjusted to free malloc space", brk, av);
mutex_lock(&av->mutex);
}
@@ -3542,7 +3557,7 @@ munmap_chunk(p) mchunkptr p;
if (__builtin_expect (((block | total_size) & (mp_.pagesize - 1)) != 0, 0))
{
malloc_printerr (check_action, "munmap_chunk(): invalid pointer",
- chunk2mem (p));
+ chunk2mem (p), NULL);
return;
}
@@ -3625,65 +3640,31 @@ public_mALLOc(size_t bytes)
if (__builtin_expect (hook != NULL, 0))
return (*hook)(bytes, RETURN_ADDRESS (0));
- arena_lookup(ar_ptr);
-#if 0
- // XXX We need double-word CAS and fastbins must be extended to also
- // XXX hold a generation counter for each entry.
- if (ar_ptr) {
- INTERNAL_SIZE_T nb; /* normalized request size */
- checked_request2size(bytes, nb);
- if (nb <= get_max_fast ()) {
- long int idx = fastbin_index(nb);
- mfastbinptr* fb = &fastbin (ar_ptr, idx);
- mchunkptr pp = *fb;
- mchunkptr v;
- do
- {
- v = pp;
- if (v == NULL)
- break;
- }
- while ((pp = catomic_compare_and_exchange_val_acq (fb, v->fd, v)) != v);
- if (v != 0) {
- if (__builtin_expect (fastbin_index (chunksize (v)) != idx, 0))
- malloc_printerr (check_action, "malloc(): memory corruption (fast)",
- chunk2mem (v));
- check_remalloced_chunk(ar_ptr, v, nb);
- void *p = chunk2mem(v);
- if (__builtin_expect (perturb_byte, 0))
- alloc_perturb (p, bytes);
- return p;
- }
- }
- }
-#endif
+ arena_get(ar_ptr, bytes);
- arena_lock(ar_ptr, bytes);
- if(!ar_ptr)
- return 0;
victim = _int_malloc(ar_ptr, bytes);
- if(!victim) {
+ if(!victim && ar_ptr != NULL) {
/* Maybe the failure is due to running out of mmapped areas. */
if(ar_ptr != &main_arena) {
(void)mutex_unlock(&ar_ptr->mutex);
ar_ptr = &main_arena;
(void)mutex_lock(&ar_ptr->mutex);
victim = _int_malloc(ar_ptr, bytes);
- (void)mutex_unlock(&ar_ptr->mutex);
} else {
#if USE_ARENAS
/* ... or sbrk() has failed and there is still a chance to mmap() */
mstate prev = ar_ptr->next ? ar_ptr : 0;
(void)mutex_unlock(&ar_ptr->mutex);
ar_ptr = arena_get2(prev, bytes, true);
- if(ar_ptr) {
+ if(ar_ptr)
victim = _int_malloc(ar_ptr, bytes);
- (void)mutex_unlock(&ar_ptr->mutex);
- }
#endif
}
- } else
+ }
+
+ if (ar_ptr != NULL)
(void)mutex_unlock(&ar_ptr->mutex);
+
assert(!victim || chunk_is_mmapped(mem2chunk(victim)) ||
ar_ptr == arena_for_chunk(mem2chunk(victim)));
return victim;
@@ -3773,6 +3754,11 @@ public_rEALLOc(Void_t* oldmem, size_t bytes)
/* its size */
const INTERNAL_SIZE_T oldsize = chunksize(oldp);
+ if (chunk_is_mmapped (oldp))
+ ar_ptr = NULL;
+ else
+ ar_ptr = arena_for_chunk (oldp);
+
/* Little security check which won't hurt performance: the
allocator never wrapps around at the end of the address space.
Therefore we can exclude some size values which might appear
@@ -3780,7 +3766,8 @@ public_rEALLOc(Void_t* oldmem, size_t bytes)
if (__builtin_expect ((uintptr_t) oldp > (uintptr_t) -oldsize, 0)
|| __builtin_expect (misaligned_chunk (oldp), 0))
{
- malloc_printerr (check_action, "realloc(): invalid pointer", oldmem);
+ malloc_printerr (check_action, "realloc(): invalid pointer", oldmem,
+ ar_ptr);
return NULL;
}
@@ -3806,7 +3793,6 @@ public_rEALLOc(Void_t* oldmem, size_t bytes)
}
#endif
- ar_ptr = arena_for_chunk(oldp);
#if THREAD_STATS
if(!mutex_trylock(&ar_ptr->mutex))
++(ar_ptr->stat_lock_direct);
@@ -3887,31 +3873,29 @@ public_mEMALIGn(size_t alignment, size_t bytes)
}
arena_get(ar_ptr, bytes + alignment + MINSIZE);
- if(!ar_ptr)
- return 0;
p = _int_memalign(ar_ptr, alignment, bytes);
- if(!p) {
+ if(!p && ar_ptr != NULL) {
/* Maybe the failure is due to running out of mmapped areas. */
if(ar_ptr != &main_arena) {
(void)mutex_unlock(&ar_ptr->mutex);
ar_ptr = &main_arena;
(void)mutex_lock(&ar_ptr->mutex);
p = _int_memalign(ar_ptr, alignment, bytes);
- (void)mutex_unlock(&ar_ptr->mutex);
} else {
#if USE_ARENAS
/* ... or sbrk() has failed and there is still a chance to mmap() */
mstate prev = ar_ptr->next ? ar_ptr : 0;
(void)mutex_unlock(&ar_ptr->mutex);
ar_ptr = arena_get2(prev, bytes, true);
- if(ar_ptr) {
+ if(ar_ptr)
p = _int_memalign(ar_ptr, alignment, bytes);
- (void)mutex_unlock(&ar_ptr->mutex);
- }
#endif
}
- } else
+ }
+
+ if (ar_ptr != NULL)
(void)mutex_unlock(&ar_ptr->mutex);
+
assert(!p || chunk_is_mmapped(mem2chunk(p)) ||
ar_ptr == arena_for_chunk(mem2chunk(p)));
return p;
@@ -3945,31 +3929,29 @@ public_vALLOc(size_t bytes)
return (*hook)(pagesz, bytes, RETURN_ADDRESS (0));
arena_get(ar_ptr, bytes + pagesz + MINSIZE);
- if(!ar_ptr)
- return 0;
p = _int_valloc(ar_ptr, bytes);
- if(!p) {
+ if(!p && ar_ptr != NULL) {
/* Maybe the failure is due to running out of mmapped areas. */
if(ar_ptr != &main_arena) {
(void)mutex_unlock(&ar_ptr->mutex);
ar_ptr = &main_arena;
(void)mutex_lock(&ar_ptr->mutex);
p = _int_memalign(ar_ptr, pagesz, bytes);
- (void)mutex_unlock(&ar_ptr->mutex);
} else {
#if USE_ARENAS
/* ... or sbrk() has failed and there is still a chance to mmap() */
mstate prev = ar_ptr->next ? ar_ptr : 0;
(void)mutex_unlock(&ar_ptr->mutex);
ar_ptr = arena_get2(prev, bytes, true);
- if(ar_ptr) {
+ if(ar_ptr)
p = _int_memalign(ar_ptr, pagesz, bytes);
- (void)mutex_unlock(&ar_ptr->mutex);
- }
#endif
}
- } else
+ }
+
+ if (ar_ptr != NULL)
(void)mutex_unlock(&ar_ptr->mutex);
+
assert(!p || chunk_is_mmapped(mem2chunk(p)) ||
ar_ptr == arena_for_chunk(mem2chunk(p)));
@@ -4004,28 +3986,28 @@ public_pVALLOc(size_t bytes)
arena_get(ar_ptr, bytes + 2*pagesz + MINSIZE);
p = _int_pvalloc(ar_ptr, bytes);
- if(!p) {
+ if(!p && ar_ptr != NULL) {
/* Maybe the failure is due to running out of mmapped areas. */
if(ar_ptr != &main_arena) {
(void)mutex_unlock(&ar_ptr->mutex);
ar_ptr = &main_arena;
(void)mutex_lock(&ar_ptr->mutex);
p = _int_memalign(ar_ptr, pagesz, rounded_bytes);
- (void)mutex_unlock(&ar_ptr->mutex);
} else {
#if USE_ARENAS
/* ... or sbrk() has failed and there is still a chance to mmap() */
mstate prev = ar_ptr->next ? ar_ptr : 0;
(void)mutex_unlock(&ar_ptr->mutex);
ar_ptr = arena_get2(prev, bytes + 2*pagesz + MINSIZE, true);
- if(ar_ptr) {
+ if(ar_ptr)
p = _int_memalign(ar_ptr, pagesz, rounded_bytes);
- (void)mutex_unlock(&ar_ptr->mutex);
- }
#endif
}
- } else
+ }
+
+ if (ar_ptr != NULL)
(void)mutex_unlock(&ar_ptr->mutex);
+
assert(!p || chunk_is_mmapped(mem2chunk(p)) ||
ar_ptr == arena_for_chunk(mem2chunk(p)));
@@ -4072,55 +4054,65 @@ public_cALLOc(size_t n, size_t elem_size)
sz = bytes;
arena_get(av, sz);
- if(!av)
- return 0;
- /* Check if we hand out the top chunk, in which case there may be no
- need to clear. */
+ if (av)
+ {
+ /* Check if we hand out the top chunk, in which case there may be no
+ need to clear. */
#if MORECORE_CLEARS
- oldtop = top(av);
- oldtopsize = chunksize(top(av));
+ oldtop = top(av);
+ oldtopsize = chunksize(top(av));
#if MORECORE_CLEARS < 2
- /* Only newly allocated memory is guaranteed to be cleared. */
- if (av == &main_arena &&
- oldtopsize < mp_.sbrk_base + av->max_system_mem - (char *)oldtop)
- oldtopsize = (mp_.sbrk_base + av->max_system_mem - (char *)oldtop);
+ /* Only newly allocated memory is guaranteed to be cleared. */
+ if (av == &main_arena &&
+ oldtopsize < mp_.sbrk_base + av->max_system_mem - (char *)oldtop)
+ oldtopsize = (mp_.sbrk_base + av->max_system_mem - (char *)oldtop);
#endif
- if (av != &main_arena)
+ if (av != &main_arena)
+ {
+ heap_info *heap = heap_for_ptr (oldtop);
+ if (oldtopsize < (char *) heap + heap->mprotect_size - (char *) oldtop)
+ oldtopsize = (char *) heap + heap->mprotect_size - (char *) oldtop;
+ }
+#endif
+ }
+ else
{
- heap_info *heap = heap_for_ptr (oldtop);
- if (oldtopsize < (char *) heap + heap->mprotect_size - (char *) oldtop)
- oldtopsize = (char *) heap + heap->mprotect_size - (char *) oldtop;
+ /* No usable arenas. */
+ oldtop = 0;
+ oldtopsize = 0;
}
-#endif
mem = _int_malloc(av, sz);
-
assert(!mem || chunk_is_mmapped(mem2chunk(mem)) ||
av == arena_for_chunk(mem2chunk(mem)));
- if (mem == 0) {
+ if (mem == 0 && av != NULL) {
/* Maybe the failure is due to running out of mmapped areas. */
if(av != &main_arena) {
(void)mutex_unlock(&av->mutex);
(void)mutex_lock(&main_arena.mutex);
mem = _int_malloc(&main_arena, sz);
- (void)mutex_unlock(&main_arena.mutex);
} else {
#if USE_ARENAS
/* ... or sbrk() has failed and there is still a chance to mmap() */
mstate prev = av->next ? av : 0;
(void)mutex_unlock(&av->mutex);
av = arena_get2(prev, sz, true);
- if(av) {
+ if(av)
mem = _int_malloc(av, sz);
- (void)mutex_unlock(&av->mutex);
- }
#endif
}
if (mem == 0) return 0;
- } else
+ }
+
+ if (av != NULL)
(void)mutex_unlock(&av->mutex);
+
+ /* Allocation failed even after a retry. */
+ if (mem == 0)
+ return 0;
+
p = mem2chunk(mem);
/* Two optional cases in which clearing not necessary */
@@ -4175,6 +4167,8 @@ public_cALLOc(size_t n, size_t elem_size)
}
#ifndef _LIBC
+/* XXX These functions are not patched to detect arena corruption because they
+ are not built in glibc. */
Void_t**
public_iCALLOc(size_t n, size_t elem_size, Void_t** chunks)
@@ -4309,6 +4303,16 @@ _int_malloc(mstate av, size_t bytes)
checked_request2size(bytes, nb);
+ /* There are no usable arenas. Fall back to sysmalloc to get a chunk from
+ mmap. */
+ if (__glibc_unlikely (av == NULL))
+ {
+ void *p = sYSMALLOc (nb, av);
+ if (p != NULL)
+ alloc_perturb (p, bytes);
+ return p;
+ }
+
/*
If the size qualifies as a fastbin, first check corresponding bin.
This code is safe to execute even if av is not yet initialized, so we
@@ -4337,7 +4341,7 @@ _int_malloc(mstate av, size_t bytes)
errstr = "malloc(): memory corruption (fast)";
errout:
mutex_unlock(&av->mutex);
- malloc_printerr (check_action, errstr, chunk2mem (victim));
+ malloc_printerr (check_action, errstr, chunk2mem (victim), av);
mutex_lock(&av->mutex);
return NULL;
}
@@ -4429,7 +4433,7 @@ _int_malloc(mstate av, size_t bytes)
{
void *p = chunk2mem(victim);
mutex_unlock(&av->mutex);
- malloc_printerr (check_action, "malloc(): memory corruption", p);
+ malloc_printerr (check_action, "malloc(): memory corruption", p, av);
mutex_lock(&av->mutex);
}
size = chunksize(victim);
@@ -4829,7 +4833,7 @@ _int_free(mstate av, mchunkptr p)
if (have_lock || locked)
(void)mutex_unlock(&av->mutex);
#endif
- malloc_printerr (check_action, errstr, chunk2mem(p));
+ malloc_printerr (check_action, errstr, chunk2mem(p), av);
#ifdef ATOMIC_FASTBINS
if (have_lock)
mutex_lock(&av->mutex);
@@ -5281,7 +5285,7 @@ _int_realloc(mstate av, mchunkptr oldp, INTERNAL_SIZE_T oldsize,
errstr = "realloc(): invalid old size";
errout:
mutex_unlock(&av->mutex);
- malloc_printerr (check_action, errstr, chunk2mem(oldp));
+ malloc_printerr (check_action, errstr, chunk2mem(oldp), av);
mutex_lock(&av->mutex);
return NULL;
}
@@ -5881,6 +5885,10 @@ static int mTRIm(mstate av, size_t pad)
static int mTRIm(av, pad) mstate av; size_t pad;
#endif
{
+ /* Don't touch corrupt arenas. */
+ if (arena_is_corrupt (av))
+ return 0;
+
/* Ensure initialization/consolidation */
malloc_consolidate (av);
@@ -6320,8 +6328,14 @@ int mALLOPt(param_number, value) int param_number; int value;
extern char **__libc_argv attribute_hidden;
static void
-malloc_printerr(int action, const char *str, void *ptr)
+malloc_printerr(int action, const char *str, void *ptr, mstate ar_ptr)
{
+ /* Avoid using this arena in future. We do not attempt to synchronize this
+ with anything else because we minimally want to ensure that __libc_message
+ gets its resources safely without stumbling on the current corruption. */
+ if (ar_ptr)
+ set_arena_corrupt (ar_ptr);
+
if ((action & 5) == 5)
__libc_message (action & 2, "%s\n", str);
else if (action & 1)
diff --git a/malloc/tst-malloc-backtrace.c b/malloc/tst-malloc-backtrace.c
new file mode 100644
index 0000000..796a42f
--- /dev/null
+++ b/malloc/tst-malloc-backtrace.c
@@ -0,0 +1,50 @@
+/* Verify that backtrace does not deadlock on itself on memory corruption.
+ Copyright (C) 2015 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 <stdlib.h>
+
+#define SIZE 4096
+
+/* Wrap free with a function to prevent gcc from optimizing it out. */
+static void
+__attribute__((noinline))
+call_free (void *ptr)
+{
+ free (ptr);
+ *(size_t *)(ptr - sizeof (size_t)) = 1;
+}
+
+int
+do_test (void)
+{
+ void *ptr1 = malloc (SIZE);
+ void *ptr2 = malloc (SIZE);
+
+ call_free ((void *) ptr1);
+ ptr1 = malloc (SIZE);
+
+ /* Not reached. The return statement is to put ptr2 into use so that gcc
+ doesn't optimize out that malloc call. */
+ return (ptr1 == ptr2);
+}
+
+#define TEST_FUNCTION do_test ()
+#define EXPECTED_SIGNAL SIGABRT
+
+#include "../test-skeleton.c"

View File

@@ -0,0 +1,26 @@
commit c44496df2f090a56d3bf75df930592dac6bba46f
Author: Siddhesh Poyarekar <siddhesh@redhat.com>
Date: Wed Mar 12 17:27:22 2014 +0530
Provide correct buffer length to netgroup queries in nscd (BZ #16695)
The buffer to query netgroup entries is allocated sufficient space for
the netgroup entries and the key to be appended at the end, but it
sends in an incorrect available length to the NSS netgroup query
functions, resulting in overflow of the buffer in some special cases.
The fix here is to factor in the key length when sending the available
buffer and buffer length to the query functions.
diff --git a/nscd/netgroupcache.c b/nscd/netgroupcache.c
index 426d3c5..5ba1e1f 100644
--- a/nscd/netgroupcache.c
+++ b/nscd/netgroupcache.c
@@ -202,7 +202,7 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
{
int e;
status = getfct.f (&data, buffer + buffilled,
- buflen - buffilled, &e);
+ buflen - buffilled - req->key_len, &e);
if (status == NSS_STATUS_RETURN
|| status == NSS_STATUS_NOTFOUND)
/* This was either the last one for this group or the

View File

@@ -0,0 +1,398 @@
commit bc8f194c8c29e46e8ee4034f06e46988dfff38f7
Author: Siddhesh Poyarekar <siddhesh@redhat.com>
Date: Wed Apr 30 12:00:39 2014 +0530
Initialize all of datahead structure in nscd (BZ #16791)
The datahead structure has an unused padding field that remains
uninitialized. Valgrind prints out a warning for it on querying a
netgroups entry. This is harmless, but is a potential data leak since
it would result in writing out an uninitialized byte to the cache
file. Besides, this happens only when there is a cache miss, so we're
not adding computation to any fast path.
commit 1cdeb2372ddecac0dfe0c132a033e9590ffa07d2
Author: Siddhesh Poyarekar <siddhesh@redhat.com>
Date: Wed Apr 30 11:57:09 2014 +0530
Consolidate code to initialize nscd dataset header
This patch consolidates the code to initialize the header of a dataset
into a single set of functions (one for positive and another for
negative datasets) primarily to reduce repetition of code. The
secondary reason is to simplify Patch 2/2 which fixes the problem of
an uninitialized byte in the header by initializing an unused field in
the structure and hence preventing a possible data leak into the cache
file.
diff --git a/nscd/aicache.c b/nscd/aicache.c
index 98d40a1..d7966bd 100644
--- a/nscd/aicache.c
+++ b/nscd/aicache.c
@@ -383,17 +383,12 @@ addhstaiX (struct database_dyn *db, int fd, request_header *req,
cp = family;
}
- /* Fill in the rest of the dataset. */
- dataset->head.allocsize = total + req->key_len;
- dataset->head.recsize = total - offsetof (struct dataset, resp);
- dataset->head.notfound = false;
- dataset->head.nreloads = he == NULL ? 0 : (dh->nreloads + 1);
- dataset->head.usable = true;
-
- /* Compute the timeout time. */
- dataset->head.ttl = ttl == INT32_MAX ? db->postimeout : ttl;
- timeout = dataset->head.timeout = time (NULL) + dataset->head.ttl;
+ timeout = datahead_init_pos (&dataset->head, total + req->key_len,
+ total - offsetof (struct dataset, resp),
+ he == NULL ? 0 : dh->nreloads + 1,
+ ttl == INT32_MAX ? db->postimeout : ttl);
+ /* Fill in the rest of the dataset. */
dataset->resp.version = NSCD_VERSION;
dataset->resp.found = 1;
dataset->resp.naddrs = naddrs;
@@ -528,15 +523,9 @@ next_nip:
else if ((dataset = mempool_alloc (db, (sizeof (struct dataset)
+ req->key_len), 1)) != NULL)
{
- dataset->head.allocsize = sizeof (struct dataset) + req->key_len;
- dataset->head.recsize = total;
- dataset->head.notfound = true;
- dataset->head.nreloads = 0;
- dataset->head.usable = true;
-
- /* Compute the timeout time. */
- timeout = dataset->head.timeout = time (NULL) + db->negtimeout;
- dataset->head.ttl = db->negtimeout;
+ timeout = datahead_init_neg (&dataset->head,
+ sizeof (struct dataset) + req->key_len,
+ total, db->negtimeout);
/* This is the reply. */
memcpy (&dataset->resp, &notfound, total);
diff --git a/nscd/grpcache.c b/nscd/grpcache.c
index b5a33eb..df59fa7 100644
--- a/nscd/grpcache.c
+++ b/nscd/grpcache.c
@@ -128,14 +128,10 @@ cache_addgr (struct database_dyn *db, int fd, request_header *req,
}
else if ((dataset = mempool_alloc (db, sizeof (struct dataset) + req->key_len, 1)) != NULL)
{
- dataset->head.allocsize = sizeof (struct dataset) + req->key_len;
- dataset->head.recsize = total;
- dataset->head.notfound = true;
- dataset->head.nreloads = 0;
- dataset->head.usable = true;
-
- /* Compute the timeout time. */
- timeout = dataset->head.timeout = t + db->negtimeout;
+ timeout = datahead_init_neg (&dataset->head,
+ (sizeof (struct dataset)
+ + req->key_len), total,
+ db->negtimeout);
/* This is the reply. */
memcpy (&dataset->resp, &notfound, total);
@@ -232,14 +228,10 @@ cache_addgr (struct database_dyn *db, int fd, request_header *req,
dataset_temporary = true;
}
- dataset->head.allocsize = total + n;
- dataset->head.recsize = total - offsetof (struct dataset, resp);
- dataset->head.notfound = false;
- dataset->head.nreloads = he == NULL ? 0 : (dh->nreloads + 1);
- dataset->head.usable = true;
-
- /* Compute the timeout time. */
- timeout = dataset->head.timeout = t + db->postimeout;
+ timeout = datahead_init_pos (&dataset->head, total + n,
+ total - offsetof (struct dataset, resp),
+ he == NULL ? 0 : dh->nreloads + 1,
+ db->postimeout);
dataset->resp.version = NSCD_VERSION;
dataset->resp.found = 1;
diff --git a/nscd/hstcache.c b/nscd/hstcache.c
index a79b67a..d4f1ad2 100644
--- a/nscd/hstcache.c
+++ b/nscd/hstcache.c
@@ -152,15 +152,11 @@ cache_addhst (struct database_dyn *db, int fd, request_header *req,
else if ((dataset = mempool_alloc (db, (sizeof (struct dataset)
+ req->key_len), 1)) != NULL)
{
- dataset->head.allocsize = sizeof (struct dataset) + req->key_len;
- dataset->head.recsize = total;
- dataset->head.notfound = true;
- dataset->head.nreloads = 0;
- dataset->head.usable = true;
-
- /* Compute the timeout time. */
- dataset->head.ttl = ttl == INT32_MAX ? db->negtimeout : ttl;
- timeout = dataset->head.timeout = t + dataset->head.ttl;
+ timeout = datahead_init_neg (&dataset->head,
+ (sizeof (struct dataset)
+ + req->key_len), total,
+ (ttl == INT32_MAX
+ ? db->negtimeout : ttl));
/* This is the reply. */
memcpy (&dataset->resp, resp, total);
@@ -257,15 +253,10 @@ cache_addhst (struct database_dyn *db, int fd, request_header *req,
alloca_used = true;
}
- dataset->head.allocsize = total + req->key_len;
- dataset->head.recsize = total - offsetof (struct dataset, resp);
- dataset->head.notfound = false;
- dataset->head.nreloads = he == NULL ? 0 : (dh->nreloads + 1);
- dataset->head.usable = true;
-
- /* Compute the timeout time. */
- dataset->head.ttl = ttl == INT32_MAX ? db->postimeout : ttl;
- timeout = dataset->head.timeout = t + dataset->head.ttl;
+ timeout = datahead_init_pos (&dataset->head, total + req->key_len,
+ total - offsetof (struct dataset, resp),
+ he == NULL ? 0 : dh->nreloads + 1,
+ ttl == INT32_MAX ? db->postimeout : ttl);
dataset->resp.version = NSCD_VERSION;
dataset->resp.found = 1;
diff --git a/nscd/initgrcache.c b/nscd/initgrcache.c
index 1bf9f0d..361319f 100644
--- a/nscd/initgrcache.c
+++ b/nscd/initgrcache.c
@@ -213,14 +213,10 @@ addinitgroupsX (struct database_dyn *db, int fd, request_header *req,
else if ((dataset = mempool_alloc (db, (sizeof (struct dataset)
+ req->key_len), 1)) != NULL)
{
- dataset->head.allocsize = sizeof (struct dataset) + req->key_len;
- dataset->head.recsize = total;
- dataset->head.notfound = true;
- dataset->head.nreloads = 0;
- dataset->head.usable = true;
-
- /* Compute the timeout time. */
- timeout = dataset->head.timeout = time (NULL) + db->negtimeout;
+ timeout = datahead_init_neg (&dataset->head,
+ (sizeof (struct dataset)
+ + req->key_len), total,
+ db->negtimeout);
/* This is the reply. */
memcpy (&dataset->resp, &notfound, total);
@@ -276,14 +272,10 @@ addinitgroupsX (struct database_dyn *db, int fd, request_header *req,
alloca_used = true;
}
- dataset->head.allocsize = total + req->key_len;
- dataset->head.recsize = total - offsetof (struct dataset, resp);
- dataset->head.notfound = false;
- dataset->head.nreloads = he == NULL ? 0 : (dh->nreloads + 1);
- dataset->head.usable = true;
-
- /* Compute the timeout time. */
- timeout = dataset->head.timeout = time (NULL) + db->postimeout;
+ timeout = datahead_init_pos (&dataset->head, total + req->key_len,
+ total - offsetof (struct dataset, resp),
+ he == NULL ? 0 : dh->nreloads + 1,
+ db->postimeout);
dataset->resp.version = NSCD_VERSION;
dataset->resp.found = 1;
diff --git a/nscd/netgroupcache.c b/nscd/netgroupcache.c
index 820d823..b3d40e9 100644
--- a/nscd/netgroupcache.c
+++ b/nscd/netgroupcache.c
@@ -90,15 +90,9 @@ do_notfound (struct database_dyn *db, int fd, request_header *req,
/* If we cannot permanently store the result, so be it. */
if (dataset != NULL)
{
- dataset->head.allocsize = sizeof (struct dataset) + req->key_len;
- dataset->head.recsize = total;
- dataset->head.notfound = true;
- dataset->head.nreloads = 0;
- dataset->head.usable = true;
-
- /* Compute the timeout time. */
- timeout = dataset->head.timeout = time (NULL) + db->negtimeout;
- dataset->head.ttl = db->negtimeout;
+ timeout = datahead_init_neg (&dataset->head,
+ sizeof (struct dataset) + req->key_len,
+ total, db->negtimeout);
/* This is the reply. */
memcpy (&dataset->resp, &notfound, total);
@@ -359,13 +353,10 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
/* Fill in the dataset. */
dataset = (struct dataset *) buffer;
- dataset->head.allocsize = total + req->key_len;
- dataset->head.recsize = total - offsetof (struct dataset, resp);
- dataset->head.notfound = false;
- dataset->head.nreloads = he == NULL ? 0 : (dh->nreloads + 1);
- dataset->head.usable = true;
- dataset->head.ttl = db->postimeout;
- timeout = dataset->head.timeout = time (NULL) + dataset->head.ttl;
+ timeout = datahead_init_pos (&dataset->head, total + req->key_len,
+ total - offsetof (struct dataset, resp),
+ he == NULL ? 0 : dh->nreloads + 1,
+ db->postimeout);
dataset->resp.version = NSCD_VERSION;
dataset->resp.found = 1;
@@ -541,12 +532,12 @@ addinnetgrX (struct database_dyn *db, int fd, request_header *req,
dataset = &dataset_mem;
}
- dataset->head.allocsize = sizeof (*dataset) + req->key_len;
- dataset->head.recsize = sizeof (innetgroup_response_header);
+ datahead_init_pos (&dataset->head, sizeof (*dataset) + req->key_len,
+ sizeof (innetgroup_response_header),
+ he == NULL ? 0 : dh->nreloads + 1, result->head.ttl);
+ /* Set the notfound status and timeout based on the result from
+ getnetgrent. */
dataset->head.notfound = result->head.notfound;
- dataset->head.nreloads = he == NULL ? 0 : (dh->nreloads + 1);
- dataset->head.usable = true;
- dataset->head.ttl = result->head.ttl;
dataset->head.timeout = timeout;
dataset->resp.version = NSCD_VERSION;
diff --git a/nscd/nscd-client.h b/nscd/nscd-client.h
index 98f77e7..ee16df6 100644
--- a/nscd/nscd-client.h
+++ b/nscd/nscd-client.h
@@ -236,6 +236,48 @@ struct datahead
} data[0];
};
+static inline time_t
+datahead_init_common (struct datahead *head, nscd_ssize_t allocsize,
+ nscd_ssize_t recsize, uint32_t ttl)
+{
+ /* Initialize so that we don't write out junk in uninitialized data to the
+ cache. */
+ memset (head, 0, sizeof (*head));
+
+ head->allocsize = allocsize;
+ head->recsize = recsize;
+ head->usable = true;
+
+ head->ttl = ttl;
+
+ /* Compute and return the timeout time. */
+ return head->timeout = time (NULL) + ttl;
+}
+
+static inline time_t
+datahead_init_pos (struct datahead *head, nscd_ssize_t allocsize,
+ nscd_ssize_t recsize, uint8_t nreloads, uint32_t ttl)
+{
+ time_t ret = datahead_init_common (head, allocsize, recsize, ttl);
+
+ head->notfound = false;
+ head->nreloads = nreloads;
+
+ return ret;
+}
+
+static inline time_t
+datahead_init_neg (struct datahead *head, nscd_ssize_t allocsize,
+ nscd_ssize_t recsize, uint32_t ttl)
+{
+ time_t ret = datahead_init_common (head, allocsize, recsize, ttl);
+
+ /* We don't need to touch nreloads here since it is set to our desired value
+ (0) when we clear the structure. */
+ head->notfound = true;
+
+ return ret;
+}
/* Structure for one hash table entry. */
struct hashentry
diff --git a/nscd/pwdcache.c b/nscd/pwdcache.c
index fa355c3..41c245b 100644
--- a/nscd/pwdcache.c
+++ b/nscd/pwdcache.c
@@ -135,14 +135,10 @@ cache_addpw (struct database_dyn *db, int fd, request_header *req,
else if ((dataset = mempool_alloc (db, (sizeof (struct dataset)
+ req->key_len), 1)) != NULL)
{
- dataset->head.allocsize = sizeof (struct dataset) + req->key_len;
- dataset->head.recsize = total;
- dataset->head.notfound = true;
- dataset->head.nreloads = 0;
- dataset->head.usable = true;
-
- /* Compute the timeout time. */
- timeout = dataset->head.timeout = t + db->negtimeout;
+ timeout = datahead_init_neg (&dataset->head,
+ (sizeof (struct dataset)
+ + req->key_len), total,
+ db->negtimeout);
/* This is the reply. */
memcpy (&dataset->resp, &notfound, total);
@@ -215,14 +211,10 @@ cache_addpw (struct database_dyn *db, int fd, request_header *req,
alloca_used = true;
}
- dataset->head.allocsize = total + n;
- dataset->head.recsize = total - offsetof (struct dataset, resp);
- dataset->head.notfound = false;
- dataset->head.nreloads = he == NULL ? 0 : (dh->nreloads + 1);
- dataset->head.usable = true;
-
- /* Compute the timeout time. */
- timeout = dataset->head.timeout = t + db->postimeout;
+ timeout = datahead_init_pos (&dataset->head, total + n,
+ total - offsetof (struct dataset, resp),
+ he == NULL ? 0 : dh->nreloads + 1,
+ db->postimeout);
dataset->resp.version = NSCD_VERSION;
dataset->resp.found = 1;
diff --git a/nscd/servicescache.c b/nscd/servicescache.c
index 12ce9b2..95bdcfe 100644
--- a/nscd/servicescache.c
+++ b/nscd/servicescache.c
@@ -120,14 +120,10 @@ cache_addserv (struct database_dyn *db, int fd, request_header *req,
else if ((dataset = mempool_alloc (db, (sizeof (struct dataset)
+ req->key_len), 1)) != NULL)
{
- dataset->head.allocsize = sizeof (struct dataset) + req->key_len;
- dataset->head.recsize = total;
- dataset->head.notfound = true;
- dataset->head.nreloads = 0;
- dataset->head.usable = true;
-
- /* Compute the timeout time. */
- timeout = dataset->head.timeout = t + db->negtimeout;
+ timeout = datahead_init_neg (&dataset->head,
+ (sizeof (struct dataset)
+ + req->key_len), total,
+ db->negtimeout);
/* This is the reply. */
memcpy (&dataset->resp, &notfound, total);
@@ -207,14 +203,10 @@ cache_addserv (struct database_dyn *db, int fd, request_header *req,
alloca_used = true;
}
- dataset->head.allocsize = total + req->key_len;
- dataset->head.recsize = total - offsetof (struct dataset, resp);
- dataset->head.notfound = false;
- dataset->head.nreloads = he == NULL ? 0 : (dh->nreloads + 1);
- dataset->head.usable = true;
-
- /* Compute the timeout time. */
- timeout = dataset->head.timeout = t + db->postimeout;
+ timeout = datahead_init_pos (&dataset->head, total + req->key_len,
+ total - offsetof (struct dataset, resp),
+ he == NULL ? 0 : dh->nreloads + 1,
+ db->postimeout);
dataset->resp.version = NSCD_VERSION;
dataset->resp.found = 1;

View File

@@ -0,0 +1,63 @@
commit ea7d8b95e2fcb81f68b04ed7787a3dbda023991a
Author: Siddhesh Poyarekar <siddhesh@redhat.com>
Date: Thu Mar 27 19:48:15 2014 +0530
Avoid overlapping addresses to stpcpy calls in nscd (BZ #16760)
Calls to stpcpy from nscd netgroups code will have overlapping source
and destination when all three values in the returned triplet are
non-NULL and in the expected (host,user,domain) order. This is seen
in valgrind as:
==3181== Source and destination overlap in stpcpy(0x19973b48, 0x19973b48)
==3181== at 0x4C2F30A: stpcpy (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==3181== by 0x12567A: addgetnetgrentX (string3.h:111)
==3181== by 0x12722D: addgetnetgrent (netgroupcache.c:665)
==3181== by 0x11114C: nscd_run_worker (connections.c:1338)
==3181== by 0x4E3C102: start_thread (pthread_create.c:309)
==3181== by 0x59B81AC: clone (clone.S:111)
==3181==
Fix this by using memmove instead of stpcpy.
diff --git a/nscd/netgroupcache.c b/nscd/netgroupcache.c
index 5d15aa4..820d823 100644
--- a/nscd/netgroupcache.c
+++ b/nscd/netgroupcache.c
@@ -216,6 +216,10 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
const char *nuser = data.val.triple.user;
const char *ndomain = data.val.triple.domain;
+ size_t hostlen = strlen (nhost ?: "") + 1;
+ size_t userlen = strlen (nuser ?: "") + 1;
+ size_t domainlen = strlen (ndomain ?: "") + 1;
+
if (nhost == NULL || nuser == NULL || ndomain == NULL
|| nhost > nuser || nuser > ndomain)
{
@@ -233,9 +237,6 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
: last + strlen (last) + 1 - buffer);
/* We have to make temporary copies. */
- size_t hostlen = strlen (nhost ?: "") + 1;
- size_t userlen = strlen (nuser ?: "") + 1;
- size_t domainlen = strlen (ndomain ?: "") + 1;
size_t needed = hostlen + userlen + domainlen;
if (buflen - req->key_len - bufused < needed)
@@ -269,9 +270,12 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
}
char *wp = buffer + buffilled;
- wp = stpcpy (wp, nhost) + 1;
- wp = stpcpy (wp, nuser) + 1;
- wp = stpcpy (wp, ndomain) + 1;
+ wp = memmove (wp, nhost ?: "", hostlen);
+ wp += hostlen;
+ wp = memmove (wp, nuser ?: "", userlen);
+ wp += userlen;
+ wp = memmove (wp, ndomain ?: "", domainlen);
+ wp += domainlen;
buffilled = wp - buffer;
++nentries;
}

View File

@@ -0,0 +1,31 @@
commit d41242129ba693cdbc8db85b846fcaccf9f0b7c4
Author: Siddhesh Poyarekar <siddhesh@redhat.com>
Date: Thu Jan 2 10:03:12 2014 +0530
Fix infinite loop in nscd when netgroup is empty (bz #16365)
Currently, when a user looks up a netgroup that does not have any
members, nscd goes into an infinite loop trying to find members in the
group. This is because it does not handle cases when getnetgrent
returns an NSS_STATUS_NOTFOUND (which is what it does on empty group).
Fixed to handle this in the same way as NSS_STATUS_RETURN, similar to
what getgrent does by itself.
diff --git a/nscd/netgroupcache.c b/nscd/netgroupcache.c
index baebdd7..50936ee 100644
--- a/nscd/netgroupcache.c
+++ b/nscd/netgroupcache.c
@@ -180,9 +180,10 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
int e;
status = getfct.f (&data, buffer + buffilled,
buflen - buffilled, &e);
- if (status == NSS_STATUS_RETURN)
- /* This was the last one for this group. Look
- at next group if available. */
+ if (status == NSS_STATUS_RETURN
+ || status == NSS_STATUS_NOTFOUND)
+ /* This was either the last one for this group or the
+ group was empty. Look at next group if available. */
break;
if (status == NSS_STATUS_SUCCESS)
{

View File

@@ -0,0 +1,60 @@
commit dd3022d75e6fb8957843d6d84257a5d8457822d5
Author: Siddhesh Poyarekar <siddhesh@redhat.com>
Date: Thu Mar 27 19:49:51 2014 +0530
Return NULL for wildcard values in getnetgrent from nscd (BZ #16759)
getnetgrent is supposed to return NULL for values that are wildcards
in the (host, user, domain) triplet. This works correctly with nscd
disabled, but with it enabled, it returns a blank ("") instead of a
NULL. This is easily seen with the output of `getent netgroup foonet`
for a netgroup foonet defined as follows in /etc/netgroup:
foonet (,foo,)
The output with nscd disabled is:
foonet ( ,foo,)
while with nscd enabled, it is:
foonet (,foo,)
The extra space with nscd disabled is due to the fact that `getent
netgroup` adds it if the return value from getnetgrent is NULL for
either host or user.
diff --git a/inet/getnetgrent_r.c b/inet/getnetgrent_r.c
index 62cdfda..f6d064d 100644
--- a/inet/getnetgrent_r.c
+++ b/inet/getnetgrent_r.c
@@ -235,6 +235,14 @@ endnetgrent (void)
libc_hidden_proto (internal_getnetgrent_r)
+static const char *
+get_nonempty_val (const char *in)
+{
+ if (*in == '\0')
+ return NULL;
+ return in;
+}
+
static enum nss_status
nscd_getnetgrent (struct __netgrent *datap, char *buffer, size_t buflen,
int *errnop)
@@ -243,11 +251,11 @@ nscd_getnetgrent (struct __netgrent *datap, char *buffer, size_t buflen,
return NSS_STATUS_UNAVAIL;
datap->type = triple_val;
- datap->val.triple.host = datap->cursor;
+ datap->val.triple.host = get_nonempty_val (datap->cursor);
datap->cursor = (char *) __rawmemchr (datap->cursor, '\0') + 1;
- datap->val.triple.user = datap->cursor;
+ datap->val.triple.user = get_nonempty_val (datap->cursor);
datap->cursor = (char *) __rawmemchr (datap->cursor, '\0') + 1;
- datap->val.triple.domain = datap->cursor;
+ datap->val.triple.domain = get_nonempty_val (datap->cursor);
datap->cursor = (char *) __rawmemchr (datap->cursor, '\0') + 1;
return NSS_STATUS_SUCCESS;

View File

@@ -0,0 +1,34 @@
commit 58b930ae216bfa98cd60212b954b07b9963d6d04
Author: Siddhesh Poyarekar <siddhesh@redhat.com>
Date: Wed Sep 10 21:51:50 2014 +0530
Return failure in getnetgrent only when all netgroups have been searched (#17363)
The netgroups lookup code fails when one of the groups in the search
tree is empty. In such a case it only returns the leaves of the tree
after the blank netgroup. This is because the line parser returns a
NOTFOUND status when the netgroup exists but is empty. The
__getnetgrent_internal implementation needs to be fixed to try
remaining groups if the current group is entry. This patch implements
this fix. Tested on x86_64.
[BZ #17363]
* inet/getnetgrent_r.c (__internal_getnetgrent_r): Try next
group if the current group is empty.
diff --git a/inet/getnetgrent_r.c b/inet/getnetgrent_r.c
index f6d064d..e101537 100644
--- a/inet/getnetgrent_r.c
+++ b/inet/getnetgrent_r.c
@@ -297,7 +297,10 @@ __internal_getnetgrent_r (char **hostp, char **userp, char **domainp,
{
status = (*fct) (datap, buffer, buflen, &errno);
- if (status == NSS_STATUS_RETURN)
+ if (status == NSS_STATUS_RETURN
+ /* The service returned a NOTFOUND, but there are more groups that we
+ need to resolve before we give up. */
+ || (status == NSS_STATUS_NOTFOUND && datap->needed_groups != NULL))
{
/* This was the last one for this group. Look at next group
if available. */

View File

@@ -0,0 +1,65 @@
commit c3ec475c5dd16499aa040908e11d382c3ded9692
Author: Siddhesh Poyarekar <siddhesh@redhat.com>
Date: Mon May 26 11:40:08 2014 +0530
Use NSS_STATUS_TRYAGAIN to indicate insufficient buffer (BZ #16878)
The netgroups nss modules in the glibc tree use NSS_STATUS_UNAVAIL
(with errno as ERANGE) when the supplied buffer does not have
sufficient space for the result. This is wrong, because the canonical
way to indicate insufficient buffer is to set the errno to ERANGE and
the status to NSS_STATUS_TRYAGAIN, as is used by all other modules.
This fixes nscd behaviour when the nss_ldap module returns
NSS_STATUS_TRYAGAIN to indicate that a netgroup entry is too long to
fit into the supplied buffer.
diff --git a/nscd/netgroupcache.c b/nscd/netgroupcache.c
index b3d40e9..edab174 100644
--- a/nscd/netgroupcache.c
+++ b/nscd/netgroupcache.c
@@ -197,11 +197,6 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
int e;
status = getfct.f (&data, buffer + buffilled,
buflen - buffilled - req->key_len, &e);
- if (status == NSS_STATUS_RETURN
- || status == NSS_STATUS_NOTFOUND)
- /* This was either the last one for this group or the
- group was empty. Look at next group if available. */
- break;
if (status == NSS_STATUS_SUCCESS)
{
if (data.type == triple_val)
@@ -320,11 +315,18 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
}
}
}
- else if (status == NSS_STATUS_UNAVAIL && e == ERANGE)
+ else if (status == NSS_STATUS_TRYAGAIN && e == ERANGE)
{
buflen *= 2;
buffer = xrealloc (buffer, buflen);
}
+ else if (status == NSS_STATUS_RETURN
+ || status == NSS_STATUS_NOTFOUND
+ || status == NSS_STATUS_UNAVAIL)
+ /* This was either the last one for this group or the
+ group was empty or the NSS module had an internal
+ failure. Look at next group if available. */
+ break;
}
enum nss_status (*endfct) (struct __netgrent *);
diff --git a/nss/nss_files/files-netgrp.c b/nss/nss_files/files-netgrp.c
index 34eae4c..bc0b367 100644
--- a/nss/nss_files/files-netgrp.c
+++ b/nss/nss_files/files-netgrp.c
@@ -252,7 +252,7 @@ _nss_netgroup_parseline (char **cursor, struct __netgrent *result,
if (cp - host > buflen)
{
*errnop = ERANGE;
- status = NSS_STATUS_UNAVAIL;
+ status = NSS_STATUS_TRYAGAIN;
}
else
{

View File

@@ -0,0 +1,142 @@
diff --git a/resolv/arpa/nameser.h b/resolv/arpa/nameser.h
index fb8513b..372d5cd 100644
--- a/resolv/arpa/nameser.h
+++ b/resolv/arpa/nameser.h
@@ -293,6 +293,9 @@ typedef enum __ns_type {
ns_t_sink = 40, /*%< Kitchen sink (experimentatl) */
ns_t_opt = 41, /*%< EDNS0 option (meta-RR) */
ns_t_apl = 42, /*%< Address prefix list (RFC3123) */
+ ns_t_rrsig = 46, /*%< DNSSEC RRset Signature (RFC4034) */
+ ns_t_nsec = 47, /*%< DNSSEC Next-Secure Record (RFC4034)*/
+ ns_t_dnskey = 48, /*%< DNSSEC key record (RFC4034) */
ns_t_tkey = 249, /*%< Transaction key */
ns_t_tsig = 250, /*%< Transaction signature. */
ns_t_ixfr = 251, /*%< Incremental zone transfer. */
diff --git a/resolv/arpa/nameser_compat.h b/resolv/arpa/nameser_compat.h
index d59c9e4..284bff7 100644
--- a/resolv/arpa/nameser_compat.h
+++ b/resolv/arpa/nameser_compat.h
@@ -164,6 +164,9 @@ typedef struct {
#define T_NAPTR ns_t_naptr
#define T_A6 ns_t_a6
#define T_DNAME ns_t_dname
+#define T_RRSIG ns_t_rrsig
+#define T_NSEC ns_t_nsec
+#define T_DNSKEY ns_t_dnskey
#define T_TSIG ns_t_tsig
#define T_IXFR ns_t_ixfr
#define T_AXFR ns_t_axfr
diff --git a/resolv/gethnamaddr.c b/resolv/gethnamaddr.c
index a861a84..ae55fac 100644
--- a/resolv/gethnamaddr.c
+++ b/resolv/gethnamaddr.c
@@ -331,23 +331,36 @@ getanswer (const querybuf *answer, int anslen, const char *qname, int qtype)
buflen -= n;
continue;
}
- if ((type == T_SIG) || (type == T_KEY) || (type == T_NXT)) {
- /* We don't support DNSSEC yet. For now, ignore
- * the record and send a low priority message
- * to syslog.
- */
- syslog(LOG_DEBUG|LOG_AUTH,
+ if ((type == T_SIG) || (type == T_KEY) || (type == T_NXT)
+ || (type == T_RRSIG) || (type == T_NSEC)
+ || (type == T_DNSKEY)) {
+ /* We don't support DNSSEC responses yet, but we do
+ * allow setting the DO bit. If the DNS server sent us
+ * these records without us asking for it, ignore the
+ * record and send a low priority message to syslog.
+ */
+ if ((_res.options & RES_USE_DNSSEC) == 0) {
+ syslog(LOG_DEBUG|LOG_AUTH,
"gethostby*.getanswer: asked for \"%s %s %s\", got type \"%s\"",
- qname, p_class(C_IN), p_type(qtype),
- p_type(type));
+ qname, p_class(C_IN), p_type(qtype),
+ p_type(type));
+ }
cp += n;
continue;
}
if (type != qtype) {
- syslog(LOG_NOTICE|LOG_AUTH,
+ /* Skip logging if we received a DNAME when we have set
+ * the DO bit. DNAME records are a convenient way to
+ * set up DNSSEC records and such setups can make this
+ * log message needlessly noisy.
+ */
+ if (!((_res.options & RES_USE_DNSSEC)
+ && type == T_DNAME)) {
+ syslog(LOG_NOTICE|LOG_AUTH,
"gethostby*.getanswer: asked for \"%s %s %s\", got type \"%s\"",
- qname, p_class(C_IN), p_type(qtype),
- p_type(type));
+ qname, p_class(C_IN), p_type(qtype),
+ p_type(type));
+ }
cp += n;
continue; /* XXX - had_error++ ? */
}
diff --git a/resolv/nss_dns/dns-host.c b/resolv/nss_dns/dns-host.c
index f715ab0..510d388 100644
--- a/resolv/nss_dns/dns-host.c
+++ b/resolv/nss_dns/dns-host.c
@@ -822,13 +822,20 @@ getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype,
}
if (__builtin_expect (type == T_SIG, 0)
|| __builtin_expect (type == T_KEY, 0)
- || __builtin_expect (type == T_NXT, 0))
+ || __builtin_expect (type == T_NXT, 0)
+ || __builtin_expect (type == T_RRSIG, 0)
+ || __builtin_expect (type == T_NSEC, 0)
+ || __builtin_expect (type == T_DNSKEY, 0))
{
- /* We don't support DNSSEC yet. For now, ignore the record
- and send a low priority message to syslog. */
- syslog (LOG_DEBUG | LOG_AUTH,
- "gethostby*.getanswer: asked for \"%s %s %s\", got type \"%s\"",
- qname, p_class (C_IN), p_type(qtype), p_type (type));
+ /* We don't support DNSSEC responses yet, but we do allow setting the
+ DO bit. If the DNS server sent us these records without us asking
+ for it, ignore the record and send a low priority message to
+ syslog. */
+ if ((_res.options & RES_USE_DNSSEC) == 0)
+ syslog (LOG_DEBUG | LOG_AUTH,
+ "gethostby*.getanswer: asked for \"%s %s %s\", "
+ "got type \"%s\"",
+ qname, p_class (C_IN), p_type(qtype), p_type (type));
cp += n;
continue;
}
@@ -837,9 +844,14 @@ getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype,
have_to_map = 1;
else if (__builtin_expect (type != qtype, 0))
{
- syslog (LOG_NOTICE | LOG_AUTH,
- "gethostby*.getanswer: asked for \"%s %s %s\", got type \"%s\"",
- qname, p_class (C_IN), p_type (qtype), p_type (type));
+ /* Skip logging if we received a DNAME when we have set the DO bit.
+ DNAME records are a convenient way to set up DNSSEC records and
+ such setups can make this log message needlessly noisy. */
+ if (!((_res.options & RES_USE_DNSSEC) && type == T_DNAME))
+ syslog (LOG_NOTICE | LOG_AUTH,
+ "gethostby*.getanswer: asked for \"%s %s %s\", "
+ "got type \"%s\"",
+ qname, p_class (C_IN), p_type (qtype), p_type (type));
cp += n;
continue; /* XXX - had_error++ ? */
}
diff --git a/resolv/res_debug.c b/resolv/res_debug.c
index 7843439..4a49629 100644
--- a/resolv/res_debug.c
+++ b/resolv/res_debug.c
@@ -450,6 +450,8 @@ const struct res_sym __p_type_syms[] = {
{ns_t_kx, "KX", "Key Exchange"},
{ns_t_cert, "CERT", "Certificate"},
{ns_t_any, "ANY", "\"any\""},
+ /* TODO Add RRSIG, NSEC and DNSKEY once we actually do something with
+ them. */
{0, NULL, NULL}
};
libresolv_hidden_data_def (__p_type_syms)

View File

@@ -0,0 +1,40 @@
commit 3cb26316b45b23dc5cfecbafdc489b28c3a52029
Author: Siddhesh Poyarekar <siddhesh@redhat.com>
Date: Thu Jan 29 10:30:09 2015 +0530
Initialize nscd stats data [BZ #17892]
The padding bytes in the statsdata struct are not initialized, due to
which valgrind throws a warning:
==11384== Memcheck, a memory error detector
==11384== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==11384== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==11384== Command: nscd -d
==11384==
Fri 25 Apr 2014 10:34:53 AM CEST - 11384: handle_request: request received (Version = 2) from PID 11396
Fri 25 Apr 2014 10:34:53 AM CEST - 11384: GETSTAT
==11384== Thread 6:
==11384== Syscall param socketcall.sendto(msg) points to uninitialised byte(s)
==11384== at 0x4E4ACDC: send (in /lib64/libpthread-2.12.so)
==11384== by 0x11AF6B: send_stats (in /usr/sbin/nscd)
==11384== by 0x112F75: nscd_run_worker (in /usr/sbin/nscd)
==11384== by 0x4E439D0: start_thread (in /lib64/libpthread-2.12.so)
==11384== by 0x599AB6C: clone (in /lib64/libc-2.12.so)
==11384== Address 0x15708395 is on thread 6's stack
Fix the warning by initializing the structure.
diff --git a/nscd/nscd_stat.c b/nscd/nscd_stat.c
index 0f1f3c0..7aaa21b 100644
--- a/nscd/nscd_stat.c
+++ b/nscd/nscd_stat.c
@@ -94,6 +94,8 @@ send_stats (int fd, struct database_dyn dbs[lastdb])
struct statdata data;
int cnt;
+ memset (&data, 0, sizeof (data));
+
memcpy (data.version, compilation, sizeof (compilation));
data.debug_level = debug_level;
data.runtime = time (NULL) - start_time;

View File

@@ -0,0 +1,159 @@
commit d6c33fda03457ca8ca87a562fa2681af16ca4ea5
Author: Roland McGrath <roland@hack.frob.com>
Date: Thu May 24 11:37:30 2012 -0700
Switch gettimeofday from INTUSE to libc_hidden_proto.
diff --git a/include/sys/time.h b/include/sys/time.h
index d5de942..599e189 100644
--- a/include/sys/time.h
+++ b/include/sys/time.h
@@ -4,9 +4,8 @@
/* Now document the internal interfaces. */
extern int __gettimeofday (struct timeval *__tv,
struct timezone *__tz);
-extern int __gettimeofday_internal (struct timeval *__tv,
- struct timezone *__tz)
- attribute_hidden;
+libc_hidden_proto (__gettimeofday)
+libc_hidden_proto (gettimeofday)
extern int __settimeofday (__const struct timeval *__tv,
__const struct timezone *__tz)
attribute_hidden;
@@ -22,8 +21,4 @@ extern int __utimes (const char *__file, const struct timeval __tvp[2])
attribute_hidden;
extern int __futimes (int fd, __const struct timeval tvp[2]) attribute_hidden;
-#ifndef NOT_IN_libc
-# define __gettimeofday(tv, tz) INTUSE(__gettimeofday) (tv, tz)
-#endif
-
#endif
diff --git a/sysdeps/mach/gettimeofday.c b/sysdeps/mach/gettimeofday.c
index 88dca8e..293a775 100644
--- a/sysdeps/mach/gettimeofday.c
+++ b/sysdeps/mach/gettimeofday.c
@@ -20,8 +20,6 @@
#include <sys/time.h>
#include <mach.h>
-#undef __gettimeofday
-
/* Get the current time of day and timezone information,
putting it into *TV and *TZ. If TZ is NULL, *TZ is not filled.
Returns 0 on success, -1 on errors. */
@@ -42,6 +40,6 @@ __gettimeofday (tv, tz)
}
return 0;
}
-
-INTDEF(__gettimeofday)
+libc_hidden_def (__gettimeofday)
weak_alias (__gettimeofday, gettimeofday)
+libc_hidden_weak (gettimeofday)
diff --git a/sysdeps/posix/gettimeofday.c b/sysdeps/posix/gettimeofday.c
index 31b3dd3..1108ff0 100644
--- a/sysdeps/posix/gettimeofday.c
+++ b/sysdeps/posix/gettimeofday.c
@@ -19,8 +19,6 @@
#include <time.h>
#include <sys/time.h>
-#undef __gettimeofday
-
/* Get the current time of day and timezone information,
putting it into *TV and *TZ. If TZ is NULL, *TZ is not filled.
Returns 0 on success, -1 on errors. */
@@ -66,6 +64,6 @@ __gettimeofday (tv, tz)
return 0;
}
-
-INTDEF(__gettimeofday)
+libc_hidden_def (__gettimeofday)
weak_alias (__gettimeofday, gettimeofday)
+libc_hidden_weak (gettimeofday)
diff --git a/sysdeps/unix/syscalls.list b/sysdeps/unix/syscalls.list
index 39c40ed..bd780f5 100644
--- a/sysdeps/unix/common/syscalls.list
+++ b/sysdeps/unix/common/syscalls.list
@@ -5,7 +5,7 @@ getpid - getpid Ei: __getpid getpid
fchown - fchown i:iii __fchown fchown
ftruncate - ftruncate i:ii __ftruncate ftruncate
getrusage - getrusage i:ip __getrusage getrusage
-gettimeofday - gettimeofday i:PP __gettimeofday gettimeofday __gettimeofday_internal
+gettimeofday - gettimeofday i:pP __gettimeofday gettimeofday
settimeofday - settimeofday i:PP __settimeofday settimeofday
setpgid - setpgrp i:ii __setpgid setpgid
setregid - setregid i:ii __setregid setregid
diff --git a/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c b/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c
index b2ef2da..7376135 100644
--- a/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c
+++ b/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c
@@ -35,5 +35,6 @@ __gettimeofday (tv, tz)
}
-
-#endif
-INTDEF (__gettimeofday)
+libc_hidden_def (__gettimeofday)
+
+#endif
weak_alias (__gettimeofday, gettimeofday)
+libc_hidden_weak (gettimeofday)
diff --git a/sysdeps/unix/sysv/linux/s390/gettimeofday.c b/sysdeps/unix/sysv/linux/s390/gettimeofday.c
index 63faef8..efbf1e8 100644
--- a/sysdeps/unix/sysv/linux/s390/gettimeofday.c
+++ b/sysdeps/unix/sysv/linux/s390/gettimeofday.c
@@ -22,7 +22,6 @@
#include <time.h>
#include <hp-timing.h>
-#undef __gettimeofday
#include <bits/libc-vdso.h>
/* Get the current time of day and timezone information,
@@ -36,6 +35,6 @@ __gettimeofday (tv, tz)
{
return INLINE_VSYSCALL (gettimeofday, 2, CHECK_1 (tv), CHECK_1 (tz));
}
-
-INTDEF (__gettimeofday)
+libc_hidden_def (__gettimeofday)
weak_alias (__gettimeofday, gettimeofday)
+libc_hidden_weak (gettimeofday)
diff --git a/time/gettimeofday.c b/time/gettimeofday.c
index cfe6549..7eb770c 100644
--- a/time/gettimeofday.c
+++ b/time/gettimeofday.c
@@ -18,8 +18,6 @@
#include <errno.h>
#include <sys/time.h>
-#undef __gettimeofday
-
/* Get the current time of day and timezone information,
putting it into *TV and *TZ. If TZ is NULL, *TZ is not filled.
Returns 0 on success, -1 on errors. */
@@ -31,8 +29,9 @@ __gettimeofday (tv, tz)
__set_errno (ENOSYS);
return -1;
}
-stub_warning (gettimeofday)
-
-INTDEF(__gettimeofday)
+libc_hidden_def (__gettimeofday)
weak_alias (__gettimeofday, gettimeofday)
+libc_hidden_weak (gettimeofday)
+
+stub_warning (gettimeofday)
#include <stub-tag.h>
--- a/sysdeps/unix/sysv/linux/x86_64/gettimeofday.S 2014-07-28 14:40:24.640144825 +0530
+++ b/sysdeps/unix/sysv/linux/x86_64/gettimeofday.S 2014-07-28 14:40:21.320120072 +0530
@@ -45,5 +45,6 @@
ret
PSEUDO_END(__gettimeofday)
-strong_alias (__gettimeofday, __gettimeofday_internal)
+libc_hidden_def (__gettimeofday)
weak_alias (__gettimeofday, gettimeofday)
+libc_hidden_weak (gettimeofday)

View File

@@ -0,0 +1,47 @@
commit 736c304a1ab4cee36a2f3343f1698bc0abae4608
Author: Adhemerval Zanella <azanella@linux.vnet.ibm.com>
Date: Thu Jan 16 06:53:18 2014 -0600
PowerPC: Fix ftime gettimeofday internal call returning bogus data
This patches fixes BZ#16430 by setting a different symbol for internal
GLIBC calls that points to ifunc resolvers. For PPC32, if the symbol
is defined as hidden (which is the case for gettimeofday and time) the
compiler will create local branches (symbol@local) and linker will not
create PLT calls (required for IFUNC). This will leads to internal symbol
calling the IFUNC resolver instead of the resolved symbol.
For PPC64 this behavior does not occur because a call to a function in
another translation unit might use a different toc pointer thus requiring
a PLT call.
diff --git a/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c b/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c
index 29a5e08..2085b68 100644
--- a/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c
+++ b/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c
@@ -44,8 +44,24 @@ asm (".type __gettimeofday, %gnu_indirect_function");
/* This is doing "libc_hidden_def (__gettimeofday)" but the compiler won't
let us do it in C because it doesn't know we're defining __gettimeofday
here in this file. */
-asm (".globl __GI___gettimeofday\n"
- "__GI___gettimeofday = __gettimeofday");
+asm (".globl __GI___gettimeofday");
+
+/* __GI___gettimeofday is defined as hidden and for ppc32 it enables the
+ compiler make a local call (symbol@local) for internal GLIBC usage. It
+ means the PLT won't be used and the ifunc resolver will be called directly.
+ For ppc64 a call to a function in another translation unit might use a
+ different toc pointer thus disallowing direct branchess and making internal
+ ifuncs calls safe. */
+#ifdef __powerpc64__
+asm ("__GI___gettimeofday = __gettimeofday");
+#else
+int
+__gettimeofday_vsyscall (struct timeval *tv, struct timezone *tz)
+{
+ return INLINE_VSYSCALL (gettimeofday, 2, tv, tz);
+}
+asm ("__GI___gettimeofday = __gettimeofday_vsyscall");
+#endif
#else

View File

@@ -0,0 +1,57 @@
#
# In rhel-6.x the Makerules are not entirely as mature as they are
# in glibc 2.21 (from which the example link-libc-args is taken from).
# In rhel-6.x the applications are not built like their counterpart
# real applications, and because of that compiling DSOs that use TLS
# will fail with undefined references to __tls_get_addr which resides
# in ld.so and is never included in the link. This patch enhances
# only the build-module and build-module-asneeded targets to include
# a more fully and correct link line as the compiler driver would use
# when constructing an application or DSO. We do not adjust the link
# lines used to build lib* targets.
#
diff -urN glibc-2.12-2-gc4ccff1.orig/Makerules glibc-2.12-2-gc4ccff1/Makerules
--- glibc-2.12-2-gc4ccff1.orig/Makerules 2015-02-18 19:53:00.000000000 -0500
+++ glibc-2.12-2-gc4ccff1/Makerules 2015-02-18 20:08:33.299000028 -0500
@@ -443,6 +443,25 @@
load-map-file = $(map-file:%=-Wl,--version-script=%)
endif
+# Compiler arguments to use to link a shared object with libc and
+# ld.so. This is intended to be as similar as possible to a default
+# link with an installed libc.
+link-libc-args = -Wl,--start-group \
+ $(libc-for-link) \
+ $(common-objpfx)libc_nonshared.a \
+ $(as-needed) $(elf-objpfx)ld.so $(no-as-needed) \
+ -Wl,--end-group
+
+# The corresponding shared libc to use. This may be modified for a
+# particular target.
+libc-for-link = $(common-objpfx)libc.so
+
+# The corresponding dependencies. As these are used in dependencies,
+# not just commands, they cannot use target-specific variables so need
+# to name both possible libc.so objects.
+link-libc-deps = $(common-objpfx)libc.so $(common-objpfx)linkobj/libc.so \
+ $(common-objpfx)libc_nonshared.a $(elf-objpfx)ld.so
+
# Pattern rule to build a shared object from an archive of PIC objects.
# This must come after the installation rules so Make doesn't try to
# build shared libraries in place from the installed *_pic.a files.
@@ -557,12 +576,13 @@
# not for shared objects
define build-module
$(build-module-helper) -o $@ -T $(common-objpfx)shlib.lds \
- $(csu-objpfx)abi-note.o $(build-module-objlist)
+ $(csu-objpfx)abi-note.o $(build-module-objlist) $(link-libc-args)
endef
define build-module-asneeded
$(build-module-helper) -o $@ -T $(common-objpfx)shlib.lds \
$(csu-objpfx)abi-note.o \
- -Wl,--as-needed $(build-module-objlist) -Wl,--no-as-needed
+ -Wl,--as-needed $(build-module-objlist) -Wl,--no-as-needed \
+ $(link-libc-args)
endef
else
ifneq (,$(findstring aix,$(config-os)))

View File

@@ -0,0 +1,407 @@
#
# Based on this upstream commit:
#
# commit d8dd00805b8f3a011735d7a407097fb1c408d867
# Author: H.J. Lu <hjl.tools@gmail.com>
# Date: Fri Nov 28 07:54:07 2014 -0800
#
# Resize DTV if the current DTV isn't big enough
#
# This patch changes _dl_allocate_tls_init to resize DTV if the current DTV
# isn't big enough. Tested on X86-64, x32 and ia32.
#
# [BZ #13862]
# * elf/dl-tls.c: Include <atomic.h>.
# (oom): Remove #ifdef SHARED/#endif.
# (_dl_static_dtv, _dl_initial_dtv): Moved before ...
# (_dl_resize_dtv): This. Extracted from _dl_update_slotinfo.
# (_dl_allocate_tls_init): Resize DTV if the current DTV isn't
# big enough.
# (_dl_update_slotinfo): Call _dl_resize_dtv to resize DTV.
# * nptl/Makefile (tests): Add tst-stack4.
# (modules-names): Add tst-stack4mod.
# ($(objpfx)tst-stack4): New.
# (tst-stack4mod.sos): Likewise.
# ($(objpfx)tst-stack4.out): Likewise.
# ($(tst-stack4mod.sos)): Likewise.
# (clean): Likewise.
# * nptl/tst-stack4.c: New file.
# * nptl/tst-stack4mod.c: Likewise.
#
diff -urN glibc-2.12-2-gc4ccff1/elf/dl-tls.c glibc-2.12-2-gc4ccff1.mod/elf/dl-tls.c
--- glibc-2.12-2-gc4ccff1/elf/dl-tls.c 2015-02-18 14:15:28.078461873 -0500
+++ glibc-2.12-2-gc4ccff1.mod/elf/dl-tls.c 2015-02-18 14:38:37.630374771 -0500
@@ -24,6 +24,7 @@
#include <stdlib.h>
#include <unistd.h>
#include <sys/param.h>
+#include <atomic.h>
#include <tls.h>
#include <dl-tls.h>
@@ -35,14 +36,12 @@
/* Out-of-memory handler. */
-#ifdef SHARED
static void
__attribute__ ((__noreturn__))
oom (void)
{
_dl_fatal_printf ("cannot allocate memory for thread-local data: ABORT\n");
}
-#endif
size_t
@@ -392,6 +391,52 @@
return result;
}
+static dtv_t *
+_dl_resize_dtv (dtv_t *dtv)
+{
+ /* Resize the dtv. */
+ dtv_t *newp;
+ /* Load GL(dl_tls_max_dtv_idx) atomically since it may be written to by
+ other threads concurrently. -- We don't have the required atomic
+ infrastructure to load dl_tls_max_dtv_idx atomically, but on all the
+ architectures we care about it should load atomically. If this had
+ an atomic_load_acquire we would still be missing the releases for
+ the writes. */
+ size_t newsize = GL(dl_tls_max_dtv_idx) + DTV_SURPLUS;
+ size_t oldsize = dtv[-1].counter;
+
+#if SHARED
+ if (dtv == GL(dl_initial_dtv))
+ {
+ /* This is the initial dtv that was either statically allocated in
+ __libc_setup_tls or allocated during rtld startup using the
+ dl-minimal.c malloc instead of the real malloc. We can't free
+ it, we have to abandon the old storage. */
+
+ newp = malloc ((2 + newsize) * sizeof (dtv_t));
+ if (newp == NULL)
+ oom ();
+ memcpy (newp, &dtv[-1], (2 + oldsize) * sizeof (dtv_t));
+ }
+ else
+#endif
+ {
+ newp = realloc (&dtv[-1],
+ (2 + newsize) * sizeof (dtv_t));
+ if (newp == NULL)
+ oom ();
+ }
+
+ newp[0].counter = newsize;
+
+ /* Clear the newly allocated part. */
+ memset (newp + 2 + oldsize, '\0',
+ (newsize - oldsize) * sizeof (dtv_t));
+
+ /* Return the generation counter. */
+ return &newp[1];
+}
+
void *
internal_function
@@ -406,6 +451,16 @@
size_t total = 0;
size_t maxgen = 0;
+ /* Check if the current dtv is big enough. */
+ if (dtv[-1].counter < GL(dl_tls_max_dtv_idx))
+ {
+ /* Resize the dtv. */
+ dtv = _dl_resize_dtv (dtv);
+
+ /* Install this new dtv in the thread data structures. */
+ INSTALL_DTV (result, &dtv[-1]);
+ }
+
/* We have to prepare the dtv for all currently loaded modules using
TLS. For those which are dynamically loaded we add the values
indicating deferred allocation. */
@@ -637,41 +692,10 @@
assert (total + cnt == modid);
if (dtv[-1].counter < modid)
{
- /* Reallocate the dtv. */
- dtv_t *newp;
- size_t newsize = GL(dl_tls_max_dtv_idx) + DTV_SURPLUS;
- size_t oldsize = dtv[-1].counter;
-
- assert (map->l_tls_modid <= newsize);
-
- if (dtv == GL(dl_initial_dtv))
- {
- /* This is the initial dtv that was allocated
- during rtld startup using the dl-minimal.c
- malloc instead of the real malloc. We can't
- free it, we have to abandon the old storage. */
-
- newp = malloc ((2 + newsize) * sizeof (dtv_t));
- if (newp == NULL)
- oom ();
- memcpy (newp, &dtv[-1], (2 + oldsize) * sizeof (dtv_t));
- }
- else
- {
- newp = realloc (&dtv[-1],
- (2 + newsize) * sizeof (dtv_t));
- if (newp == NULL)
- oom ();
- }
-
- newp[0].counter = newsize;
-
- /* Clear the newly allocated part. */
- memset (newp + 2 + oldsize, '\0',
- (newsize - oldsize) * sizeof (dtv_t));
+ /* Resize the dtv. */
+ dtv = _dl_resize_dtv (dtv);
- /* Point dtv to the generation counter. */
- dtv = &newp[1];
+ assert (modid <= dtv[-1].counter);
/* Install this new dtv in the thread data
structures. */
diff -urN glibc-2.12-2-gc4ccff1/nptl/Makefile glibc-2.12-2-gc4ccff1.mod/nptl/Makefile
--- glibc-2.12-2-gc4ccff1/nptl/Makefile 2015-02-18 14:15:28.073462028 -0500
+++ glibc-2.12-2-gc4ccff1.mod/nptl/Makefile 2015-02-18 14:15:49.817786667 -0500
@@ -245,7 +245,7 @@
tst-exec1 tst-exec2 tst-exec3 tst-exec4 \
tst-exit1 tst-exit2 tst-exit3 \
tst-stdio1 tst-stdio2 \
- tst-stack1 tst-stack2 tst-stack3 \
+ tst-stack1 tst-stack2 tst-stack3 tst-stack4 \
tst-unload \
tst-dlsym1 \
tst-sysconf \
@@ -304,7 +304,7 @@
modules-names = tst-atfork2mod tst-tls3mod tst-tls4moda tst-tls4modb \
tst-tls5mod tst-tls5moda tst-tls5modb tst-tls5modc \
- tst-tls5modd tst-tls5mode tst-tls5modf \
+ tst-tls5modd tst-tls5mode tst-tls5modf tst-stack4mod \
tst-_res1mod1 tst-_res1mod2 tst-execstack-mod tst-fini1mod
extra-test-objs += $(addsuffix .os,$(strip $(modules-names))) tst-cleanup4aux.o
test-extras += $(modules-names)
@@ -459,6 +459,19 @@
$(common-objpfx)malloc/mtrace $(objpfx)tst-stack3.mtrace > $@
generated += tst-stack3-mem tst-stack3.mtrace
+$(objpfx)tst-stack4: $(libdl) $(shared-thread-library)
+tst-stack4mod.sos=$(shell for i in 0 1 2 3 4 5 6 7 8 9 10 \
+ 11 12 13 14 15 16 17 18 19; do \
+ for j in 0 1 2 3 4 5 6 7 8 9 10 \
+ 11 12 13 14 15 16 17 18 19; do \
+ echo $(objpfx)tst-stack4mod-$$i-$$j.so; \
+ done; done)
+$(objpfx)tst-stack4.out: $(tst-stack4mod.sos)
+$(tst-stack4mod.sos): $(objpfx)tst-stack4mod.so
+ cp -f $< $@
+clean:
+ rm -f $(tst-stack4mod.sos)
+
$(objpfx)tst-cleanup4: $(objpfx)tst-cleanup4aux.o $(shared-thread-library)
$(objpfx)tst-cleanupx4: $(objpfx)tst-cleanup4aux.o $(shared-thread-library)
diff -urN glibc-2.12-2-gc4ccff1/nptl/tst-stack4.c glibc-2.12-2-gc4ccff1.mod/nptl/tst-stack4.c
--- glibc-2.12-2-gc4ccff1/nptl/tst-stack4.c 1969-12-31 19:00:00.000000000 -0500
+++ glibc-2.12-2-gc4ccff1.mod/nptl/tst-stack4.c 2015-02-18 14:15:49.817786667 -0500
@@ -0,0 +1,159 @@
+/* Test DTV size oveflow when pthread_create reuses old DTV and TLS is
+ used by dlopened shared object.
+ Copyright (C) 2014 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 <stdint.h>
+#include <dlfcn.h>
+#include <assert.h>
+#include <pthread.h>
+
+/* The choices of thread count, and file counts are arbitary.
+ The point is simply to run enough threads that an exiting
+ thread has it's stack reused by another thread at the same
+ time as new libraries have been loaded. */
+#define DSO_SHARED_FILES 20
+#define DSO_OPEN_THREADS 20
+#define DSO_EXEC_THREADS 2
+
+/* Used to make sure that only one thread is calling dlopen and dlclose
+ at a time. */
+pthread_mutex_t g_lock;
+
+typedef void (*function) (void);
+
+void *
+dso_invoke(void *dso_fun)
+{
+ function *fun_vec = (function *) dso_fun;
+ int dso;
+
+ for (dso = 0; dso < DSO_SHARED_FILES; dso++)
+ (*fun_vec[dso]) ();
+
+ pthread_exit (NULL);
+}
+
+void *
+dso_process (void * p)
+{
+ void *handle[DSO_SHARED_FILES];
+ function fun_vec[DSO_SHARED_FILES];
+ char dso_path[DSO_SHARED_FILES][100];
+ int dso;
+ uintptr_t t = (uintptr_t) p;
+
+ /* Open DSOs and get a function. */
+ for (dso = 0; dso < DSO_SHARED_FILES; dso++)
+ {
+ sprintf (dso_path[dso], "tst-stack4mod-%i-%i.so", t, dso);
+
+ pthread_mutex_lock (&g_lock);
+
+ handle[dso] = dlopen (dso_path[dso], RTLD_NOW);
+ assert (handle[dso]);
+
+ fun_vec[dso] = (function) dlsym (handle[dso], "function");
+ assert (fun_vec[dso]);
+
+ pthread_mutex_unlock (&g_lock);
+ }
+
+ /* Spawn workers. */
+ pthread_t thread[DSO_EXEC_THREADS];
+ int i, ret;
+ uintptr_t result = 0;
+ for (i = 0; i < DSO_EXEC_THREADS; i++)
+ {
+ pthread_mutex_lock (&g_lock);
+ ret = pthread_create (&thread[i], NULL, dso_invoke, (void *) fun_vec);
+ if (ret != 0)
+ {
+ printf ("pthread_create failed: %d\n", ret);
+ result = 1;
+ }
+ pthread_mutex_unlock (&g_lock);
+ }
+
+ if (!result)
+ for (i = 0; i < DSO_EXEC_THREADS; i++)
+ {
+ ret = pthread_join (thread[i], NULL);
+ if (ret != 0)
+ {
+ printf ("pthread_join failed: %d\n", ret);
+ result = 1;
+ }
+ }
+
+ /* Close all DSOs. */
+ for (dso = 0; dso < DSO_SHARED_FILES; dso++)
+ {
+ pthread_mutex_lock (&g_lock);
+ dlclose (handle[dso]);
+ pthread_mutex_unlock (&g_lock);
+ }
+
+ /* Exit. */
+ pthread_exit ((void *) result);
+}
+
+static int
+do_test (void)
+{
+ pthread_t thread[DSO_OPEN_THREADS];
+ int i,j;
+ int ret;
+ int result = 0;
+
+ pthread_mutex_init (&g_lock, NULL);
+
+ /* 100 is arbitrary here and is known to trigger PR 13862. */
+ for (j = 0; j < 100; j++)
+ {
+ for (i = 0; i < DSO_OPEN_THREADS; i++)
+ {
+ ret = pthread_create (&thread[i], NULL, dso_process,
+ (void *) (uintptr_t) i);
+ if (ret != 0)
+ {
+ printf ("pthread_create failed: %d\n", ret);
+ result = 1;
+ }
+ }
+
+ if (result)
+ break;
+
+ for (i = 0; i < DSO_OPEN_THREADS; i++)
+ {
+ ret = pthread_join (thread[i], NULL);
+ if (ret != 0)
+ {
+ printf ("pthread_join failed: %d\n", ret);
+ result = 1;
+ }
+ }
+ }
+
+ return result;
+}
+
+#define TEST_FUNCTION do_test ()
+#define TIMEOUT 100
+#include "../test-skeleton.c"
diff -urN glibc-2.12-2-gc4ccff1/nptl/tst-stack4mod.c glibc-2.12-2-gc4ccff1.mod/nptl/tst-stack4mod.c
--- glibc-2.12-2-gc4ccff1/nptl/tst-stack4mod.c 1969-12-31 19:00:00.000000000 -0500
+++ glibc-2.12-2-gc4ccff1.mod/nptl/tst-stack4mod.c 2015-02-18 14:15:49.817786667 -0500
@@ -0,0 +1,28 @@
+/* This tests DTV usage with TLS in dlopened shared object.
+ Copyright (C) 2014 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/>. */
+
+/* 256 is arbitrary here and is known to trigger PR 13862. */
+__thread int var[256] attribute_hidden = {0};
+
+void
+function (void)
+{
+ int i;
+ for (i = 0; i < sizeof (var) / sizeof (int); i++)
+ var[i] = i;
+}

View File

@@ -0,0 +1,47 @@
#
# Derived from this upstream commit:
#
# commit 58a1335e76a553e1cf4edeebc27f16fc9b53d6e6
# Author: Petr Baudis <pasky@ucw.cz>
# Date: Thu Mar 14 01:16:53 2013 +0100
#
# Fix __times() handling of EFAULT when buf is NULL
#
# 2013-03-14 Petr Baudis <pasky@ucw.cz>
#
# * sysdeps/unix/sysv/linux/times.c (__times): On EFAULT, test
# for non-NULL pointer before the memory validity test. Pointed
# out by Holger Brunck <holger.brunck@keymile.com>.
#
diff --git a/sysdeps/unix/sysv/linux/times.c b/sysdeps/unix/sysv/linux/times.c
index f3b5f01..e59bb4e 100644
--- a/sysdeps/unix/sysv/linux/times.c
+++ b/sysdeps/unix/sysv/linux/times.c
@@ -26,13 +26,14 @@ __times (struct tms *buf)
INTERNAL_SYSCALL_DECL (err);
clock_t ret = INTERNAL_SYSCALL (times, err, 1, buf);
if (INTERNAL_SYSCALL_ERROR_P (ret, err)
- && __builtin_expect (INTERNAL_SYSCALL_ERRNO (ret, err) == EFAULT, 0))
+ && __builtin_expect (INTERNAL_SYSCALL_ERRNO (ret, err) == EFAULT, 0)
+ && buf)
{
/* This might be an error or not. For architectures which have
no separate return value and error indicators we cannot
distinguish a return value of -1 from an error. Do it the
- hard way. We crash applications which pass in an invalid BUF
- pointer. */
+ hard way. We crash applications which pass in an invalid
+ non-NULL BUF pointer. Linux allows BUF to be NULL. */
#define touch(v) \
do { \
clock_t temp = v; \
@@ -44,7 +45,8 @@ __times (struct tms *buf)
touch (buf->tms_cutime);
touch (buf->tms_cstime);
- /* If we come here the memory is valid and the kernel did not
+ /* If we come here the memory is valid (or BUF is NULL, which is
+ * a valid condition for the kernel syscall) and the kernel did not
return an EFAULT error. Return the value given by the kernel. */
}

View File

@@ -0,0 +1,19 @@
commit a11892631d92f594c690d0d50a642b0d1aba58b8
Author: Ondřej Bílka <neleai@seznam.cz>
Date: Wed May 7 14:08:57 2014 +0200
Fix typo in nscd/selinux.c
diff --git a/nscd/selinux.c b/nscd/selinux.c
index 9a8a5a8..eaed6dd 100644
--- a/nscd/selinux.c
+++ b/nscd/selinux.c
@@ -372,7 +372,7 @@ nscd_request_avc_has_perm (int fd, request_type req)
/* Get the security class for nscd. If this fails we will likely be
unable to do anything unless avc_deny_unknown is 0. */
sc_nscd = string_to_security_class ("nscd");
- if (perm == 0 && avc_deny_unknown == 1)
+ if (sc_nscd == 0 && avc_deny_unknown == 1)
dbg_log (_("Error getting security class for nscd."));
/* Convert permission to AVC bits. */

View File

@@ -0,0 +1,45 @@
commit e35c53e397e7abbd41fedacdedcfa5af7b5c2c52
Author: Siddhesh Poyarekar <siddhesh@redhat.com>
Date: Tue Jul 8 16:40:24 2014 +0530
Check value at resplen2 if it is not NULL
There was a typo in the previous patch due to which resplen2 was
checked for non-zero instead of the value at resplen2. Fix that and
improve the condition by checking resplen2 for non-NULL (instead of
answerp2) and also adding the check in a third place.
diff --git a/resolv/res_query.c b/resolv/res_query.c
index 4e6612c..e4ee2a6 100644
--- a/resolv/res_query.c
+++ b/resolv/res_query.c
@@ -384,7 +384,7 @@ __libc_res_nsearch(res_state statp,
answerp2, nanswerp2, resplen2);
if (ret > 0 || trailing_dot
/* If the second response is valid then we use that. */
- || (ret == 0 && answerp2 != NULL && resplen2 > 0))
+ || (ret == 0 && resplen2 != NULL && *resplen2 > 0))
return (ret);
saved_herrno = h_errno;
tried_as_is++;
@@ -424,8 +424,8 @@ __libc_res_nsearch(res_state statp,
answer, anslen, answerp,
answerp2, nanswerp2,
resplen2);
- if (ret > 0 || (ret == 0 && answerp2 != NULL
- && resplen2 > 0))
+ if (ret > 0 || (ret == 0 && resplen2 != NULL
+ && *resplen2 > 0))
return (ret);
if (answerp && *answerp != answer) {
@@ -494,7 +494,8 @@ __libc_res_nsearch(res_state statp,
ret = __libc_res_nquerydomain(statp, name, NULL, class, type,
answer, anslen, answerp,
answerp2, nanswerp2, resplen2);
- if (ret > 0)
+ if (ret > 0 || (ret == 0 && resplen2 != NULL
+ && *resplen2 > 0))
return (ret);
}

View File

@@ -0,0 +1,58 @@
#
# Based on this commit:
#
# commit 62058ce612ed3459501b4c4332e268edfe977f59
# Author: Carlos O'Donell <carlos@redhat.com>
# Date: Mon Sep 29 13:14:21 2014 -0400
#
# Correctly size profiling reloc table (bug 17411)
#
# During auditing or profiling modes the dynamic loader
# builds a cache of the relocated PLT entries in order
# to reuse them when called again through the same PLT
# entry. This way the PLT entry is never completed and
# the call into the resolver always results in profiling
# or auditing code running.
#
# The problem is that the PLT relocation cache size
# is not computed correctly. The size of the cache
# should be "Size of a relocation result structure"
# x "Number of PLT-related relocations". Instead the
# code erroneously computes "Size of a relocation
# result" x "Number of bytes worth of PLT-related
# relocations". I can only assume this was a mistake
# in the understanding of the value of DT_PLTRELSZ
# which is the number of bytes of PLT-related relocs.
# We do have a DT_RELACOUNT entry, which is a count
# for dynamic relative relocs, but we have no
# DT_PLTRELCOUNT and thus we need to compute it.
#
# This patch corrects the computation of the size of the
# relocation table used by the glibc profiling code.
#
# For more details see:
# https://sourceware.org/ml/libc-alpha/2014-09/msg00513.html
#
# [BZ #17411]
# * elf/dl-reloc.c (_dl_relocate_object): Allocate correct amount for
# l_reloc_result.
#
diff --git a/elf/dl-reloc.c b/elf/dl-reloc.c
index d2c6dac..97a7119 100644
--- a/elf/dl-reloc.c
+++ b/elf/dl-reloc.c
@@ -279,8 +279,12 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
l->l_name);
}
- l->l_reloc_result = calloc (sizeof (l->l_reloc_result[0]),
- l->l_info[DT_PLTRELSZ]->d_un.d_val);
+ size_t sizeofrel = l->l_info[DT_PLTREL]->d_un.d_val == DT_RELA
+ ? sizeof (ElfW(Rela))
+ : sizeof (ElfW(Rel));
+ size_t relcount = l->l_info[DT_PLTRELSZ]->d_un.d_val / sizeofrel;
+ l->l_reloc_result = calloc (sizeof (l->l_reloc_result[0]), relcount);
+
if (l->l_reloc_result == NULL)
{
errstring = N_("\

View File

@@ -0,0 +1,15 @@
diff --git a/sunrpc/svc.c b/sunrpc/svc.c
index ccf0902..30c3a93 100644
--- a/sunrpc/svc.c
+++ b/sunrpc/svc.c
@@ -97,8 +97,8 @@ xprt_register (SVCXPRT *xprt)
if (xports == NULL)
{
- xports = (SVCXPRT **) malloc (_rpc_dtablesize () * sizeof (SVCXPRT *));
- if (xports == NULL) /* Don<6F>t add handle */
+ xports = (SVCXPRT **) calloc (_rpc_dtablesize (), sizeof (SVCXPRT *));
+ if (xports == NULL) /* Don't add handle */
return;
}

View File

@@ -0,0 +1,22 @@
commit 7d81e8d6db95c112c297930a8f2f9617c305529a
Author: Florian Weimer <fweimer@redhat.com>
Date: Tue Dec 23 16:16:32 2014 +0100
iconvdata/run-iconv-test.sh: Actually test iconv modules
Arjun Shankar noticed that this test case was not testing anything
because iconv was invoked without the required arguments.
diff --git a/iconvdata/run-iconv-test.sh b/iconvdata/run-iconv-test.sh
index 5dfb69f..1d0bf52 100755
--- a/iconvdata/run-iconv-test.sh
+++ b/iconvdata/run-iconv-test.sh
@@ -189,7 +189,7 @@ printf '\016\377\377\377\377\377\377\377' > $temp1
for from in $iconv_modules ; do
echo $ac_n "test decoder $from $ac_c"
PROG=`eval echo $ICONV`
- if $PROG < $temp1 >/dev/null 2>&1 ; then
+ if $PROG -f $from -t UTF8 < $temp1 >/dev/null 2>&1 ; then
: # fall through
else
status=$?

View File

@@ -4,6 +4,19 @@ Date: Mon Jan 21 17:41:28 2013 +0100
Fix parsing of numeric hosts in gethostbyname_r
diff --git a/nss/Makefile b/nss/Makefile
index 449a258..553eafa 100644
--- a/nss/Makefile
+++ b/nss/Makefile
@@ -37,7 +37,7 @@ install-bin := getent makedb
others := getent
install-bin := getent
-tests = test-netdb tst-nss-test1
+tests = test-netdb tst-nss-test1 test-digits-dots
xtests = bug-erange
include ../Makeconfig
diff --git a/nss/digits_dots.c b/nss/digits_dots.c
index 2b86295..e007ef4 100644
--- a/nss/digits_dots.c

View File

@@ -0,0 +1,481 @@
#
# Based on AVX-512 support for glibc, but heavaily modified for rhel-6.7.
# Without assembler support we drop all of the configure checks and simply
# output using .byte directives the minimal AVX512 instructsion required
# by the loader. Likewise testing is also impossible, so instead we use
# the Intel emulator running in `-skx` (Skylake Xeon) emulation mode and
# verify that a pre-built set of tests passes.
#
# commit 6986b98a18490e76b16911d1c6b1ba013598d40d
# Author: Ulrich Drepper <drepper@gmail.com>
# Date: Wed Jul 20 14:20:00 2011 -0400
#
# Force :a_x86_64_ymm to be 16-byte aligned
#
# commit aa4de9cea5c07d43caeaca9722c2d417e9a2919c
# Author: H.J. Lu <hjl.tools@gmail.com>
# Date: Fri Mar 14 08:51:25 2014 -0700
#
# Check AVX-512 assembler support first
#
# It checks AVX-512 assembler support first and sets libc_cv_cc_avx512 to
# $libc_cv_asm_avx512, instead of yes. GCC won't support AVX-512 if
# assembler doesn't support it.
#
# * sysdeps/x86_64/configure.ac: Check AVX-512 assembler support
# first. Disable AVX-512 GCC support if assembler doesn't support
# it.
# * sysdeps/x86_64/configure: Regenerated.
#
# commit 2d63a517e4084ec80403cd9f278690fa8b676cc4
# Author: Igor Zamyatin <igor.zamyatin@intel.com>
# Date: Thu Mar 13 11:10:22 2014 -0700
#
# Save and restore AVX-512 zmm registers to x86-64 ld.so
#
# AVX-512 ISA adds 512-bit zmm registers. This patch updates
# _dl_runtime_profile to pass zmm registers to run-time audit. It also
# changes _dl_x86_64_save_sse and _dl_x86_64_restore_sse to upport zmm
# registers, which are called when only when RTLD_PREPARE_FOREIGN_CALL
# is used. Its performance impact is minimum.
#
# * config.h.in (HAVE_AVX512_SUPPORT): New #undef.
# (HAVE_AVX512_ASM_SUPPORT): Likewise.
# * sysdeps/x86_64/bits/link.h (La_x86_64_zmm): New.
# (La_x86_64_vector): Add zmm.
# * sysdeps/x86_64/Makefile (tests): Add tst-audit10.
# (modules-names): Add tst-auditmod10a and tst-auditmod10b.
# ($(objpfx)tst-audit10): New target.
# ($(objpfx)tst-audit10.out): Likewise.
# (tst-audit10-ENV): New.
# (AVX512-CFLAGS): Likewise.
# (CFLAGS-tst-audit10.c): Likewise.
# (CFLAGS-tst-auditmod10a.c): Likewise.
# (CFLAGS-tst-auditmod10b.c): Likewise.
# * sysdeps/x86_64/configure.ac: Set config-cflags-avx512,
# HAVE_AVX512_SUPPORT and HAVE_AVX512_ASM_SUPPORT.
# * sysdeps/x86_64/configure: Regenerated.
# * sysdeps/x86_64/dl-trampoline.S (_dl_runtime_profile): Add
# AVX-512 zmm register support.
# (_dl_x86_64_save_sse): Likewise.
# (_dl_x86_64_restore_sse): Likewise.
# * sysdeps/x86_64/dl-trampoline.h: Updated to support different
# size vector registers.
# * sysdeps/x86_64/link-defines.sym (YMM_SIZE): New.
# (ZMM_SIZE): Likewise.
# * sysdeps/x86_64/tst-audit10.c: New file.
# * sysdeps/x86_64/tst-auditmod10a.c: Likewise.
# * sysdeps/x86_64/tst-auditmod10b.c: Likewise.
#
# In addition adds:
# https://sourceware.org/ml/libc-alpha/2014-09/msg00228.html
# To extend zmm register checking.
#
diff -urN glibc-2.12-2-gc4ccff1/sysdeps/x86_64/bits/link.h glibc-2.12-2-gc4ccff1.mod/sysdeps/x86_64/bits/link.h
--- glibc-2.12-2-gc4ccff1/sysdeps/x86_64/bits/link.h 2010-05-04 07:27:23.000000000 -0400
+++ glibc-2.12-2-gc4ccff1.mod/sysdeps/x86_64/bits/link.h 2015-03-03 23:03:25.041829238 -0500
@@ -65,7 +65,10 @@
/* Registers for entry into PLT on x86-64. */
# if __GNUC_PREREQ (4,0)
typedef float La_x86_64_xmm __attribute__ ((__vector_size__ (16)));
-typedef float La_x86_64_ymm __attribute__ ((__vector_size__ (32)));
+typedef float La_x86_64_ymm __attribute__ ((__vector_size__ (32),
+ __aligned__ (16)));
+typedef double La_x86_64_zmm __attribute__ ((__vector_size__ (64),
+ __aligned__ (16)));
# else
typedef float La_x86_64_xmm __attribute__ ((__mode__ (__V4SF__)));
# endif
@@ -74,9 +77,10 @@
{
# if __GNUC_PREREQ (4,0)
La_x86_64_ymm ymm[2];
+ La_x86_64_zmm zmm[1];
# endif
La_x86_64_xmm xmm[4];
-} La_x86_64_vector __attribute__ ((aligned(16)));
+} La_x86_64_vector __attribute__ ((__aligned__(16)));
typedef struct La_x86_64_regs
{
diff -urN glibc-2.12-2-gc4ccff1/sysdeps/x86_64/dl-trampoline.h glibc-2.12-2-gc4ccff1.mod/sysdeps/x86_64/dl-trampoline.h
--- glibc-2.12-2-gc4ccff1/sysdeps/x86_64/dl-trampoline.h 2015-03-03 23:03:05.109457627 -0500
+++ glibc-2.12-2-gc4ccff1.mod/sysdeps/x86_64/dl-trampoline.h 2015-03-03 23:06:58.434101818 -0500
@@ -20,14 +20,26 @@
#ifdef RESTORE_AVX
/* This is to support AVX audit modules. */
- vmovdqu %ymm0, (LR_VECTOR_OFFSET)(%rsp)
- vmovdqu %ymm1, (LR_VECTOR_OFFSET + VECTOR_SIZE)(%rsp)
- vmovdqu %ymm2, (LR_VECTOR_OFFSET + VECTOR_SIZE*2)(%rsp)
- vmovdqu %ymm3, (LR_VECTOR_OFFSET + VECTOR_SIZE*3)(%rsp)
- vmovdqu %ymm4, (LR_VECTOR_OFFSET + VECTOR_SIZE*4)(%rsp)
- vmovdqu %ymm5, (LR_VECTOR_OFFSET + VECTOR_SIZE*5)(%rsp)
- vmovdqu %ymm6, (LR_VECTOR_OFFSET + VECTOR_SIZE*6)(%rsp)
- vmovdqu %ymm7, (LR_VECTOR_OFFSET + VECTOR_SIZE*7)(%rsp)
+# if HAVE_NO_AVX512_ASM_SUPPORT
+ /* Restore AVX-512 registers. Use .byte becaues we lack assembler support. */
+ .byte 0x62,0xf1,0xfe,0x48,0x7f,0x44,0x24,0x03 # vmovdqu64 %zmm0,0xc0(%rsp)
+ .byte 0x62,0xf1,0xfe,0x48,0x7f,0x4c,0x24,0x04 # vmovdqu64 %zmm1,0x100(%rsp)
+ .byte 0x62,0xf1,0xfe,0x48,0x7f,0x54,0x24,0x05 # vmovdqu64 %zmm2,0x140(%rsp)
+ .byte 0x62,0xf1,0xfe,0x48,0x7f,0x5c,0x24,0x06 # vmovdqu64 %zmm3,0x180(%rsp)
+ .byte 0x62,0xf1,0xfe,0x48,0x7f,0x64,0x24,0x07 # vmovdqu64 %zmm4,0x1c0(%rsp)
+ .byte 0x62,0xf1,0xfe,0x48,0x7f,0x6c,0x24,0x08 # vmovdqu64 %zmm5,0x200(%rsp)
+ .byte 0x62,0xf1,0xfe,0x48,0x7f,0x74,0x24,0x09 # vmovdqu64 %zmm6,0x240(%rsp)
+ .byte 0x62,0xf1,0xfe,0x48,0x7f,0x7c,0x24,0x0a # vmovdqu64 %zmm7,0x280(%rsp)
+# else
+ VMOV %VEC(0), (LR_VECTOR_OFFSET)(%rsp)
+ VMOV %VEC(1), (LR_VECTOR_OFFSET + VECTOR_SIZE)(%rsp)
+ VMOV %VEC(2), (LR_VECTOR_OFFSET + VECTOR_SIZE*2)(%rsp)
+ VMOV %VEC(3), (LR_VECTOR_OFFSET + VECTOR_SIZE*3)(%rsp)
+ VMOV %VEC(4), (LR_VECTOR_OFFSET + VECTOR_SIZE*4)(%rsp)
+ VMOV %VEC(5), (LR_VECTOR_OFFSET + VECTOR_SIZE*5)(%rsp)
+ VMOV %VEC(6), (LR_VECTOR_OFFSET + VECTOR_SIZE*6)(%rsp)
+ VMOV %VEC(7), (LR_VECTOR_OFFSET + VECTOR_SIZE*7)(%rsp)
+# endif
/* Save xmm0-xmm7 registers to detect if any of them are
changed by audit module. */
@@ -73,7 +85,11 @@
je 2f
vmovdqa %xmm0, (LR_VECTOR_OFFSET)(%rsp)
jmp 1f
-2: vmovdqu (LR_VECTOR_OFFSET)(%rsp), %ymm0
+# if HAVE_NO_AVX512_ASM_SUPPORT
+2: .byte 0x62,0xf1,0xfe,0x48,0x6f,0x44,0x24,0x03 # vmovdqu64 0xc0(%rsp),%zmm0
+# else
+2: VMOV (LR_VECTOR_OFFSET)(%rsp), %VEC(0)
+# endif
vmovdqa %xmm0, (LR_XMM_OFFSET)(%rsp)
1: vpcmpeqq (LR_SIZE + XMM_SIZE)(%rsp), %xmm1, %xmm8
@@ -82,7 +98,11 @@
je 2f
vmovdqa %xmm1, (LR_VECTOR_OFFSET + VECTOR_SIZE)(%rsp)
jmp 1f
-2: vmovdqu (LR_VECTOR_OFFSET + VECTOR_SIZE)(%rsp), %ymm1
+# if HAVE_NO_AVX512_ASM_SUPPORT
+2: .byte 0x62,0xf1,0xfe,0x48,0x6f,0x4c,0x24,0x04 # vmovdqu64 0x100(%rsp),%zmm1
+# else
+2: VMOV (LR_VECTOR_OFFSET + VECTOR_SIZE)(%rsp), %VEC(1)
+# endif
vmovdqa %xmm1, (LR_XMM_OFFSET + XMM_SIZE)(%rsp)
1: vpcmpeqq (LR_SIZE + XMM_SIZE*2)(%rsp), %xmm2, %xmm8
@@ -91,7 +111,11 @@
je 2f
vmovdqa %xmm2, (LR_VECTOR_OFFSET + VECTOR_SIZE*2)(%rsp)
jmp 1f
-2: vmovdqu (LR_VECTOR_OFFSET + VECTOR_SIZE*2)(%rsp), %ymm2
+# if HAVE_NO_AVX512_ASM_SUPPORT
+2: .byte 0x62,0xf1,0xfe,0x48,0x6f,0x54,0x24,0x05 # vmovdqu64 0x140(%rsp),%zmm2
+# else
+2: VMOV (LR_VECTOR_OFFSET + VECTOR_SIZE*2)(%rsp), %VEC(2)
+# endif
vmovdqa %xmm2, (LR_XMM_OFFSET + XMM_SIZE*2)(%rsp)
1: vpcmpeqq (LR_SIZE + XMM_SIZE*3)(%rsp), %xmm3, %xmm8
@@ -100,7 +124,11 @@
je 2f
vmovdqa %xmm3, (LR_VECTOR_OFFSET + VECTOR_SIZE*3)(%rsp)
jmp 1f
-2: vmovdqu (LR_VECTOR_OFFSET + VECTOR_SIZE*3)(%rsp), %ymm3
+# if HAVE_NO_AVX512_ASM_SUPPORT
+2: .byte 0x62,0xf1,0xfe,0x48,0x6f,0x5c,0x24,0x06 # vmovdqu64 0x180(%rsp),%zmm3
+# else
+2: VMOV (LR_VECTOR_OFFSET + VECTOR_SIZE*3)(%rsp), %VEC(3)
+# endif
vmovdqa %xmm3, (LR_XMM_OFFSET + XMM_SIZE*3)(%rsp)
1: vpcmpeqq (LR_SIZE + XMM_SIZE*4)(%rsp), %xmm4, %xmm8
@@ -109,7 +137,11 @@
je 2f
vmovdqa %xmm4, (LR_VECTOR_OFFSET + VECTOR_SIZE*4)(%rsp)
jmp 1f
-2: vmovdqu (LR_VECTOR_OFFSET + VECTOR_SIZE*4)(%rsp), %ymm4
+# if HAVE_NO_AVX512_ASM_SUPPORT
+2: .byte 0x62,0xf1,0xfe,0x48,0x6f,0x64,0x24,0x07 # vmovdqu64 0x1c0(%rsp),%zmm4
+# else
+2: VMOV (LR_VECTOR_OFFSET + VECTOR_SIZE*4)(%rsp), %VEC(4)
+# endif
vmovdqa %xmm4, (LR_XMM_OFFSET + XMM_SIZE*4)(%rsp)
1: vpcmpeqq (LR_SIZE + XMM_SIZE*5)(%rsp), %xmm5, %xmm8
@@ -118,7 +150,11 @@
je 2f
vmovdqa %xmm5, (LR_VECTOR_OFFSET + VECTOR_SIZE*5)(%rsp)
jmp 1f
-2: vmovdqu (LR_VECTOR_OFFSET + VECTOR_SIZE*5)(%rsp), %ymm5
+# if HAVE_NO_AVX512_ASM_SUPPORT
+2: .byte 0x62,0xf1,0xfe,0x48,0x6f,0x6c,0x24,0x08 # vmovdqu64 0x200(%rsp),%zmm5
+# else
+2: VMOV (LR_VECTOR_OFFSET + VECTOR_SIZE*5)(%rsp), %VEC(5)
+# endif
vmovdqa %xmm5, (LR_XMM_OFFSET + XMM_SIZE*5)(%rsp)
1: vpcmpeqq (LR_SIZE + XMM_SIZE*6)(%rsp), %xmm6, %xmm8
@@ -127,7 +163,11 @@
je 2f
vmovdqa %xmm6, (LR_VECTOR_OFFSET + VECTOR_SIZE*6)(%rsp)
jmp 1f
-2: vmovdqu (LR_VECTOR_OFFSET + VECTOR_SIZE*6)(%rsp), %ymm6
+# if HAVE_NO_AVX512_ASM_SUPPORT
+2: .byte 0x62,0xf1,0xfe,0x48,0x6f,0x74,0x24,0x09 # vmovdqu64 0x240(%rsp),%zmm6
+# else
+2: VMOV (LR_VECTOR_OFFSET + VECTOR_SIZE*6)(%rsp), %VEC(6)
+# endif
vmovdqa %xmm6, (LR_XMM_OFFSET + XMM_SIZE*6)(%rsp)
1: vpcmpeqq (LR_SIZE + XMM_SIZE*7)(%rsp), %xmm7, %xmm8
@@ -136,7 +176,11 @@
je 2f
vmovdqa %xmm7, (LR_VECTOR_OFFSET + VECTOR_SIZE*7)(%rsp)
jmp 1f
-2: vmovdqu (LR_VECTOR_OFFSET + VECTOR_SIZE*7)(%rsp), %ymm7
+# if HAVE_NO_AVX512_ASM_SUPPORT
+2: .byte 0x62,0xf1,0xfe,0x48,0x6f,0x7c,0x24,0x0a # vmovdqu64 0x280(%rsp),%zmm7
+# else
+2: VMOV (LR_VECTOR_OFFSET + VECTOR_SIZE*7)(%rsp), %VEC(7)
+# endif
vmovdqa %xmm7, (LR_XMM_OFFSET + XMM_SIZE*7)(%rsp)
1:
@@ -214,8 +258,13 @@
#ifdef RESTORE_AVX
/* This is to support AVX audit modules. */
- vmovdqu %ymm0, LRV_VECTOR0_OFFSET(%rcx)
- vmovdqu %ymm1, LRV_VECTOR1_OFFSET(%rcx)
+# if HAVE_NO_AVX512_ASM_SUPPORT
+ .byte 0x62,0xf1,0xfe,0x48,0x7f,0x81,0x50,0x00,0x00,0x00 # vmovdqu64 %zmm0,0x50(%rcx)
+ .byte 0x62,0xf1,0xfe,0x48,0x7f,0x89,0x90,0x00,0x00,0x00 # vmovdqu64 %zmm1,0x90(%rcx)
+# else
+ VMOV %VEC(0), LRV_VECTOR0_OFFSET(%rcx)
+ VMOV %VEC(1), LRV_VECTOR1_OFFSET(%rcx)
+# endif
/* Save xmm0/xmm1 registers to detect if they are changed
by audit module. */
@@ -244,13 +293,21 @@
vpmovmskb %xmm2, %esi
cmpl $0xffff, %esi
jne 1f
- vmovdqu LRV_VECTOR0_OFFSET(%rsp), %ymm0
+# if HAVE_NO_AVX512_ASM_SUPPORT
+ .byte 0x62,0xf1,0xfe,0x48,0x6f,0x84,0x24,0x50,0x00,0x00,0x00 # vmovdqu64 0x50(%rsp),%zmm0
+# else
+ VMOV LRV_VECTOR0_OFFSET(%rsp), %VEC(0)
+# endif
1: vpcmpeqq (LRV_SIZE + XMM_SIZE)(%rsp), %xmm1, %xmm2
vpmovmskb %xmm2, %esi
cmpl $0xffff, %esi
jne 1f
- vmovdqu LRV_VECTOR1_OFFSET(%rsp), %ymm1
+# if HAVE_NO_AVX512_ASM_SUPPORT
+ .byte 0x62,0xf1,0xfe,0x48,0x6f,0x8c,0x24,0x90,0x00,0x00,0x00 # vmovdqu64 0x90(%rsp),%zmm1
+# else
+ VMOV LRV_VECTOR1_OFFSET(%rsp), %VEC(1)
+# endif
1:
#endif
diff -urN glibc-2.12-2-gc4ccff1/sysdeps/x86_64/dl-trampoline.S glibc-2.12-2-gc4ccff1.mod/sysdeps/x86_64/dl-trampoline.S
--- glibc-2.12-2-gc4ccff1/sysdeps/x86_64/dl-trampoline.S 2015-03-03 23:03:05.108457659 -0500
+++ glibc-2.12-2-gc4ccff1.mod/sysdeps/x86_64/dl-trampoline.S 2015-03-03 23:07:31.799049953 -0500
@@ -134,7 +134,7 @@
.previous
cmpl $0, L(have_avx)(%rip)
- jne 1f
+ jne L(defined)
movq %rbx, %r11 # Save rbx
movl $1, %eax
cpuid
@@ -143,18 +143,51 @@
// AVX and XSAVE supported?
andl $((1 << 28) | (1 << 27)), %ecx
cmpl $((1 << 28) | (1 << 27)), %ecx
- jne 2f
+ jne 10f
+ // AVX512 supported in processor?
+ movq %rbx, %r11 # Save rbx
+ xorl %ecx, %ecx
+ mov $0x7, %eax
+ cpuid
+ andl $(1 << 16), %ebx
xorl %ecx, %ecx
// Get XFEATURE_ENABLED_MASK
xgetbv
- andl $0x6, %eax
-2: subl $0x5, %eax
+ test %ebx, %ebx
+ movq %r11, %rbx # Restore rbx
+ je 20f
+ // Verify that XCR0[7:5] = '111b' and
+ // XCR0[2:1] = '11b' which means
+ // that zmm state is enabled
+ andl $0xe6, %eax
+ cmpl $0xe6, %eax
+ jne 20f
+ movl %eax, L(have_avx)(%rip)
+L(avx512):
+# define RESTORE_AVX
+# define HAVE_NO_AVX512_ASM_SUPPORT 1
+# define VMOV vmovdqu64
+# define VEC(i) zmm##i
+# define MORE_CODE
+# include "dl-trampoline.h"
+# undef VMOV
+# undef VEC
+# undef RESTORE_AVX
+# undef HAVE_NO_AVX512_ASM_SUPPORT
+20: andl $0x6, %eax
+10: subl $0x5, %eax
movl %eax, L(have_avx)(%rip)
cmpl $0, %eax
-1: js L(no_avx)
+L(defined):
+ js L(no_avx)
+ cmpl $0xe6, L(have_avx)(%rip)
+ je L(avx512)
+
# define RESTORE_AVX
+# define VMOV vmovdqu
+# define VEC(i) ymm##i
# define MORE_CODE
# include "dl-trampoline.h"
@@ -178,7 +211,7 @@
_dl_x86_64_save_sse:
# ifdef HAVE_AVX_SUPPORT
cmpl $0, L(have_avx)(%rip)
- jne 1f
+ jne L(defined_5)
movq %rbx, %r11 # Save rbx
movl $1, %eax
cpuid
@@ -187,21 +220,37 @@
// AVX and XSAVE supported?
andl $((1 << 28) | (1 << 27)), %ecx
cmpl $((1 << 28) | (1 << 27)), %ecx
- jne 2f
+ jne 1f
+ // AVX512 supported in a processor?
+ movq %rbx, %r11 # Save rbx
+ xorl %ecx,%ecx
+ mov $0x7,%eax
+ cpuid
+ andl $(1 << 16), %ebx
xorl %ecx, %ecx
// Get XFEATURE_ENABLED_MASK
xgetbv
- andl $0x6, %eax
- cmpl $0x6, %eax
- // Nonzero if SSE and AVX state saving is enabled.
- sete %al
-2: leal -1(%eax,%eax), %eax
+ test %ebx, %ebx
+ movq %r11, %rbx # Restore rbx
+ je 2f
+ // Verify that XCR0[7:5] = '111b' and
+ // XCR0[2:1] = '11b' which means
+ // that zmm state is enabled
+ andl $0xe6, %eax
movl %eax, L(have_avx)(%rip)
- cmpl $0, %eax
+ cmpl $0xe6, %eax
+ je L(avx512_5)
-1: js L(no_avx5)
+2: andl $0x6, %eax
+1: subl $0x5, %eax
+ movl %eax, L(have_avx)(%rip)
+ cmpl $0, %eax
-# define YMM_SIZE 32
+L(defined_5):
+ js L(no_avx5)
+ cmpl $0xe6, L(have_avx)(%rip)
+ je L(avx512_5)
+
vmovdqa %ymm0, %fs:RTLD_SAVESPACE_SSE+0*YMM_SIZE
vmovdqa %ymm1, %fs:RTLD_SAVESPACE_SSE+1*YMM_SIZE
vmovdqa %ymm2, %fs:RTLD_SAVESPACE_SSE+2*YMM_SIZE
@@ -211,6 +260,26 @@
vmovdqa %ymm6, %fs:RTLD_SAVESPACE_SSE+6*YMM_SIZE
vmovdqa %ymm7, %fs:RTLD_SAVESPACE_SSE+7*YMM_SIZE
ret
+L(avx512_5):
+# Original instructions:
+# vmovdqu64 %zmm0, %fs:RTLD_SAVESPACE_SSE+0*ZMM_SIZE
+# vmovdqu64 %zmm1, %fs:RTLD_SAVESPACE_SSE+1*ZMM_SIZE
+# vmovdqu64 %zmm2, %fs:RTLD_SAVESPACE_SSE+2*ZMM_SIZE
+# vmovdqu64 %zmm3, %fs:RTLD_SAVESPACE_SSE+3*ZMM_SIZE
+# vmovdqu64 %zmm4, %fs:RTLD_SAVESPACE_SSE+4*ZMM_SIZE
+# vmovdqu64 %zmm5, %fs:RTLD_SAVESPACE_SSE+5*ZMM_SIZE
+# vmovdqu64 %zmm6, %fs:RTLD_SAVESPACE_SSE+6*ZMM_SIZE
+# vmovdqu64 %zmm7, %fs:RTLD_SAVESPACE_SSE+7*ZMM_SIZE
+# Assembled instructions:
+ .byte 0x64,0x62,0xf1,0xfe,0x48,0x7f,0x04,0x25,0x80,0x00,0x00,0x00 # vmovdqu64 %zmm0,%fs:0x80
+ .byte 0x64,0x62,0xf1,0xfe,0x48,0x7f,0x0c,0x25,0xc0,0x00,0x00,0x00 # vmovdqu64 %zmm1,%fs:0xc0
+ .byte 0x64,0x62,0xf1,0xfe,0x48,0x7f,0x14,0x25,0x00,0x01,0x00,0x00 # vmovdqu64 %zmm2,%fs:0x100
+ .byte 0x64,0x62,0xf1,0xfe,0x48,0x7f,0x1c,0x25,0x40,0x01,0x00,0x00 # vmovdqu64 %zmm3,%fs:0x140
+ .byte 0x64,0x62,0xf1,0xfe,0x48,0x7f,0x24,0x25,0x80,0x01,0x00,0x00 # vmovdqu64 %zmm4,%fs:0x180
+ .byte 0x64,0x62,0xf1,0xfe,0x48,0x7f,0x2c,0x25,0xc0,0x01,0x00,0x00 # vmovdqu64 %zmm5,%fs:0x1c0
+ .byte 0x64,0x62,0xf1,0xfe,0x48,0x7f,0x34,0x25,0x00,0x02,0x00,0x00 # vmovdqu64 %zmm6,%fs:0x200
+ .byte 0x64,0x62,0xf1,0xfe,0x48,0x7f,0x3c,0x25,0x40,0x02,0x00,0x00 # vmovdqu64 %zmm7,%fs:0x240
+ ret
L(no_avx5):
# endif
movdqa %xmm0, %fs:RTLD_SAVESPACE_SSE+0*XMM_SIZE
@@ -234,6 +303,8 @@
# ifdef HAVE_AVX_SUPPORT
cmpl $0, L(have_avx)(%rip)
js L(no_avx6)
+ cmpl $0xe6, L(have_avx)(%rip)
+ je L(avx512_6)
vmovdqa %fs:RTLD_SAVESPACE_SSE+0*YMM_SIZE, %ymm0
vmovdqa %fs:RTLD_SAVESPACE_SSE+1*YMM_SIZE, %ymm1
@@ -244,6 +315,26 @@
vmovdqa %fs:RTLD_SAVESPACE_SSE+6*YMM_SIZE, %ymm6
vmovdqa %fs:RTLD_SAVESPACE_SSE+7*YMM_SIZE, %ymm7
ret
+L(avx512_6):
+# Original instructions:
+# vmovdqu64 %fs:RTLD_SAVESPACE_SSE+0*ZMM_SIZE, %zmm0
+# vmovdqu64 %fs:RTLD_SAVESPACE_SSE+1*ZMM_SIZE, %zmm1
+# vmovdqu64 %fs:RTLD_SAVESPACE_SSE+2*ZMM_SIZE, %zmm2
+# vmovdqu64 %fs:RTLD_SAVESPACE_SSE+3*ZMM_SIZE, %zmm3
+# vmovdqu64 %fs:RTLD_SAVESPACE_SSE+4*ZMM_SIZE, %zmm4
+# vmovdqu64 %fs:RTLD_SAVESPACE_SSE+5*ZMM_SIZE, %zmm5
+# vmovdqu64 %fs:RTLD_SAVESPACE_SSE+6*ZMM_SIZE, %zmm6
+# vmovdqu64 %fs:RTLD_SAVESPACE_SSE+7*ZMM_SIZE, %zmm7
+# Assembled instructions:
+ .byte 0x64,0x62,0xf1,0xfe,0x48,0x6f,0x04,0x25,0x80,0x00,0x00,0x00 # vmovdqu64 %fs:0x80,%zmm0
+ .byte 0x64,0x62,0xf1,0xfe,0x48,0x6f,0x0c,0x25,0xc0,0x00,0x00,0x00 # vmovdqu64 %fs:0xc0,%zmm1
+ .byte 0x64,0x62,0xf1,0xfe,0x48,0x6f,0x14,0x25,0x00,0x01,0x00,0x00 # vmovdqu64 %fs:0x100,%zmm2
+ .byte 0x64,0x62,0xf1,0xfe,0x48,0x6f,0x1c,0x25,0x40,0x01,0x00,0x00 # vmovdqu64 %fs:0x140,%zmm3
+ .byte 0x64,0x62,0xf1,0xfe,0x48,0x6f,0x24,0x25,0x80,0x01,0x00,0x00 # vmovdqu64 %fs:0x180,%zmm4
+ .byte 0x64,0x62,0xf1,0xfe,0x48,0x6f,0x2c,0x25,0xc0,0x01,0x00,0x00 # vmovdqu64 %fs:0x1c0,%zmm5
+ .byte 0x64,0x62,0xf1,0xfe,0x48,0x6f,0x34,0x25,0x00,0x02,0x00,0x00 # vmovdqu64 %fs:0x200,%zmm6
+ .byte 0x64,0x62,0xf1,0xfe,0x48,0x6f,0x3c,0x25,0x40,0x02,0x00,0x00 # vmovdqu64 %fs:0x240,%zmm7
+ ret
L(no_avx6):
# endif
movdqa %fs:RTLD_SAVESPACE_SSE+0*XMM_SIZE, %xmm0
diff -urN glibc-2.12-2-gc4ccff1/sysdeps/x86_64/link-defines.sym glibc-2.12-2-gc4ccff1.mod/sysdeps/x86_64/link-defines.sym
--- glibc-2.12-2-gc4ccff1/sysdeps/x86_64/link-defines.sym 2010-05-04 07:27:23.000000000 -0400
+++ glibc-2.12-2-gc4ccff1.mod/sysdeps/x86_64/link-defines.sym 2015-03-03 23:03:25.042829206 -0500
@@ -4,6 +4,8 @@
--
VECTOR_SIZE sizeof (La_x86_64_vector)
XMM_SIZE sizeof (La_x86_64_xmm)
+YMM_SIZE sizeof (La_x86_64_ymm)
+ZMM_SIZE sizeof (La_x86_64_zmm)
LR_SIZE sizeof (struct La_x86_64_regs)
LR_RDX_OFFSET offsetof (struct La_x86_64_regs, lr_rdx)

View File

@@ -0,0 +1,12 @@
diff -pruN glibc-2.12-2-gc4ccff1/malloc/malloc.c glibc-2.12-2-gc4ccff1.new/malloc/malloc.c
--- glibc-2.12-2-gc4ccff1/malloc/malloc.c 2015-04-10 12:02:54.011106386 +0530
+++ glibc-2.12-2-gc4ccff1.new/malloc/malloc.c 2015-04-10 12:02:35.867958292 +0530
@@ -5850,7 +5850,7 @@ _int_valloc(av, bytes) mstate av; size_t
#endif
{
/* Ensure initialization/consolidation */
- if (have_fastchunks(av)) malloc_consolidate(av);
+ if (av && have_fastchunks(av)) malloc_consolidate(av);
return _int_memalign(av, mp_.pagesize, bytes);
}

View File

@@ -0,0 +1,15 @@
diff -pruN glibc-2.12-2-gc4ccff1/malloc/malloc.c glibc-2.12-2-gc4ccff1.new/malloc/malloc.c
--- glibc-2.12-2-gc4ccff1/malloc/malloc.c 2015-07-28 22:28:22.517107147 +0530
+++ glibc-2.12-2-gc4ccff1.new/malloc/malloc.c 2015-07-28 22:24:59.541394493 +0530
@@ -4087,8 +4087,9 @@ public_cALLOc(size_t n, size_t elem_size
/* Maybe the failure is due to running out of mmapped areas. */
if(av != &main_arena) {
(void)mutex_unlock(&av->mutex);
- (void)mutex_lock(&main_arena.mutex);
- mem = _int_malloc(&main_arena, sz);
+ av = &main_arena;
+ (void)mutex_lock(&av->mutex);
+ mem = _int_malloc(av, sz);
} else {
#if USE_ARENAS
/* ... or sbrk() has failed and there is still a chance to mmap() */

View File

@@ -0,0 +1,138 @@
commit fdc0f374bcd2d0513569aa8d600f960e43e8af1d
Author: Ulrich Drepper <drepper@redhat.com>
Date: Sun Oct 24 22:37:00 2010 -0400
Fix perturbing in malloc on free.
commit e8349efd466cfedc0aa98be61d88ca8795c9e565
Author: Ondřej Bílka <neleai@seznam.cz>
Date: Mon Dec 9 17:25:19 2013 +0100
Simplify perturb_byte logic.
diff --git a/malloc/malloc.c b/malloc/malloc.c
index 4821deb..ac8c3f6 100644
--- a/malloc/malloc.c
+++ b/malloc/malloc.c
@@ -1870,8 +1870,20 @@ static int check_action = DEFAULT_CHECK_ACTION;
static int perturb_byte;
-#define alloc_perturb(p, n) memset (p, (perturb_byte ^ 0xff) & 0xff, n)
-#define free_perturb(p, n) memset (p, perturb_byte & 0xff, n)
+static inline void
+alloc_perturb (char *p, size_t n)
+{
+ if (__glibc_unlikely (perturb_byte))
+ memset (p, perturb_byte ^ 0xff, n);
+}
+
+static inline void
+free_perturb (char *p, size_t n)
+{
+ if (__glibc_unlikely (perturb_byte))
+ memset (p, perturb_byte, n);
+}
+
/* ------------------- Support for multiple arenas -------------------- */
@@ -3287,8 +3299,7 @@ _int_malloc(mstate av, size_t bytes)
#endif
check_remalloced_chunk(av, victim, nb);
void *p = chunk2mem(victim);
- if (__builtin_expect (perturb_byte, 0))
- alloc_perturb (p, bytes);
+ alloc_perturb (p, bytes);
return p;
}
}
@@ -3323,8 +3334,7 @@ _int_malloc(mstate av, size_t bytes)
victim->size |= NON_MAIN_ARENA;
check_malloced_chunk(av, victim, nb);
void *p = chunk2mem(victim);
- if (__builtin_expect (perturb_byte, 0))
- alloc_perturb (p, bytes);
+ alloc_perturb (p, bytes);
return p;
}
}
@@ -3403,8 +3413,7 @@ _int_malloc(mstate av, size_t bytes)
check_malloced_chunk(av, victim, nb);
void *p = chunk2mem(victim);
- if (__builtin_expect (perturb_byte, 0))
- alloc_perturb (p, bytes);
+ alloc_perturb (p, bytes);
return p;
}
@@ -3420,8 +3429,7 @@ _int_malloc(mstate av, size_t bytes)
victim->size |= NON_MAIN_ARENA;
check_malloced_chunk(av, victim, nb);
void *p = chunk2mem(victim);
- if (__builtin_expect (perturb_byte, 0))
- alloc_perturb (p, bytes);
+ alloc_perturb (p, bytes);
return p;
}
@@ -3545,8 +3553,7 @@ _int_malloc(mstate av, size_t bytes)
}
check_malloced_chunk(av, victim, nb);
void *p = chunk2mem(victim);
- if (__builtin_expect (perturb_byte, 0))
- alloc_perturb (p, bytes);
+ alloc_perturb (p, bytes);
return p;
}
}
@@ -3649,8 +3656,7 @@ _int_malloc(mstate av, size_t bytes)
}
check_malloced_chunk(av, victim, nb);
void *p = chunk2mem(victim);
- if (__builtin_expect (perturb_byte, 0))
- alloc_perturb (p, bytes);
+ alloc_perturb (p, bytes);
return p;
}
}
@@ -3684,8 +3690,7 @@ _int_malloc(mstate av, size_t bytes)
check_malloced_chunk(av, victim, nb);
void *p = chunk2mem(victim);
- if (__builtin_expect (perturb_byte, 0))
- alloc_perturb (p, bytes);
+ alloc_perturb (p, bytes);
return p;
}
@@ -3705,7 +3710,7 @@ _int_malloc(mstate av, size_t bytes)
*/
else {
void *p = sYSMALLOc(nb, av);
- if (p != NULL && __builtin_expect (perturb_byte, 0))
+ if (p != NULL)
alloc_perturb (p, bytes);
return p;
}
@@ -3798,8 +3803,7 @@ _int_free(mstate av, mchunkptr p, int have_lock)
#endif
}
- if (__builtin_expect (perturb_byte, 0))
- free_perturb (chunk2mem(p), size - SIZE_SZ);
+ free_perturb (chunk2mem(p), size - 2 * SIZE_SZ);
set_fastchunks(av);
unsigned int idx = fastbin_index(size);
@@ -3881,8 +3885,7 @@ _int_free(mstate av, mchunkptr p, int have_lock)
goto errout;
}
- if (__builtin_expect (perturb_byte, 0))
- free_perturb (chunk2mem(p), size - SIZE_SZ);
+ free_perturb (chunk2mem(p), size - 2 * SIZE_SZ);
/* consolidate backward */
if (!prev_inuse(p)) {

View File

@@ -0,0 +1,45 @@
commit 55765a349a96482207fbf927d3666a51878f973b
Author: Josef Bacik <josef@toxicpanda.com>
Date: Wed Aug 19 14:06:56 2015 +0530
Don't fall back to mmap if the original arena is not corrupt
The new logic to find an uncontended non-corrupt arena misses a case
where the current arena is contended, but is not corrupt. In the
degenerate case, this is the only arena. In both cases, the logic
falls back to using mmap despite there being an available arena.
Attached patch by Josef Bacik makes sure that all arenas are indeed
corrupt before falling back to malloc. Verified on x86_64.
* malloc/arena.c (reused_arena): return NULL only if all
arenas are corrupt.
diff --git a/malloc/arena.c b/malloc/arena.c
index 21ecc5a1..0424273 100644
--- a/malloc/arena.c
+++ b/malloc/arena.c
@@ -823,16 +823,21 @@ reused_arena (mstate avoid_arena)
/* Make sure that the arena we get is not corrupted. */
mstate begin = result;
+ bool looped = false;
+
while (arena_is_corrupt (result))
{
result = result->next;
if (result == begin)
- break;
+ {
+ looped = true;
+ break;
+ }
}
/* We could not find any arena that was either not corrupted or not the one
we wanted to avoid. */
- if (result == begin)
+ if (looped)
return NULL;
/* No arena available without contention. Wait for the next in line. */

View File

@@ -0,0 +1,56 @@
diff -pruN glibc-2.12-2-gc4ccff1/malloc/malloc.c glibc-2.12-2-gc4ccff1.v2/malloc/malloc.c
--- glibc-2.12-2-gc4ccff1/malloc/malloc.c 2015-07-24 19:29:37.679907396 +0530
+++ glibc-2.12-2-gc4ccff1.v2/malloc/malloc.c 2015-07-24 18:59:59.928055174 +0530
@@ -3737,8 +3737,7 @@ public_mALLOc(size_t bytes)
mstate prev = ar_ptr->next ? ar_ptr : 0;
(void)mutex_unlock(&ar_ptr->mutex);
ar_ptr = arena_get2(prev, bytes, true);
- if(ar_ptr)
- victim = _int_malloc(ar_ptr, bytes);
+ victim = _int_malloc(ar_ptr, bytes);
#endif
}
}
@@ -3968,8 +3967,7 @@ public_mEMALIGn(size_t alignment, size_t
mstate prev = ar_ptr->next ? ar_ptr : 0;
(void)mutex_unlock(&ar_ptr->mutex);
ar_ptr = arena_get2(prev, bytes, true);
- if(ar_ptr)
- p = _int_memalign(ar_ptr, alignment, bytes);
+ p = _int_memalign(ar_ptr, alignment, bytes);
#endif
}
}
@@ -4024,8 +4022,7 @@ public_vALLOc(size_t bytes)
mstate prev = ar_ptr->next ? ar_ptr : 0;
(void)mutex_unlock(&ar_ptr->mutex);
ar_ptr = arena_get2(prev, bytes, true);
- if(ar_ptr)
- p = _int_memalign(ar_ptr, pagesz, bytes);
+ p = _int_memalign(ar_ptr, pagesz, bytes);
#endif
}
}
@@ -4080,8 +4077,7 @@ public_pVALLOc(size_t bytes)
mstate prev = ar_ptr->next ? ar_ptr : 0;
(void)mutex_unlock(&ar_ptr->mutex);
ar_ptr = arena_get2(prev, bytes + 2*pagesz + MINSIZE, true);
- if(ar_ptr)
- p = _int_memalign(ar_ptr, pagesz, rounded_bytes);
+ p = _int_memalign(ar_ptr, pagesz, rounded_bytes);
#endif
}
}
@@ -4180,11 +4176,9 @@ public_cALLOc(size_t n, size_t elem_size
mstate prev = av->next ? av : 0;
(void)mutex_unlock(&av->mutex);
av = arena_get2(prev, sz, true);
- if(av)
- mem = _int_malloc(av, sz);
+ mem = _int_malloc(av, sz);
#endif
}
- if (mem == 0) return 0;
}
if (av != NULL)

View File

@@ -0,0 +1,12 @@
diff -pruN glibc-2.12-2-gc4ccff1/malloc/malloc.c glibc-2.12-2-gc4ccff1.new/malloc/malloc.c
--- glibc-2.12-2-gc4ccff1/malloc/malloc.c 2015-08-19 23:13:52.826205930 +0530
+++ glibc-2.12-2-gc4ccff1.new/malloc/malloc.c 2015-08-19 23:13:40.021049289 +0530
@@ -5867,7 +5867,7 @@ _int_pvalloc(av, bytes) mstate av, size_
size_t pagesz;
/* Ensure initialization/consolidation */
- if (have_fastchunks(av)) malloc_consolidate(av);
+ if (av && have_fastchunks(av)) malloc_consolidate(av);
pagesz = mp_.pagesize;
return _int_memalign(av, pagesz, (bytes + pagesz - 1) & ~(pagesz - 1));
}

View File

@@ -0,0 +1,26 @@
commit 5c44738353ecaa1c81efca063ee8b55e092d7a43
Author: Alexandre Oliva <aoliva@redhat.com>
Date: Wed Sep 5 15:43:04 2012 -0300
Don't change no_dyn_threshold on mallopt failure
* malloc/malloc.c (__libc_mallopt) <M_MMAP_THRESHOLD>: Do not
change internal state upon failure.
diff --git a/malloc/malloc.c b/malloc/malloc.c
index bd562df..c69e281 100644
--- a/malloc/malloc.c
+++ b/malloc/malloc.c
@@ -4769,8 +4769,10 @@ int __libc_mallopt(int param_number, int value)
res = 0;
else
#endif
- mp_.mmap_threshold = value;
- mp_.no_dyn_threshold = 1;
+ {
+ mp_.mmap_threshold = value;
+ mp_.no_dyn_threshold = 1;
+ }
break;
case M_MMAP_MAX:

View File

@@ -0,0 +1,41 @@
Description: Allow loading more libraries with static TLS.
Author: Carlos O'Donell <codonell@redhat.com>
Origin: PATCH
Bug-RHEL: #1291270 (rhel-6.7.z), #1198802 (rhel-6.8), #1202952 (rhel-7.2)
Bug-Fedora: #1124987 (F21)
Bug-Upstream: #17090, #17620, #17621, #17628 (2.22)
Upstream status: not-needed
#
# The correct fix for this is already upstream and involves
# changing the heuristics for DTV slot increases. In RHEL6
# we take the conservative approach and provide a larger
# slot surplus. This matches what was done in Fedora 21 before
# we had the upstream fix: f8aeae347377f3dfa8cbadde057adf1827fb1d44.
# In RHEL7 we have the upstream fix. This is fixed upstream as of
# glibc 2.22.
#
Index: glibc-2.12-2-gc4ccff1/sysdeps/generic/ldsodefs.h
===================================================================
--- glibc-2.12-2-gc4ccff1.orig/sysdeps/generic/ldsodefs.h
+++ glibc-2.12-2-gc4ccff1/sysdeps/generic/ldsodefs.h
@@ -496,8 +496,18 @@ struct rtld_global
have to iterate beyond the first element in the slotinfo list. */
#define TLS_SLOTINFO_SURPLUS (62)
-/* Number of additional slots in the dtv allocated. */
-#define DTV_SURPLUS (14)
+/* Number of additional allocated dtv slots. This was initially
+ 14, but problems with python, MESA, and X11's uses of static TLS meant
+ that most distributions were very close to this limit when they loaded
+ dynamically interpreted languages that used graphics. The simplest
+ solution was to roughly double the number of slots. The actual static
+ image space usage was relatively small, for example in MESA you
+ had only two dispatch pointers for a total of 16 bytes. If we hit up
+ against this limit again we should start a campaign with the
+ distributions to coordinate the usage of static TLS. Any user of this
+ resource is effectively coordinating a global resource since this
+ surplus is allocated for each thread at startup. */
+#define DTV_SURPLUS (32)
/* Initial dtv of the main thread, not allocated with normal malloc. */
EXTERN void *_dl_initial_dtv;

View File

@@ -0,0 +1,465 @@
Sourceware bug 16574
commit d668061994a7486a3ba9c7d5e7882d85a2883707
Author: Andreas Schwab <schwab@suse.de>
Date: Thu Feb 13 11:01:57 2014 +0100
Fix memory leak in _nss_dns_gethostbyname4_r with big DNS answer
commit ab7ac0f2cf8731fe4c3f3aea6088a7c0127b5725
Author: Ondřej Bílka <neleai@seznam.cz>
Date: Sun Feb 16 12:59:23 2014 +0100
Deduplicate resolv/nss_dns/dns-host.c
In resolv/nss_dns/dns-host.c one of code path duplicated code after
that. We merge these paths.
commit ab09bf616ad527b249aca5f2a4956fd526f0712f
Author: Andreas Schwab <schwab@suse.de>
Date: Tue Feb 18 10:57:25 2014 +0100
Properly fix memory leak in _nss_dns_gethostbyname4_r with big DNS answer
Instead of trying to guess whether the second buffer needs to be freed
set a flag at the place it is allocated
Index: glibc-2.12-2-gc4ccff1/include/resolv.h
===================================================================
--- glibc-2.12-2-gc4ccff1.orig/include/resolv.h
+++ glibc-2.12-2-gc4ccff1/include/resolv.h
@@ -58,11 +58,11 @@ libc_hidden_proto (__res_randomid)
libc_hidden_proto (__res_state)
int __libc_res_nquery (res_state, const char *, int, int, u_char *, int,
- u_char **, u_char **, int *, int *);
+ u_char **, u_char **, int *, int *, int *);
int __libc_res_nsearch (res_state, const char *, int, int, u_char *, int,
- u_char **, u_char **, int *, int *);
+ u_char **, u_char **, int *, int *, int *);
int __libc_res_nsend (res_state, const u_char *, int, const u_char *, int,
- u_char *, int, u_char **, u_char **, int *, int *)
+ u_char *, int, u_char **, u_char **, int *, int *, int *)
attribute_hidden;
libresolv_hidden_proto (_sethtent)
Index: glibc-2.12-2-gc4ccff1/resolv/gethnamaddr.c
===================================================================
--- glibc-2.12-2-gc4ccff1.orig/resolv/gethnamaddr.c
+++ glibc-2.12-2-gc4ccff1/resolv/gethnamaddr.c
@@ -634,7 +634,7 @@ gethostbyname2(name, af)
buf.buf = origbuf = (querybuf *) alloca (1024);
if ((n = __libc_res_nsearch(&_res, name, C_IN, type, buf.buf->buf, 1024,
- &buf.ptr, NULL, NULL, NULL)) < 0) {
+ &buf.ptr, NULL, NULL, NULL, NULL)) < 0) {
if (buf.buf != origbuf)
free (buf.buf);
Dprintf("res_nsearch failed (%d)\n", n);
@@ -729,12 +729,12 @@ gethostbyaddr(addr, len, af)
buf.buf = orig_buf = (querybuf *) alloca (1024);
n = __libc_res_nquery(&_res, qbuf, C_IN, T_PTR, buf.buf->buf, 1024,
- &buf.ptr, NULL, NULL, NULL);
+ &buf.ptr, NULL, NULL, NULL, NULL);
if (n < 0 && af == AF_INET6 && (_res.options & RES_NOIP6DOTINT) == 0) {
strcpy(qp, "ip6.int");
n = __libc_res_nquery(&_res, qbuf, C_IN, T_PTR, buf.buf->buf,
buf.buf != orig_buf ? MAXPACKET : 1024,
- &buf.ptr, NULL, NULL, NULL);
+ &buf.ptr, NULL, NULL, NULL, NULL);
}
if (n < 0) {
if (buf.buf != orig_buf)
Index: glibc-2.12-2-gc4ccff1/resolv/nss_dns/dns-canon.c
===================================================================
--- glibc-2.12-2-gc4ccff1.orig/resolv/nss_dns/dns-canon.c
+++ glibc-2.12-2-gc4ccff1/resolv/nss_dns/dns-canon.c
@@ -62,7 +62,7 @@ _nss_dns_getcanonname_r (const char *nam
{
int r = __libc_res_nquery (&_res, name, ns_c_in, qtypes[i],
buf, sizeof (buf), &ansp.ptr, NULL, NULL,
- NULL);
+ NULL, NULL);
if (r > 0)
{
/* We need to decode the response. Just one question record.
Index: glibc-2.12-2-gc4ccff1/resolv/nss_dns/dns-host.c
===================================================================
--- glibc-2.12-2-gc4ccff1.orig/resolv/nss_dns/dns-host.c
+++ glibc-2.12-2-gc4ccff1/resolv/nss_dns/dns-host.c
@@ -191,7 +191,7 @@ _nss_dns_gethostbyname3_r (const char *n
host_buffer.buf = orig_host_buffer = (querybuf *) alloca (1024);
n = __libc_res_nsearch (&_res, name, C_IN, type, host_buffer.buf->buf,
- 1024, &host_buffer.ptr, NULL, NULL, NULL);
+ 1024, &host_buffer.ptr, NULL, NULL, NULL, NULL);
if (n < 0)
{
switch (errno)
@@ -221,7 +221,7 @@ _nss_dns_gethostbyname3_r (const char *n
n = __libc_res_nsearch (&_res, name, C_IN, T_A, host_buffer.buf->buf,
host_buffer.buf != orig_host_buffer
? MAXPACKET : 1024, &host_buffer.ptr,
- NULL, NULL, NULL);
+ NULL, NULL, NULL, NULL);
if (n < 0)
{
@@ -304,13 +304,20 @@ _nss_dns_gethostbyname4_r (const char *n
u_char *ans2p = NULL;
int nans2p = 0;
int resplen2 = 0;
+ int ans2p_malloced = 0;
int olderr = errno;
enum nss_status status;
int n = __libc_res_nsearch (&_res, name, C_IN, T_UNSPEC,
host_buffer.buf->buf, 2048, &host_buffer.ptr,
- &ans2p, &nans2p, &resplen2);
- if (n < 0)
+ &ans2p, &nans2p, &resplen2, &ans2p_malloced);
+ if (n >= 0)
+ {
+ status = gaih_getanswer (host_buffer.buf, n, (const querybuf *) ans2p,
+ resplen2, name, pat, buffer, buflen,
+ errnop, herrnop, ttlp);
+ }
+ else
{
if (errno == ESRCH)
{
@@ -325,16 +332,11 @@ _nss_dns_gethostbyname4_r (const char *n
*errnop = EAGAIN;
else
__set_errno (olderr);
-
- if (host_buffer.buf != orig_host_buffer)
- free (host_buffer.buf);
-
- return status;
}
- status = gaih_getanswer(host_buffer.buf, n, (const querybuf *) ans2p,
- resplen2, name, pat, buffer, buflen,
- errnop, herrnop, ttlp);
+ /* Check whether ans2p was separately allocated. */
+ if (ans2p_malloced)
+ free (ans2p);
if (host_buffer.buf != orig_host_buffer)
free (host_buffer.buf);
@@ -444,7 +446,7 @@ _nss_dns_gethostbyaddr2_r (const void *a
strcpy (qp, "].ip6.arpa");
n = __libc_res_nquery (&_res, qbuf, C_IN, T_PTR,
host_buffer.buf->buf, 1024, &host_buffer.ptr,
- NULL, NULL, NULL);
+ NULL, NULL, NULL, NULL);
if (n >= 0)
goto got_it_already;
}
@@ -465,14 +467,14 @@ _nss_dns_gethostbyaddr2_r (const void *a
}
n = __libc_res_nquery (&_res, qbuf, C_IN, T_PTR, host_buffer.buf->buf,
- 1024, &host_buffer.ptr, NULL, NULL, NULL);
+ 1024, &host_buffer.ptr, NULL, NULL, NULL, NULL);
if (n < 0 && af == AF_INET6 && (_res.options & RES_NOIP6DOTINT) == 0)
{
strcpy (qp, "ip6.int");
n = __libc_res_nquery (&_res, qbuf, C_IN, T_PTR, host_buffer.buf->buf,
host_buffer.buf != orig_host_buffer
? MAXPACKET : 1024, &host_buffer.ptr,
- NULL, NULL, NULL);
+ NULL, NULL, NULL, NULL);
}
if (n < 0)
{
Index: glibc-2.12-2-gc4ccff1/resolv/nss_dns/dns-network.c
===================================================================
--- glibc-2.12-2-gc4ccff1.orig/resolv/nss_dns/dns-network.c
+++ glibc-2.12-2-gc4ccff1/resolv/nss_dns/dns-network.c
@@ -130,7 +130,7 @@ _nss_dns_getnetbyname_r (const char *nam
net_buffer.buf = orig_net_buffer = (querybuf *) alloca (1024);
anslen = __libc_res_nsearch (&_res, qbuf, C_IN, T_PTR, net_buffer.buf->buf,
- 1024, &net_buffer.ptr, NULL, NULL, NULL);
+ 1024, &net_buffer.ptr, NULL, NULL, NULL, NULL);
if (anslen < 0)
{
/* Nothing found. */
@@ -206,7 +206,7 @@ _nss_dns_getnetbyaddr_r (uint32_t net, i
net_buffer.buf = orig_net_buffer = (querybuf *) alloca (1024);
anslen = __libc_res_nquery (&_res, qbuf, C_IN, T_PTR, net_buffer.buf->buf,
- 1024, &net_buffer.ptr, NULL, NULL, NULL);
+ 1024, &net_buffer.ptr, NULL, NULL, NULL, NULL);
if (anslen < 0)
{
/* Nothing found. */
Index: glibc-2.12-2-gc4ccff1/resolv/res_query.c
===================================================================
--- glibc-2.12-2-gc4ccff1.orig/resolv/res_query.c
+++ glibc-2.12-2-gc4ccff1/resolv/res_query.c
@@ -98,7 +98,7 @@ static int
__libc_res_nquerydomain(res_state statp, const char *name, const char *domain,
int class, int type, u_char *answer, int anslen,
u_char **answerp, u_char **answerp2, int *nanswerp2,
- int *resplen2);
+ int *resplen2, int *answerp2_malloced);
/*
* Formulate a normal query, send, and await answer.
@@ -119,7 +119,8 @@ __libc_res_nquery(res_state statp,
u_char **answerp, /* if buffer needs to be enlarged */
u_char **answerp2,
int *nanswerp2,
- int *resplen2)
+ int *resplen2,
+ int *answerp2_malloced)
{
HEADER *hp = (HEADER *) answer;
HEADER *hp2;
@@ -224,7 +225,8 @@ __libc_res_nquery(res_state statp,
}
assert (answerp == NULL || (void *) *answerp == (void *) answer);
n = __libc_res_nsend(statp, query1, nquery1, query2, nquery2, answer,
- anslen, answerp, answerp2, nanswerp2, resplen2);
+ anslen, answerp, answerp2, nanswerp2, resplen2,
+ answerp2_malloced);
if (use_malloc)
free (buf);
if (n < 0) {
@@ -316,7 +318,7 @@ res_nquery(res_state statp,
int anslen) /* size of answer buffer */
{
return __libc_res_nquery(statp, name, class, type, answer, anslen,
- NULL, NULL, NULL, NULL);
+ NULL, NULL, NULL, NULL, NULL);
}
libresolv_hidden_def (res_nquery)
@@ -335,7 +337,8 @@ __libc_res_nsearch(res_state statp,
u_char **answerp,
u_char **answerp2,
int *nanswerp2,
- int *resplen2)
+ int *resplen2,
+ int *answerp2_malloced)
{
const char *cp, * const *domain;
HEADER *hp = (HEADER *) answer;
@@ -359,7 +362,7 @@ __libc_res_nsearch(res_state statp,
if (!dots && (cp = res_hostalias(statp, name, tmp, sizeof tmp))!= NULL)
return (__libc_res_nquery(statp, cp, class, type, answer,
anslen, answerp, answerp2,
- nanswerp2, resplen2));
+ nanswerp2, resplen2, answerp2_malloced));
#ifdef DEBUG
if (statp->options & RES_DEBUG)
@@ -376,7 +379,8 @@ __libc_res_nsearch(res_state statp,
if (dots >= statp->ndots || trailing_dot) {
ret = __libc_res_nquerydomain(statp, name, NULL, class, type,
answer, anslen, answerp,
- answerp2, nanswerp2, resplen2);
+ answerp2, nanswerp2, resplen2,
+ answerp2_malloced);
if (ret > 0 || trailing_dot
/* If the second response is valid then we use that. */
|| (ret == 0 && resplen2 != NULL && *resplen2 > 0))
@@ -387,12 +391,12 @@ __libc_res_nsearch(res_state statp,
answer = *answerp;
anslen = MAXPACKET;
}
- if (answerp2
- && (*answerp2 < answer || *answerp2 >= answer + anslen))
+ if (answerp2 && *answerp2_malloced)
{
free (*answerp2);
*nanswerp2 = 0;
*answerp2 = NULL;
+ *answerp2_malloced = 0;
}
}
@@ -418,7 +422,7 @@ __libc_res_nsearch(res_state statp,
class, type,
answer, anslen, answerp,
answerp2, nanswerp2,
- resplen2);
+ resplen2, answerp2_malloced);
if (ret > 0 || (ret == 0 && resplen2 != NULL
&& *resplen2 > 0))
return (ret);
@@ -427,13 +431,12 @@ __libc_res_nsearch(res_state statp,
answer = *answerp;
anslen = MAXPACKET;
}
- if (answerp2
- && (*answerp2 < answer
- || *answerp2 >= answer + anslen))
+ if (answerp2 && *answerp2_malloced)
{
free (*answerp2);
*nanswerp2 = 0;
*answerp2 = NULL;
+ *answerp2_malloced = 0;
}
/*
@@ -489,7 +492,8 @@ __libc_res_nsearch(res_state statp,
if (dots && !(tried_as_is || root_on_list)) {
ret = __libc_res_nquerydomain(statp, name, NULL, class, type,
answer, anslen, answerp,
- answerp2, nanswerp2, resplen2);
+ answerp2, nanswerp2, resplen2,
+ answerp2_malloced);
if (ret > 0 || (ret == 0 && resplen2 != NULL
&& *resplen2 > 0))
return (ret);
@@ -502,11 +506,12 @@ __libc_res_nsearch(res_state statp,
* else send back meaningless H_ERRNO, that being the one from
* the last DNSRCH we did.
*/
- if (answerp2 && (*answerp2 < answer || *answerp2 >= answer + anslen))
+ if (answerp2 && *answerp2_malloced)
{
free (*answerp2);
- *nanswerp2 = NULL;
+ *nanswerp2 = 0;
*answerp2 = NULL;
+ *answerp2_malloced = 0;
}
if (saved_herrno != -1)
RES_SET_H_ERRNO(statp, saved_herrno);
@@ -526,7 +531,7 @@ res_nsearch(res_state statp,
int anslen) /* size of answer */
{
return __libc_res_nsearch(statp, name, class, type, answer,
- anslen, NULL, NULL, NULL, NULL);
+ anslen, NULL, NULL, NULL, NULL, NULL);
}
libresolv_hidden_def (res_nsearch)
@@ -544,7 +549,8 @@ __libc_res_nquerydomain(res_state statp,
u_char **answerp,
u_char **answerp2,
int *nanswerp2,
- int *resplen2)
+ int *resplen2,
+ int *answerp2_malloced)
{
char nbuf[MAXDNAME];
const char *longname = nbuf;
@@ -582,7 +588,7 @@ __libc_res_nquerydomain(res_state statp,
}
return (__libc_res_nquery(statp, longname, class, type, answer,
anslen, answerp, answerp2, nanswerp2,
- resplen2));
+ resplen2, answerp2_malloced));
}
int
@@ -594,7 +600,8 @@ res_nquerydomain(res_state statp,
int anslen) /* size of answer */
{
return __libc_res_nquerydomain(statp, name, domain, class, type,
- answer, anslen, NULL, NULL, NULL, NULL);
+ answer, anslen, NULL, NULL, NULL, NULL,
+ NULL);
}
libresolv_hidden_def (res_nquerydomain)
Index: glibc-2.12-2-gc4ccff1/resolv/res_send.c
===================================================================
--- glibc-2.12-2-gc4ccff1.orig/resolv/res_send.c
+++ glibc-2.12-2-gc4ccff1/resolv/res_send.c
@@ -203,12 +203,12 @@ evNowTime(struct timespec *res) {
static int send_vc(res_state, const u_char *, int,
const u_char *, int,
u_char **, int *, int *, int, u_char **,
- u_char **, int *, int *);
+ u_char **, int *, int *, int *);
static int send_dg(res_state, const u_char *, int,
const u_char *, int,
u_char **, int *, int *, int,
int *, int *, u_char **,
- u_char **, int *, int *);
+ u_char **, int *, int *, int *);
#ifdef DEBUG
static void Aerror(const res_state, FILE *, const char *, int,
const struct sockaddr *);
@@ -360,7 +360,7 @@ int
__libc_res_nsend(res_state statp, const u_char *buf, int buflen,
const u_char *buf2, int buflen2,
u_char *ans, int anssiz, u_char **ansp, u_char **ansp2,
- int *nansp2, int *resplen2)
+ int *nansp2, int *resplen2, int *ansp2_malloced)
{
int gotsomewhere, terrno, try, v_circuit, resplen, ns, n;
@@ -565,7 +565,8 @@ __libc_res_nsend(res_state statp, const
try = statp->retry;
n = send_vc(statp, buf, buflen, buf2, buflen2,
&ans, &anssiz, &terrno,
- ns, ansp, ansp2, nansp2, resplen2);
+ ns, ansp, ansp2, nansp2, resplen2,
+ ansp2_malloced);
if (n < 0)
return (-1);
if (n == 0 && (buf2 == NULL || *resplen2 == 0))
@@ -575,7 +576,7 @@ __libc_res_nsend(res_state statp, const
n = send_dg(statp, buf, buflen, buf2, buflen2,
&ans, &anssiz, &terrno,
ns, &v_circuit, &gotsomewhere, ansp,
- ansp2, nansp2, resplen2);
+ ansp2, nansp2, resplen2, ansp2_malloced);
if (n < 0)
return (-1);
if (n == 0 && (buf2 == NULL || *resplen2 == 0))
@@ -665,7 +666,7 @@ res_nsend(res_state statp,
const u_char *buf, int buflen, u_char *ans, int anssiz)
{
return __libc_res_nsend(statp, buf, buflen, NULL, 0, ans, anssiz,
- NULL, NULL, NULL, NULL);
+ NULL, NULL, NULL, NULL, NULL);
}
libresolv_hidden_def (res_nsend)
@@ -747,7 +748,7 @@ send_vc(res_state statp,
const u_char *buf, int buflen, const u_char *buf2, int buflen2,
u_char **ansp, int *anssizp,
int *terrno, int ns, u_char **anscp, u_char **ansp2, int *anssizp2,
- int *resplen2)
+ int *resplen2, int *ansp2_malloced)
{
const HEADER *hp = (HEADER *) buf;
const HEADER *hp2 = (HEADER *) buf2;
@@ -896,6 +897,8 @@ send_vc(res_state statp,
}
*thisanssizp = MAXPACKET;
*thisansp = newp;
+ if (thisansp == ansp2)
+ *ansp2_malloced = 1;
anhp = (HEADER *) newp;
/* A uint16_t can't be larger than MAXPACKET
thus it's safe to allocate MAXPACKET but
@@ -1128,7 +1131,7 @@ send_dg(res_state statp,
const u_char *buf, int buflen, const u_char *buf2, int buflen2,
u_char **ansp, int *anssizp,
int *terrno, int ns, int *v_circuit, int *gotsomewhere, u_char **anscp,
- u_char **ansp2, int *anssizp2, int *resplen2)
+ u_char **ansp2, int *anssizp2, int *resplen2, int *ansp2_malloced)
{
const HEADER *hp = (HEADER *) buf;
const HEADER *hp2 = (HEADER *) buf2;
@@ -1289,6 +1292,8 @@ send_dg(res_state statp,
if (newp != NULL) {
*thisanssizp = MAXPACKET;
*thisansp = newp;
+ if (thisansp == ansp2)
+ *ansp2_malloced = 1;
}
}
/* We could end up with truncation if anscp was NULL

View File

@@ -0,0 +1,544 @@
Index: glibc-2.12-2-gc4ccff1/resolv/nss_dns/dns-host.c
===================================================================
--- glibc-2.12-2-gc4ccff1.orig/resolv/nss_dns/dns-host.c
+++ glibc-2.12-2-gc4ccff1/resolv/nss_dns/dns-host.c
@@ -1043,7 +1043,10 @@ gaih_getanswer_slice (const querybuf *an
int h_namelen = 0;
if (ancount == 0)
- return NSS_STATUS_NOTFOUND;
+ {
+ *h_errnop = HOST_NOT_FOUND;
+ return NSS_STATUS_NOTFOUND;
+ }
while (ancount-- > 0 && cp < end_of_message && had_error == 0)
{
@@ -1217,7 +1220,14 @@ gaih_getanswer_slice (const querybuf *an
/* Special case here: if the resolver sent a result but it only
contains a CNAME while we are looking for a T_A or T_AAAA record,
we fail with NOTFOUND instead of TRYAGAIN. */
- return canon == NULL ? NSS_STATUS_TRYAGAIN : NSS_STATUS_NOTFOUND;
+ if (canon != NULL)
+ {
+ *h_errnop = HOST_NOT_FOUND;
+ return NSS_STATUS_NOTFOUND;
+ }
+
+ *h_errnop = NETDB_INTERNAL;
+ return NSS_STATUS_TRYAGAIN;
}
@@ -1231,11 +1241,101 @@ gaih_getanswer (const querybuf *answer1,
enum nss_status status = NSS_STATUS_NOTFOUND;
+ /* Combining the NSS status of two distinct queries requires some
+ compromise and attention to symmetry (A or AAAA queries can be
+ returned in any order). What follows is a breakdown of how this
+ code is expected to work and why. We discuss only SUCCESS,
+ TRYAGAIN, NOTFOUND and UNAVAIL, since they are the only returns
+ that apply (though RETURN and MERGE exist). We make a distinction
+ between TRYAGAIN (recoverable) and TRYAGAIN' (not-recoverable).
+ A recoverable TRYAGAIN is almost always due to buffer size issues
+ and returns ERANGE in errno and the caller is expected to retry
+ with a larger buffer.
+
+ Lastly, you may be tempted to make significant changes to the
+ conditions in this code to bring about symmetry between responses.
+ Please don't change anything without due consideration for
+ expected application behaviour. Some of the synthesized responses
+ aren't very well thought out and sometimes appear to imply that
+ IPv4 responses are always answer 1, and IPv6 responses are always
+ answer 2, but that's not true (see the implemetnation of send_dg
+ and send_vc to see response can arrive in any order, particlarly
+ for UDP). However, we expect it holds roughly enough of the time
+ that this code works, but certainly needs to be fixed to make this
+ a more robust implementation.
+
+ ----------------------------------------------
+ | Answer 1 Status / | Synthesized | Reason |
+ | Answer 2 Status | Status | |
+ |--------------------------------------------|
+ | SUCCESS/SUCCESS | SUCCESS | [1] |
+ | SUCCESS/TRYAGAIN | TRYAGAIN | [5] |
+ | SUCCESS/TRYAGAIN' | SUCCESS | [1] |
+ | SUCCESS/NOTFOUND | SUCCESS | [1] |
+ | SUCCESS/UNAVAIL | SUCCESS | [1] |
+ | TRYAGAIN/SUCCESS | TRYAGAIN | [2] |
+ | TRYAGAIN/TRYAGAIN | TRYAGAIN | [2] |
+ | TRYAGAIN/TRYAGAIN' | TRYAGAIN | [2] |
+ | TRYAGAIN/NOTFOUND | TRYAGAIN | [2] |
+ | TRYAGAIN/UNAVAIL | TRYAGAIN | [2] |
+ | TRYAGAIN'/SUCCESS | SUCCESS | [3] |
+ | TRYAGAIN'/TRYAGAIN | TRYAGAIN | [3] |
+ | TRYAGAIN'/TRYAGAIN' | TRYAGAIN' | [3] |
+ | TRYAGAIN'/NOTFOUND | TRYAGAIN' | [3] |
+ | TRYAGAIN'/UNAVAIL | UNAVAIL | [3] |
+ | NOTFOUND/SUCCESS | SUCCESS | [3] |
+ | NOTFOUND/TRYAGAIN | TRYAGAIN | [3] |
+ | NOTFOUND/TRYAGAIN' | TRYAGAIN' | [3] |
+ | NOTFOUND/NOTFOUND | NOTFOUND | [3] |
+ | NOTFOUND/UNAVAIL | UNAVAIL | [3] |
+ | UNAVAIL/SUCCESS | UNAVAIL | [4] |
+ | UNAVAIL/TRYAGAIN | UNAVAIL | [4] |
+ | UNAVAIL/TRYAGAIN' | UNAVAIL | [4] |
+ | UNAVAIL/NOTFOUND | UNAVAIL | [4] |
+ | UNAVAIL/UNAVAIL | UNAVAIL | [4] |
+ ----------------------------------------------
+
+ [1] If the first response is a success we return success.
+ This ignores the state of the second answer and in fact
+ incorrectly sets errno and h_errno to that of the second
+ answer. However because the response is a success we ignore
+ *errnop and *h_errnop (though that means you touched errno on
+ success). We are being conservative here and returning the
+ likely IPv4 response in the first answer as a success.
+
+ [2] If the first response is a recoverable TRYAGAIN we return
+ that instead of looking at the second response. The
+ expectation here is that we have failed to get an IPv4 response
+ and should retry both queries.
+
+ [3] If the first response was not a SUCCESS and the second
+ response is not NOTFOUND (had a SUCCESS, need to TRYAGAIN,
+ or failed entirely e.g. TRYAGAIN' and UNAVAIL) then use the
+ result from the second response, otherwise the first responses
+ status is used. Again we have some odd side-effects when the
+ second response is NOTFOUND because we overwrite *errnop and
+ *h_errnop that means that a first answer of NOTFOUND might see
+ its *errnop and *h_errnop values altered. Whether it matters
+ in practice that a first response NOTFOUND has the wrong
+ *errnop and *h_errnop is undecided.
+
+ [4] If the first response is UNAVAIL we return that instead of
+ looking at the second response. The expectation here is that
+ it will have failed similarly e.g. configuration failure.
+
+ [5] Testing this code is complicated by the fact that truncated
+ second response buffers might be returned as SUCCESS if the
+ first answer is a SUCCESS. To fix this we add symmetry to
+ TRYAGAIN with the second response. If the second response
+ is a recoverable error we now return TRYAGIN even if the first
+ response was SUCCESS. */
+
if (anslen1 > 0)
status = gaih_getanswer_slice(answer1, anslen1, qname,
&pat, &buffer, &buflen,
errnop, h_errnop, ttlp,
&first);
+
if ((status == NSS_STATUS_SUCCESS || status == NSS_STATUS_NOTFOUND
|| (status == NSS_STATUS_TRYAGAIN
&& (*errnop != ERANGE || *h_errnop == NO_RECOVERY)))
@@ -1245,8 +1345,15 @@ gaih_getanswer (const querybuf *answer1,
&pat, &buffer, &buflen,
errnop, h_errnop, ttlp,
&first);
+ /* Use the second response status in some cases. */
if (status != NSS_STATUS_SUCCESS && status2 != NSS_STATUS_NOTFOUND)
status = status2;
+ /* Do not return a truncated second response (unless it was
+ unavoidable e.g. unrecoverable TRYAGAIN). */
+ if (status == NSS_STATUS_SUCCESS
+ && (status2 == NSS_STATUS_TRYAGAIN
+ && *errnop == ERANGE && *h_errnop != NO_RECOVERY))
+ status = NSS_STATUS_TRYAGAIN;
}
return status;
Index: glibc-2.12-2-gc4ccff1/resolv/res_send.c
===================================================================
--- glibc-2.12-2-gc4ccff1.orig/resolv/res_send.c
+++ glibc-2.12-2-gc4ccff1/resolv/res_send.c
@@ -1,3 +1,20 @@
+/* Copyright (C) 2016 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/>. */
+
/*
* Copyright (c) 1985, 1989, 1993
* The Regents of the University of California. All rights reserved.
@@ -360,6 +377,8 @@ __libc_res_nsend(res_state statp, const
#ifdef USE_HOOKS
if (__builtin_expect (statp->qhook || statp->rhook, 0)) {
if (anssiz < MAXPACKET && ansp) {
+ /* Always allocate MAXPACKET, callers expect
+ this specific size. */
u_char *buf = malloc (MAXPACKET);
if (buf == NULL)
return (-1);
@@ -652,6 +671,77 @@ libresolv_hidden_def (res_nsend)
/* Private */
+/* The send_vc function is responsible for sending a DNS query over TCP
+ to the nameserver numbered NS from the res_state STATP i.e.
+ EXT(statp).nssocks[ns]. The function supports sending both IPv4 and
+ IPv6 queries at the same serially on the same socket.
+
+ Please note that for TCP there is no way to disable sending both
+ queries, unlike UDP, which honours RES_SNGLKUP and RES_SNGLKUPREOP
+ and sends the queries serially and waits for the result after each
+ sent query. This implemetnation should be corrected to honour these
+ options.
+
+ Please also note that for TCP we send both queries over the same
+ socket one after another. This technically violates best practice
+ since the server is allowed to read the first query, respond, and
+ then close the socket (to service another client). If the server
+ does this, then the remaining second query in the socket data buffer
+ will cause the server to send the client an RST which will arrive
+ asynchronously and the client's OS will likely tear down the socket
+ receive buffer resulting in a potentially short read and lost
+ response data. This will force the client to retry the query again,
+ and this process may repeat until all servers and connection resets
+ are exhausted and then the query will fail. It's not known if this
+ happens with any frequency in real DNS server implementations. This
+ implementation should be corrected to use two sockets by default for
+ parallel queries.
+
+ The query stored in BUF of BUFLEN length is sent first followed by
+ the query stored in BUF2 of BUFLEN2 length. Queries are sent
+ serially on the same socket.
+
+ Answers to the query are stored firstly in *ANSP up to a max of
+ *ANSSIZP bytes. If more than *ANSSIZP bytes are needed and ANSCP
+ is non-NULL (to indicate that modifying the answer buffer is allowed)
+ then malloc is used to allocate a new response buffer and ANSCP and
+ ANSP will both point to the new buffer. If more than *ANSSIZP bytes
+ are needed but ANSCP is NULL, then as much of the response as
+ possible is read into the buffer, but the results will be truncated.
+ When truncation happens because of a small answer buffer the DNS
+ packets header feild TC will bet set to 1, indicating a truncated
+ message and the rest of the socket data will be read and discarded.
+
+ Answers to the query are stored secondly in *ANSP2 up to a max of
+ *ANSSIZP2 bytes, with the actual response length stored in
+ *RESPLEN2. If more than *ANSSIZP bytes are needed and ANSP2
+ is non-NULL (required for a second query) then malloc is used to
+ allocate a new response buffer, *ANSSIZP2 is set to the new buffer
+ size and *ANSP2_MALLOCED is set to 1.
+
+ The ANSP2_MALLOCED argument will eventually be removed as the
+ change in buffer pointer can be used to detect the buffer has
+ changed and that the caller should use free on the new buffer.
+
+ Note that the answers may arrive in any order from the server and
+ therefore the first and second answer buffers may not correspond to
+ the first and second queries.
+
+ It is not supported to call this function with a non-NULL ANSP2
+ but a NULL ANSCP. Put another way, you can call send_vc with a
+ single unmodifiable buffer or two modifiable buffers, but no other
+ combination is supported.
+
+ It is the caller's responsibility to free the malloc allocated
+ buffers by detecting that the pointers have changed from their
+ original values i.e. *ANSCP or *ANSP2 has changed.
+
+ If errors are encountered then *TERRNO is set to an appropriate
+ errno value and a zero result is returned for a recoverable error,
+ and a less-than zero result is returned for a non-recoverable error.
+
+ If no errors are encountered then *TERRNO is left unmodified and
+ a the length of the first response in bytes is returned. */
static int
send_vc(res_state statp,
const u_char *buf, int buflen, const u_char *buf2, int buflen2,
@@ -661,11 +751,7 @@ send_vc(res_state statp,
{
const HEADER *hp = (HEADER *) buf;
const HEADER *hp2 = (HEADER *) buf2;
- u_char *ans = *ansp;
- int orig_anssizp = *anssizp;
- // XXX REMOVE
- // int anssiz = *anssizp;
- HEADER *anhp = (HEADER *) ans;
+ HEADER *anhp = (HEADER *) *ansp;
struct sockaddr_in6 *nsap = EXT(statp).nsaddrs[ns];
int truncating, connreset, resplen, n;
struct iovec iov[4];
@@ -741,6 +827,8 @@ send_vc(res_state statp,
* Receive length & response
*/
int recvresp1 = 0;
+ /* Skip the second response if there is no second query.
+ To do that we mark the second response as received. */
int recvresp2 = buf2 == NULL;
uint16_t rlen16;
read_len:
@@ -777,33 +865,14 @@ send_vc(res_state statp,
u_char **thisansp;
int *thisresplenp;
if ((recvresp1 | recvresp2) == 0 || buf2 == NULL) {
+ /* We have not received any responses
+ yet or we only have one response to
+ receive. */
thisanssizp = anssizp;
thisansp = anscp ?: ansp;
assert (anscp != NULL || ansp2 == NULL);
thisresplenp = &resplen;
} else {
- if (*anssizp != MAXPACKET) {
- /* No buffer allocated for the first
- reply. We can try to use the rest
- of the user-provided buffer. */
-#ifdef _STRING_ARCH_unaligned
- *anssizp2 = orig_anssizp - resplen;
- *ansp2 = *ansp + resplen;
-#else
- int aligned_resplen
- = ((resplen + __alignof__ (HEADER) - 1)
- & ~(__alignof__ (HEADER) - 1));
- *anssizp2 = orig_anssizp - aligned_resplen;
- *ansp2 = *ansp + aligned_resplen;
-#endif
- } else {
- /* The first reply did not fit into the
- user-provided buffer. Maybe the second
- answer will. */
- *anssizp2 = orig_anssizp;
- *ansp2 = *ansp;
- }
-
thisanssizp = anssizp2;
thisansp = ansp2;
thisresplenp = resplen2;
@@ -811,10 +880,14 @@ send_vc(res_state statp,
anhp = (HEADER *) *thisansp;
*thisresplenp = rlen;
- if (rlen > *thisanssizp) {
- /* Yes, we test ANSCP here. If we have two buffers
- both will be allocatable. */
- if (__builtin_expect (anscp != NULL, 1)) {
+ /* Is the answer buffer too small? */
+ if (*thisanssizp < rlen) {
+ /* If the current buffer is non-NULL and it's not
+ pointing at the static user-supplied buffer then
+ we can reallocate it. */
+ if (thisansp != NULL && thisansp != ansp) {
+ /* Always allocate MAXPACKET, callers expect
+ this specific size. */
u_char *newp = malloc (MAXPACKET);
if (newp == NULL) {
*terrno = ENOMEM;
@@ -824,6 +897,9 @@ send_vc(res_state statp,
*thisanssizp = MAXPACKET;
*thisansp = newp;
anhp = (HEADER *) newp;
+ /* A uint16_t can't be larger than MAXPACKET
+ thus it's safe to allocate MAXPACKET but
+ read RLEN bytes instead. */
len = rlen;
} else {
Dprint(statp->options & RES_DEBUG,
@@ -987,6 +1063,66 @@ reopen (res_state statp, int *terrno, in
return 1;
}
+/* The send_dg function is responsible for sending a DNS query over UDP
+ to the nameserver numbered NS from the res_state STATP i.e.
+ EXT(statp).nssocks[ns]. The function supports IPv4 and IPv6 queries
+ along with the ability to send the query in parallel for both stacks
+ (default) or serially (RES_SINGLKUP). It also supports serial lookup
+ with a close and reopen of the socket used to talk to the server
+ (RES_SNGLKUPREOP) to work around broken name servers.
+
+ The query stored in BUF of BUFLEN length is sent first followed by
+ the query stored in BUF2 of BUFLEN2 length. Queries are sent
+ in parallel (default) or serially (RES_SINGLKUP or RES_SNGLKUPREOP).
+
+ Answers to the query are stored firstly in *ANSP up to a max of
+ *ANSSIZP bytes. If more than *ANSSIZP bytes are needed and ANSCP
+ is non-NULL (to indicate that modifying the answer buffer is allowed)
+ then malloc is used to allocate a new response buffer and ANSCP and
+ ANSP will both point to the new buffer. If more than *ANSSIZP bytes
+ are needed but ANSCP is NULL, then as much of the response as
+ possible is read into the buffer, but the results will be truncated.
+ When truncation happens because of a small answer buffer the DNS
+ packets header feild TC will bet set to 1, indicating a truncated
+ message, while the rest of the UDP packet is discarded.
+
+ Answers to the query are stored secondly in *ANSP2 up to a max of
+ *ANSSIZP2 bytes, with the actual response length stored in
+ *RESPLEN2. If more than *ANSSIZP bytes are needed and ANSP2
+ is non-NULL (required for a second query) then malloc is used to
+ allocate a new response buffer, *ANSSIZP2 is set to the new buffer
+ size and *ANSP2_MALLOCED is set to 1.
+
+ The ANSP2_MALLOCED argument will eventually be removed as the
+ change in buffer pointer can be used to detect the buffer has
+ changed and that the caller should use free on the new buffer.
+
+ Note that the answers may arrive in any order from the server and
+ therefore the first and second answer buffers may not correspond to
+ the first and second queries.
+
+ It is not supported to call this function with a non-NULL ANSP2
+ but a NULL ANSCP. Put another way, you can call send_vc with a
+ single unmodifiable buffer or two modifiable buffers, but no other
+ combination is supported.
+
+ It is the caller's responsibility to free the malloc allocated
+ buffers by detecting that the pointers have changed from their
+ original values i.e. *ANSCP or *ANSP2 has changed.
+
+ If an answer is truncated because of UDP datagram DNS limits then
+ *V_CIRCUIT is set to 1 and the return value non-zero to indicate to
+ the caller to retry with TCP. The value *GOTSOMEWHERE is set to 1
+ if any progress was made reading a response from the nameserver and
+ is used by the caller to distinguish between ECONNREFUSED and
+ ETIMEDOUT (the latter if *GOTSOMEWHERE is 1).
+
+ If errors are encountered then *TERRNO is set to an appropriate
+ errno value and a zero result is returned for a recoverable error,
+ and a less-than zero result is returned for a non-recoverable error.
+
+ If no errors are encountered then *TERRNO is left unmodified and
+ a the length of the first response in bytes is returned. */
static int
send_dg(res_state statp,
const u_char *buf, int buflen, const u_char *buf2, int buflen2,
@@ -996,8 +1132,6 @@ send_dg(res_state statp,
{
const HEADER *hp = (HEADER *) buf;
const HEADER *hp2 = (HEADER *) buf2;
- u_char *ans = *ansp;
- int orig_anssizp = *anssizp;
struct timespec now, timeout, finish;
struct pollfd pfd[1];
int ptimeout;
@@ -1029,6 +1163,8 @@ send_dg(res_state statp,
int need_recompute = 0;
int nwritten = 0;
int recvresp1 = 0;
+ /* Skip the second response if there is no second query.
+ To do that we mark the second response as received. */
int recvresp2 = buf2 == NULL;
pfd[0].fd = EXT(statp).nssocks[ns];
pfd[0].events = POLLOUT;
@@ -1125,50 +1261,52 @@ send_dg(res_state statp,
int *thisresplenp;
if ((recvresp1 | recvresp2) == 0 || buf2 == NULL) {
+ /* We have not received any responses
+ yet or we only have one response to
+ receive. */
thisanssizp = anssizp;
thisansp = anscp ?: ansp;
assert (anscp != NULL || ansp2 == NULL);
thisresplenp = &resplen;
} else {
- if (*anssizp != MAXPACKET) {
- /* No buffer allocated for the first
- reply. We can try to use the rest
- of the user-provided buffer. */
-#ifdef _STRING_ARCH_unaligned
- *anssizp2 = orig_anssizp - resplen;
- *ansp2 = *ansp + resplen;
-#else
- int aligned_resplen
- = ((resplen + __alignof__ (HEADER) - 1)
- & ~(__alignof__ (HEADER) - 1));
- *anssizp2 = orig_anssizp - aligned_resplen;
- *ansp2 = *ansp + aligned_resplen;
-#endif
- } else {
- /* The first reply did not fit into the
- user-provided buffer. Maybe the second
- answer will. */
- *anssizp2 = orig_anssizp;
- *ansp2 = *ansp;
- }
-
thisanssizp = anssizp2;
thisansp = ansp2;
thisresplenp = resplen2;
}
if (*thisanssizp < MAXPACKET
- /* Yes, we test ANSCP here. If we have two buffers
- both will be allocatable. */
- && anscp
+ /* If the current buffer is non-NULL and it's not
+ pointing at the static user-supplied buffer then
+ we can reallocate it. */
+ && (thisansp != NULL && thisansp != ansp)
+ /* Is the size too small? */
&& (ioctl (pfd[0].fd, FIONREAD, thisresplenp) < 0
- || *thisanssizp < *thisresplenp)) {
+ || *thisanssizp < *thisresplenp)
+ ) {
+ /* Always allocate MAXPACKET, callers expect
+ this specific size. */
u_char *newp = malloc (MAXPACKET);
if (newp != NULL) {
- *anssizp = MAXPACKET;
- *thisansp = ans = newp;
+ *thisanssizp = MAXPACKET;
+ *thisansp = newp;
}
}
+ /* We could end up with truncation if anscp was NULL
+ (not allowed to change caller's buffer) and the
+ response buffer size is too small. This isn't a
+ reliable way to detect truncation because the ioctl
+ may be an inaccurate report of the UDP message size.
+ Therefore we use this only to issue debug output.
+ To do truncation accurately with UDP we need
+ MSG_TRUNC which is only available on Linux. We
+ can abstract out the Linux-specific feature in the
+ future to detect truncation. */
+ if (__glibc_unlikely (*thisanssizp < *thisresplenp)) {
+ Dprint(statp->options & RES_DEBUG,
+ (stdout, ";; response may be truncated (UDP)\n")
+ );
+ }
+
HEADER *anhp = (HEADER *) *thisansp;
socklen_t fromlen = sizeof(struct sockaddr_in6);
assert (sizeof(from) <= fromlen);
Index: glibc-2.12-2-gc4ccff1/resolv/res_query.c
===================================================================
--- glibc-2.12-2-gc4ccff1.orig/resolv/res_query.c
+++ glibc-2.12-2-gc4ccff1/resolv/res_query.c
@@ -391,6 +391,7 @@ __libc_res_nsearch(res_state statp,
&& (*answerp2 < answer || *answerp2 >= answer + anslen))
{
free (*answerp2);
+ *nanswerp2 = 0;
*answerp2 = NULL;
}
}
@@ -431,6 +432,7 @@ __libc_res_nsearch(res_state statp,
|| *answerp2 >= answer + anslen))
{
free (*answerp2);
+ *nanswerp2 = 0;
*answerp2 = NULL;
}
@@ -503,6 +505,7 @@ __libc_res_nsearch(res_state statp,
if (answerp2 && (*answerp2 < answer || *answerp2 >= answer + anslen))
{
free (*answerp2);
+ *nanswerp2 = NULL;
*answerp2 = NULL;
}
if (saved_herrno != -1)

View File

@@ -0,0 +1,61 @@
commit 2c1094bd700e63a8d7f547b3f5495bedb55c0a08
Author: Ulrich Drepper <drepper@gmail.com>
Date: Thu Dec 22 22:43:39 2011 -0500
Create internal threads with sufficient stack size
Index: glibc-2.12-2-gc4ccff1/nptl/Versions
===================================================================
--- glibc-2.12-2-gc4ccff1.orig/nptl/Versions
+++ glibc-2.12-2-gc4ccff1/nptl/Versions
@@ -255,6 +255,6 @@ libpthread {
GLIBC_PRIVATE {
__pthread_initialize_minimal;
__pthread_clock_gettime; __pthread_clock_settime;
- __pthread_unwind;
+ __pthread_unwind; __pthread_get_minstack;
}
}
Index: glibc-2.12-2-gc4ccff1/nptl/nptl-init.c
===================================================================
--- glibc-2.12-2-gc4ccff1.orig/nptl/nptl-init.c
+++ glibc-2.12-2-gc4ccff1/nptl/nptl-init.c
@@ -507,3 +507,13 @@ __pthread_initialize_minimal_internal (i
}
strong_alias (__pthread_initialize_minimal_internal,
__pthread_initialize_minimal)
+
+
+size_t
+__pthread_get_minstack (const pthread_attr_t *attr)
+{
+ struct pthread_attr *iattr = (struct pthread_attr *) attr;
+
+ return (GLRO(dl_pagesize) + __static_tls_size + PTHREAD_STACK_MIN
+ + iattr->guardsize);
+}
Index: glibc-2.12-2-gc4ccff1/nptl/pthreadP.h
===================================================================
--- glibc-2.12-2-gc4ccff1.orig/nptl/pthreadP.h
+++ glibc-2.12-2-gc4ccff1/nptl/pthreadP.h
@@ -397,6 +397,7 @@ weak_function;
extern void __pthread_init_static_tls (struct link_map *) attribute_hidden;
+extern size_t __pthread_get_minstack (const pthread_attr_t *attr);
/* Namespace save aliases. */
extern int __pthread_getschedparam (pthread_t thread_id, int *policy,
Index: glibc-2.12-2-gc4ccff1/nptl/sysdeps/unix/sysv/linux/timer_routines.c
===================================================================
--- glibc-2.12-2-gc4ccff1.orig/nptl/sysdeps/unix/sysv/linux/timer_routines.c
+++ glibc-2.12-2-gc4ccff1/nptl/sysdeps/unix/sysv/linux/timer_routines.c
@@ -165,7 +165,7 @@ __start_helper_thread (void)
and should go away automatically when canceled. */
pthread_attr_t attr;
(void) pthread_attr_init (&attr);
- (void) pthread_attr_setstacksize (&attr, PTHREAD_STACK_MIN);
+ (void) pthread_attr_setstacksize (&attr, __pthread_get_minstack (&attr));
/* Block all signals in the helper thread but SIGSETXID. To do this
thoroughly we temporarily have to block all signals here. The

View File

@@ -0,0 +1,19 @@
commit 232872379ee82cd040a52a48cbbae65a249b5765
Author: Adhemerval Zanella <azanella@linux.vnet.ibm.com>
Date: Sun Jan 8 19:56:52 2012 -0500
Use __pthread_get_minstack for AIO helper thread
diff --git a/nptl/sysdeps/unix/sysv/linux/aio_misc.h b/nptl/sysdeps/unix/sysv/linux/aio_misc.h
index 406d96e..8011c3e 100644
--- a/nptl/sysdeps/unix/sysv/linux/aio_misc.h
+++ b/nptl/sysdeps/unix/sysv/linux/aio_misc.h
@@ -47,7 +47,7 @@ __aio_create_helper_thread (pthread_t *threadp, void *(*tf) (void *),
pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
/* The helper thread needs only very little resources. */
- (void) pthread_attr_setstacksize (&attr, PTHREAD_STACK_MIN);
+ (void) pthread_attr_setstacksize (&attr, __pthread_get_minstack (&attr));
/* Block all signals in the helper thread. To do this thoroughly we
temporarily have to block all signals here. */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,95 @@
commit 50fd745b4dec07e8e213cf2703b5cabcfa128225
Author: Andreas Schwab <schwab@suse.de>
Date: Mon Jun 10 14:39:09 2013 +0200
Fix handling of netgroup cache in nscd
diff --git a/nscd/connections.c b/nscd/connections.c
index 7099215..69e3e7d 100644
--- a/nscd/connections.c
+++ b/nscd/connections.c
@@ -1779,7 +1779,7 @@ nscd_run_worker (void *p)
else
{
/* Get the key. */
- char keybuf[MAXKEYLEN];
+ char keybuf[MAXKEYLEN + 1];
if (__builtin_expect (TEMP_FAILURE_RETRY (read (fd, keybuf,
req.key_len))
@@ -1791,6 +1791,7 @@ nscd_run_worker (void *p)
strerror_r (errno, buf, sizeof (buf)));
goto close_and_out;
}
+ keybuf[req.key_len] = '\0';
if (__builtin_expect (debug_level, 0) > 0)
{
diff --git a/nscd/netgroupcache.c b/nscd/netgroupcache.c
index 2d6c5aa..dd06ce4 100644
--- a/nscd/netgroupcache.c
+++ b/nscd/netgroupcache.c
@@ -192,18 +192,26 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
const char *nuser = data.val.triple.user;
const char *ndomain = data.val.triple.domain;
- if (data.val.triple.host > data.val.triple.user
- || data.val.triple.user > data.val.triple.domain)
+ if (nhost == NULL || nuser == NULL || ndomain == NULL
+ || nhost > nuser || nuser > ndomain)
{
- const char *last = MAX (nhost,
- MAX (nuser, ndomain));
- size_t bufused = (last + strlen (last) + 1
- - buffer);
+ const char *last = nhost;
+ if (last == NULL
+ || (nuser != NULL && nuser > last))
+ last = nuser;
+ if (last == NULL
+ || (ndomain != NULL && ndomain > last))
+ last = ndomain;
+
+ size_t bufused
+ = (last == NULL
+ ? buffilled
+ : last + strlen (last) + 1 - buffer);
/* We have to make temporary copies. */
- size_t hostlen = strlen (nhost) + 1;
- size_t userlen = strlen (nuser) + 1;
- size_t domainlen = strlen (ndomain) + 1;
+ size_t hostlen = strlen (nhost ?: "") + 1;
+ size_t userlen = strlen (nuser ?: "") + 1;
+ size_t domainlen = strlen (ndomain ?: "") + 1;
size_t needed = hostlen + userlen + domainlen;
if (buflen - req->key_len - bufused < needed)
@@ -226,11 +234,11 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
}
nhost = memcpy (buffer + bufused,
- nhost, hostlen);
+ nhost ?: "", hostlen);
nuser = memcpy ((char *) nhost + hostlen,
- nuser, userlen);
+ nuser ?: "", userlen);
ndomain = memcpy ((char *) nuser + userlen,
- ndomain, domainlen);
+ ndomain ?: "", domainlen);
}
char *wp = buffer + buffilled;
diff --git a/nscd/nscd_netgroup.c b/nscd/nscd_netgroup.c
index cac4ebf..acb2c81 100644
--- a/nscd/nscd_netgroup.c
+++ b/nscd/nscd_netgroup.c
@@ -48,7 +48,7 @@ __nscd_setnetgrent (const char *group, struct __netgrent *datap)
{
int gc_cycle;
int nretries = 0;
- size_t group_len = strlen (group);
+ size_t group_len = strlen (group) + 1;
/* If the mapping is available, try to search there instead of
communicating with the nscd. */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,279 @@
diff -pruN glibc-2.12-2-gc4ccff1/csu/libc-start.c glibc-2.12-2-gc4ccff1.fixed/csu/libc-start.c
--- glibc-2.12-2-gc4ccff1/csu/libc-start.c 2010-05-04 16:57:23.000000000 +0530
+++ glibc-2.12-2-gc4ccff1.fixed/csu/libc-start.c 2013-07-09 23:34:59.596859295 +0530
@@ -33,7 +33,7 @@ extern int __libc_multiple_libcs;
#include <tls.h>
#ifndef SHARED
# include <dl-osinfo.h>
-extern void __pthread_initialize_minimal (void);
+extern void __pthread_initialize_minimal (int, char **, char **);
# ifndef THREAD_SET_STACK_GUARD
/* Only exported for architectures that don't store the stack guard canary
in thread local area. */
@@ -143,7 +143,7 @@ LIBC_START_MAIN (int (*main) (int, char
/* Initialize the thread library at least a bit since the libgcc
functions are using thread functions if these are available and
we need to setup errno. */
- __pthread_initialize_minimal ();
+ __pthread_initialize_minimal (argc, argv, __environ);
/* Set up the stack checker's canary. */
uintptr_t stack_chk_guard = _dl_setup_stack_chk_guard (_dl_random);
diff -pruN glibc-2.12-2-gc4ccff1/csu/libc-tls.c glibc-2.12-2-gc4ccff1.fixed/csu/libc-tls.c
--- glibc-2.12-2-gc4ccff1/csu/libc-tls.c 2010-05-04 16:57:23.000000000 +0530
+++ glibc-2.12-2-gc4ccff1.fixed/csu/libc-tls.c 2013-07-09 23:34:59.596859295 +0530
@@ -244,7 +244,7 @@ _dl_tls_setup (void)
not used. */
void
__attribute__ ((weak))
-__pthread_initialize_minimal (void)
+__pthread_initialize_minimal (int argc, char **argv, char **envp)
{
__libc_setup_tls (TLS_INIT_TCB_SIZE, TLS_INIT_TCB_ALIGN);
}
diff -pruN glibc-2.12-2-gc4ccff1/nptl/Makefile glibc-2.12-2-gc4ccff1.fixed/nptl/Makefile
--- glibc-2.12-2-gc4ccff1/nptl/Makefile 2013-07-09 23:35:21.692858252 +0530
+++ glibc-2.12-2-gc4ccff1.fixed/nptl/Makefile 2013-07-09 23:34:59.597859295 +0530
@@ -197,7 +197,7 @@ CFLAGS-pt-system.c = -fexceptions
tests = tst-typesizes \
- tst-attr1 tst-attr2 tst-attr3 \
+ tst-attr1 tst-attr2 tst-attr3 tst-default-attr \
tst-mutex1 tst-mutex2 tst-mutex3 tst-mutex4 tst-mutex5 tst-mutex6 \
tst-mutex7 tst-mutex8 tst-mutex9 tst-mutex5a tst-mutex7a \
tst-mutexpi1 tst-mutexpi2 tst-mutexpi3 tst-mutexpi4 tst-mutexpi5 \
@@ -279,6 +279,13 @@ LDFLAGS-pthread.so = -Wl,--enable-new-dt
LDFLAGS-tst-cond24 = -lrt
LDFLAGS-tst-cond25 = -lrt
+# The size is 1MB + 4KB. The extra 4KB has been added to prevent allocatestack
+# from resizing the input size to avoid the 64K aliasing conflict on Intel
+# processors.
+DEFAULT_STACKSIZE=1052672
+CFLAGS-tst-default-attr.c = -DDEFAULT_STACKSIZE=$(DEFAULT_STACKSIZE)
+tst-default-attr-ENV = GLIBC_PTHREAD_STACKSIZE=$(DEFAULT_STACKSIZE)
+
include ../Makeconfig
ifeq ($(have-forced-unwind),yes)
diff -pruN glibc-2.12-2-gc4ccff1/nptl/nptl-init.c glibc-2.12-2-gc4ccff1.fixed/nptl/nptl-init.c
--- glibc-2.12-2-gc4ccff1/nptl/nptl-init.c 2013-07-09 23:35:21.723858250 +0530
+++ glibc-2.12-2-gc4ccff1.fixed/nptl/nptl-init.c 2013-07-09 23:36:35.070854789 +0530
@@ -36,6 +36,7 @@
#include <smp.h>
#include <lowlevellock.h>
#include <kernel-features.h>
+#include <libc-internal.h>
/* Size and alignment of static TLS block. */
@@ -288,8 +289,28 @@ extern void **__libc_dl_error_tsd (void)
/* This can be set by the debugger before initialization is complete. */
static bool __nptl_initial_report_events __attribute_used__;
+/* Validate and set the default stacksize. */
+static void
+set_default_stacksize (size_t stacksize)
+{
+ if (stacksize < PTHREAD_STACK_MIN)
+ stacksize = PTHREAD_STACK_MIN;
+
+ /* Make sure it meets the minimum size that allocate_stack
+ (allocatestack.c) will demand, which depends on the page size. */
+ const uintptr_t pagesz = GLRO(dl_pagesize);
+ const size_t minstack = pagesz + __static_tls_size + MINIMAL_REST_STACK;
+
+ if (stacksize < minstack)
+ stacksize = minstack;
+
+ /* Round the resource limit up to page size. */
+ stacksize = ALIGN_UP (stacksize, pagesz);
+ __default_pthread_attr.stacksize = stacksize;
+}
+
void
-__pthread_initialize_minimal_internal (void)
+__pthread_initialize_minimal_internal (int argc, char **argv, char **envp)
{
#ifndef SHARED
/* Unlike in the dynamically linked case the dynamic linker has not
@@ -413,29 +434,44 @@ __pthread_initialize_minimal_internal (v
__static_tls_size = roundup (__static_tls_size, static_tls_align);
- /* Determine the default allowed stack size. This is the size used
- in case the user does not specify one. */
- struct rlimit limit;
- if (getrlimit (RLIMIT_STACK, &limit) != 0
- || limit.rlim_cur == RLIM_INFINITY)
- /* The system limit is not usable. Use an architecture-specific
- default. */
- limit.rlim_cur = ARCH_STACK_DEFAULT_SIZE;
- else if (limit.rlim_cur < PTHREAD_STACK_MIN)
- /* The system limit is unusably small.
- Use the minimal size acceptable. */
- limit.rlim_cur = PTHREAD_STACK_MIN;
+ /* Initialize the environment. libc.so gets initialized after us due to a
+ circular dependency and hence __environ is not available otherwise. */
+ __environ = envp;
- /* Make sure it meets the minimum size that allocate_stack
- (allocatestack.c) will demand, which depends on the page size. */
- const uintptr_t pagesz = __sysconf (_SC_PAGESIZE);
- const size_t minstack = pagesz + __static_tls_size + MINIMAL_REST_STACK;
- if (limit.rlim_cur < minstack)
- limit.rlim_cur = minstack;
+#ifndef SHARED
+ __libc_init_secure ();
+#endif
- /* Round the resource limit up to page size. */
- limit.rlim_cur = (limit.rlim_cur + pagesz - 1) & -pagesz;
- __default_pthread_attr.stacksize = limit.rlim_cur;
+ /* Get the default stack size from the environment variable if it is set and
+ is valid. */
+ size_t stacksize = 0;
+ char *envval = __secure_getenv ("GLIBC_PTHREAD_STACKSIZE");
+
+ if (__builtin_expect (envval != NULL && envval[0] != '\0', 0))
+ {
+ char *env_conv = envval;
+ size_t ret = strtoul (envval, &env_conv, 0);
+
+ if (*env_conv == '\0' && env_conv != envval)
+ stacksize = ret;
+ }
+
+ if (stacksize == 0)
+ {
+ /* Determine the default allowed stack size. */
+ struct rlimit limit;
+ if (getrlimit (RLIMIT_STACK, &limit) != 0
+ || limit.rlim_cur == RLIM_INFINITY)
+ /* The system limit is not usable. Use an architecture-specific
+ default. */
+ stacksize = ARCH_STACK_DEFAULT_SIZE;
+ else
+ stacksize = limit.rlim_cur;
+ }
+
+ /* Finally, set the default stack size. This size is used when the user does
+ not specify a stack size during thread creation. */
+ set_default_stacksize (stacksize);
__default_pthread_attr.guardsize = GLRO (dl_pagesize);
#ifdef SHARED
diff -pruN glibc-2.12-2-gc4ccff1/nptl/tst-default-attr.c glibc-2.12-2-gc4ccff1.fixed/nptl/tst-default-attr.c
--- glibc-2.12-2-gc4ccff1/nptl/tst-default-attr.c 1970-01-01 05:30:00.000000000 +0530
+++ glibc-2.12-2-gc4ccff1.fixed/nptl/tst-default-attr.c 2013-07-09 23:34:59.598859295 +0530
@@ -0,0 +1,109 @@
+/* Verify that default stack size gets set correctly from the environment
+ variable.
+
+ Copyright (C) 2013 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 <pthread.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+
+#define RETURN_IF_FAIL(f, ...) \
+ ({ \
+ int ret = f (__VA_ARGS__); \
+ if (ret != 0) \
+ { \
+ printf ("%s:%d: %s returned %d (errno = %d)\n", __FILE__, __LINE__, \
+ #f, ret, errno); \
+ return ret; \
+ } \
+ })
+
+/* DEFAULT_STACKSIZE macro is defined in the Makefile. */
+static size_t stacksize = DEFAULT_STACKSIZE;
+
+static int
+verify_stacksize_result (pthread_attr_t *attr)
+{
+ size_t stack;
+
+ RETURN_IF_FAIL (pthread_attr_getstacksize, attr, &stack);
+
+ if (stacksize != stack)
+ {
+ printf ("failed to set default stacksize (%zu, %zu)\n", stacksize, stack);
+ return 1;
+ }
+
+ return 0;
+}
+
+static void *
+thr (void *unused __attribute__ ((unused)))
+{
+ pthread_attr_t attr;
+ int ret;
+
+ memset (&attr, 0xab, sizeof attr);
+ /* To verify that the attributes actually got applied. */
+ if ((ret = pthread_getattr_np (pthread_self (), &attr)) != 0)
+ {
+ printf ("pthread_getattr_np failed: %s\n", strerror (ret));
+ goto out;
+ }
+
+ ret = verify_stacksize_result (&attr);
+
+out:
+ return (void *) (uintptr_t) ret;
+}
+
+static int
+run_threads (void)
+{
+ pthread_t t;
+ void *tret = NULL;
+
+ /* Run twice to ensure that the attributes do not get overwritten in the
+ first run somehow. */
+ for (int i = 0; i < 2; i++)
+ {
+ RETURN_IF_FAIL (pthread_create, &t, NULL, thr, NULL);
+ RETURN_IF_FAIL (pthread_join, t, &tret);
+
+ if (tret != NULL)
+ {
+ puts ("Thread failed");
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+static int
+do_test (void)
+{
+ RETURN_IF_FAIL (run_threads);
+ return 0;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"

View File

@@ -0,0 +1,31 @@
diff -pruN glibc-2.12-2-gc4ccff1/nptl/sysdeps/pthread/pt-initfini.c glibc-2.12-2-gc4ccff1.fixed/nptl/sysdeps/pthread/pt-initfini.c
--- glibc-2.12-2-gc4ccff1/nptl/sysdeps/pthread/pt-initfini.c 2010-05-04 16:57:23.000000000 +0530
+++ glibc-2.12-2-gc4ccff1.fixed/nptl/sysdeps/pthread/pt-initfini.c 2013-07-22 21:52:03.519184065 +0530
@@ -63,21 +63,21 @@ asm ("\n/*@TESTS_END*/");
asm ("\n/*@_init_PROLOG_BEGINS*/");
static void
-call_initialize_minimal (void)
+call_initialize_minimal (int argc, char **argv, char **envp)
{
- extern void __pthread_initialize_minimal_internal (void)
+ extern void __pthread_initialize_minimal_internal (int, char **, char **)
__attribute ((visibility ("hidden")));
- __pthread_initialize_minimal_internal ();
+ __pthread_initialize_minimal_internal (argc, argv, envp);
}
SECTION (".init");
-extern void __attribute__ ((section (".init"))) _init (void);
+extern void __attribute__ ((section (".init"))) _init (int, char **, char **);
void
-_init (void)
+_init (int argc, char **argv, char **envp)
{
/* The very first thing we must do is to set up the registers. */
- call_initialize_minimal ();
+ call_initialize_minimal (argc, argv, envp);
asm ("ALIGN");
asm("END_INIT");

View File

@@ -0,0 +1,191 @@
diff -pruN glibc-2.12-2-gc4ccff1/include/libc-internal.h glibc-2.12-2-gc4ccff1.fixed/include/libc-internal.h
--- glibc-2.12-2-gc4ccff1/include/libc-internal.h 2010-05-04 16:57:23.000000000 +0530
+++ glibc-2.12-2-gc4ccff1.fixed/include/libc-internal.h 2013-07-09 23:44:00.272833779 +0530
@@ -34,4 +34,24 @@ extern void __libc_thread_freeres (void)
/* Define and initialize `__progname' et. al. */
extern void __init_misc (int, char **, char **);
+/* Align a value by rounding down to closest size.
+ e.g. Using size of 4096, we get this behavior:
+ {4095, 4096, 4097} = {0, 4096, 4096}. */
+#define ALIGN_DOWN(base, size) ((base) & -((__typeof__ (base)) (size)))
+
+/* Align a value by rounding up to closest size.
+ e.g. Using size of 4096, we get this behavior:
+ {4095, 4096, 4097} = {4096, 4096, 8192}.
+
+ Note: The size argument has side effects (expanded multiple times). */
+#define ALIGN_UP(base, size) ALIGN_DOWN ((base) + (size) - 1, (size))
+
+/* Same as ALIGN_DOWN(), but automatically casts when base is a pointer. */
+#define PTR_ALIGN_DOWN(base, size) \
+ ((__typeof__ (base)) ALIGN_DOWN ((uintptr_t) (base), (size)))
+
+/* Same as ALIGN_UP(), but automatically casts when base is a pointer. */
+#define PTR_ALIGN_UP(base, size) \
+ ((__typeof__ (base)) ALIGN_UP ((uintptr_t) (base), (size)))
+
#endif /* _LIBC_INTERNAL */
diff -pruN glibc-2.12-2-gc4ccff1/nptl/allocatestack.c glibc-2.12-2-gc4ccff1.fixed/nptl/allocatestack.c
--- glibc-2.12-2-gc4ccff1/nptl/allocatestack.c 2013-07-09 23:43:09.427836179 +0530
+++ glibc-2.12-2-gc4ccff1.fixed/nptl/allocatestack.c 2013-07-09 23:43:52.727834136 +0530
@@ -351,7 +351,7 @@ allocate_stack (const struct pthread_att
/* Get the stack size from the attribute if it is set. Otherwise we
use the default we determined at start time. */
- size = attr->stacksize ?: __default_stacksize;
+ size = attr->stacksize ?: __default_pthread_attr.stacksize;
/* Get memory for the stack. */
if (__builtin_expect (attr->flags & ATTR_FLAG_STACKADDR, 0))
diff -pruN glibc-2.12-2-gc4ccff1/nptl/nptl-init.c glibc-2.12-2-gc4ccff1.fixed/nptl/nptl-init.c
--- glibc-2.12-2-gc4ccff1/nptl/nptl-init.c 2013-07-09 23:43:09.553836173 +0530
+++ glibc-2.12-2-gc4ccff1.fixed/nptl/nptl-init.c 2013-07-09 23:43:52.728834135 +0530
@@ -435,7 +435,8 @@ __pthread_initialize_minimal_internal (v
/* Round the resource limit up to page size. */
limit.rlim_cur = (limit.rlim_cur + pagesz - 1) & -pagesz;
- __default_stacksize = limit.rlim_cur;
+ __default_pthread_attr.stacksize = limit.rlim_cur;
+ __default_pthread_attr.guardsize = GLRO (dl_pagesize);
#ifdef SHARED
/* Transfer the old value from the dynamic linker's internal location. */
diff -pruN glibc-2.12-2-gc4ccff1/nptl/pthread_attr_getstacksize.c glibc-2.12-2-gc4ccff1.fixed/nptl/pthread_attr_getstacksize.c
--- glibc-2.12-2-gc4ccff1/nptl/pthread_attr_getstacksize.c 2010-05-04 16:57:23.000000000 +0530
+++ glibc-2.12-2-gc4ccff1.fixed/nptl/pthread_attr_getstacksize.c 2013-07-09 23:43:52.817834131 +0530
@@ -33,7 +33,7 @@ __pthread_attr_getstacksize (attr, stack
/* If the user has not set a stack size we return what the system
will use as the default. */
- *stacksize = iattr->stacksize ?: __default_stacksize;
+ *stacksize = iattr->stacksize ?: __default_pthread_attr.stacksize;
return 0;
}
diff -pruN glibc-2.12-2-gc4ccff1/nptl/pthread_barrier_init.c glibc-2.12-2-gc4ccff1.fixed/nptl/pthread_barrier_init.c
--- glibc-2.12-2-gc4ccff1/nptl/pthread_barrier_init.c 2010-05-04 16:57:23.000000000 +0530
+++ glibc-2.12-2-gc4ccff1.fixed/nptl/pthread_barrier_init.c 2013-07-09 23:43:52.821834131 +0530
@@ -23,7 +23,7 @@
#include <kernel-features.h>
-static const struct pthread_barrierattr default_attr =
+static const struct pthread_barrierattr default_barrierattr =
{
.pshared = PTHREAD_PROCESS_PRIVATE
};
@@ -43,7 +43,7 @@ pthread_barrier_init (barrier, attr, cou
const struct pthread_barrierattr *iattr
= (attr != NULL
? iattr = (struct pthread_barrierattr *) attr
- : &default_attr);
+ : &default_barrierattr);
if (iattr->pshared != PTHREAD_PROCESS_PRIVATE
&& __builtin_expect (iattr->pshared != PTHREAD_PROCESS_SHARED, 0))
diff -pruN glibc-2.12-2-gc4ccff1/nptl/pthread_create.c glibc-2.12-2-gc4ccff1.fixed/nptl/pthread_create.c
--- glibc-2.12-2-gc4ccff1/nptl/pthread_create.c 2013-07-09 23:43:09.542836173 +0530
+++ glibc-2.12-2-gc4ccff1.fixed/nptl/pthread_create.c 2013-07-09 23:43:52.822834131 +0530
@@ -425,15 +425,6 @@ start_thread (void *arg)
}
-/* Default thread attributes for the case when the user does not
- provide any. */
-static const struct pthread_attr default_attr =
- {
- /* Just some value > 0 which gets rounded to the nearest page size. */
- .guardsize = 1,
- };
-
-
int
__pthread_create_2_1 (newthread, attr, start_routine, arg)
pthread_t *newthread;
@@ -447,7 +438,7 @@ __pthread_create_2_1 (newthread, attr, s
if (iattr == NULL)
/* Is this the best idea? On NUMA machines this could mean
accessing far-away memory. */
- iattr = &default_attr;
+ iattr = &__default_pthread_attr;
struct pthread *pd = NULL;
int err = ALLOCATE_STACK (iattr, &pd);
diff -pruN glibc-2.12-2-gc4ccff1/nptl/pthread_mutex_init.c glibc-2.12-2-gc4ccff1.fixed/nptl/pthread_mutex_init.c
--- glibc-2.12-2-gc4ccff1/nptl/pthread_mutex_init.c 2010-05-04 16:57:23.000000000 +0530
+++ glibc-2.12-2-gc4ccff1.fixed/nptl/pthread_mutex_init.c 2013-07-09 23:43:52.822834131 +0530
@@ -24,7 +24,7 @@
#include <kernel-features.h>
#include "pthreadP.h"
-static const struct pthread_mutexattr default_attr =
+static const struct pthread_mutexattr default_mutexattr =
{
/* Default is a normal mutex, not shared between processes. */
.mutexkind = PTHREAD_MUTEX_NORMAL
@@ -45,7 +45,8 @@ __pthread_mutex_init (mutex, mutexattr)
assert (sizeof (pthread_mutex_t) <= __SIZEOF_PTHREAD_MUTEX_T);
- imutexattr = (const struct pthread_mutexattr *) mutexattr ?: &default_attr;
+ imutexattr = ((const struct pthread_mutexattr *) mutexattr
+ ?: &default_mutexattr);
/* Sanity checks. */
switch (__builtin_expect (imutexattr->mutexkind
diff -pruN glibc-2.12-2-gc4ccff1/nptl/pthreadP.h glibc-2.12-2-gc4ccff1.fixed/nptl/pthreadP.h
--- glibc-2.12-2-gc4ccff1/nptl/pthreadP.h 2013-07-09 23:43:09.553836173 +0530
+++ glibc-2.12-2-gc4ccff1.fixed/nptl/pthreadP.h 2013-07-09 23:43:52.823834131 +0530
@@ -148,8 +148,8 @@ enum
/* Internal variables. */
-/* Default stack size. */
-extern size_t __default_stacksize attribute_hidden;
+/* Default pthread attributes. */
+extern struct pthread_attr __default_pthread_attr attribute_hidden;
/* Size and alignment of static TLS block. */
extern size_t __static_tls_size attribute_hidden;
diff -pruN glibc-2.12-2-gc4ccff1/nptl/pthread_rwlock_init.c glibc-2.12-2-gc4ccff1.fixed/nptl/pthread_rwlock_init.c
--- glibc-2.12-2-gc4ccff1/nptl/pthread_rwlock_init.c 2010-05-04 16:57:23.000000000 +0530
+++ glibc-2.12-2-gc4ccff1.fixed/nptl/pthread_rwlock_init.c 2013-07-09 23:43:52.823834131 +0530
@@ -21,7 +21,7 @@
#include <kernel-features.h>
-static const struct pthread_rwlockattr default_attr =
+static const struct pthread_rwlockattr default_rwlockattr =
{
.lockkind = PTHREAD_RWLOCK_DEFAULT_NP,
.pshared = PTHREAD_PROCESS_PRIVATE
@@ -35,7 +35,7 @@ __pthread_rwlock_init (rwlock, attr)
{
const struct pthread_rwlockattr *iattr;
- iattr = ((const struct pthread_rwlockattr *) attr) ?: &default_attr;
+ iattr = ((const struct pthread_rwlockattr *) attr) ?: &default_rwlockattr;
memset (rwlock, '\0', sizeof (*rwlock));
diff -pruN glibc-2.12-2-gc4ccff1/nptl/vars.c glibc-2.12-2-gc4ccff1.fixed/nptl/vars.c
--- glibc-2.12-2-gc4ccff1/nptl/vars.c 2010-05-04 16:57:23.000000000 +0530
+++ glibc-2.12-2-gc4ccff1.fixed/nptl/vars.c 2013-07-09 23:43:52.824834131 +0530
@@ -21,13 +21,9 @@
#include <tls.h>
#include <unistd.h>
-/* Default stack size. */
-size_t __default_stacksize attribute_hidden
-#ifdef SHARED
-;
-#else
- = PTHREAD_STACK_MIN;
-#endif
+/* Default thread attributes for the case when the user does not
+ provide any. */
+struct pthread_attr __default_pthread_attr attribute_hidden;
/* Flag whether the machine is SMP or not. */
int __is_smp attribute_hidden;

View File

@@ -1,153 +1,92 @@
diff -rcp a/nscd/grpcache.c b/nscd/grpcache.c
*** a/nscd/grpcache.c Wed Apr 11 12:50:07 2012
--- b/nscd/grpcache.c Wed Apr 11 21:45:58 2012
*************** cache_addgr (struct database_dyn *db, in
*** 178,184 ****
char *cp;
const size_t key_len = strlen (key);
const size_t buf_len = 3 * sizeof (grp->gr_gid) + key_len + 1;
! char *buf = alloca (buf_len);
ssize_t n;
size_t cnt;
--- 178,185 ----
char *cp;
const size_t key_len = strlen (key);
const size_t buf_len = 3 * sizeof (grp->gr_gid) + key_len + 1;
! size_t alloca_used = 0;
! char *buf = alloca_account (buf_len, alloca_used);
ssize_t n;
size_t cnt;
*************** cache_addgr (struct database_dyn *db, in
*** 190,196 ****
/* Determine the length of all members. */
while (grp->gr_mem[gr_mem_cnt])
++gr_mem_cnt;
! gr_mem_len = (uint32_t *) alloca (gr_mem_cnt * sizeof (uint32_t));
for (gr_mem_cnt = 0; grp->gr_mem[gr_mem_cnt]; ++gr_mem_cnt)
{
gr_mem_len[gr_mem_cnt] = strlen (grp->gr_mem[gr_mem_cnt]) + 1;
--- 191,198 ----
/* Determine the length of all members. */
while (grp->gr_mem[gr_mem_cnt])
++gr_mem_cnt;
! gr_mem_len = (uint32_t *) alloca_account (gr_mem_cnt * sizeof (uint32_t),
! alloca_used);
for (gr_mem_cnt = 0; grp->gr_mem[gr_mem_cnt]; ++gr_mem_cnt)
{
gr_mem_len[gr_mem_cnt] = strlen (grp->gr_mem[gr_mem_cnt]) + 1;
*************** cache_addgr (struct database_dyn *db, in
*** 205,214 ****
change. Allocate memory on the cache since it is likely
discarded anyway. If it turns out to be necessary to have a
new record we can still allocate real memory. */
! bool alloca_used = false;
dataset = NULL;
! if (he == NULL)
dataset = (struct dataset *) mempool_alloc (db, total + n, 1);
if (dataset == NULL)
--- 207,216 ----
change. Allocate memory on the cache since it is likely
discarded anyway. If it turns out to be necessary to have a
new record we can still allocate real memory. */
! bool dataset_in_stack_or_freed = false;
dataset = NULL;
! if (he == NULL || ! __libc_use_alloca (alloca_used + total + n))
dataset = (struct dataset *) mempool_alloc (db, total + n, 1);
if (dataset == NULL)
*************** cache_addgr (struct database_dyn *db, in
*** 216,225 ****
/* We cannot permanently add the result in the moment. But
we can provide the result as is. Store the data in some
temporary memory. */
! dataset = (struct dataset *) alloca (total + n);
/* We cannot add this record to the permanent database. */
! alloca_used = true;
}
dataset->head.allocsize = total + n;
--- 218,227 ----
/* We cannot permanently add the result in the moment. But
we can provide the result as is. Store the data in some
temporary memory. */
! dataset = (struct dataset *) alloca_account (total + n, alloca_used);
/* We cannot add this record to the permanent database. */
! dataset_in_stack_or_freed = true;
}
dataset->head.allocsize = total + n;
*************** cache_addgr (struct database_dyn *db, in
*** 273,278 ****
--- 275,288 ----
allocated on the stack and need not be freed. */
dh->timeout = dataset->head.timeout;
++dh->nreloads;
+
+ /* If the new record was not allocated on the stack, then it must
+ be freed. Note that it can no longer be used. */
+ if (! dataset_in_stack_or_freed)
+ {
+ free (dataset);
+ dataset_in_stack_or_freed = true;
+ }
}
else
{
*************** cache_addgr (struct database_dyn *db, in
*** 288,294 ****
key_copy = (char *) newp + (key_copy - (char *) dataset);
dataset = memcpy (newp, dataset, total + n);
! alloca_used = false;
}
/* Mark the old record as obsolete. */
--- 298,304 ----
key_copy = (char *) newp + (key_copy - (char *) dataset);
dataset = memcpy (newp, dataset, total + n);
! dataset_in_stack_or_freed = false;
}
/* Mark the old record as obsolete. */
*************** cache_addgr (struct database_dyn *db, in
*** 303,309 ****
assert (fd != -1);
#ifdef HAVE_SENDFILE
! if (__builtin_expect (db->mmap_used, 1) && !alloca_used)
{
assert (db->wr_fd != -1);
assert ((char *) &dataset->resp > (char *) db->data);
--- 313,319 ----
assert (fd != -1);
#ifdef HAVE_SENDFILE
! if (__builtin_expect (db->mmap_used, 1) && !dataset_in_stack_or_freed)
{
assert (db->wr_fd != -1);
assert ((char *) &dataset->resp > (char *) db->data);
*************** cache_addgr (struct database_dyn *db, in
*** 330,336 ****
/* Add the record to the database. But only if it has not been
stored on the stack. */
! if (! alloca_used)
{
/* If necessary, we also propagate the data to disk. */
if (db->persistent)
--- 340,346 ----
/* Add the record to the database. But only if it has not been
stored on the stack. */
! if (! dataset_in_stack_or_freed)
{
/* If necessary, we also propagate the data to disk. */
if (db->persistent)
Index: glibc-2.12-2-gc4ccff1/nscd/grpcache.c
===================================================================
--- glibc-2.12-2-gc4ccff1.orig/nscd/grpcache.c
+++ glibc-2.12-2-gc4ccff1/nscd/grpcache.c
@@ -178,7 +178,8 @@ cache_addgr (struct database_dyn *db, in
char *cp;
const size_t key_len = strlen (key);
const size_t buf_len = 3 * sizeof (grp->gr_gid) + key_len + 1;
- char *buf = alloca (buf_len);
+ size_t alloca_used = 0;
+ char *buf = alloca_account (buf_len, alloca_used);
ssize_t n;
size_t cnt;
@@ -190,7 +191,8 @@ cache_addgr (struct database_dyn *db, in
/* Determine the length of all members. */
while (grp->gr_mem[gr_mem_cnt])
++gr_mem_cnt;
- gr_mem_len = (uint32_t *) alloca (gr_mem_cnt * sizeof (uint32_t));
+ gr_mem_len = (uint32_t *) alloca_account (gr_mem_cnt * sizeof (uint32_t),
+ alloca_used);
for (gr_mem_cnt = 0; grp->gr_mem[gr_mem_cnt]; ++gr_mem_cnt)
{
gr_mem_len[gr_mem_cnt] = strlen (grp->gr_mem[gr_mem_cnt]) + 1;
@@ -205,10 +207,10 @@ cache_addgr (struct database_dyn *db, in
change. Allocate memory on the cache since it is likely
discarded anyway. If it turns out to be necessary to have a
new record we can still allocate real memory. */
- bool alloca_used = false;
+ bool dataset_in_stack_or_freed = false;
dataset = NULL;
- if (he == NULL)
+ if (he == NULL || ! __libc_use_alloca (alloca_used + total + n))
dataset = (struct dataset *) mempool_alloc (db, total + n, 1);
if (dataset == NULL)
@@ -216,10 +218,10 @@ cache_addgr (struct database_dyn *db, in
/* We cannot permanently add the result in the moment. But
we can provide the result as is. Store the data in some
temporary memory. */
- dataset = (struct dataset *) alloca (total + n);
+ dataset = (struct dataset *) alloca_account (total + n, alloca_used);
/* We cannot add this record to the permanent database. */
- alloca_used = true;
+ dataset_in_stack_or_freed = true;
}
dataset->head.allocsize = total + n;
@@ -273,6 +275,14 @@ cache_addgr (struct database_dyn *db, in
allocated on the stack and need not be freed. */
dh->timeout = dataset->head.timeout;
++dh->nreloads;
+
+ /* If the new record was not allocated on the stack, then it must
+ be freed. Note that it can no longer be used. */
+ if (! dataset_in_stack_or_freed)
+ {
+ free (dataset);
+ dataset_in_stack_or_freed = true;
+ }
}
else
{
@@ -288,7 +298,7 @@ cache_addgr (struct database_dyn *db, in
key_copy = (char *) newp + (key_copy - (char *) dataset);
dataset = memcpy (newp, dataset, total + n);
- alloca_used = false;
+ dataset_in_stack_or_freed = false;
}
/* Mark the old record as obsolete. */
@@ -303,7 +313,7 @@ cache_addgr (struct database_dyn *db, in
assert (fd != -1);
#ifdef HAVE_SENDFILE
- if (__builtin_expect (db->mmap_used, 1) && !alloca_used)
+ if (__builtin_expect (db->mmap_used, 1) && !dataset_in_stack_or_freed)
{
assert (db->wr_fd != -1);
assert ((char *) &dataset->resp > (char *) db->data);
@@ -330,7 +340,7 @@ cache_addgr (struct database_dyn *db, in
/* Add the record to the database. But only if it has not been
stored on the stack. */
- if (! alloca_used)
+ if (! dataset_in_stack_or_freed)
{
/* If necessary, we also propagate the data to disk. */
if (db->persistent)

View File

@@ -0,0 +1,218 @@
commit 16b293a7a6f65d8ff348a603d19e8fd4372fa3a9
Author: Siddhesh Poyarekar <siddhesh@redhat.com>
Date: Wed Apr 30 11:48:43 2014 +0530
Do not fail if one of the two responses to AF_UNSPEC fails (BZ #14308)
[Fixes BZ #14308, #12994, #13651]
AF_UNSPEC results in sending two queries in parallel, one for the A
record and the other for the AAAA record. If one of these is a
referral, then the query fails, which is wrong. It should return at
least the one successful response.
The fix has two parts. The first part makes the referral fall back to
the SERVFAIL path, which results in using the successful response.
There is a bug in that path however, due to which the second part is
necessary. The bug here is that if the first response is a failure
and the second succeeds, __libc_res_nsearch does not detect that and
assumes a failure. The case where the first response is a success and
the second fails, works correctly.
This condition is produced by buggy routers, so here's a crude
interposable library that can simulate such a condition. The library
overrides the recvfrom syscall and modifies the header of the packet
received to reproduce this scenario. It has two key variables:
mod_packet and first_error.
The mod_packet variable when set to 0, results in odd packets being
modified to be a referral. When set to 1, even packets are modified
to be a referral.
The first_error causes the first response to be a failure so that a
domain-appended search is performed to test the second part of the
__libc_nsearch fix.
The driver for this fix is a simple getaddrinfo program that does an
AF_UNSPEC query. I have omitted this since it should be easy to
implement.
I have tested this on x86_64.
The interceptor library source:
/* Override recvfrom and modify the header of the first DNS response to make it
a referral and reproduce bz #845218. We have to resort to this ugly hack
because we cannot make bind return the buggy response of a referral for the
AAAA record and an authoritative response for the A record. */
#define _GNU_SOURCE
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdbool.h>
#include <endian.h>
#include <dlfcn.h>
#include <stdlib.h>
/* Lifted from resolv/arpa/nameser_compat.h. */
typedef struct {
unsigned id :16; /*%< query identification number */
#if BYTE_ORDER == BIG_ENDIAN
/* fields in third byte */
unsigned qr: 1; /*%< response flag */
unsigned opcode: 4; /*%< purpose of message */
unsigned aa: 1; /*%< authoritive answer */
unsigned tc: 1; /*%< truncated message */
unsigned rd: 1; /*%< recursion desired */
/* fields
* in
* fourth
* byte
* */
unsigned ra: 1; /*%< recursion available */
unsigned unused :1; /*%< unused bits (MBZ as of 4.9.3a3) */
unsigned ad: 1; /*%< authentic data from named */
unsigned cd: 1; /*%< checking disabled by resolver */
unsigned rcode :4; /*%< response code */
#endif
#if BYTE_ORDER == LITTLE_ENDIAN || BYTE_ORDER == PDP_ENDIAN
/* fields
* in
* third
* byte
* */
unsigned rd :1; /*%< recursion desired */
unsigned tc :1; /*%< truncated message */
unsigned aa :1; /*%< authoritive answer */
unsigned opcode :4; /*%< purpose of message */
unsigned qr :1; /*%< response flag */
/* fields
* in
* fourth
* byte
* */
unsigned rcode :4; /*%< response code */
unsigned cd: 1; /*%< checking disabled by resolver */
unsigned ad: 1; /*%< authentic data from named */
unsigned unused :1; /*%< unused bits (MBZ as of 4.9.3a3) */
unsigned ra :1; /*%< recursion available */
#endif
/* remaining
* bytes
* */
unsigned qdcount :16; /*%< number of question entries */
unsigned ancount :16; /*%< number of answer entries */
unsigned nscount :16; /*%< number of authority entries */
unsigned arcount :16; /*%< number of resource entries */
} HEADER;
static int done = 0;
/* Packets to modify. 0 for the odd packets and 1 for even packets. */
static const int mod_packet = 0;
/* Set to true if the first request should result in an error, resulting in a
search query. */
static bool first_error = true;
static ssize_t (*real_recvfrom) (int sockfd, void *buf, size_t len, int flags,
struct sockaddr *src_addr, socklen_t *addrlen);
void
__attribute__ ((constructor))
init (void)
{
real_recvfrom = dlsym (RTLD_NEXT, "recvfrom");
if (real_recvfrom == NULL)
{
printf ("Failed to get reference to recvfrom: %s\n", dlerror ());
printf ("Cannot simulate test\n");
abort ();
}
}
/* Modify the second packet that we receive to set the header in a manner as to
reproduce BZ #845218. */
static void
mod_buf (HEADER *h, int port)
{
if (done % 2 == mod_packet || (first_error && done == 1))
{
printf ("(Modifying header)");
if (first_error && done == 1)
h->rcode = 3;
else
h->rcode = 0; /* NOERROR == 0. */
h->ancount = 0;
h->aa = 0;
h->ra = 0;
h->arcount = 0;
}
done++;
}
ssize_t
recvfrom (int sockfd, void *buf, size_t len, int flags,
struct sockaddr *src_addr, socklen_t *addrlen)
{
ssize_t ret = real_recvfrom (sockfd, buf, len, flags, src_addr, addrlen);
int port = htons (((struct sockaddr_in *) src_addr)->sin_port);
struct in_addr addr = ((struct sockaddr_in *) src_addr)->sin_addr;
const char *host = inet_ntoa (addr);
printf ("\n*** From %s:%d: ", host, port);
mod_buf (buf, port);
printf ("returned %zd\n", ret);
return ret;
}
diff --git a/resolv/res_query.c b/resolv/res_query.c
index a9db837..4e6612c 100644
--- a/resolv/res_query.c
+++ b/resolv/res_query.c
@@ -382,7 +382,9 @@ __libc_res_nsearch(res_state statp,
ret = __libc_res_nquerydomain(statp, name, NULL, class, type,
answer, anslen, answerp,
answerp2, nanswerp2, resplen2);
- if (ret > 0 || trailing_dot)
+ if (ret > 0 || trailing_dot
+ /* If the second response is valid then we use that. */
+ || (ret == 0 && answerp2 != NULL && resplen2 > 0))
return (ret);
saved_herrno = h_errno;
tried_as_is++;
@@ -422,7 +424,8 @@ __libc_res_nsearch(res_state statp,
answer, anslen, answerp,
answerp2, nanswerp2,
resplen2);
- if (ret > 0)
+ if (ret > 0 || (ret == 0 && answerp2 != NULL
+ && resplen2 > 0))
return (ret);
if (answerp && *answerp != answer) {
diff --git a/resolv/res_send.c b/resolv/res_send.c
index 60743df..3273d55 100644
--- a/resolv/res_send.c
+++ b/resolv/res_send.c
@@ -1351,6 +1351,7 @@ send_dg(res_state statp,
(*thisresplenp > *thisanssizp)
? *thisanssizp : *thisresplenp);
+ next_ns:
if (recvresp1 || (buf2 != NULL && recvresp2)) {
*resplen2 = 0;
return resplen;
@@ -1368,7 +1369,6 @@ send_dg(res_state statp,
goto wait;
}
- next_ns:
__res_iclose(statp, false);
/* don't retry if called from dig */
if (!statp->pfcode)

View File

@@ -0,0 +1,70 @@
2013-04-30 Patsy Franklin <pfrankli@redhat.com>
* nis/yp_xdr.c: Defined XDRMAXNAME and XDRMAXRECORD.
(xdr_domainname): Use XDRMAXNAME as maxsize.
(xdr_mapname): Use XDRMAXNAME as maxsize.
(xdr_peername): Use XDRMAXNAME as maxsize.
(xdr_keydat): Use XDRMAXRECORD as maxsize.
(xdr_valdat): Use XDRMAXRECORD as maxsize.
diff -Nrup a/nis/yp_xdr.c b/nis/yp_xdr.c
--- a/nis/yp_xdr.c 2012-06-30 15:12:34.000000000 -0400
+++ b/nis/yp_xdr.c 2013-04-30 05:36:02.492835503 -0400
@@ -32,6 +32,14 @@
#include <rpcsvc/yp.h>
#include <rpcsvc/ypclnt.h>
+/* The specification suggests 1024 as a maximum length of all fields,
+ but current linux systems usually don't use any limits. So, to stay
+ as much compatible as possible with recent linux systems we choose
+ limits large enough to avoid problems. */
+
+#define XDRMAXNAME 1024
+#define XDRMAXRECORD 16 * 1024 * 1024
+
bool_t
xdr_ypstat (XDR *xdrs, ypstat *objp)
{
@@ -49,21 +57,21 @@ libnsl_hidden_def (xdr_ypxfrstat)
bool_t
xdr_domainname (XDR *xdrs, domainname *objp)
{
- return xdr_string (xdrs, objp, ~0);
+ return xdr_string (xdrs, objp, XDRMAXNAME);
}
libnsl_hidden_def (xdr_domainname)
bool_t
xdr_mapname (XDR *xdrs, mapname *objp)
{
- return xdr_string (xdrs, objp, ~0);
+ return xdr_string (xdrs, objp, XDRMAXNAME);
}
libnsl_hidden_def (xdr_mapname)
bool_t
xdr_peername (XDR *xdrs, peername *objp)
{
- return xdr_string (xdrs, objp, ~0);
+ return xdr_string (xdrs, objp, XDRMAXNAME);
}
libnsl_hidden_def (xdr_peername)
@@ -71,7 +79,7 @@ bool_t
xdr_keydat (XDR *xdrs, keydat *objp)
{
return xdr_bytes (xdrs, (char **) &objp->keydat_val,
- (u_int *) &objp->keydat_len, ~0);
+ (u_int *) &objp->keydat_len, XDRMAXRECORD);
}
libnsl_hidden_def (xdr_keydat)
@@ -79,7 +87,7 @@ bool_t
xdr_valdat (XDR *xdrs, valdat *objp)
{
return xdr_bytes (xdrs, (char **) &objp->valdat_val,
- (u_int *) &objp->valdat_len, ~0);
+ (u_int *) &objp->valdat_len, XDRMAXRECORD);
}
libnsl_hidden_def (xdr_valdat)

View File

@@ -0,0 +1,52 @@
commit 050af9c4e86eeecd484ed44b7765e750523276eb
Author: Siddhesh Poyarekar <siddhesh@redhat.com>
Date: Wed Aug 29 10:03:39 2012 +0530
Don't make ttyname* fail if proc filesystem is not available
The ttyname and ttyname_r functions on Linux now fall back to
searching for the tty file descriptor in /dev/pts or /dev if /proc is
not available. This allows creation of chroots without the procfs
mounted on /proc.
Fixes BZ #14516.
2012-08-29 Siddhesh Poyarekar <siddhesh@redhat.com>
[BZ #14516]
* sysdeps/unix/sysv/linux/ttyname.c (ttyname): Don't return
failure if reading from procfs failed.
* sysdeps/unix/sysv/linux/ttyname_r.c (ttyname_r): Likewise.
diff -rup a/sysdeps/unix/sysv/linux/ttyname.c b/sysdeps/unix/sysv/linux/ttyname.c
--- a/sysdeps/unix/sysv/linux/ttyname.c 2010-05-04 05:27:23.000000000 -0600
+++ b/sysdeps/unix/sysv/linux/ttyname.c 2012-08-27 10:53:29.326671475 -0600
@@ -146,12 +146,6 @@ ttyname (int fd)
}
ssize_t len = __readlink (procname, ttyname_buf, buflen);
- if (__builtin_expect (len == -1 && errno == ENOENT, 0))
- {
- __set_errno (EBADF);
- return NULL;
- }
-
if (__builtin_expect (len != -1
#ifndef __ASSUME_PROC_SELF_FD_SYMLINK
/* This is for Linux 2.0. */
diff -rup a/sysdeps/unix/sysv/linux/ttyname_r.c b/sysdeps/unix/sysv/linux/ttyname_r.c
--- a/sysdeps/unix/sysv/linux/ttyname_r.c 2010-05-04 05:27:23.000000000 -0600
+++ b/sysdeps/unix/sysv/linux/ttyname_r.c 2012-08-27 10:54:05.406528501 -0600
@@ -126,12 +126,6 @@ __ttyname_r (int fd, char *buf, size_t b
*_fitoa_word (fd, __stpcpy (procname, "/proc/self/fd/"), 10, 0) = '\0';
ssize_t ret = __readlink (procname, buf, buflen - 1);
- if (__builtin_expect (ret == -1 && errno == ENOENT, 0))
- {
- __set_errno (EBADF);
- return EBADF;
- }
-
if (__builtin_expect (ret == -1 && errno == ENAMETOOLONG, 0))
{
__set_errno (ERANGE);

View File

@@ -0,0 +1,854 @@
#
# Based on the following patch:
#
# Upstream bug: https://sourceware.org/bugzilla/show_bug.cgi?id=14906
# URL: https://sourceware.org/ml/libc-alpha/2015-02/msg00504.html
#
# 2015-02-17 Carlos O'Donell <carlos@redhat.com>
#
# [BZ #14906]
# * nscd/cache.c (prune_cache): Use TRACED_FILE. Compare and update
# traced file mtime. Use consistent log message.
# * nscd/connections.c [HAVE_INOTIFY] (install_watches): New function.
# (register_traced_file): Call install_watches. Always set mtime.
# (invalidate_cache): Iterate over all trace files. Call install_watches.
# (inotify_check_files): Don't inline. Handle watching parent
# directories and configuration file movement in and out.
# (handle_inotify_events): New function.
# (main_loop_poll): Call handle_inotify_events.
# (main_loop_epoll): Likewise.
# * nscd/nscd.h: Define TRACED_FILE, TRACED_DIR, and PATH_MAX.
# (struct traced_file): Use array of inotify fds. Add parent directory,
# and basename.
# (struct database_dyn): Remove unused file_mtime.
# (init_traced_file): New inline function.
# (define_traced_file): New macro.
# * nss/nss_db/db-init.c: Use define_traced_file.
# (_nss_db_init): Use init_traced_file.
# * nss/nss_files/files-init.c: Use define_traced_file.
# (_nss_files_init): Use init_traced_file.
#
diff -urN glibc-2.12-2-gc4ccff1.orig/misc/sys/cdefs.h glibc-2.12-2-gc4ccff1.mod1/misc/sys/cdefs.h
--- glibc-2.12-2-gc4ccff1.orig/misc/sys/cdefs.h 2015-02-18 04:42:12.115187116 -0500
+++ glibc-2.12-2-gc4ccff1.mod1/misc/sys/cdefs.h 2015-02-18 04:02:03.635159090 -0500
@@ -362,6 +362,14 @@
# endif
#endif
+#if __GNUC__ >= 3
+# define __glibc_unlikely(cond) __builtin_expect ((cond), 0)
+# define __glibc_likely(cond) __builtin_expect ((cond), 1)
+#else
+# define __glibc_unlikely(cond) (cond)
+# define __glibc_likely(cond) (cond)
+#endif
+
#include <bits/wordsize.h>
#if defined __LONG_DOUBLE_MATH_OPTIONAL && defined __NO_LONG_DOUBLE_MATH
diff -urN glibc-2.12-2-gc4ccff1.orig/nscd/cache.c glibc-2.12-2-gc4ccff1.mod1/nscd/cache.c
--- glibc-2.12-2-gc4ccff1.orig/nscd/cache.c 2015-02-18 04:42:12.329180362 -0500
+++ glibc-2.12-2-gc4ccff1.mod1/nscd/cache.c 2015-02-18 04:02:03.635159090 -0500
@@ -266,29 +266,52 @@
/* If we check for the modification of the underlying file we invalidate
the entries also in this case. */
- if (table->inotify_descr < 0 && table->check_file && now != LONG_MAX)
+ if (table->check_file && now != LONG_MAX)
{
- struct stat64 st;
+ struct traced_file *runp = table->traced_files;
- if (stat64 (table->filename, &st) < 0)
+ while (runp != NULL)
{
- char buf[128];
- /* We cannot stat() the file, disable file checking if the
- file does not exist. */
- dbg_log (_("cannot stat() file `%s': %s"),
- table->filename, strerror_r (errno, buf, sizeof (buf)));
- if (errno == ENOENT)
- table->check_file = 0;
- }
- else
- {
- if (st.st_mtime != table->file_mtime)
+#ifdef HAVE_INOTIFY
+ if (runp->inotify_descr[TRACED_FILE] == -1)
+#endif
{
- /* The file changed. Invalidate all entries. */
- now = LONG_MAX;
- table->file_mtime = st.st_mtime;
+ struct stat64 st;
+
+ if (stat64 (runp->fname, &st) < 0)
+ {
+ /* Print a diagnostic that the traced file was missing.
+ We must not disable tracing since the file might return
+ shortly and we want to reload it at the next pruning.
+ Disabling tracing here would go against the configuration
+ as specified by the user via check-files. */
+ char buf[128];
+ dbg_log (_("checking for monitored file `%s': %s"),
+ runp->fname, strerror_r (errno, buf, sizeof (buf)));
+ }
+ else
+ {
+ /* This must be `!=` to catch cases where users turn the
+ clocks back and we still want to detect any time difference
+ in mtime. */
+ if (st.st_mtime != runp->mtime)
+ {
+ dbg_log (_("monitored file `%s` changed (mtime)"),
+ runp->fname);
+ /* The file changed. Invalidate all entries. */
+ now = LONG_MAX;
+ runp->mtime = st.st_mtime;
+#ifdef HAVE_INOTIFY
+ /* Attempt to install a watch on the file. */
+ install_watches (runp);
+#endif
+ }
+ }
}
+
+ runp = runp->next;
}
+
}
/* We run through the table and find values which are not valid anymore.
diff -urN glibc-2.12-2-gc4ccff1.orig/nscd/connections.c glibc-2.12-2-gc4ccff1.mod1/nscd/connections.c
--- glibc-2.12-2-gc4ccff1.orig/nscd/connections.c 2015-02-18 04:42:12.333180236 -0500
+++ glibc-2.12-2-gc4ccff1.mod1/nscd/connections.c 2015-02-18 04:40:51.674726008 -0500
@@ -74,6 +74,25 @@
static void begin_drop_privileges (void);
static void finish_drop_privileges (void);
+/* Define the traced files. */
+#define PWD_FILENAME "/etc/passwd"
+define_traced_file (pwd, PWD_FILENAME);
+
+#define GRP_FILENAME "/etc/group"
+define_traced_file (grp, GRP_FILENAME);
+
+#define HST_FILENAME "/etc/hosts"
+define_traced_file (hst, HST_FILENAME);
+
+#define RESOLV_FILENAME "/etc/resolv.conf"
+define_traced_file (resolv, RESOLV_FILENAME);
+
+#define SERV_FILENAME "/etc/services"
+define_traced_file (serv, SERV_FILENAME);
+
+#define NETGR_FILENAME "/etc/netgroup"
+define_traced_file (netgr, NETGR_FILENAME);
+
/* Map request type to a string. */
const char *const serv2str[LASTREQ] =
{
@@ -115,8 +134,6 @@
.shared = 0,
.max_db_size = DEFAULT_MAX_DB_SIZE,
.suggested_module = DEFAULT_SUGGESTED_MODULE,
- .reset_res = 0,
- .filename = "/etc/passwd",
.db_filename = _PATH_NSCD_PASSWD_DB,
.disabled_iov = &pwd_iov_disabled,
.postimeout = 3600,
@@ -136,8 +153,6 @@
.shared = 0,
.max_db_size = DEFAULT_MAX_DB_SIZE,
.suggested_module = DEFAULT_SUGGESTED_MODULE,
- .reset_res = 0,
- .filename = "/etc/group",
.db_filename = _PATH_NSCD_GROUP_DB,
.disabled_iov = &grp_iov_disabled,
.postimeout = 3600,
@@ -157,8 +172,6 @@
.shared = 0,
.max_db_size = DEFAULT_MAX_DB_SIZE,
.suggested_module = DEFAULT_SUGGESTED_MODULE,
- .reset_res = 1,
- .filename = "/etc/hosts",
.db_filename = _PATH_NSCD_HOSTS_DB,
.disabled_iov = &hst_iov_disabled,
.postimeout = 3600,
@@ -178,8 +191,6 @@
.shared = 0,
.max_db_size = DEFAULT_MAX_DB_SIZE,
.suggested_module = DEFAULT_SUGGESTED_MODULE,
- .reset_res = 0,
- .filename = "/etc/services",
.db_filename = _PATH_NSCD_SERVICES_DB,
.disabled_iov = &serv_iov_disabled,
.postimeout = 28800,
@@ -199,8 +210,6 @@
.shared = 0,
.max_db_size = DEFAULT_MAX_DB_SIZE,
.suggested_module = DEFAULT_SUGGESTED_MODULE,
- .reset_res = 0,
- .filename = "/etc/netgroup",
.db_filename = _PATH_NSCD_NETGROUP_DB,
.disabled_iov = &netgroup_iov_disabled,
.postimeout = 28800,
@@ -863,41 +872,26 @@
dbs[cnt].shared = 0;
assert (dbs[cnt].ro_fd == -1);
}
+ }
- dbs[cnt].inotify_descr = -1;
- if (dbs[cnt].check_file)
- {
-#ifdef HAVE_INOTIFY
- if (inotify_fd < 0
- || (dbs[cnt].inotify_descr
- = inotify_add_watch (inotify_fd, dbs[cnt].filename,
- IN_DELETE_SELF | IN_MODIFY)) < 0)
- /* We cannot notice changes in the main thread. */
-#endif
- {
- /* We need the modification date of the file. */
- struct stat64 st;
+ /* Initialize and register the traced files. */
+ init_traced_file (&pwd_traced_file.file, PWD_FILENAME, 0);
+ register_traced_file (pwddb, &pwd_traced_file.file);
- if (stat64 (dbs[cnt].filename, &st) < 0)
- {
- /* We cannot stat() the file, disable file checking. */
- dbg_log (_("cannot stat() file `%s': %s"),
- dbs[cnt].filename, strerror (errno));
- dbs[cnt].check_file = 0;
- }
- else
- dbs[cnt].file_mtime = st.st_mtime;
- }
- }
+ init_traced_file (&grp_traced_file.file, GRP_FILENAME, 0);
+ register_traced_file (grpdb, &grp_traced_file.file);
-#ifdef HAVE_INOTIFY
- if (cnt == hstdb && inotify_fd >= -1)
- /* We also monitor the resolver configuration file. */
- resolv_conf_descr = inotify_add_watch (inotify_fd,
- _PATH_RESCONF,
- IN_DELETE_SELF | IN_MODIFY);
-#endif
- }
+ init_traced_file (&hst_traced_file.file, HST_FILENAME, 0);
+ register_traced_file (hstdb, &hst_traced_file.file);
+
+ init_traced_file (&resolv_traced_file.file, RESOLV_FILENAME, 1);
+ register_traced_file (hstdb, &resolv_traced_file.file);
+
+ init_traced_file (&serv_traced_file.file, SERV_FILENAME, 0);
+ register_traced_file (servdb, &serv_traced_file.file);
+
+ init_traced_file (&netgr_traced_file.file, NETGR_FILENAME, 0);
+ register_traced_file (netgrdb, &netgr_traced_file.file);
/* Create the socket. */
#ifndef __ASSUME_SOCK_CLOEXEC
@@ -968,6 +962,92 @@
finish_drop_privileges ();
}
+#ifdef HAVE_INOTIFY
+#define TRACED_FILE_MASK (IN_DELETE_SELF | IN_CLOSE_WRITE | IN_MOVE_SELF)
+#define TRACED_DIR_MASK (IN_DELETE_SELF | IN_CREATE | IN_MOVED_TO | IN_MOVE_SELF)
+void
+install_watches (struct traced_file *finfo)
+{
+ /* If we have inotify support use it exclusively with no fallback
+ to stat. This is a design decision to make the implementation
+ sipmler. Either we use fstat for the file name or we use inotify
+ for both the file and parent directory. */
+ if (finfo->inotify_descr[TRACED_FILE] < 0)
+ finfo->inotify_descr[TRACED_FILE] = inotify_add_watch (inotify_fd,
+ finfo->fname,
+ TRACED_FILE_MASK);
+ if (finfo->inotify_descr[TRACED_FILE] < 0)
+ {
+ dbg_log (_("disabled inotify-based monitoring for file `%s': %s"),
+ finfo->fname, strerror (errno));
+ return;
+ }
+ dbg_log (_("monitoring file `%s` (%d)"),
+ finfo->fname, finfo->inotify_descr[TRACED_FILE]);
+ /* Additionally listen for IN_CREATE events in the files parent
+ directory. We do this because the file to be watched might be
+ deleted and then added back again. When it is added back again
+ we must re-add the watch. We must also cover IN_MOVED_TO to
+ detect a file being moved into the directory. */
+ if (finfo->inotify_descr[TRACED_DIR] < 0)
+ finfo->inotify_descr[TRACED_DIR] = inotify_add_watch (inotify_fd,
+ finfo->dname,
+ TRACED_DIR_MASK);
+ if (finfo->inotify_descr[TRACED_DIR] < 0)
+ {
+ dbg_log (_("disabled inotify-based monitoring for directory `%s': %s"),
+ finfo->fname, strerror (errno));
+ return;
+ }
+ dbg_log (_("monitoring directory `%s` (%d)"),
+ finfo->dname, finfo->inotify_descr[TRACED_DIR]);
+}
+#endif
+
+/* Register the file in FINFO as a traced file for the database DBS[DBIX].
+
+ We support registering multiple files per database. Each call to
+ register_traced_file adds to the list of registered files.
+
+ When we prune the database, either through timeout or a request to
+ invalidate, we will check to see if any of the registered files has changed.
+ When we accept new connections to handle a cache request we will also
+ check to see if any of the registered files has changed.
+
+ If we have inotify support then we install an inotify fd to notify us of
+ file deletion or modification, both of which will require we invalidate
+ the cache for the database. Without inotify support we stat the file and
+ store st_mtime to determine if the file has been modified. */
+void
+register_traced_file (size_t dbidx, struct traced_file *finfo)
+{
+ /* If the database is disabled or file checking is disabled
+ then ignore the registration. */
+ if (! dbs[dbidx].enabled || ! dbs[dbidx].check_file)
+ return;
+
+ if (__glibc_unlikely (debug_level > 0))
+ dbg_log (_("monitoring file %s for database %s"),
+ finfo->fname, dbnames[dbidx]);
+
+#ifdef HAVE_INOTIFY
+ install_watches (finfo);
+#endif
+ struct stat64 st;
+ if (stat64 (finfo->fname, &st) < 0)
+ {
+ /* We cannot stat() the file, disable file checking. */
+ dbg_log (_("disabled monitoring for file `%s': %s"),
+ finfo->fname, strerror (errno));
+ finfo->mtime = 0;
+ }
+ else
+ finfo->mtime = st.st_mtime;
+
+ /* Queue up the file name. */
+ finfo->next = dbs[dbidx].traced_files;
+ dbs[dbidx].traced_files = finfo;
+}
/* Close the connections. */
void
@@ -986,9 +1066,25 @@
for (number = pwddb; number < lastdb; ++number)
if (strcmp (key, dbnames[number]) == 0)
{
- if (dbs[number].reset_res)
- res_init ();
-
+ struct traced_file *runp = dbs[number].traced_files;
+ while (runp != NULL)
+ {
+ /* Make sure we reload from file when checking mtime. */
+ runp->mtime = 0;
+#ifdef HAVE_INOTIFY
+ /* During an invalidation we try to reload the traced
+ file watches. This allows the user to re-sync if
+ inotify events were lost. Similar to what we do during
+ pruning. */
+ install_watches (runp);
+#endif
+ if (runp->call_res_init)
+ {
+ res_init ();
+ break;
+ }
+ runp = runp->next;
+ }
break;
}
@@ -1817,6 +1913,231 @@
/* Array for times a connection was accepted. */
static time_t *starttime;
+#ifdef HAVE_INOTIFY
+/* Inotify event for changed file. */
+union __inev
+{
+ struct inotify_event i;
+# ifndef PATH_MAX
+# define PATH_MAX 1024
+# endif
+ char buf[sizeof (struct inotify_event) + PATH_MAX];
+};
+
+/* Returns 0 if the file is there and matches the last mtime
+ on record, otherwise -1. */
+int
+check_file (struct traced_file *finfo)
+{
+ struct stat64 st;
+ if (stat64 (finfo->fname, &st) < 0)
+ return -1;
+ return 0;
+}
+
+/* Process the inotify event in INEV. If the event matches any of the files
+ registered with a database then mark that database as requiring its cache
+ to be cleared. We indicate the cache needs clearing by setting
+ TO_CLEAR[DBCNT] to true for the matching database. */
+static void
+inotify_check_files (bool *to_clear, union __inev *inev)
+{
+ /* Check which of the files changed. */
+ for (size_t dbcnt = 0; dbcnt < lastdb; ++dbcnt)
+ {
+ struct traced_file *finfo = dbs[dbcnt].traced_files;
+
+ while (finfo != NULL)
+ {
+ /* The configuration file was moved or deleted.
+ We stop watching it at that point, and reinitialize. */
+ if (finfo->inotify_descr[TRACED_FILE] == inev->i.wd
+ && ((inev->i.mask & IN_MOVE_SELF)
+ || (inev->i.mask & IN_DELETE_SELF)
+ || (inev->i.mask & IN_IGNORED)))
+ {
+ int ret;
+ bool moved = (inev->i.mask & IN_MOVE_SELF) != 0;
+
+ if (check_file (finfo) == 0)
+ {
+ dbg_log (_("ignored out of order inotify event for `%s`"),
+ finfo->fname);
+ return;
+ }
+
+ dbg_log (_("monitored file `%s` was %s, removing watch"),
+ finfo->fname, moved ? "moved" : "deleted");
+ /* File was moved out, remove the watch. Watches are
+ automatically removed when the file is deleted. */
+ if (moved)
+ {
+ ret = inotify_rm_watch (inotify_fd, inev->i.wd);
+ if (ret < 0)
+ dbg_log (_("failed to remove file watch `%s`: %s"),
+ finfo->fname, strerror (errno));
+ }
+ finfo->inotify_descr[TRACED_FILE] = -1;
+ to_clear[dbcnt] = true;
+ if (finfo->call_res_init)
+ res_init ();
+ return;
+ }
+ /* The configuration file was open for writing and has just closed.
+ We reset the cache and reinitialize. */
+ if (finfo->inotify_descr[TRACED_FILE] == inev->i.wd
+ && inev->i.mask & IN_CLOSE_WRITE)
+ {
+ /* Mark cache as needing to be cleared and reinitialize. */
+ dbg_log (_("monitored file `%s` was written to"), finfo->fname);
+ to_clear[dbcnt] = true;
+ if (finfo->call_res_init)
+ res_init ();
+ return;
+ }
+ /* The parent directory was moved or deleted. There is no coming
+ back from this. We do not track the parent of the parent, and
+ once this happens we trigger one last invalidation. You must
+ restart nscd to track subsequent changes. We track this to
+ do one last robust re-initialization and then we're done. */
+ if (finfo->inotify_descr[TRACED_DIR] == inev->i.wd
+ && ((inev->i.mask & IN_DELETE_SELF)
+ || (inev->i.mask & IN_MOVE_SELF)
+ || (inev->i.mask & IN_IGNORED)))
+ {
+ bool moved = (inev->i.mask & IN_MOVE_SELF) != 0;
+ /* The directory watch may have already been removed
+ but we don't know so we just remove it again and
+ ignore the error. Then we remove the file watch.
+ Note: watches are automatically removed for deleted
+ files. */
+ if (moved)
+ inotify_rm_watch (inotify_fd, inev->i.wd);
+ if (finfo->inotify_descr[TRACED_FILE] != -1)
+ {
+ dbg_log (_("monitored parent directory `%s` was %s, removing watch on `%s`"),
+ finfo->dname, moved ? "moved" : "deleted", finfo->fname);
+ if (inotify_rm_watch (inotify_fd, finfo->inotify_descr[TRACED_FILE]) < 0)
+ dbg_log (_("failed to remove file watch `%s`: %s"),
+ finfo->dname, strerror (errno));
+ }
+ finfo->inotify_descr[TRACED_FILE] = -1;
+ finfo->inotify_descr[TRACED_DIR] = -1;
+ to_clear[dbcnt] = true;
+ if (finfo->call_res_init)
+ res_init ();
+ /* Continue to the next entry since this might be the
+ parent directory for multiple registered files and
+ we want to remove watches for all registered files. */
+ continue;
+ }
+ /* The parent directory had a create or moved to event. */
+ if (finfo->inotify_descr[TRACED_DIR] == inev->i.wd
+ && ((inev->i.mask & IN_MOVED_TO)
+ || (inev->i.mask & IN_CREATE))
+ && strcmp (inev->i.name, finfo->sfname) == 0)
+ {
+ /* We detected a directory change. We look for the creation
+ of the file we are tracking or the move of the same file
+ into the directory. */
+ int ret;
+ dbg_log (_("monitored file `%s` was %s, adding watch"),
+ finfo->fname,
+ inev->i.mask & IN_CREATE ? "created" : "moved into place");
+ /* File was moved in or created. Regenerate the watch. */
+ if (finfo->inotify_descr[TRACED_FILE] != -1)
+ inotify_rm_watch (inotify_fd,
+ finfo->inotify_descr[TRACED_FILE]);
+
+ ret = inotify_add_watch (inotify_fd,
+ finfo->fname,
+ TRACED_FILE_MASK);
+ if (ret < 0)
+ dbg_log (_("failed to add file watch `%s`: %s"),
+ finfo->fname, strerror (errno));
+
+ finfo->inotify_descr[TRACED_FILE] = ret;
+
+ /* The file is new or moved so mark cache as needing to
+ be cleared and reinitialize. */
+ to_clear[dbcnt] = true;
+ if (finfo->call_res_init)
+ res_init ();
+
+ /* Done re-adding the watch. Don't return, we may still
+ have other files in this same directory, same watch
+ descriptor, and need to process them. */
+ }
+ /* Other events are ignored, and we move on to the next file. */
+ finfo = finfo->next;
+ }
+ }
+}
+
+/* If an entry in the array of booleans TO_CLEAR is TRUE then clear the cache
+ for the associated database, otherwise do nothing. The TO_CLEAR array must
+ have LASTDB entries. */
+static inline void
+clear_db_cache (bool *to_clear)
+{
+ for (size_t dbcnt = 0; dbcnt < lastdb; ++dbcnt)
+ if (to_clear[dbcnt])
+ {
+ pthread_mutex_lock (&dbs[dbcnt].prune_lock);
+ dbs[dbcnt].clear_cache = 1;
+ pthread_mutex_unlock (&dbs[dbcnt].prune_lock);
+ pthread_cond_signal (&dbs[dbcnt].prune_cond);
+ }
+}
+
+int
+handle_inotify_events (void)
+{
+ bool to_clear[lastdb] = { false, };
+ union __inev inev;
+
+ /* Read all inotify events for files registered via
+ register_traced_file(). */
+ while (1)
+ {
+ /* Potentially read multiple events into buf. */
+ ssize_t nb = TEMP_FAILURE_RETRY (read (inotify_fd,
+ &inev.buf,
+ sizeof (inev)));
+ if (nb < (ssize_t) sizeof (struct inotify_event))
+ {
+ /* Not even 1 event. */
+ if (__glibc_unlikely (nb == -1 && errno != EAGAIN))
+ return -1;
+ /* Done reading events that are ready. */
+ break;
+ }
+ /* Process all events. The normal inotify interface delivers
+ complete events on a read and never a partial event. */
+ char *eptr = &inev.buf[0];
+ ssize_t count;
+ while (1)
+ {
+ /* Check which of the files changed. */
+ inotify_check_files (to_clear, &inev);
+ count = sizeof (struct inotify_event) + inev.i.len;
+ eptr += count;
+ nb -= count;
+ if (nb >= (ssize_t) sizeof (struct inotify_event))
+ memcpy (&inev, eptr, nb);
+ else
+ break;
+ }
+ continue;
+ }
+ /* Actually perform the cache clearing. */
+ clear_db_cache (to_clear);
+ return 0;
+}
+
+
+#endif
+
static void
__attribute__ ((__noreturn__))
@@ -1910,66 +2231,21 @@
{
if (conns[1].revents != 0)
{
- bool to_clear[lastdb] = { false, };
- union
- {
-# ifndef PATH_MAX
-# define PATH_MAX 1024
-# endif
- struct inotify_event i;
- char buf[sizeof (struct inotify_event) + PATH_MAX];
- } inev;
+ int ret;
+ ret = handle_inotify_events ();
- while (1)
+ if (ret == -1)
{
- ssize_t nb = TEMP_FAILURE_RETRY (read (inotify_fd, &inev,
- sizeof (inev)));
- if (nb < (ssize_t) sizeof (struct inotify_event))
- {
- if (__builtin_expect (nb == -1 && errno != EAGAIN,
- 0))
- {
- /* Something went wrong when reading the inotify
- data. Better disable inotify. */
- dbg_log (_("\
-disabled inotify after read error %d"),
- errno);
- conns[1].fd = -1;
- firstfree = 1;
- if (nused == 2)
- nused = 1;
- close (inotify_fd);
- inotify_fd = -1;
- }
- break;
- }
-
- /* Check which of the files changed. */
- for (size_t dbcnt = 0; dbcnt < lastdb; ++dbcnt)
- if (inev.i.wd == dbs[dbcnt].inotify_descr)
- {
- to_clear[dbcnt] = true;
- goto next;
- }
-
- if (inev.i.wd == resolv_conf_descr)
- {
- res_init ();
- to_clear[hstdb] = true;
- }
- next:;
+ /* Something went wrong when reading the inotify
+ data. Better disable inotify. */
+ dbg_log (_("disabled inotify-based monitoring after read error %d"), errno);
+ conns[1].fd = -1;
+ firstfree = 1;
+ if (nused == 2)
+ nused = 1;
+ close (inotify_fd);
+ inotify_fd = -1;
}
-
- /* Actually perform the cache clearing. */
- for (size_t dbcnt = 0; dbcnt < lastdb; ++dbcnt)
- if (to_clear[dbcnt])
- {
- pthread_mutex_lock (&dbs[dbcnt].prune_lock);
- dbs[dbcnt].clear_cache = 1;
- pthread_mutex_unlock (&dbs[dbcnt].prune_lock);
- pthread_cond_signal (&dbs[dbcnt].prune_cond);
- }
-
--n;
}
@@ -2112,58 +2388,18 @@
# ifdef HAVE_INOTIFY
else if (revs[cnt].data.fd == inotify_fd)
{
- bool to_clear[lastdb] = { false, };
- union
- {
- struct inotify_event i;
- char buf[sizeof (struct inotify_event) + PATH_MAX];
- } inev;
-
- while (1)
+ int ret;
+ ret = handle_inotify_events ();
+ if (ret == -1)
{
- ssize_t nb = TEMP_FAILURE_RETRY (read (inotify_fd, &inev,
- sizeof (inev)));
- if (nb < (ssize_t) sizeof (struct inotify_event))
- {
- if (__builtin_expect (nb == -1 && errno != EAGAIN, 0))
- {
- /* Something went wrong when reading the inotify
- data. Better disable inotify. */
- dbg_log (_("disabled inotify after read error %d"),
- errno);
- (void) epoll_ctl (efd, EPOLL_CTL_DEL, inotify_fd,
- NULL);
- close (inotify_fd);
- inotify_fd = -1;
- }
- break;
- }
-
- /* Check which of the files changed. */
- for (size_t dbcnt = 0; dbcnt < lastdb; ++dbcnt)
- if (inev.i.wd == dbs[dbcnt].inotify_descr)
- {
- to_clear[dbcnt] = true;
- goto next;
- }
-
- if (inev.i.wd == resolv_conf_descr)
- {
- res_init ();
- to_clear[hstdb] = true;
- }
- next:;
+ /* Something went wrong when reading the inotify
+ data. Better disable inotify. */
+ dbg_log (_("disabled inotify-based monitoring after read error %d"), errno);
+ (void) epoll_ctl (efd, EPOLL_CTL_DEL, inotify_fd, NULL);
+ close (inotify_fd);
+ inotify_fd = -1;
+ break;
}
-
- /* Actually perform the cache clearing. */
- for (size_t dbcnt = 0; dbcnt < lastdb; ++dbcnt)
- if (to_clear[dbcnt])
- {
- pthread_mutex_lock (&dbs[dbcnt].prune_lock);
- dbs[dbcnt].clear_cache = 1;
- pthread_mutex_unlock (&dbs[dbcnt].prune_lock);
- pthread_cond_signal (&dbs[dbcnt].prune_cond);
- }
}
# endif
else
diff -urN glibc-2.12-2-gc4ccff1.orig/nscd/nscd.h glibc-2.12-2-gc4ccff1.mod1/nscd/nscd.h
--- glibc-2.12-2-gc4ccff1.orig/nscd/nscd.h 2015-02-18 04:42:12.329180362 -0500
+++ glibc-2.12-2-gc4ccff1.mod1/nscd/nscd.h 2015-02-18 04:02:03.636159059 -0500
@@ -62,6 +62,67 @@
80% of the thread stack size. */
#define MAX_STACK_USE ((8 * NSCD_THREAD_STACKSIZE) / 10)
+/* Records the file registered per database that when changed
+ or modified requires invalidating the database. */
+struct traced_file
+{
+ /* Tracks the last modified time of the traced file. */
+ time_t mtime;
+ /* Support multiple registered files per database. */
+ struct traced_file *next;
+ int call_res_init;
+ /* Requires Inotify support to do anything useful. */
+#define TRACED_FILE 0
+#define TRACED_DIR 1
+ int inotify_descr[2];
+# ifndef PATH_MAX
+# define PATH_MAX 1024
+# endif
+ /* The parent directory is used to scan for creation/deletion. */
+ char dname[PATH_MAX];
+ /* Just the name of the file with no directory component. */
+ char *sfname;
+ /* The full-path name of the registered file. */
+ char fname[];
+};
+
+/* Initialize a `struct traced_file`. As input we need the name
+ of the file, and if invalidation requires calling res_init.
+ If CRINIT is 1 then res_init will be called after invalidation
+ or if the traced file is changed in any way, otherwise it will
+ not. */
+static inline void
+init_traced_file(struct traced_file *file, const char *fname, int crinit)
+{
+ char *dname;
+ file->mtime = 0;
+ file->inotify_descr[TRACED_FILE] = -1;
+ file->inotify_descr[TRACED_DIR] = -1;
+ strcpy (file->fname, fname);
+ /* Compute the parent directory name and store a copy. The copy makes
+ it much faster to add/remove watches while nscd is running instead
+ of computing this over and over again in a temp buffer. */
+ file->dname[0] = '\0';
+ dname = strrchr (fname, '/');
+ if (dname != NULL)
+ {
+ size_t len = (size_t)(dname - fname);
+ if (len > sizeof (file->dname))
+ abort ();
+ strncpy (file->dname, file->fname, len);
+ file->dname[len] = '\0';
+ }
+ /* The basename is the name just after the last forward slash. */
+ file->sfname = &dname[1];
+ file->call_res_init = crinit;
+}
+
+#define define_traced_file(id, filename) \
+static union \
+{ \
+ struct traced_file file; \
+ char buf[sizeof (struct traced_file) + sizeof (filename)]; \
+} id##_traced_file;
/* Structure describing dynamic part of one database. */
struct database_dyn
@@ -74,15 +135,12 @@
int enabled;
int check_file;
- int inotify_descr;
int clear_cache;
int persistent;
int shared;
int propagate;
- int reset_res;
- const char filename[16];
+ struct traced_file *traced_files;
const char *db_filename;
- time_t file_mtime;
size_t suggested_module;
size_t max_db_size;
@@ -199,6 +257,10 @@
/* connections.c */
extern void nscd_init (void);
+extern void register_traced_file (size_t dbidx, struct traced_file *finfo);
+#ifdef HAVE_INOTIFY
+extern void install_watches (struct traced_file *finfo);
+#endif
extern void close_sockets (void);
extern void start_threads (void) __attribute__ ((__noreturn__));

View File

@@ -0,0 +1,68 @@
From bc5fb0374c3ce6eca92f44d13a55b066e707c4a0 Mon Sep 17 00:00:00 2001
From: Andreas Schwab <schwab@redhat.com>
Date: Wed, 15 Sep 2010 07:20:57 -0700
Subject: [PATCH] Don't try to free rpath strings allocated during startup
---
ChangeLog | 10 ++++++++++
elf/dl-load.c | 3 ---
elf/dl-support.c | 3 +++
elf/rtld.c | 4 ++++
4 files changed, 17 insertions(+), 3 deletions(-)
2010-09-13 Andreas Schwab <schwab@redhat.com>
Ulrich Drepper <drepper@redhat.com>
* elf/rtld.c (dl_main): Set GLRO(dl_init_all_dirs) just before
re-relocationg ld.so.
* elf/dl-support.c (_dl_non_dynamic_init): And here after the
_dl_init_paths call.
* elf/dl-load.c (_dl_init_paths). Don't set GLRO(dl_init_all_dirs)
here anymore.
diff --git a/elf/dl-load.c b/elf/dl-load.c
index 0adddf5..a7162eb 100644
--- a/elf/dl-load.c
+++ b/elf/dl-load.c
@@ -787,9 +787,6 @@ _dl_init_paths (const char *llp)
}
else
env_path_list.dirs = (void *) -1;
-
- /* Remember the last search directory added at startup. */
- GLRO(dl_init_all_dirs) = GL(dl_all_dirs);
}
diff --git a/elf/dl-support.c b/elf/dl-support.c
index f94d2c4..5897b32 100644
--- a/elf/dl-support.c
+++ b/elf/dl-support.c
@@ -264,6 +264,9 @@ _dl_non_dynamic_init (void)
objects. */
_dl_init_paths (getenv ("LD_LIBRARY_PATH"));
+ /* Remember the last search directory added at startup. */
+ _dl_init_all_dirs = GL(dl_all_dirs);
+
_dl_lazy = *(getenv ("LD_BIND_NOW") ?: "") == '\0';
_dl_bind_not = *(getenv ("LD_BIND_NOT") ?: "") != '\0';
diff --git a/elf/rtld.c b/elf/rtld.c
index 90f3ff1..5ecc4fe 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -2291,6 +2291,10 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
lossage);
}
+ /* Remember the last search directory added at startup, now that
+ malloc will no longer be the one from dl-minimal.c. */
+ GLRO(dl_init_all_dirs) = GL(dl_all_dirs);
+
if (! prelinked && rtld_multiple_ref)
{
/* There was an explicit ref to the dynamic linker as a shared lib.
--
1.7.1

View File

@@ -0,0 +1,14 @@
diff -pruN glibc-2.12-2-gc4ccff1/sysdeps/posix/getaddrinfo.c glibc-2.12-2-gc4ccff1.fixed/sysdeps/posix/getaddrinfo.c
--- glibc-2.12-2-gc4ccff1/sysdeps/posix/getaddrinfo.c 2013-07-23 15:23:42.011941780 +0530
+++ glibc-2.12-2-gc4ccff1.fixed/sysdeps/posix/getaddrinfo.c 2013-07-23 15:24:54.032938976 +0530
@@ -562,8 +562,8 @@ gaih_inet (const char *name, const struc
/* If we do not have to look for IPv6 addresses, use
the simple, old functions, which do not support
- IPv6 scope ids. */
- if (req->ai_family == AF_INET)
+ IPv6 scope ids, nor retrieving the canonical name. */
+ if (req->ai_family == AF_INET && (req->ai_flags & AI_CANONNAME) == 0)
{
/* Add room for struct host_data in resolv/nss_dns/dns-host.c */
size_t tmpbuflen = 512 + (MAX_NR_ALIASES+MAX_NR_ADDRS+1)*sizeof(char*)

View File

@@ -0,0 +1,139 @@
commit 9fab36eb583c0e585e83a01253299afed9ea9a11
Author: Siddhesh Poyarekar <siddhesh@redhat.com>
Date: Tue Sep 25 14:10:29 2012 +0530
Shrink heap on linux when overcommit_memory == 2
Using madvise with MADV_DONTNEED to release memory back to the kernel
is not sufficient to change the commit charge accounted against the
process on Linux. It is OK however, when overcommit is enabled or is
heuristic. However, when overcommit is restricted to a percentage of
memory setting the contents of /proc/sys/vm/overcommit_memory as 2, it
makes a difference since memory requests will fail. Hence, we do what
we do with secure exec binaries, which is to call mmap on the region
to be dropped with MAP_FIXED. This internally unmaps the pages in
question and reduces the amount of memory accounted against the
process.
diff --git a/malloc/arena.c b/malloc/arena.c
index f24e76c..b209e3b 100644
--- a/malloc/arena.c
+++ b/malloc/arena.c
@@ -19,6 +19,9 @@
#include <stdbool.h>
+/* Get the implementation for check_may_shrink_heap. */
+#include <malloc-sysdep.h>
+
/* Compile-time constants. */
#define HEAP_MIN_SIZE (32*1024)
@@ -621,10 +624,10 @@ shrink_heap(heap_info *h, long diff)
new_size = (long)h->size - diff;
if(new_size < (long)sizeof(*h))
return -1;
- /* Try to re-map the extra heap space freshly to save memory, and
- make it inaccessible. */
#ifdef _LIBC
- if (__builtin_expect (__libc_enable_secure, 0))
+ /* Try to re-map the extra heap space freshly to save memory, and make it
+ inaccessible. See malloc-sysdep.h to know when this is true. */
+ if (__builtin_expect (check_may_shrink_heap (), 0))
#else
if (1)
#endif
diff --git a/sysdeps/generic/malloc-sysdep.h b/sysdeps/generic/malloc-sysdep.h
new file mode 100644
index 0000000..bbc48c0
--- /dev/null
+++ b/sysdeps/generic/malloc-sysdep.h
@@ -0,0 +1,25 @@
+/* System-specific malloc support functions. Generic version.
+ 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/>. */
+
+/* Force an unmap when the heap shrinks in a secure exec. This ensures that
+ the old data pages immediately cease to be accessible. */
+static inline bool
+check_may_shrink_heap (void)
+{
+ return __libc_enable_secure;
+}
diff --git a/sysdeps/unix/sysv/linux/malloc-sysdep.h b/sysdeps/unix/sysv/linux/malloc-sysdep.h
new file mode 100644
index 0000000..f926aea
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/malloc-sysdep.h
@@ -0,0 +1,57 @@
+/* System-specific malloc support functions. Linux version.
+ 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 <fcntl.h>
+#include <not-cancel.h>
+
+/* The Linux kernel overcommits address space by default and if there is not
+ enough memory available, it uses various parameters to decide the process to
+ kill. It is however possible to disable or curb this overcommit behavior
+ by setting the proc sysctl vm.overcommit_memory to the value '2' and with
+ that, a process is only allowed to use the maximum of a pre-determined
+ fraction of the total address space. In such a case, we want to make sure
+ that we are judicious with our heap usage as well, and explicitly give away
+ the freed top of the heap to reduce our commit charge. See the proc(5) man
+ page to know more about overcommit behavior.
+
+ Other than that, we also force an unmap in a secure exec. */
+static inline bool
+check_may_shrink_heap (void)
+{
+ static int may_shrink_heap = -1;
+
+ if (__builtin_expect (may_shrink_heap >= 0, 1))
+ return may_shrink_heap;
+
+ may_shrink_heap = __libc_enable_secure;
+
+ if (__builtin_expect (may_shrink_heap == 0, 1))
+ {
+ int fd = open_not_cancel_2 ("/proc/sys/vm/overcommit_memory",
+ O_RDONLY | O_CLOEXEC);
+ if (fd >= 0)
+ {
+ char val;
+ ssize_t n = read_not_cancel (fd, &val, 1);
+ may_shrink_heap = n > 0 && val == '2';
+ close_not_cancel_no_status (fd);
+ }
+ }
+
+ return may_shrink_heap;
+}

View File

@@ -0,0 +1,99 @@
From d6f67f7d833b4e2039f832355fb0edd65522c9f4 Mon Sep 17 00:00:00 2001
From: Ulrich Drepper <drepper@gmail.com>
Date: Sat, 14 May 2011 10:46:17 -0400
Subject: [PATCH] Handle recursive calls in backtrace better
---
ChangeLog | 7 +++++++
NEWS | 12 ++++++------
sysdeps/ia64/backtrace.c | 27 +++++++++++++++++++++++----
3 files changed, 36 insertions(+), 10 deletions(-)
2011-05-14 Ulrich Drepper <drepper@gmail.com>
[BZ #12432]
* sysdeps/ia64/backtrace.c (struct trace_reg): Add cfa element.
(dummy_getcfa): New function.
(init): Get _Unwind_GetCFA address, use dummy if not found.
(backtrace_helper): In recursion check, also check whether CFA changes.
(__backtrace): Completely initialize arg.
diff --git a/sysdeps/ia64/backtrace.c b/sysdeps/ia64/backtrace.c
index 5cefb86..d4ff291 100644
--- a/sysdeps/ia64/backtrace.c
+++ b/sysdeps/ia64/backtrace.c
@@ -1,5 +1,5 @@
/* Return backtrace of current program state.
- Copyright (C) 2003, 2004, 2005, 2007, 2009 Free Software Foundation, Inc.
+ Copyright (C) 2003-2005, 2007, 2009, 2011 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
@@ -27,14 +27,26 @@
struct trace_arg
{
void **array;
- int cnt, size;
+ _Unwind_Word cfa;
+ int cnt;
+ int size;
};
#ifdef SHARED
static _Unwind_Reason_Code (*unwind_backtrace) (_Unwind_Trace_Fn, void *);
static _Unwind_Ptr (*unwind_getip) (struct _Unwind_Context *);
+static _Unwind_Word (*unwind_getcfa) (struct _Unwind_Context *);
static void *libgcc_handle;
+
+/* Dummy version in case libgcc_s does not contain the real code. */
+static _Unwind_Word
+dummy_getcfa (struct _Unwind_Context *ctx __attribute__ ((unused)))
+{
+ return 0;
+}
+
+
static void
init (void)
{
@@ -47,10 +59,13 @@ init (void)
unwind_getip = __libc_dlsym (libgcc_handle, "_Unwind_GetIP");
if (unwind_getip == NULL)
unwind_backtrace = NULL;
+ unwind_getcfa = (__libc_dlsym (libgcc_handle, "_Unwind_GetCFA")
+ ?: dummy_getcfa);
}
#else
# define unwind_backtrace _Unwind_Backtrace
# define unwind_getip _Unwind_GetIP
+# define unwind_getcfa _Unwind_GetCFA
#endif
static _Unwind_Reason_Code
@@ -65,8 +80,12 @@ backtrace_helper (struct _Unwind_Context *ctx, void *a)
arg->array[arg->cnt] = (void *) unwind_getip (ctx);
/* Check whether we make any progress. */
- if (arg->cnt > 0 && arg->array[arg->cnt - 1] == arg->array[arg->cnt])
+ _Unwind_Word cfa = unwind_getcfa (ctx);
+
+ if (arg->cnt > 0 && arg->array[arg->cnt - 1] == arg->array[arg->cnt]
+ && cfa == arg->cfa)
return _URC_END_OF_STACK;
+ arg->cfa = cfa;
}
if (++arg->cnt == arg->size)
return _URC_END_OF_STACK;
@@ -78,7 +97,7 @@ __backtrace (array, size)
void **array;
int size;
{
- struct trace_arg arg = { .array = array, .size = size, .cnt = -1 };
+ struct trace_arg arg = { .array = array, .cfa = 0, .size = size, .cnt = -1 };
#ifdef SHARED
__libc_once_define (static, once);
--
1.7.1

View File

@@ -0,0 +1,146 @@
diff -pruN a/nptl/sysdeps/pthread/unwind-forcedunwind.c b/nptl/sysdeps/pthread/unwind-forcedunwind.c
--- a/nptl/sysdeps/pthread/unwind-forcedunwind.c 2010-05-04 16:57:23.000000000 +0530
+++ b/nptl/sysdeps/pthread/unwind-forcedunwind.c 2014-06-02 23:00:02.901013275 +0530
@@ -45,8 +45,10 @@ pthread_cancel_init (void)
if (__builtin_expect (libgcc_s_handle != NULL, 1))
{
- /* Force gcc to reload all values. */
- asm volatile ("" ::: "memory");
+ /* Order reads so as to prevent speculation of loads
+ of libgcc_s_{resume,personality,forcedunwind,getcfa}
+ to points prior to the write barrier. */
+ atomic_read_barrier ();
return;
}
@@ -72,9 +74,14 @@ pthread_cancel_init (void)
libgcc_s_forcedunwind = forcedunwind;
PTR_MANGLE (getcfa);
libgcc_s_getcfa = getcfa;
- /* Make sure libgcc_s_handle is written last. Otherwise,
- pthread_cancel_init might return early even when the pointer the
- caller is interested in is not initialized yet. */
+ /* At the point at which any thread writes the handle
+ to libgcc_s_handle, the initialization is complete.
+ The writing of libgcc_s_handle is atomic. All other
+ threads reading libgcc_s_handle do so atomically. Any
+ thread that does not execute this function must issue
+ a read barrier to ensure that all of the above has
+ actually completed and that the values of the
+ function pointers are correct. */
atomic_write_barrier ();
libgcc_s_handle = handle;
}
@@ -91,11 +98,19 @@ __unwind_freeres (void)
}
}
-void
-_Unwind_Resume (struct _Unwind_Exception *exc)
+static __always_inline void
+_maybe_pthread_cancel_init (void)
{
if (__builtin_expect (libgcc_s_handle == NULL, 0))
pthread_cancel_init ();
+ else
+ atomic_read_barrier ();
+}
+
+void
+_Unwind_Resume (struct _Unwind_Exception *exc)
+{
+ _maybe_pthread_cancel_init ();
void (*resume) (struct _Unwind_Exception *exc) = libgcc_s_resume;
PTR_DEMANGLE (resume);
@@ -108,8 +123,7 @@ __gcc_personality_v0 (int version, _Unwi
struct _Unwind_Exception *ue_header,
struct _Unwind_Context *context)
{
- if (__builtin_expect (libgcc_s_handle == NULL, 0))
- pthread_cancel_init ();
+ _maybe_pthread_cancel_init ();
_Unwind_Reason_Code (*personality)
(int, _Unwind_Action, _Unwind_Exception_Class, struct _Unwind_Exception *,
@@ -122,8 +136,7 @@ _Unwind_Reason_Code
_Unwind_ForcedUnwind (struct _Unwind_Exception *exc, _Unwind_Stop_Fn stop,
void *stop_argument)
{
- if (__builtin_expect (libgcc_s_handle == NULL, 0))
- pthread_cancel_init ();
+ _maybe_pthread_cancel_init ();
_Unwind_Reason_Code (*forcedunwind)
(struct _Unwind_Exception *, _Unwind_Stop_Fn, void *)
@@ -135,8 +148,7 @@ _Unwind_ForcedUnwind (struct _Unwind_Exc
_Unwind_Word
_Unwind_GetCFA (struct _Unwind_Context *context)
{
- if (__builtin_expect (libgcc_s_handle == NULL, 0))
- pthread_cancel_init ();
+ _maybe_pthread_cancel_init ();
_Unwind_Word (*getcfa) (struct _Unwind_Context *) = libgcc_s_getcfa;
PTR_DEMANGLE (getcfa);
diff -pruN a/sysdeps/gnu/unwind-resume.c b/sysdeps/gnu/unwind-resume.c
--- a/sysdeps/gnu/unwind-resume.c 2010-05-04 16:57:23.000000000 +0530
+++ b/sysdeps/gnu/unwind-resume.c 2014-06-02 23:02:26.812007078 +0530
@@ -20,8 +20,11 @@
#include <dlfcn.h>
#include <stdio.h>
#include <unwind.h>
+#include <pthreadP.h>
+#include <sysdep.h>
#include <libgcc_s.h>
+static void *libgcc_s_handle;
static void (*libgcc_s_resume) (struct _Unwind_Exception *exc);
static _Unwind_Reason_Code (*libgcc_s_personality)
(int, _Unwind_Action, _Unwind_Exception_Class, struct _Unwind_Exception *,
@@ -42,13 +45,32 @@ init (void)
libgcc_s_resume = resume;
libgcc_s_personality = personality;
+ atomic_write_barrier ();
+ /* At the point at which any thread writes the handle
+ to libgcc_s_handle, the initialization is complete.
+ The writing of libgcc_s_handle is atomic. All other
+ threads reading libgcc_s_handle do so atomically. Any
+ thread that does not execute this function must issue
+ a read barrier to ensure that all of the above has
+ actually completed and that the values of the
+ function pointers are correct. */
+ libgcc_s_handle = handle;
}
+static __always_inline void
+_maybe_init (void)
+{
+ if (__builtin_expect (libgcc_s_handle == NULL, 0))
+ init ();
+ else
+ atomic_read_barrier ();
+}
+
+
void
_Unwind_Resume (struct _Unwind_Exception *exc)
{
- if (__builtin_expect (libgcc_s_resume == NULL, 0))
- init ();
+ _maybe_init ();
libgcc_s_resume (exc);
}
@@ -58,8 +80,7 @@ __gcc_personality_v0 (int version, _Unwi
struct _Unwind_Exception *ue_header,
struct _Unwind_Context *context)
{
- if (__builtin_expect (libgcc_s_personality == NULL, 0))
- init ();
+ _maybe_init ();
return libgcc_s_personality (version, actions, exception_class,
ue_header, context);
}

View File

@@ -0,0 +1,98 @@
From decadad73858bc108828eed5540c7955dc2a977b Mon Sep 17 00:00:00 2001
From: Adhemerval Zanella <azanella@linux.vnet.ibm.com>
Date: Fri, 7 Jun 2013 14:44:58 -0500
Subject: [PATCH 1/2] PowerPC: Change sched_getcpu to use vDSO getcpu instead of syscall.
Backport of d5e0b9bd6e296f3ec5263fa296d39f3fed9b8fa2 from master.
---
sysdeps/unix/sysv/linux/powerpc/Versions | 1 +
sysdeps/unix/sysv/linux/powerpc/bits/libc-vdso.h | 2 +
sysdeps/unix/sysv/linux/powerpc/init-first.c | 3 ++
sysdeps/unix/sysv/linux/powerpc/sched_getcpu.c | 30 ++++++++++++++++++++++
4 files changed, 36 insertions(+), 0 deletions(-)
create mode 100644 sysdeps/unix/sysv/linux/powerpc/sched_getcpu.c
diff --git a/sysdeps/unix/sysv/linux/powerpc/Versions b/sysdeps/unix/sysv/linux/powerpc/Versions
index 1ef53b9..396a423 100644
--- a/sysdeps/unix/sysv/linux/powerpc/Versions
+++ b/sysdeps/unix/sysv/linux/powerpc/Versions
@@ -3,5 +3,6 @@ libc {
__vdso_get_tbfreq;
__vdso_clock_gettime;
__vdso_clock_getres;
+ __vdso_getcpu;
}
}
diff --git a/sysdeps/unix/sysv/linux/powerpc/bits/libc-vdso.h b/sysdeps/unix/sysv/linux/powerpc/bits/libc-vdso.h
index 746d9ce..c3026d5 100644
--- a/sysdeps/unix/sysv/linux/powerpc/bits/libc-vdso.h
+++ b/sysdeps/unix/sysv/linux/powerpc/bits/libc-vdso.h
@@ -31,6 +31,8 @@ extern void *__vdso_clock_getres;
extern void *__vdso_get_tbfreq;
+extern void *__vdso_getcpu;
+
#endif
#endif /* _LIBC_VDSO_H */
diff --git a/sysdeps/unix/sysv/linux/powerpc/init-first.c b/sysdeps/unix/sysv/linux/powerpc/init-first.c
index 92dacc7..cfed655 100644
--- a/sysdeps/unix/sysv/linux/powerpc/init-first.c
+++ b/sysdeps/unix/sysv/linux/powerpc/init-first.c
@@ -27,6 +27,7 @@ void *__vdso_gettimeofday attribute_hidden;
void *__vdso_clock_gettime;
void *__vdso_clock_getres;
void *__vdso_get_tbfreq;
+void *__vdso_getcpu;
static inline void
@@ -41,6 +42,8 @@ _libc_vdso_platform_setup (void)
__vdso_clock_getres = _dl_vdso_vsym ("__kernel_clock_getres", &linux2615);
__vdso_get_tbfreq = _dl_vdso_vsym ("__kernel_vdso_get_tbfreq", &linux2615);
+
+ __vdso_getcpu = _dl_vdso_vsym ("__kernel_getcpu", &linux2615);
}
# define VDSO_SETUP _libc_vdso_platform_setup
diff --git a/sysdeps/unix/sysv/linux/powerpc/sched_getcpu.c b/sysdeps/unix/sysv/linux/powerpc/sched_getcpu.c
new file mode 100644
index 0000000..617e6f1
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/powerpc/sched_getcpu.c
@@ -0,0 +1,30 @@
+/* Copyright (C) 2013 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 <sched.h>
+#include <sysdep.h>
+#include <bits/libc-vdso.h>
+
+
+int
+sched_getcpu (void)
+{
+ unsigned int cpu;
+ int r = INLINE_VSYSCALL (getcpu, 3, &cpu, NULL, NULL);
+
+ return r == -1 ? r : cpu;
+}
--
1.7.1

View File

@@ -0,0 +1,279 @@
Patch attached to bugzilla by Ankit Patel, from Red Hat translation team.
Index: glibc-2.12-2-gc4ccff1/po/de.po
===================================================================
--- glibc-2.12-2-gc4ccff1.orig/po/de.po 2010-05-04 08:27:23.000000000 -0300
+++ glibc-2.12-2-gc4ccff1/po/de.po 2013-07-23 20:35:03.213177408 -0300
@@ -2396,14 +2396,14 @@ msgstr "Zu viele Benutzer"
msgid "Disk quota exceeded"
msgstr "Der zugewiesene Plattenplatz (Quota) ist überschritten"
-#. TRANS Stale NFS file handle. This indicates an internal confusion in the NFS
-#. TRANS system which is due to file system rearrangements on the server host.
-#. TRANS Repairing this condition usually requires unmounting and remounting
-#. TRANS the NFS file system on the local host.
-#: stdio-common/../sysdeps/gnu/errlist.c:779
-#: stdio-common/../sysdeps/unix/sysv/sysv4/solaris2/sparc/errlist.c:181
-msgid "Stale NFS file handle"
-msgstr "Veraltete NFS-Dateizugriffsnummer"
+#. TRANS Stale file handle. This indicates an internal confusion in the
+#. TRANS file system which is due to file system rearrangements on the server host
+#. TRANS for NFS filesystems or corruption in other filesystems.
+#. TRANS Repairing this condition usually requires unmounting, possibly
+#. TRANS repairing and remounting the file system.
+#: sysdeps/gnu/errlist.c:787
+msgid "Stale file handle"
+msgstr "Veraltetes Datei-Handle"
#. TRANS An attempt was made to NFS-mount a remote file system with a file name that
#. TRANS already specifies an NFS-mounted file.
Index: glibc-2.12-2-gc4ccff1/po/es.po
===================================================================
--- glibc-2.12-2-gc4ccff1.orig/po/es.po 2010-05-04 08:27:23.000000000 -0300
+++ glibc-2.12-2-gc4ccff1/po/es.po 2013-07-23 20:35:03.243175029 -0300
@@ -2533,14 +2533,14 @@ msgstr "Se ha excedido la cuota de disco
# Muy bien, he buscado "stale" y por lo que parece es algo que "caduca"
# o que "vence", como las letras comerciales. Me he decidido por "en desuso".
#
-#. TRANS Stale NFS file handle. This indicates an internal confusion in the NFS
-#. TRANS system which is due to file system rearrangements on the server host.
-#. TRANS Repairing this condition usually requires unmounting and remounting
-#. TRANS the NFS file system on the local host.
-#: stdio-common/../sysdeps/gnu/errlist.c:779
-#: stdio-common/../sysdeps/unix/sysv/sysv4/solaris2/sparc/errlist.c:181
-msgid "Stale NFS file handle"
-msgstr "`handle' de fichero NFS en desuso"
+#. TRANS Stale file handle. This indicates an internal confusion in the
+#. TRANS file system which is due to file system rearrangements on the server host
+#. TRANS for NFS filesystems or corruption in other filesystems.
+#. TRANS Repairing this condition usually requires unmounting, possibly
+#. TRANS repairing and remounting the file system.
+#: sysdeps/gnu/errlist.c:787
+msgid "Stale file handle"
+msgstr "Identificador de archivos obsoletos"
#. TRANS An attempt was made to NFS-mount a remote file system with a file name that
#. TRANS already specifies an NFS-mounted file.
Index: glibc-2.12-2-gc4ccff1/po/fr.po
===================================================================
--- glibc-2.12-2-gc4ccff1.orig/po/fr.po 2010-05-04 08:27:23.000000000 -0300
+++ glibc-2.12-2-gc4ccff1/po/fr.po 2013-07-23 20:35:03.250174474 -0300
@@ -5802,13 +5802,14 @@ msgstr "Trop d'usagers"
msgid "Disk quota exceeded"
msgstr "Débordement du quota d'espace disque"
-#. TRANS Stale NFS file handle. This indicates an internal confusion in the NFS
-#. TRANS system which is due to file system rearrangements on the server host.
-#. TRANS Repairing this condition usually requires unmounting and remounting
-#. TRANS the NFS file system on the local host.
+#. TRANS Stale file handle. This indicates an internal confusion in the
+#. TRANS file system which is due to file system rearrangements on the server host
+#. TRANS for NFS filesystems or corruption in other filesystems.
+#. TRANS Repairing this condition usually requires unmounting, possibly
+#. TRANS repairing and remounting the file system.
#: sysdeps/gnu/errlist.c:787
-msgid "Stale NFS file handle"
-msgstr "Panne d'accès au fichier NFS"
+msgid "Stale file handle"
+msgstr "Gestionnaire de fichiers périmés"
#. TRANS An attempt was made to NFS-mount a remote file system with a file name that
#. TRANS already specifies an NFS-mounted file.
Index: glibc-2.12-2-gc4ccff1/po/it.po
===================================================================
--- glibc-2.12-2-gc4ccff1.orig/po/it.po 2010-05-04 08:27:23.000000000 -0300
+++ glibc-2.12-2-gc4ccff1/po/it.po 2013-07-23 20:35:03.253174237 -0300
@@ -1662,6 +1662,15 @@ msgstr "Superata la quota di disco"
msgid "Disk quota exceeded"
msgstr "Superata la quota di disco"
+#. TRANS Stale file handle. This indicates an internal confusion in the
+#. TRANS file system which is due to file system rearrangements on the server host
+#. TRANS for NFS filesystems or corruption in other filesystems.
+#. TRANS Repairing this condition usually requires unmounting, possibly
+#. TRANS repairing and remounting the file system.
+#: sysdeps/gnu/errlist.c:787
+msgid "Stale file handle"
+msgstr "Gestione file obsoleti"
+
#: nscd/nscd.c:86
msgid "Do not fork and display messages on the current tty"
msgstr "Non fa fork e stampa i messaggi sul tty corrente"
Index: glibc-2.12-2-gc4ccff1/po/ja.po
===================================================================
--- glibc-2.12-2-gc4ccff1.orig/po/ja.po 2013-07-23 04:01:34.628665260 -0300
+++ glibc-2.12-2-gc4ccff1/po/ja.po 2013-07-23 20:35:03.304170193 -0300
@@ -2333,14 +2333,14 @@ msgstr "<22><EFBFBD><E6A1BC><EFBFBD><EFBFBD>¿<EFBFBD><C2BF><EFBFBD><EFBFBD><EFBFBD>ޤ<EFBFBD>"
msgid "Disk quota exceeded"
msgstr "<22>ǥ<EFBFBD><C7A5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¤<EFBFBD>Ķ<EFBFBD><EFBFBD>ޤ<EFBFBD><DEA4><EFBFBD>"
-#. TRANS Stale NFS file handle. This indicates an internal confusion in the NFS
-#. TRANS system which is due to file system rearrangements on the server host.
-#. TRANS Repairing this condition usually requires unmounting and remounting
-#. TRANS the NFS file system on the local host.
-#: stdio-common/../sysdeps/gnu/errlist.c:779
-#: stdio-common/../sysdeps/unix/sysv/sysv4/solaris2/sparc/errlist.c:181
-msgid "Stale NFS file handle"
-msgstr "<22>¸<EFBFBD><C2B8><EFBFBD><EFBFBD>Τʤ<CEA4>NFS<46>ե<EFBFBD><D5A5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϥ<EFBFBD><CFA5>ɥ<EFBFBD><C9A5>Ǥ<EFBFBD>"
+#. TRANS Stale file handle. This indicates an internal confusion in the
+#. TRANS file system which is due to file system rearrangements on the server host
+#. TRANS for NFS filesystems or corruption in other filesystems.
+#. TRANS Repairing this condition usually requires unmounting, possibly
+#. TRANS repairing and remounting the file system.
+#: sysdeps/gnu/errlist.c:787
+msgid "Stale file handle"
+msgstr "<22>Ť<EFBFBD><C5A4>ե<EFBFBD><D5A5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϥ<EFBFBD><CFA5>ɥ<EFBFBD><C9A5>Ǥ<EFBFBD>"
#. TRANS An attempt was made to NFS-mount a remote file system with a file name that
#. TRANS already specifies an NFS-mounted file.
Index: glibc-2.12-2-gc4ccff1/po/ko.po
===================================================================
--- glibc-2.12-2-gc4ccff1.orig/po/ko.po 2010-05-04 08:27:23.000000000 -0300
+++ glibc-2.12-2-gc4ccff1/po/ko.po 2013-07-23 20:35:03.311169638 -0300
@@ -5803,13 +5803,14 @@ msgstr "사용자가 너무 많음"
msgid "Disk quota exceeded"
msgstr "디스크 할당량이 초과됨"
-#. TRANS Stale NFS file handle. This indicates an internal confusion in the NFS
-#. TRANS system which is due to file system rearrangements on the server host.
-#. TRANS Repairing this condition usually requires unmounting and remounting
-#. TRANS the NFS file system on the local host.
+#. TRANS Stale file handle. This indicates an internal confusion in the
+#. TRANS file system which is due to file system rearrangements on the server host
+#. TRANS for NFS filesystems or corruption in other filesystems.
+#. TRANS Repairing this condition usually requires unmounting, possibly
+#. TRANS repairing and remounting the file system.
#: sysdeps/gnu/errlist.c:787
-msgid "Stale NFS file handle"
-msgstr "끊어진 NFS 파일 핸들"
+msgid "Stale file handle"
+msgstr "오래된 파일 처리"
#. TRANS An attempt was made to NFS-mount a remote file system with a file name that
#. TRANS already specifies an NFS-mounted file.
Index: glibc-2.12-2-gc4ccff1/po/libc.pot
===================================================================
--- glibc-2.12-2-gc4ccff1.orig/po/libc.pot 2010-05-04 08:27:23.000000000 -0300
+++ glibc-2.12-2-gc4ccff1/po/libc.pot 2013-07-23 20:35:03.326168449 -0300
@@ -5696,12 +5696,13 @@ msgstr ""
msgid "Disk quota exceeded"
msgstr ""
-#. TRANS Stale NFS file handle. This indicates an internal confusion in the NFS
-#. TRANS system which is due to file system rearrangements on the server host.
-#. TRANS Repairing this condition usually requires unmounting and remounting
-#. TRANS the NFS file system on the local host.
+#. TRANS Stale file handle. This indicates an internal confusion in the
+#. TRANS file system which is due to file system rearrangements on the server host
+#. TRANS for NFS filesystems or corruption in other filesystems.
+#. TRANS Repairing this condition usually requires unmounting, possibly
+#. TRANS repairing and remounting the file system.
#: sysdeps/gnu/errlist.c:787
-msgid "Stale NFS file handle"
+msgid "Stale file handle"
msgstr ""
#. TRANS An attempt was made to NFS-mount a remote file system with a file name that
Index: glibc-2.12-2-gc4ccff1/po/pt_BR.po
===================================================================
--- glibc-2.12-2-gc4ccff1.orig/po/pt_BR.po 2010-05-04 08:27:23.000000000 -0300
+++ glibc-2.12-2-gc4ccff1/po/pt_BR.po 2013-07-23 20:35:03.331168053 -0300
@@ -2287,13 +2287,14 @@ msgstr "Erro de Srmount"
msgid "Stack fault"
msgstr "Falha de pilha"
-#. TRANS Stale NFS file handle. This indicates an internal confusion in the NFS
-#. TRANS system which is due to file system rearrangements on the server host.
-#. TRANS Repairing this condition usually requires unmounting and remounting
-#. TRANS the NFS file system on the local host.
-#: stdio-common/../sysdeps/gnu/errlist.c:506
-msgid "Stale NFS file handle"
-msgstr "Manipulador de arquivo NFS corrompido"
+#. TRANS Stale file handle. This indicates an internal confusion in the
+#. TRANS file system which is due to file system rearrangements on the server host
+#. TRANS for NFS filesystems or corruption in other filesystems.
+#. TRANS Repairing this condition usually requires unmounting, possibly
+#. TRANS repairing and remounting the file system.
+#: sysdeps/gnu/errlist.c:787
+msgid "Stale file handle"
+msgstr "Manipulador de arquivo obsoleto"
#: nscd/nscd.c:81
msgid "Start NUMBER threads"
Index: glibc-2.12-2-gc4ccff1/po/ru.po
===================================================================
--- glibc-2.12-2-gc4ccff1.orig/po/ru.po 2010-05-04 08:27:23.000000000 -0300
+++ glibc-2.12-2-gc4ccff1/po/ru.po 2013-07-23 20:35:03.338167498 -0300
@@ -5798,13 +5798,14 @@ msgstr "Слишком много пол
msgid "Disk quota exceeded"
msgstr "Превышена дисковая квота"
-#. TRANS Stale NFS file handle. This indicates an internal confusion in the NFS
-#. TRANS system which is due to file system rearrangements on the server host.
-#. TRANS Repairing this condition usually requires unmounting and remounting
-#. TRANS the NFS file system on the local host.
+#. TRANS Stale file handle. This indicates an internal confusion in the
+#. TRANS file system which is due to file system rearrangements on the server host
+#. TRANS for NFS filesystems or corruption in other filesystems.
+#. TRANS Repairing this condition usually requires unmounting, possibly
+#. TRANS repairing and remounting the file system.
#: sysdeps/gnu/errlist.c:787
-msgid "Stale NFS file handle"
-msgstr "Устаревший хэндл файла NFS"
+msgid "Stale file handle"
+msgstr "Устаревший дескриптор файла"
#. TRANS An attempt was made to NFS-mount a remote file system with a file name that
#. TRANS already specifies an NFS-mounted file.
Index: glibc-2.12-2-gc4ccff1/po/zh_CN.po
===================================================================
--- glibc-2.12-2-gc4ccff1.orig/po/zh_CN.po 2010-05-04 08:27:23.000000000 -0300
+++ glibc-2.12-2-gc4ccff1/po/zh_CN.po 2013-07-23 20:35:03.344167022 -0300
@@ -5519,13 +5519,14 @@ msgstr "用户过多"
msgid "Disk quota exceeded"
msgstr "超出磁盘限额"
-#. TRANS Stale NFS file handle. This indicates an internal confusion in the NFS
-#. TRANS system which is due to file system rearrangements on the server host.
-#. TRANS Repairing this condition usually requires unmounting and remounting
-#. TRANS the NFS file system on the local host.
+#. TRANS Stale file handle. This indicates an internal confusion in the
+#. TRANS file system which is due to file system rearrangements on the server host
+#. TRANS for NFS filesystems or corruption in other filesystems.
+#. TRANS Repairing this condition usually requires unmounting, possibly
+#. TRANS repairing and remounting the file system.
#: sysdeps/gnu/errlist.c:787
-msgid "Stale NFS file handle"
-msgstr ""
+msgid "Stale file handle"
+msgstr "失效文件句柄"
#. TRANS An attempt was made to NFS-mount a remote file system with a file name that
#. TRANS already specifies an NFS-mounted file.
Index: glibc-2.12-2-gc4ccff1/po/zh_TW.po
===================================================================
--- glibc-2.12-2-gc4ccff1.orig/po/zh_TW.po 2010-05-04 08:27:23.000000000 -0300
+++ glibc-2.12-2-gc4ccff1/po/zh_TW.po 2013-07-23 20:35:03.349166626 -0300
@@ -2333,14 +2333,14 @@ msgstr "太多使用者"
msgid "Disk quota exceeded"
msgstr "硬碟 quota 滿了"
-#. TRANS Stale NFS file handle. This indicates an internal confusion in the NFS
-#. TRANS system which is due to file system rearrangements on the server host.
-#. TRANS Repairing this condition usually requires unmounting and remounting
-#. TRANS the NFS file system on the local host.
-#: stdio-common/../sysdeps/gnu/errlist.c:779
-#: stdio-common/../sysdeps/unix/sysv/sysv4/solaris2/sparc/errlist.c:181
-msgid "Stale NFS file handle"
-msgstr "過舊的 NFS 檔案控制碼"
+#. TRANS Stale file handle. This indicates an internal confusion in the
+#. TRANS file system which is due to file system rearrangements on the server host
+#. TRANS for NFS filesystems or corruption in other filesystems.
+#. TRANS Repairing this condition usually requires unmounting, possibly
+#. TRANS repairing and remounting the file system.
+#: sysdeps/gnu/errlist.c:787
+msgid "Stale file handle"
+msgstr "過舊的檔案處理"
#. TRANS An attempt was made to NFS-mount a remote file system with a file name that
#. TRANS already specifies an NFS-mounted file.

View File

@@ -0,0 +1,124 @@
#
# Based on commit e6c61494125126d2ba77e5d99f83887a2ed49783.
#
# 2011-04-10 Ulrich Drepper <drepper@gmail.com>
#
# [BZ #12650]
# * sysdeps/i386/dl-tls.h: Define TLS_DTV_UNALLOCATED.
# * sysdeps/ia64/dl-tls.h: Likewise.
# * sysdeps/powerpc/dl-tls.h: Likewise.
# * sysdeps/s390/dl-tls.h: Likewise.
# * sysdeps/sh/dl-tls.h: Likewise.
# * sysdeps/sparc/dl-tls.h: Likewise.
# * sysdeps/x86_64/dl-tls.h: Likewise.
# * elf/dl-tls.c: Don't define TLS_DTV_UNALLOCATED here.
#
diff -urN glibc-2.12-2-gc4ccff1/elf/dl-tls.c glibc-2.12-2-gc4ccff1.mod/elf/dl-tls.c
--- glibc-2.12-2-gc4ccff1/elf/dl-tls.c 2015-02-18 05:16:56.087096028 -0500
+++ glibc-2.12-2-gc4ccff1.mod/elf/dl-tls.c 2015-02-18 05:21:04.018424445 -0500
@@ -33,9 +33,6 @@
to allow dynamic loading of modules defining IE-model TLS data. */
#define TLS_STATIC_SURPLUS 64 + DL_NNS * 100
-/* Value used for dtv entries for which the allocation is delayed. */
-#define TLS_DTV_UNALLOCATED ((void *) -1l)
-
/* Out-of-memory handler. */
#ifdef SHARED
diff -urN glibc-2.12-2-gc4ccff1/nptl/allocatestack.c glibc-2.12-2-gc4ccff1.mod/nptl/allocatestack.c
--- glibc-2.12-2-gc4ccff1/nptl/allocatestack.c 2015-02-18 05:16:56.101095594 -0500
+++ glibc-2.12-2-gc4ccff1.mod/nptl/allocatestack.c 2015-02-18 05:21:04.019424414 -0500
@@ -26,6 +26,7 @@
#include <sys/mman.h>
#include <sys/param.h>
#include <dl-sysdep.h>
+#include <dl-tls.h>
#include <tls.h>
#include <list.h>
#include <lowlevellock.h>
@@ -242,6 +243,10 @@
/* Clear the DTV. */
dtv_t *dtv = GET_DTV (TLS_TPADJ (result));
+ for (size_t cnt = 0; cnt < dtv[-1].counter; ++cnt)
+ if (! dtv[1 + cnt].pointer.is_static
+ && dtv[1 + cnt].pointer.val != TLS_DTV_UNALLOCATED)
+ free (dtv[1 + cnt].pointer.val);
memset (dtv, '\0', (dtv[-1].counter + 1) * sizeof (dtv_t));
/* Re-initialize the TLS. */
diff -urN glibc-2.12-2-gc4ccff1/sysdeps/i386/dl-tls.h glibc-2.12-2-gc4ccff1.mod/sysdeps/i386/dl-tls.h
--- glibc-2.12-2-gc4ccff1/sysdeps/i386/dl-tls.h 2010-05-04 07:27:23.000000000 -0400
+++ glibc-2.12-2-gc4ccff1.mod/sysdeps/i386/dl-tls.h 2015-02-18 05:21:04.019424414 -0500
@@ -58,3 +58,6 @@
# endif
#endif
+
+/* Value used for dtv entries for which the allocation is delayed. */
+#define TLS_DTV_UNALLOCATED ((void *) -1l)
diff -urN glibc-2.12-2-gc4ccff1/sysdeps/ia64/dl-tls.h glibc-2.12-2-gc4ccff1.mod/sysdeps/ia64/dl-tls.h
--- glibc-2.12-2-gc4ccff1/sysdeps/ia64/dl-tls.h 2010-05-04 07:27:23.000000000 -0400
+++ glibc-2.12-2-gc4ccff1.mod/sysdeps/ia64/dl-tls.h 2015-02-18 05:21:04.019424414 -0500
@@ -28,3 +28,6 @@
#define DONT_USE_TLS_INDEX 1
extern void *__tls_get_addr (size_t m, size_t offset);
+
+/* Value used for dtv entries for which the allocation is delayed. */
+#define TLS_DTV_UNALLOCATED ((void *) -1l)
diff -urN glibc-2.12-2-gc4ccff1/sysdeps/powerpc/dl-tls.h glibc-2.12-2-gc4ccff1.mod/sysdeps/powerpc/dl-tls.h
--- glibc-2.12-2-gc4ccff1/sysdeps/powerpc/dl-tls.h 2010-05-04 07:27:23.000000000 -0400
+++ glibc-2.12-2-gc4ccff1.mod/sysdeps/powerpc/dl-tls.h 2015-02-18 05:21:04.019424414 -0500
@@ -47,3 +47,6 @@
# define GET_ADDR_OFFSET (ti->ti_offset + TLS_DTV_OFFSET)
# define __TLS_GET_ADDR(__ti) (__tls_get_addr (__ti) - TLS_DTV_OFFSET)
#endif
+
+/* Value used for dtv entries for which the allocation is delayed. */
+#define TLS_DTV_UNALLOCATED ((void *) -1l)
diff -urN glibc-2.12-2-gc4ccff1/sysdeps/s390/dl-tls.h glibc-2.12-2-gc4ccff1.mod/sysdeps/s390/dl-tls.h
--- glibc-2.12-2-gc4ccff1/sysdeps/s390/dl-tls.h 2010-05-04 07:27:23.000000000 -0400
+++ glibc-2.12-2-gc4ccff1.mod/sysdeps/s390/dl-tls.h 2015-02-18 05:21:04.019424414 -0500
@@ -72,6 +72,9 @@
# define __TLS_GET_ADDR(__ti) \
({ extern char _GLOBAL_OFFSET_TABLE_[] attribute_hidden; \
(void *) __tls_get_offset ((char *) (__ti) - _GLOBAL_OFFSET_TABLE_) \
- + (unsigned long) __builtin_thread_pointer (); })
+ + (unsigned long) __builtin_thread_pointer (); })
#endif
+
+/* Value used for dtv entries for which the allocation is delayed. */
+#define TLS_DTV_UNALLOCATED ((void *) -1l)
diff -urN glibc-2.12-2-gc4ccff1/sysdeps/sh/dl-tls.h glibc-2.12-2-gc4ccff1.mod/sysdeps/sh/dl-tls.h
--- glibc-2.12-2-gc4ccff1/sysdeps/sh/dl-tls.h 2010-05-04 07:27:23.000000000 -0400
+++ glibc-2.12-2-gc4ccff1.mod/sysdeps/sh/dl-tls.h 2015-02-18 05:21:04.019424414 -0500
@@ -27,3 +27,6 @@
extern void *__tls_get_addr (tls_index *ti);
+
+/* Value used for dtv entries for which the allocation is delayed. */
+#define TLS_DTV_UNALLOCATED ((void *) -1l)
diff -urN glibc-2.12-2-gc4ccff1/sysdeps/sparc/dl-tls.h glibc-2.12-2-gc4ccff1.mod/sysdeps/sparc/dl-tls.h
--- glibc-2.12-2-gc4ccff1/sysdeps/sparc/dl-tls.h 2010-05-04 07:27:23.000000000 -0400
+++ glibc-2.12-2-gc4ccff1.mod/sysdeps/sparc/dl-tls.h 2015-02-18 05:21:04.019424414 -0500
@@ -27,3 +27,6 @@
extern void *__tls_get_addr (tls_index *ti);
+
+/* Value used for dtv entries for which the allocation is delayed. */
+#define TLS_DTV_UNALLOCATED ((void *) -1l)
diff -urN glibc-2.12-2-gc4ccff1/sysdeps/x86_64/dl-tls.h glibc-2.12-2-gc4ccff1.mod/sysdeps/x86_64/dl-tls.h
--- glibc-2.12-2-gc4ccff1/sysdeps/x86_64/dl-tls.h 2010-05-04 07:27:23.000000000 -0400
+++ glibc-2.12-2-gc4ccff1.mod/sysdeps/x86_64/dl-tls.h 2015-02-18 05:21:04.019424414 -0500
@@ -27,3 +27,6 @@
extern void *__tls_get_addr (tls_index *ti);
+
+/* Value used for dtv entries for which the allocation is delayed. */
+#define TLS_DTV_UNALLOCATED ((void *) -1l)

View File

@@ -0,0 +1,22 @@
commit 2e96f1c73b06e81da59ef7fffa426dc201875f31
Author: Andreas Schwab <schwab@redhat.com>
Date: Thu Aug 4 15:42:10 2011 -0400
Fix encoding name for IDN in getaddrinfo
diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
index 6d574c5..a5aafe9 100644
--- a/sysdeps/posix/getaddrinfo.c
+++ b/sysdeps/posix/getaddrinfo.c
@@ -432,7 +432,10 @@ gaih_inet (const char *name, const struct gaih_service *service,
/* In case the output string is the same as the input string
no new string has been allocated. */
if (p != name)
- malloc_name = true;
+ {
+ name = p;
+ malloc_name = true;
+ }
}
#endif

View File

@@ -0,0 +1,33 @@
commit e23fe25b33324a9ea992276c1a4f04127bf9ba4b
Author: Andreas Schwab <schwab@redhat.com>
Date: Sun Feb 20 07:24:56 2011 -0500
Move setting variable in relro data earlier in ld.so.
diff --git a/elf/rtld.c b/elf/rtld.c
index 8510380..174954b 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -2179,6 +2179,10 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
we need it in the memory handling later. */
GLRO(dl_initial_searchlist) = *GL(dl_ns)[LM_ID_BASE]._ns_main_searchlist;
+ /* Remember the last search directory added at startup, now that
+ malloc will no longer be the one from dl-minimal.c. */
+ GLRO(dl_init_all_dirs) = GL(dl_all_dirs);
+
if (prelinked)
{
if (main_map->l_info [ADDRIDX (DT_GNU_CONFLICT)] != NULL)
@@ -2298,9 +2302,8 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
lossage);
}
- /* Remember the last search directory added at startup, now that
- malloc will no longer be the one from dl-minimal.c. */
- GLRO(dl_init_all_dirs) = GL(dl_all_dirs);
+ /* Make sure no new search directories have been added. */
+ assert (GLRO(dl_init_all_dirs) == GL(dl_all_dirs));
if (! prelinked && rtld_multiple_ref)
{