diff -u pam-1.1.2/debian/changelog pam-1.1.2/debian/changelog --- pam-1.1.2/debian/changelog +++ pam-1.1.2/debian/changelog @@ -1,3 +1,11 @@ +pam (1.1.2-2ubuntu7~kees1) natty; urgency=low + + * debian/patches-applied/parse-kernel-rlimits.patch: actually parse the + kernel default rlimits instead of using internal defaults. Fall back + to internals for unknown rlimits. (LP: #746655, #391761) + + -- Kees Cook Thu, 31 Mar 2011 12:27:38 -0700 + pam (1.1.2-2ubuntu6) natty; urgency=low * debian/libpam0g.postinst: according to Kubuntu developers, kdm no longer diff -u pam-1.1.2/debian/control pam-1.1.2/debian/control --- pam-1.1.2/debian/control +++ pam-1.1.2/debian/control @@ -2,7 +2,7 @@ Section: libs Priority: optional Uploaders: Sam Hartman , Roger Leigh -Maintainer: Ubuntu Core Developers +Maintainer: Ubuntu Developers XSBC-Original-Maintainer: Steve Langasek Standards-Version: 3.9.1 Build-Depends: libcrack2-dev (>= 2.8), bzip2, debhelper (>= 8.1.2ubuntu3), quilt (>= 0.48-1), flex, libdb-dev, libselinux1-dev [!hurd-i386 !kfreebsd-i386 !kfreebsd-amd64 !netbsd-i386], po-debconf diff -u pam-1.1.2/debian/patches-applied/series pam-1.1.2/debian/patches-applied/series --- pam-1.1.2/debian/patches-applied/series +++ pam-1.1.2/debian/patches-applied/series @@ -27,0 +28 @@ +parse-kernel-rlimits.patch only in patch2: unchanged: --- pam-1.1.2.orig/debian/patches-applied/parse-kernel-rlimits.patch +++ pam-1.1.2/debian/patches-applied/parse-kernel-rlimits.patch @@ -0,0 +1,206 @@ +Description: Since the kernel sets a number of dynamic rlimits based on the + system properities (e.g. physical memory for nproc), these rlimits should + be respected by PAM. Parse /proc/1/limits for the kernel-defined rlimits. +Author: Kees Cook +Bug-Ubuntu: https://launchpad.net/bugs/746655 + +Index: pam-1.1.2/modules/pam_limits/pam_limits.c +=================================================================== +--- pam-1.1.2.orig/modules/pam_limits/pam_limits.c 2011-03-31 12:33:35.965260935 -0700 ++++ pam-1.1.2/modules/pam_limits/pam_limits.c 2011-03-31 12:35:50.057084000 -0700 +@@ -55,9 +55,10 @@ + #define LIMITS_DEF_USER 0 /* limit was set by an user entry */ + #define LIMITS_DEF_GROUP 1 /* limit was set by a group entry */ + #define LIMITS_DEF_ALLGROUP 2 /* limit was set by a group entry */ +-#define LIMITS_DEF_ALL 3 /* limit was set by an default entry */ +-#define LIMITS_DEF_DEFAULT 4 /* limit was set by an default entry */ +-#define LIMITS_DEF_NONE 5 /* this limit was not set yet */ ++#define LIMITS_DEF_ALL 3 /* limit was set by an all entry */ ++#define LIMITS_DEF_DEFAULT 4 /* limit was set by an internal default entry */ ++#define LIMITS_DEF_KERNEL 5 /* limit was set from /proc/1/limits */ ++#define LIMITS_DEF_NONE 6 /* this limit was not set yet */ + + static const char *limits_def_names[] = { + "USER", +@@ -65,6 +66,7 @@ + "ALLGROUP", + "ALL", + "DEFAULT", ++ "KERNEL", + "NONE", + NULL + }; +@@ -296,7 +298,139 @@ + return 0; + } + +-static int init_limits(struct pam_limit_s *pl) ++static const char * lnames[RLIM_NLIMITS] = { ++ [RLIMIT_CPU] = "Max cpu time", ++ [RLIMIT_FSIZE] = "Max file size", ++ [RLIMIT_DATA] = "Max data size", ++ [RLIMIT_STACK] = "Max stack size", ++ [RLIMIT_CORE] = "Max core file size", ++ [RLIMIT_RSS] = "Max resident set", ++ [RLIMIT_NPROC] = "Max processes", ++ [RLIMIT_NOFILE] = "Max open files", ++ [RLIMIT_MEMLOCK] = "Max locked memory", ++#ifdef RLIMIT_AS ++ [RLIMIT_AS] = "Max address space", ++#endif ++#ifdef RLIMIT_LOCKS ++ [RLIMIT_LOCKS] = "Max file locks", ++#endif ++#ifdef RLIMIT_SIGPENDING ++ [RLIMIT_SIGPENDING] = "Max pending signals", ++#endif ++#ifdef RLIMIT_MSGQUEUE ++ [RLIMIT_MSGQUEUE] = "Max msgqueue size", ++#endif ++#ifdef RLIMIT_NICE ++ [RLIMIT_NICE] = "Max nice priority", ++#endif ++#ifdef RLIMIT_RTPRIO ++ [RLIMIT_RTPRIO] = "Max realtime priority", ++#endif ++#ifdef RLIMIT_RTTIME ++ [RLIMIT_RTTIME] = "Max realtime timeout", ++#endif ++}; ++ ++static int str2rlimit(char *name) { ++ int i; ++ if (!name || *name == '\0') ++ return -1; ++ for(i = 0; i < RLIM_NLIMITS; i++) { ++ if (strcmp(name, lnames[i]) == 0) return i; ++ } ++ return -1; ++} ++ ++static rlim_t str2rlim_t(char *value) { ++ unsigned long long rlimit = 0; ++ ++ if (!value) return (rlim_t)rlimit; ++ if (strcmp(value, "unlimited") == 0) { ++ return RLIM_INFINITY; ++ } ++ rlimit = strtoull(value, NULL, 10); ++ return (rlim_t)rlimit; ++} ++ ++#define LIMITS_SKIP_WHITESPACE { \ ++ /* step backwards over spaces */ \ ++ pos--; \ ++ while (pos && line[pos] == ' ') pos--; \ ++ if (!pos) continue; \ ++ line[pos+1] = '\0'; \ ++} ++#define LIMITS_MARK_ITEM(item) { \ ++ /* step backwards over non-spaces */ \ ++ pos--; \ ++ while (pos && line[pos] != ' ') pos--; \ ++ if (!pos) continue; \ ++ item = line + pos + 1; \ ++} ++ ++static void parse_kernel_limits(pam_handle_t *pamh, struct pam_limit_s *pl) ++{ ++ int i, maxlen = 0; ++ FILE *limitsfile; ++ const char *proclimits = "/proc/1/limits"; ++ char line[256]; ++ char *units, *hard, *soft, *name; ++ ++ if (!(limitsfile = fopen(proclimits, "r"))) { ++ pam_syslog(pamh, LOG_WARNING, "Could not read %s (%s), using PAM internal defaults", proclimits, strerror(errno)); ++ return; ++ } ++ ++ while (fgets(line, 256, limitsfile)) { ++ int pos = strlen(line); ++ if (pos < 2) continue; ++ ++ /* drop trailing newline */ ++ if (line[pos-1] == '\n') { ++ pos--; ++ line[pos] = '\0'; ++ } ++ ++ /* determine formatting boundry of limits report */ ++ if (!maxlen && strncmp(line, "Limit", 5) == 0) { ++ maxlen = pos; ++ continue; ++ } ++ ++ if (pos == maxlen) { ++ /* step backwards over "Units" name */ ++ LIMITS_SKIP_WHITESPACE; ++ LIMITS_MARK_ITEM(units); ++ } ++ else { ++ units = ""; ++ } ++ ++ /* step backwards over "Hard Limit" value */ ++ LIMITS_SKIP_WHITESPACE; ++ LIMITS_MARK_ITEM(hard); ++ ++ /* step backwards over "Soft Limit" value */ ++ LIMITS_SKIP_WHITESPACE; ++ LIMITS_MARK_ITEM(soft); ++ ++ /* step backwards over name of limit */ ++ LIMITS_SKIP_WHITESPACE; ++ name = line; ++ ++ i = str2rlimit(name); ++ if (i < 0 || i >= RLIM_NLIMITS) { ++ pam_syslog(pamh, LOG_DEBUG, "Unknown kernel rlimit '%s' ignored", name); ++ continue; ++ } ++ pl->limits[i].limit.rlim_cur = str2rlim_t(soft); ++ pl->limits[i].limit.rlim_max = str2rlim_t(hard); ++ pl->limits[i].src_soft = LIMITS_DEF_KERNEL; ++ pl->limits[i].src_hard = LIMITS_DEF_KERNEL; ++ } ++ fclose(limitsfile); ++} ++ ++static int init_limits(pam_handle_t *pamh, struct pam_limit_s *pl) + { + int i; + int retval = PAM_SUCCESS; +@@ -321,6 +455,23 @@ + } + } else { + pl->limits[i].supported = 1; ++ pl->limits[i].src_soft = LIMITS_DEF_NONE; ++ pl->limits[i].src_hard = LIMITS_DEF_NONE; ++ } ++ } ++ ++#ifdef __linux__ ++ parse_kernel_limits(pamh, pl); ++#endif ++ ++ for(i = 0; i < RLIM_NLIMITS; i++) { ++ if (pl->limits[i].supported && ++ (pl->limits[i].src_soft == LIMITS_DEF_NONE || ++ pl->limits[i].src_hard == LIMITS_DEF_NONE)) { ++#ifdef __linux__ ++ pam_syslog(pamh, LOG_WARNING, "Did not find kernel RLIMIT for %s, using PAM internal default", rlimit2str(i)); ++#endif ++ + pl->limits[i].src_soft = LIMITS_DEF_DEFAULT; + pl->limits[i].src_hard = LIMITS_DEF_DEFAULT; + switch(i) { +@@ -829,7 +980,7 @@ + return PAM_USER_UNKNOWN; + } + +- retval = init_limits(pl); ++ retval = init_limits(pamh, pl); + if (retval != PAM_SUCCESS) { + pam_syslog(pamh, LOG_WARNING, "cannot initialize"); + return PAM_ABORT;