#define EXIT_EPERM 18
#define EXIT_ENOPROTOOPT 19
#define EXIT_EPROTONOSUPPORT 20
+#define EXIT_EACCESS 21
#define _U_ __attribute__((__unused__))
sd = socket(family, SOCK_DGRAM, protocol);
if (sd < 0)
- err(EXIT_FAILURE,
+ err((errno == EACCES? EXIT_EACCESS: EXIT_FAILURE),
"failed to make an icmp socket");
if (sd != fdescs[0].fd) {
int e = errno;
close(sd);
errno = e;
- err(EXIT_FAILURE, "failed in bind(2)");
+ err((errno == EACCES? EXIT_EACCESS: EXIT_FAILURE),
+ "failed in bind(2)");
}
}
ts_skip_nonroot
+. "$TS_SELF"/lsfd-functions.bash
+
ts_check_test_command "$TS_CMD_LSFD"
ts_check_test_command "$TS_HELPER_MKFDS"
+ts_check_prog "id"
+
ts_check_native_byteorder
ts_cd "$TS_OUTDIR"
)
ID=9999
+range_check()
+{
+ local v=$1
+ local min=$2
+ local max=$3
+
+ [[ $min -le $v && $v -le $max ]]
+ return $?
+}
+
+ping_group_range_check()
+{
+ local g
+ local group_min group_max
+
+ if ! read group_min group_max < /proc/sys/net/ipv4/ping_group_range; then
+ # We can say nothing. Just allow to go ahead.
+ return 0
+ fi
+
+ if [[ -z "$group_min" || -z "$group_max" ]]; then
+ # We can say nothing. Just allow to go ahead.
+ return 0
+ fi
+
+ for g in $(id -G); do
+ if range_check "$g" "$group_min" "$group_max"; then
+ return 0
+ fi
+ done
+
+ return 1
+}
+
+ERRMSG=
for i in 0 1; do
- if ! "$TS_HELPER_MKFDS" -c -q "${FACTORY[$i]}" 3 id=$ID; then
- ts_skip "making ${TYPE[$i]} socket with specifying id is failed (blocked by SELinux?)"
+ ERRMSG=$("$TS_HELPER_MKFDS" -c -q "${FACTORY[$i]}" 3 id=$ID 2>&1)
+ ERR="$?"
+ if [[ "$ERR" == "$EACCESS" ]]; then
+ case "$ERRMSG" in
+ *bind*)
+ MSG="making ${TYPE[$i]} socket with specifying id is not allowed (blocked by SELinux?)"
+ ;;
+ *socket*)
+ if ! ping_group_range_check; then
+ MSG="the group(s) ($(id -G)) of the process is not in the expected range"
+ MSG+=" [$(cat /proc/sys/net/ipv4/ping_group_range)])"
+ else
+ MSG="$ERRMSG"
+ fi
+ ;;
+ *)
+ MSG="$ERRMSG"
+ ;;
+ esac
+ ts_skip "${MSG}"
+ elif [[ "$ERR" != 0 ]]; then
+ ts_skip "making ${TYPE[$i]} socket is failed ($ERR: $ERRMSG)"
fi
done