Index: uspace/drv/time/cmos-rtc/cmos-rtc.c
===================================================================
--- uspace/drv/time/cmos-rtc/cmos-rtc.c	(revision a8a0d43569cffc3f37bdb2d40073470acce08a26)
+++ uspace/drv/time/cmos-rtc/cmos-rtc.c	(revision 80d3f846b70c4427d3fee6bae79e385976a7ff1c)
@@ -92,5 +92,7 @@
 static int rtc_tm_sanity_check(struct tm *t);
 static void rtc_register_write(rtc_t *rtc, int reg, int data);
-
+static bool is_leap_year(int year);
+
+static int days_month[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
 
 static ddf_dev_ops_t rtc_dev_ops;
@@ -429,4 +431,6 @@
 rtc_tm_sanity_check(struct tm *t)
 {
+	int ndays;
+
 	if (t->tm_sec < 0 || t->tm_sec > 59)
 		return EINVAL;
@@ -442,6 +446,34 @@
 		return EINVAL;
 
-	/* XXX Some months have less than 31 days... */
+	if (t->tm_mon == 1/* FEB */ && is_leap_year(t->tm_year))
+		ndays = 29;
+	else
+		ndays = days_month[t->tm_mon];
+
+	if (t->tm_mday > ndays)
+		return EINVAL;
+
 	return EOK;
+}
+
+/** Check if a year is a leap year
+ *
+ * @param year   The year to check
+ *
+ * @return       true if it is a leap year, false otherwise
+ */
+static bool
+is_leap_year(int year)
+{
+	bool r = false;
+
+	if (year % 4 == 0) {
+		if (year % 100 == 0)
+			r = year % 400 == 0;
+		else
+			r = true;
+	}
+
+	return r;
 }
 
